CmsWing源码分析(五)

2021SC@SDUSC


此次接着分析文件 src/controller/admin/model.js
该文件中的方法为模型操作,在整个项目中有着举足轻重的地位。

一、editextAction()

此方法用于编辑独立模型。

如果请求加载了数据,获取post的数据,并设置数据的更新时间。如果获取的数据 post.attribute_list 为数组,那么将它作为字符串返回,数组中的元素由分隔符“,”分隔。
变量res用于确定数据是否成功更新到数据库中。若更新成功,那么将模型添加到钩子里并更新钩子。之后生成或更新配置文件,更新缓存,告知系统更新模型成功。

如果没有请求加载数据,获取id,并依照id在数据库中查找单条数据,赋值给data。若data的attribute_list不为空,那么我们将 attribute_list 依照“,”分割成字符串数组。
实例化模型 attribute ,查找 model_id = data.id 、字段限制为id,name,title,is_show 的多条数据,并将得到的数据赋值给 fields 。
判断 data 是否继承了其他模型。若继承了其他模型,则获取相应数据赋值给 extend_field ,并将 extend_field 与 fields 合并赋值给 allfields ;否则将 fields 赋值给 allfields 。
使用 JSON.parse() 方法将 data.field_sort 转换为JavaScript对象,并赋值给 field_sort。
最后,将变量 fields,extend_fields,orderbgy,data 中的值分配给模型字段 ‘fields’, ‘extend_fields’, ‘allfields’, ‘info’ ,方法结束并返回。

到这里可以发现,这里的编辑独立模型方法和前一篇中的编辑模型方法逻辑基本一致,只是多了与钩子相关的一些方法。关于钩子的具体分析,可以在同组同学的博客中找到,在此不再赘述。

async editextAction() {
    if (this.isPost) {
      const post = this.post();
      post.ismod = 1;
      post.update_time = new Date().valueOf();
      if (think.isArray(post.attribute_list)) {
        post.attribute_list = post.attribute_list.join(',');
      }
      console.log(post);
      if (!think.isEmpty(post.hooks) && think.isArray(post.hooks)) {
        post.hooks = post.hooks.join(',');
      }
      const res = await this.db.update(post);
      if (res) {
        if (!think.isEmpty(post.hooks)) {
          for (const h of post.hooks.split(',')) {
            const hooks = await this.model('hooks').where({name: h}).find();
            let extarr = hooks.ext ? hooks.ext.split(',') : [];
            extarr.push(post.name);
            extarr = think._.uniq(extarr);
            await this.model('hooks').where({name: h}).update({ext: extarr.join(',')});
          }
        }
        const configs = await this.model('model').fieldReverse('id').find(post.id);
        const moddir = `${think.APP_PATH}/controller/mod`;
        const modpath = `${moddir}/${configs.name}`;
        fs.writeFileSync(`${modpath}/config.js`, `module.exports = ${JSON.stringify(configs)}`);
        await update_cache('model');
        return this.success({name: '更新模型成功!', url: '/admin/model/ext'});
      }
    } else {
      const id = this.get('id');
      let allfields;
      if (think.isEmpty(id)) {
        this.fail('参数不能为空!');
      }
      const data = await this.db.find(id);
      data.attribute_list = think.isEmpty(data.attribute_list) ? '' : data.attribute_list.split(',');
      const fields = await this.model('attribute').where({model_id: data.id}).field('id,name,title,is_show').select();
      if (data.extend != 0) {
        var extend_fields = await this.model('attribute').where({model_id: data.extend}).field('id,name,title,is_show').select();
        allfields = fields.concat(extend_fields);
      } else {
        allfields = fields;
      }
      for (const field of allfields) {
        if (!think.isEmpty(data.attribute_list) && !in_array(field.id, data.attribute_list)) {
          field.is_show = 0;
        }
      var obj = {};
      if (allfields) {
        for (const v of allfields) {
          obj[v.id] = v;
        }
      } else {
        for (const v of fields) {
          obj[v.id] = v;
        }
      }
      const field_sort = JSON.parse(data.field_sort);
      if (!think.isEmpty(field_sort)) {
        for (const group in field_sort) {
          field_sort[group].forEach((v, k) => {
            if (obj[v]) {
              obj[v].group = group;
              obj[v].sort = k;
            }
          });
        }
      }

      const order = think._.values(obj);
      const orderbgy = think._.orderBy(order, ['group', 'sort'], ['asc', 'asc']);
      if (!think.isEmpty(data.hooks)) {
        data.hooks = data.hooks.split(',');
      }
      const hooks = await this.model('hooks').select();
      this.assign('hooks', hooks);
      this.assign({'fields': fields, 'extend_fields': extend_fields, 'allfields': orderbgy, 'info': data});
      this.tactive = 'ext';
      this.active = 'admin/model/ext';
      this.meta_title = '编辑模型';
      return this.display();
    }
  }

二、unextAction()

此方法用于卸载独立模型。
首先获取 id,并依照 id 在数据库中查找单条数据,赋值给 m 。依据 m ,我们可以通过 think.isEmpty(m.table) 来判断数据库的数据库表是否为空,若不为空则删除。随后我们通过数据库查找数据并进行删除:删除该模型的分类、清除搜索索引、清除搜索配置、清除话题数据。
最后删除整个模型并更新缓存,告知系统 “ 卸载成功,移动到未安装!”

async unextAction() {
    const id = this.get('id');
    const m = await this.model('model').find(id);
    console.log(m);
    if (!think.isEmpty(m.table)) {
      await this.deltable(m.table.split(','), m.name);
    }
    const cats = await this.model('category').where({model: m.id}).getField('id');
    if (!think.isEmpty(cats)) {
      await this.model('category').where({id: ['IN', cats]}).delete();
      console.log('删除分类');
      await this.model('category_priv').where({catid: ['IN', cats]}).delete();
      console.log('清除分类权限');
    }
    await this.model('search').where({m_id: m.id}).delete();
    console.log('清除 搜索索引');
    await this.model('search_model').where({mod: m.id}).delete();
    if (m.key_show === 1) {
      await this.model('keyword_data').where({mod_id: m.id}).delete();
      console.log('清除 话题数据');
    }
    await this.model('model').where({id: m.id}).delete();
    await update_cache('model');
    return this.success({name: '卸载成功,移动到未安装!'});
  }

三、delextAction()

此方法用于删除插件。
首先根据 mod 判断该插件是否允许被删除,若 mod 与 ‘demo’ 等价则不允许删除。若允许删除,获取相应目录下的数据 data ,以进行后续操作。
由 data 获取数据库中的表,若数据库不为空,则删除数据库内的表和数据库。删除完成后,给主进程发送重启的指令,告知系统“删除成功!”。
删除表的方法为 deltable() 方法,此方法为自定义方法。

async delextAction() {
    const mod = this.get('mod');
    if (mod === 'demo') return this.fail('不允许删除');
    const modpath = `${think.APP_PATH}/controller/mod/${mod}`;
    const data = think.app.controllers[`mod/${mod}/config`];
    const tables = data.table;
    if (!think.isEmpty(tables)) {
      await this.deltable(tables.split(','), mod);
    }
    await think.rmdir(modpath).then(() => {
      console.log('删除完成');
    });
    process.send('think-cluster-reload-workers');
    return this.success({name: '删除成功!'});
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值