当前位置: 首页 > 工具软件 > CmsWing > 使用案例 >

【20211123】CmsWing代码分析 - src/controller/home/ceshi.js

曹新觉
2023-12-01

2021SC@SDUSC

src/controller/home/

这个文件夹名字看起来像是控制器的主页部分。实际上代表了什么含义呢?这就要靠我们的分析去探索了。

src/controller/home/ceshi.js

我们猜测这是测试的相关代码。(那么为什么不写成test而是写成拼音的ceshi呢,要知道这是一个不好的习惯。)

开头就是很长的一段代码,让我们一点点拆解。

const fs = require('fs');

开头的require调用include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行。

module.exports = class extends think.Controller {}

https://www.cnblogs.com/fayin/p/6831071.html介绍了module.exports的用处:CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。require方法用于加载模块。这也可以解释上面为何调用require方法。

https://thinkjs.org/zh-cn/doc/3.0/controller.html解释了think.Controller的作用。MVC 模型中,控制器是用户请求的逻辑处理部分。比如:将用户相关的操作都放在 user.js 里,每一个操作就是里面一个 Action。项目中的 controller 需要继承 think.Controller 类,这样能使用一些内置的方法。当然项目中可以创建一些通用的基类,然后实际的 controller 都继承自这个基类。

之后的定义其中有几个async函数。具体解释见这里https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function,我这里只把介绍搬运过来:async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。await 关键字 只能放在 async 函数内部, await关键字的作用 就是获取 Promise中返回的内容, 获取的是Promise函数中resolve或者reject的值

async fetchAction() {
    const res = await this.fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png');
   	// console.log(res);
    // const dest = fs.createWriteStream('./octocat.png');
    // res.body.pipe(dest);
    this.header('Content-Type', 'image/png');
    return this.body = res.body;
  }

这一段是“获取”的动作,如上文所示使用await关键字获取资源,并在最后返回标题和图片。

  async donatesAction() {
    return this.body = 'donates';
  }

这一段是定义了一个“捐赠”的动作,返回结果是把内容body换成捐赠相关的内容。

async emailAction() {
    const transport = {
      service: 'qq',
      auth: {
        user: 'arterli@qq.com', // your account
        pass: 'vxheoipkldjgbhgi' // authorization code, not the email password
      }
    };
    const options = {
      from: 'arterli@qq.com', // sender address
      to: 'cmswing@126.com', // list of receivers
      subject: 'this is subject', // subject line
      html: '<b>this is HTML content <img src="cid:00000001"/></b>' // html content

    };
    const send = await this.sendEmail(transport, options).then(info => {
      console.log(info);
    }, err => {
      console.log(err);
    });
    console.log(send);
    return this.body = 'emial';
  }

这一段是定义了一个邮件的页面并且设置了选项(并且是不是最后把email拼错了!);邮件的收件人,发件人,内容,打印信息,如果错误会打印返回情况。总体看来是一个普通的发送邮件功能。

  cookAction() {
    // this.cookie("hz", 'sfs|dfg|fdsfs');
    // $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
    // $orderSn = $yCode[intval(date('Y')) - 2011] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
    const d = new Date();
    const ycode = ['C', 'M', 'S', 'W', 'I', 'N', 'G', 'N', 'E', 'T'];
    // return this.body= ycode[this.moment().format('YYYY')-2017]+ (d.getMonth()+1).toString(16).toUpperCase()+this.moment().format('DD')+m.substr(8);
    const m = new Date().getTime().toString();
    return this.body = think._.padEnd('1', 10, '0') + m.substr(8);
  }

先不考虑注释的功能,看起来内容是对日期时间(有个getTime函数)做出某种处理。padEnd函数是补全字符串的作用,详情见这里https://www.zhangxinxu.com/wordpress/2018/07/js-padstart-padend/。据此猜测是对时间处理成规定格式。不得不说使用PadEnd要比注释里之前使用的方式要简洁明了许多的。

