UNPKG

mm_os

Version:

这是超级美眉服务端框架,用于快速构建应用程序。

354 lines (329 loc) 7.97 kB
const Index = require('mm_machine').Index; const Drive = require('./drive'); /** * Cmd导航类 * @extends {Index} * @class */ class Cmd extends Index { /** * 构造函数 * @param {Object} scope 作用域 * @param {String} title 标题 * @constructor */ constructor(scope, title) { super(scope, __dirname); this.Drive = Drive; this.type = "cmd"; this.title = title; this.list_before = []; this.list_check = []; this.list_main = []; this.list_render = []; this.list_after = []; // 默认启用热更新 this.mode = 3; /** * 配置参数 */ this.config = { table: "wechat_message", key: "message_id", // 聊天间隔时长,单位:秒,600秒为10分钟 interval: 600 }; } } /** * 设置配置 * @param {Object} config 配置参数 */ Cmd.prototype.set_config = function(config) { Object.assign(this.config, config); } /** * 执行指令 * @param {Object} msg 消息对象 * @param {Object} db 数据库对象 * @param {Object} list 数据库对象 * @return {Object} 返回值 */ Cmd.prototype.run_cmd_sub = async function(msg, db, tense = 'main') { var list = this['list_' + tense]; if (!list) { return } var ret; for (var i = 0, o; o = list[i++];) { if (o.config.state === 1) { ret = await o.run(msg, db); if (ret) { db.ret = ret; // 如果匹配指令则将该消息定义为使用该指令 msg.cmd = o.config.name; if (o.config.end) { break; } } } } return ret; } // // 获取当前未结束的会话记录 // var log = await db.getObj(query); // // 如果不存在未结束会话,则创建新会话记录 // if (!log) { // var bl = await db.add(msg); // if (bl) { // log = await db.getObj(query); // if (log) { // log.time_create = new Date().toStr('yyyy-MM-dd hh:mm:ss'); // } // } else { // $.log.error('添加微信消息到wechat_message表失败!', log); // return null; // } // } else if (log.content_last !== msg.content) { // // 判断是否重复会话内容,如果未重复则添加新内容 // log.content += '\r\n' + msg.content; // } // log.content_last = msg.content; // db.msg = log; // var lt = this.list_before; // for (var i = 0, o; o = lt[i++];) { // if (o.config.state === 1) { // ret = await o.run_cmd(msg, db); // if (ret) { // break; // } // } // } // if (!ret) { // // 判断会话记录是否锁定了指令, 如果存在则继续执行该指令程序 // if (msg_log.cmd) { // // 检索指令驱动是否存在 // var drive = this.list.getObj({ // config: { // name: msg_log.cmd // } // }); // if (drive) { // // 如果存在则执行指令 // ret = await drive.run(msg, db); // } else { // // 如果不存在则结束会话, 并创建新会话 // db.msg.end = 1; // var bl = await db.add(msg); // if (bl) { // msg_log = await db.getObj(query); // if (msg_log) { // msg_log.time_create =; // } // db.msg = msg_log; // } // } // } // if (db.msg.keyword) { // // 添加消息 // msg.content = db.msg.keyword + "\r\n" + msg.content; // } // } /** * 获取上下文 * @param {Object} msg 消息 * @param {Object} db 数据管理器 * @return {Object} */ Cmd.prototype.get_context = async function(msg, db) { var cg = this.config; var now = new Date(); var query = { from_user: msg.from_user, to_user: msg.to_user, group: msg.group, type: msg.type, time_create_max: now.addSeconds(cg.interval).toStr('yyyy-MM-dd hh:mm:ss') }; var db1 = db.new(cg.table, cg.key); var log = await db1.getObj(query, '`time_create` desc'); if(log && !log.end) { return log; } return null; } /** * 合并消息 * @param {Object} msg * @param {Array} log */ Cmd.prototype.merge_msg = function(msg, log) { var m = Object.assign({}, msg, log); m.content = log.content + "\r\n" + msg.content; m.content_last = msg.content; return m; } /** * 保存消息 * @param {Object} msg 消息 * @param {Object} db 数据管理器 */ Cmd.prototype.save_msg = async function(msg, db) { var cg = this.config; var db1 = db.new(cg.table, cg.key); var ret = db.ret; if (ret) { if (typeof(ret) == "object") { ret = JSON.stringify(ret); } msg.result = ret; } if (msg[cg.key]) { var qy = {}; qy[cg.key] = msg[cg.key]; return await db1.set(qy, msg); } else { return await db1.add(msg); } } /** * 执行指令 * @param {Object} msg 消息 * @param {Object} db 数据管理器 * @return {Object|String} */ Cmd.prototype.run = async function(msg, db) { // 判断是否含有消息和消息正文 if (!msg || !msg.content) { return; } db.table = this.config.table; db.key = this.config.key; msg.stage = 1; // 1.先执行前时态指令 var ret = await this.run_cmd_sub(msg, db, 'before'); db.ret = ret; // console.log("执行前", ret); // 2.先执行验证时态指令,如果通过则返回空,否则返回验证失败结果。 var ret_check = await this.run_cmd_sub(msg, db, 'check'); // console.log("执行检查", ret_check); if (ret_check || ret_check === "") { ret = ret_check; } else { // 3-1.先判断本次内容是否为指令,如果是则执行指令。 var ret_main = await this.run_cmd_sub(msg, db, 'main'); console.log("执行", ret_main); if (ret_main) { ret = ret_main; } if (!ret) { // 3-2.如果本次内容非指令,则先获取历史未完成的指令。拼接本次内容,并执行指令。 var log = await this.get_context(msg, db); if (log) { msg = this.merge_msg(msg, log); ret_main = await this.run_cmd_sub(msg, db, 'main'); console.log("合并执行", ret_main); if (ret_main) { ret = ret_main; } } } } // 4.执行后时态指令 var ret_after = await this.run_cmd_sub(msg, db, 'after'); if (ret_after) { ret = ret_after; // console.log("执行后", ret); } if (ret) { db.ret = ret; } // 5.记录本次消息 await this.save_msg(msg, db); return ret; }; /** * 执行排序 */ Cmd.prototype.sort = async function() { this.list.sort(function(o1, o2) { var p1 = o1.sort; var p2 = o2.sort; return p2 - p1; }); this.sort_tense(); }; /** * 排序时态 */ Cmd.prototype.sort_tense = async function() { this.list_before.clear(); this.list_check.clear(); this.list_main.clear(); this.list_render.clear(); this.list_after.clear(); var lt = this.list; for (var i = 0; i < lt.length; i++) { var o = lt[i]; switch (o.config.tense) { case "before": this.list_before.push(o); break; case "check": this.list_check.push(o); break; case "render": this.list_render.push(o); break; case "after": this.list_after.push(o); break; default: this.list_main.push(o); break; } } }; /** * 下达指令 * @param {String} name 名称 * @param {Number} state 状态 * @param {Array} ...params 参数集合 */ Cmd.prototype.cmd = async function(name, state, ...params) { var obj = this.get(name); if (!obj) { return "error: program does not exist"; } return await obj.exec("cmd", state, ...params); } /* 导出指令 */ exports.Cmd = Cmd; /** * Cmd事件池 */ if (!$.pool.cmd) { $.pool.cmd = {}; } /** * Cmd管理器,用于创建缓存 * @param {String} scope 作用域 * @param {string} title 标题 * @return {Object} 返回一个缓存类 */ function cmd_admin(scope, title) { if (!scope) { scope = $.val.scope + ''; } var obj = $.pool.cmd[scope]; if (!obj) { $.pool.cmd[scope] = new Cmd(scope, title); obj = $.pool.cmd[scope]; } return obj; } /** * @module 导出Cmd管理器 */ $.cmd_admin = cmd_admin;