ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【20211222】CmsWing代码分析 - src/controller/extend/controller.js(三)

2021-12-22 12:02:18  阅读:220  来源: 互联网

标签:CmsWing const extend hooks await controller type think


2021SC@SDUSC

目录

src/controller/extend/controller.js

modModel(modelName = '', extName = '', config = this.config('model.mysql'), prefix = '') {
    let p = this.ctx.controller.split('/');
    if (this.ctx.controller === 'cmswing/route' || this.ctx.controller === 'cmswing/modadminbase') {
      p = `mod/${this.mod.name}/index`.split('/');
    }
    extName = think.isEmpty(extName) ? p[1] : extName;
    return think.modModel(modelName, extName, config, prefix);
  },

模型。参数是:模型名称,扩展名称,配置,前缀。

config处官方文档给出的使用方法如下:think.config(name, value, m)
name {String} 配置名
value {Mixed} 配置值
m {String} 模块名,多模块项目下使用
读取或者设置配置,该功能由think-config模块实现。在 context、controller、logic上可以直接通过this.config方法来操作配置。

// 获取配置
const value1 = think.config('name');
// 指定模块获取配置,多模块项目下有效
const value2 = think.config('name', undefined, 'admin');

// 设置配置
think.config('name', 'value');
// 指定模块设置配置值
think.config('name', 'value', 'admin');

于是在这里读取的是model.mysql,数据库相关。

ctx.controller是路由解析后的控制器名,split方法用于把一个字符串分割成字符串数组。因此变量p就是控制器名(如果以斜杠/分隔);如果控制器名是cmswing/route或者cmswing/modadminbase,则是这个字符串mod/${this.mod.name}/index分割成数组。

如果扩展名是空的,就设置成变量p的[1]位置。

modService(name = '', ser = '', ...args) {
    let p = this.ctx.controller.split('/');
    if (this.ctx.controller === 'cmswing/route' || this.ctx.controller === 'cmswing/modadminbase') {
      p = `mod/${this.mod.name}/index`.split('/');
    }
    ser = think.isEmpty(ser) ? p[1] : ser;
    return think.modService(name, ser, ...args);
  },

整个和上一段的逻辑几乎一致,不再重复分析。

async hook(hooks, ...args) {
    try {
      const h = await this.model('cmswing/hooks').hookscache(hooks);
      if (!think.isEmpty(h.ext)) {
        const ext = h.ext.split(',');
        const hookarr = [];
        for (const c of ext) {
          // 查询插件状态
          const status = await this.model('cmswing/ext').extcache(c, 'status');
          if (Number(status) === 1) {
            const ep = `ext/${c}/hooks`;
            const Cls = this.controller(ep);
            if (Number(h.type) === 1) {
              hookarr.push(await Cls[hooks](...args));
            } else {
              return Cls[hooks](...args);
            }
          } else {
            const models = await this.model('cmswing/model').get_model(null, null, {name: c});
            // console.log(models);
            if (!think.isEmpty(models)) {
              const ep = `mod/${c}/hooks`;
              const Cls = this.controller(ep);
              if (Number(h.type) === 1) {
                hookarr.push(await Cls[hooks](...args));
              } else {
                return Cls[hooks](...args);
              }
            }
          }
        }

        const type = think._.last(args);
        if (think.isObject(type) && !think.isEmpty(type.$hook_key) && !think.isEmpty(type.$hook_type)) {
          const cachehook = await think.cache(`hooks_${hooks}${type.$hook_type}${this.cookie('thinkjs')}`);
          const hookobj = think.isEmpty(cachehook) ? {} : cachehook;
          if (!think.isEmpty(hookarr)) {
            hookobj[type.$hook_key] = hookarr.join('');
          }
          await think.cache(`hooks_${hooks}${type.$hook_type}${this.cookie('thinkjs')}`, hookobj);
          return this.assign(`HOOKS@${hooks}@${type.$hook_type}`, await think.cache(`hooks_${hooks}${type.$hook_type}${this.cookie('thinkjs')}`));
        }
        if (think.isObject(type) && !think.isEmpty(type.$hook_type)) {
          return this.assign(`HOOK@${hooks}@${type.$hook_type}`, hookarr.join(''));
        }
        if (think.isObject(type) && !think.isEmpty(type.$hook_key)) {
          const hookobj = think.isEmpty(await think.cache(`hooks_${hooks}${this.cookie('thinkjs')}`)) ? {} : await think.cache(`hooks_${hooks}${this.cookie('thinkjs')}`);
          if (!think.isEmpty(hookarr)) {
            hookobj[type.$hook_key] = hookarr.join('');
          }
          await think.cache(`hooks_${hooks}${this.cookie('thinkjs')}`, hookobj);
          return this.assign(`HOOKS@${hooks}`, await think.cache(`hooks_${hooks}${this.cookie('thinkjs')}`));
        }
        this.assign(`HOOK@${hooks}`, hookarr.join(''));
      }
    } catch (e) {
      think.logger.error(e);
    }
  },

非常长的一段和hook相关的代码,整体可以拆成这样的结构。首先最外层是一个try-catch结构捕获异常:

async hook(hooks, ...args) {
    try {^} catch (e) {
      think.logger.error(e);
    }
  },

在其中又是一层if判断:

const h = await this.model('cmswing/hooks').hookscache(hooks);
if (!think.isEmpty(h.ext)) {^}

h表示hook的缓存,非空才能够进入内层的逻辑:

const ext = h.ext.split(',');
const hookarr = [];
for (const c of ext) {
	// 查询插件状态
	const status = await this.model('cmswing/ext').extcache(c, 'status');
	if (Number(status) === 1) {
		const ep = `ext/${c}/hooks`;
		const Cls = this.controller(ep);
		if (Number(h.type) === 1) {
			hookarr.push(await Cls[hooks](...args));
		} else {
			return Cls[hooks](...args);
		}
	} else {
		const models = await this.model('cmswing/model').get_model(null, null, {name: c});
		// console.log(models);
		if (!think.isEmpty(models)) {
			const ep = `mod/${c}/hooks`;
			const Cls = this.controller(ep);
			if (Number(h.type) === 1) {
				hookarr.push(await Cls[hooks](...args));
			} else {
				return Cls[hooks](...args);
			}
		}
	}
}

内层包括了一系列判断条件。对每个hook进行状态判断,并且针对空的情况做出不同的处理方式。

标签:CmsWing,const,extend,hooks,await,controller,type,think
来源: https://blog.csdn.net/mu_qingyu/article/details/122049255

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有