async addAction() {
    const data = { group_id: '0',
      name: '',
      title: 'fdsafsafa',
      description: '',
      type: '2',
      cover_id: '0',
      keyname: '',
      link_id: '0',
      display: '1',
      'date|||deadline': '',
      view: '0',
      comment: '0',
      level: '0',
      'date|||create_time': '',
      bookmark: '0',
      template: '',
      pid: '0',
      topid: '0',
      model_id: '2',
      category_id: '1',
      uid: '1',
      content: '<p>请填写内容...</p>',
      position: 0,
      deadline: 0,
      create_time: 1504000783284,
      update_time: 1504000783284,
      status: 1,
      id: 251 };
    return await this.model('document_ttt').add(data);
  }

以上是一段测试的添加内容代码,看起来是把各项参数写进去了,来检测是否正常显示。从中我们也可以看出,一个添加动作需要多少参数。

  ipAction() {
    return this.body = this.ip;
  }

ip相关。值得注意的是在src/bootstrap也出现过ip相关操作。

  async extAction() {
    console.log(parse_config_attr(think.config('ext.attachment.loactionurl'), '@')[1]);
    return this.body = this.config('ext.qq.appkey');
  }

ext文件夹里有许多与外界api交际的地方,此处可以视作对api调用的测试。此处的一个函数parse_config_attr,这里有更多的使用例子:https://vimsky.com/examples/detail/php-ex-----parse_config_attr.html

async hooksAction() {
    // 带 $hook_type 参数的 视图钩子调用, 参数1,参数2,...{'$hook_type':1},如果由多个参数,{'$hook_type':1} 放最后一个。
    await this.hook('adminArticleEdit', '风的撒风的撒风的撒发达富啊222', '的撒风大师傅撒', {'$hook_type': 1});
    // 带 $hook_key 参数的 视图钩子调用, 参数1,参数2,...{'$hook_key':'aaaa'},如果由多个参数,{'$hook_key':'aaaa'} 放最后一个。
    await this.hook('adminArticleEdit', 'aaaa', '的撒风大师傅撒', {'$hook_key': 'aaaa'});
    await this.hook('adminArticleEdit', 'bbbb', '的撒风大师傅撒', {'$hook_key': 'bbbb'});
    // 带 $hook_key 和 $hook_type 参数的 视图钩子调用, 参数1,参数2,...{'$hook_key':'bbbb','$hook_type':2},如果由多个参数,{'$hook_key':'bbbb','$hook_type':2} 放最后一个。
    await this.hook('adminArticleEdit', 'bbbb', '的撒风大师傅撒', {'$hook_key': 'bbbb', '$hook_type': 2});
    // 普通调用
    await this.hook('adminArticleEdit', {'$hook_key2': 'bbbb', '$hook_type2': 2});
    return this.display();
  }

让我们忽略这些脸滚键盘般的测试参数,总之得出的是hook,钩子调用的测试。

  async cacheAction() {
    const data = await this.model('cmswing/ext').extcache('editor', 'setting');

    // console.log(data);
    return this.body = data;
  }

data获得了编辑器和设置的缓存,由return将其展示出来。

async topicsAction() {
    const list = await this.model('document_picture').where({id: ['!=', 311]}).select();
    for (const v of list) {
      const arr = [];
      if (v.pictureurls) {
        for (const vv of v.pictureurls.split(',')) {
          const obj = {};
          obj.id = vv;
          obj.name = vv;
          obj.src = vv;
          obj.info = vv;
          arr.push(obj);
        }
      }
      console.log(arr);
      const data = {atlas: JSON.stringify(arr)};
      await this.model('document_picture').where({id: v.id}).update(data);
    }
    return this.body = 22;
  }

主题的测试代码,令人疑惑的是为什么返回值是22。总之遍历了特定情况的list,并展示。

总结

看到这里,这个文件的作用已经很明了了:一个测试用的文件,测试从钩子到邮件发送等功能,并将结果放在body中展示或者打印出来。属于在开发和修改过程中用到的文件,虽然最终呈现结果时可能关系不大,但还是很重要的部分。
可是,ceshi.js这个名字真的好吗……行吧……

 类似资料: