lrf402788946 před 4 roky
rodič
revize
de83d0bd3f

+ 35 - 0
app/controller/system/.schedule.js

@@ -0,0 +1,35 @@
+module.exports = {
+  create: {
+    requestBody: ["!table", "!column", "!number", "!unit", "user_ids"],
+  },
+  destroy: {
+    params: ["!id"],
+    service: "delete",
+  },
+  update: {
+    params: ["!id"],
+    requestBody: ["!table", "!column", "!number", "!unit", "status", 'user_ids'],
+  },
+  show: {
+    parameters: {
+      params: ["!id"],
+    },
+    service: "fetch",
+  },
+  index: {
+    parameters: {
+      query: {
+        table: "table",
+        column: "column",
+        status: "status",
+      },
+    },
+    service: "query",
+    options: {
+      query: ["skip", "limit"],
+      sort: ["meta.createdAt"],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 21 - 0
app/controller/system/schedule.js

@@ -0,0 +1,21 @@
+'use strict';
+
+// const _ = require('lodash');
+const meta = require('./.schedule.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose/lib/controller');
+
+// 定时任务
+class ScheduleController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.system.schedule;
+  }
+
+  async check() {
+    this.service.check();
+    this.ctx.ok();
+  }
+}
+
+module.exports = CrudController(ScheduleController, meta);

+ 18 - 3
app/model/car.js

@@ -148,14 +148,24 @@ const car = {
     type: String,
     required: false,
     maxLength: 200,
-    field: { label: '强制险起始时间', required: true, notable: true },
+    field: {
+      label: '强制险起始时间',
+      type: 'date',
+      required: true,
+      notable: true,
+    },
     row: 19,
   }, // 强制险起始时间
   f_end_date: {
     type: String,
     required: false,
     maxLength: 200,
-    field: { label: '强制险截止时间', required: true, notable: true },
+    field: {
+      label: '强制险截止时间',
+      type: 'date',
+      required: true,
+      notable: true,
+    },
     row: 20,
   }, // 强制险截止时间
   f_solve: {
@@ -176,7 +186,12 @@ const car = {
     type: String,
     required: false,
     maxLength: 200,
-    field: { label: '强制险签单日期', required: true, notable: true },
+    field: {
+      label: '强制险签单日期',
+      type: 'date',
+      required: true,
+      notable: true,
+    },
     row: 23,
   }, // 强制险签单日期
   b_company: {

+ 0 - 1
app/model/client.js

@@ -62,7 +62,6 @@ const Client = {
     },
   }, // 状态:0=>使用;1禁用
 };
-const zh = '客户';
 
 const schema = new Schema(Client, { toJSON: { virtuals: true } });
 schema.index({ id: 1 });

+ 60 - 0
app/model/notice.js

@@ -0,0 +1,60 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+// 消息
+const notice = {
+  message: {
+    type: String,
+    required: true,
+    maxLength: 200,
+    field: { label: '提示信息', required: true },
+  },
+  effect_id: {
+    type: String,
+    required: true,
+    maxLength: 200,
+    field: { label: '产生警告的id', required: true },
+  },
+  column: {
+    type: String,
+    required: true,
+    maxLength: 200,
+    field: { label: '产生警告的字段', required: true },
+  },
+  check_date: {
+    type: String,
+    required: true,
+    maxLength: 200,
+    field: { label: '产生警告时,受检查的日期(最后日期)', required: true },
+  },
+  user_id: {
+    type: String,
+    required: true,
+    maxLength: 200,
+    field: { label: '被提示人员', required: true },
+  },
+  status: {
+    type: String,
+    maxLength: 200,
+    default: '0',
+    field: {
+      label: '状态',
+      filter: 'select',
+      type: 'select',
+      format: (i => (i === '0' ? '提示' : '禁止')).toString(),
+      list: [
+        { label: '提示', value: '0' },
+        { label: '禁止', value: '1' },
+      ],
+    },
+  }, // 状态:0=>使用;1禁用
+};
+
+const schema = new Schema(notice, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.plugin(metaPlugin);
+
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Notice', schema, 'notice');
+};

+ 2 - 2
app/model/order.js

@@ -117,7 +117,7 @@ const order = {
   rq_send_time: {
     type: String,
     maxLength: 200,
-    field: { label: '要求发货日期' },
+    field: { label: '要求发货日期', type: 'date' },
   },
   send_time: {
     type: [ sendList ],
@@ -127,7 +127,7 @@ const order = {
   rq_arrive_time: {
     type: String,
     maxLength: 200,
-    field: { label: '要求到达日期' },
+    field: { label: '要求到达日期', type: 'date' },
   },
   // 到达日期有问题:应该有多种货物不同到达日期 或 某种货物被拆分,不同的到达日期
   // 但是这并不影响要求 到达日期

+ 57 - 0
app/model/schedule.js

@@ -0,0 +1,57 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+// 定时任务表
+const schedule = {
+  table: {
+    type: String,
+    required: true,
+    maxLength: 200,
+    field: { label: '表', filter: 'select', required: true },
+  },
+  column: {
+    type: String,
+    required: true,
+    maxLength: 200,
+    field: { label: '监控内容', filter: true, required: true },
+  },
+  number: {
+    type: String,
+    maxLength: 200,
+    field: { label: '时间数', filter: true, required: true },
+  },
+  unit: {
+    type: String,
+    maxLength: 200,
+    field: { label: '时间单位', filter: true, required: true },
+  },
+  user_ids: {
+    type: Array,
+    required: true,
+    field: { label: '要发送的用户id' },
+  },
+  status: {
+    type: String,
+    maxLength: 200,
+    default: '0',
+    field: {
+      label: '状态',
+      filter: 'select',
+      type: 'select',
+      format: (i => (i === '0' ? '使用' : '禁用')).toString(),
+      list: [
+        { label: '使用', value: '0' },
+        { label: '禁用', value: '1' },
+      ],
+    },
+  }, // 状态:0=>使用;1禁用
+};
+
+const schema = new Schema(schedule, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.plugin(metaPlugin);
+
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Schedule', schema, 'schedule');
+};

+ 1 - 1
app/model/treaty.js

@@ -37,7 +37,7 @@ const treaty = {
     maxLength: 200,
     field: { label: '结算周期' },
   },
-  expiry_date: { type: String, required: true, maxLength: 200, field: { label: '有效日期' } },
+  expiry_date: { type: String, required: true, maxLength: 200, field: { label: '截止日期', type: 'date' } },
   status: {
     type: String,
     maxLength: 200,

+ 4 - 0
app/router/system.js

@@ -9,5 +9,9 @@ module.exports = app => {
   router.get(`${prefix}/dictionary/tree`, controller[index].dictionary.tree);
   router.resources('dictionary', `${prefix}/dictionary`, controller[index].dictionary); // index、create、show、destroy
   router.post('dictionary', `${prefix}/dictionary/update/:id`, controller[index].dictionary.update);
+  // 定时任务
+  router.get('schedule', `${prefix}/schedule/check`, controller[index].schedule.check);
+  router.resources('schedule', `${prefix}/schedule`, controller[index].schedule); // index、create、show、destroy
+  router.post('schedule', `${prefix}/schedule/update/:id`, controller[index].schedule.update);
 
 };

+ 22 - 0
app/schedule/check.js

@@ -0,0 +1,22 @@
+'use strict';
+
+const Subscription = require('egg').Subscription;
+
+class CheckCheck extends Subscription {
+  // 通过 schedule 属性来设置定时任务的执行间隔等配置
+  // 更改执行时间
+  static get schedule() {
+    return {
+      cron: '0 0 0 * * *',
+      // interval: '1d',
+      type: 'worker', // 指定所有的 worker 都需要执行
+    };
+  }
+
+  // subscribe 是真正定时任务执行时被运行的函数
+  async subscribe() {
+    console.log('in function:');
+    await this.ctx.service.system.schedule.check();
+  }
+}
+module.exports = CheckCheck;

+ 1 - 0
app/service/car/car.js

@@ -11,6 +11,7 @@ class CarService extends CrudService {
     super(ctx, 'car');
     this.model = this.ctx.model.Car;
   }
+
 }
 
 module.exports = CarService;

+ 113 - 0
app/service/system/schedule.js

@@ -0,0 +1,113 @@
+'use strict';
+
+const assert = require('assert');
+const _ = require('lodash');
+const moment = require('moment');
+const { ObjectId } = require('mongoose').Types;
+const { CrudService } = require('naf-framework-mongoose/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+class ScheduleService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'schedule');
+    this.model = this.ctx.model.Schedule;
+    this.notice = this.ctx.model.Notice;
+  }
+
+  /**
+   * 查询定时任务表,进行检查
+   */
+  async check() {
+    let list = await this.model.find();
+    if (list.length > 0) list = JSON.parse(JSON.stringify(list));
+    const group = _.groupBy(list, 'table');
+    const keys = Object.keys(group);
+    for (const key of keys) {
+      const klist = await this.ctx.model[key].find();
+      this.checkData(klist, group[key]);
+    }
+  }
+
+  /**
+   * 检查数据
+   * @param {Array} data 各个表的数据
+   * @param {Array} columns 对应各个表需要检查的字段集合
+   */
+  async checkData(data, columns) {
+    const msg = [];
+    for (const i of data) {
+      for (const col of columns) {
+        // 检查每个数据中,需要检查的字段是否符合要求
+        const { column, number, unit, user_ids, table } = col;
+        const prop = _.get(i, column);
+        if (!prop) continue;
+        const res = this.getLimitResult(prop, number, unit);
+        if (!res) continue;
+        const obj = { effect_id: i._id, check_date: prop, column };
+        // 检查effect_id和check_date,column是否存在,提示过的就不再重发了
+        const noticeList = await this.notice.find(obj);
+        // 过滤出没有发送过消息的人员(可能有后加的情况)
+        const not_send_user = user_ids.filter(f => !noticeList.find(nf => nf.user_id === f));
+        // 拼message,然后发消息
+        const meta = await this.ctx.service.util.getModel(table);
+        obj.message = this.getMessage(i, col, meta);
+        this.addNotice(obj, not_send_user);
+      }
+    }
+  }
+
+  /**
+   * 根据3个参数+检查的时刻判断是否进入警告范围并开始提示
+   * @param {String} date 检查源日期
+   * @param {Number} number 时间-数
+   * @param {String} unit 时间-单位
+   * @return {Boolean} true=>提示;false=>不提示
+   */
+  getLimitResult(date, number, unit) {
+    // 不是日期就不查了
+    if (!moment(date).isValid()) return false;
+    const line = moment(date).subtract(number, unit).format('YYYY-MM-DD');
+    // const now = moment().format('YYYY-MM-DD');
+    // now 当前日期, line警告日期, date最后日期
+    const res = moment().isBetween(line, date, null, '[)');
+    return res;
+  }
+
+  /**
+   * 获取提示信息内容
+   * @param {Object} data 被检查的数据
+   * @param {Object} column 检查的字段信息
+   * @param {Array} meta 该表的字段信息
+   */
+  getMessage(data, column, meta) {
+    const { table, column: colName } = column;
+    const field = meta.find(f => f.model === colName);
+    if (!field) return;
+    const { label } = field;
+    let to;
+    // 车辆表的信息编辑
+    if (table === 'Car') to = data.car_no;
+    else if (table === 'Driver') to = data.name;
+    else if (table === 'Order') to = data.order_no;
+    else if (table === 'Treaty') to = data.number;
+    const res = `${to}---- ${label} 于 ${_.get(
+      data,
+      colName
+    )}  到期,请及时处理以免造成不必要的损失!`;
+
+    // TODO 按监控管理的选择列表的选项去补充完信息
+    return res;
+  }
+
+  /**
+   * 批量产生提示消息
+   * @param {Object} obj 整理的消息数据
+   * @param {Array} user_ids 要发送的用户id
+   */
+  async addNotice(obj, user_ids) {
+    const arr = user_ids.map(i => ({ ...obj, user_id: i }));
+    this.notice.insertMany(arr);
+  }
+}
+
+module.exports = ScheduleService;

+ 11 - 5
app/service/util.js

@@ -1,6 +1,7 @@
 'use strict';
 const assert = require('assert');
 const _ = require('lodash');
+const moment = require('moment');
 const { ObjectId } = require('mongoose').Types;
 const { CrudService } = require('naf-framework-mongoose/lib/service');
 const { BusinessError, ErrorCode } = require('naf-core').Error;
@@ -21,10 +22,17 @@ class UtilService extends CrudService {
     const keys = Object.keys(modelList);
     const arr = [];
     for (const key of keys) {
-      if (key !== 'Test') { arr.push({ zh: this.modelToZh(key), table: key, value: await this.getModel(key) }); }
+      if (key !== 'Test') {
+        const zh = this.modelToZh(key);
+        if (!zh) continue;
+        arr.push({
+          zh,
+          table: key,
+          value: await this.getModel(key),
+        });
+      }
     }
     return arr;
-
   }
 
   /**
@@ -67,8 +75,6 @@ class UtilService extends CrudService {
     };
     return obj[_.lowerCase(model)];
   }
-
-  async utilMethod(query, body) {
-  }
+  async utilMethod(query, body) {}
 }
 module.exports = UtilService;