فهرست منبع

后台定时任务跑用户专业版状态和发送短信

laiguoran 4 سال پیش
والد
کامیت
211c144c45
6فایلهای تغییر یافته به همراه1133 افزوده شده و 807 حذف شده
  1. 5 1
      modules/all_models/user.js
  2. 76 1
      modules/sys_tools/models/sys_model.js
  3. 225 0
      modules/users/models/sms.js
  4. 22 0
      operation.js
  5. 804 804
      package-lock.json
  6. 1 1
      package.json

+ 5 - 1
modules/all_models/user.js

@@ -14,7 +14,11 @@ let upgrade = mongoose.Schema({
     compilationID:String,//编办ID
     upgrade_time:Number,
     isUpgrade:Boolean,
-    remark:String//描述:广东办刘飞 2018-06-17 启用/关闭
+    remark:String,//描述:广东办刘飞 2018-06-17 启用/关闭
+    deadline: {
+        type:String,
+        default: '',
+    },
 }, { _id: false })
 
 

+ 76 - 1
modules/sys_tools/models/sys_model.js

@@ -10,6 +10,8 @@
 
 import mongoose from 'mongoose';
 import async from 'async';
+import moment from 'moment';
+const SMS = require('../../users/models/sms');
 const projectModel = mongoose.model('projects');
 const projSettingModel = mongoose.model('proj_setting');
 const calcProgramModel = mongoose.model('calc_programs');
@@ -33,6 +35,8 @@ const feeRateFileModel = mongoose.model('fee_rate_file');
 const feeRateModel = mongoose.model('fee_rates');
 const compleRationSection = mongoose.model('complementary_ration_section_tree');
 let divideModel = mongoose.model("divide_setting");
+const userModel = mongoose.model('users');
+const compilationModel = mongoose.model('compilation');
 
 //删除垃圾数据
 async function clearJunkData(callback){
@@ -177,9 +181,80 @@ async function clearFakeData(callback) {
     });
 }
 
+/*
+* 每天定时清理用户限期的专业版编办,降为免费公用版。
+* */
+async function checkUserCompilationStatus(callback) {
+    let functions = [];
+    let today = moment(new Date()-86400*1000).format('YYYY-MM-DD');
+    let userList = await userModel.find({upgrade_list: {$elemMatch:{ deadline: today }}});
+    if (userList.length > 0) {
+        for (let user of userList) {
+            let ssoId = JSON.parse(JSON.stringify(user)).ssoId; // 坑啊,没法直接获取到user.ssoId,要转义
+            for (let cul of user.upgrade_list) {
+                if (cul.deadline === today) {
+                    // cul.deadline = '';
+                    cul.isUpgrade = false;
+                }
+            }
+            functions.push(function (cb) {
+                userModel.update({ssoId: ssoId}, {upgrade_list: user.upgrade_list}, { safe: true }, cb);
+            });
+        }
+    }
+    if(functions.length > 0){
+        async.parallel(functions, async function(err, result){
+            if(callback){
+                callback(err);
+            }
+        });
+    } else {
+        if(callback) callback(0);
+    }
+
+}
+
+/*
+* 为每天降为免费公用版的用户发送降级短信。
+* */
+async function sendCompilationStatusSms(callback) {
+    let functions = [];
+    let today = moment(new Date()-86400*1000).format('YYYY-MM-DD');
+    let userList = await userModel.find({upgrade_list: {$elemMatch:{ deadline: today }}});
+    if (userList.length > 0) {
+        const Sms = new SMS();
+        for (let user of userList) {
+            let ssoId = JSON.parse(JSON.stringify(user)).ssoId;
+            for (let cul of user.upgrade_list) {
+                if (cul.deadline === today) {
+                    cul.deadline = '';
+                    // cul.isUpgrade = false;
+                    // 发送短信
+                    let compilationData = await compilationModel.findOne({_id: cul.compilationID});
+                    await Sms.sendProductMsg(user.mobile, 2, user.real_name, compilationData.name, '');
+                }
+            }
+            functions.push(function (cb) {
+                userModel.update({ssoId: ssoId}, {upgrade_list: user.upgrade_list}, { multi: true }, cb);
+            });
+        }
+    }
+    if(functions.length > 0){
+        async.parallel(functions, async function(err, result){
+            if(callback){
+                callback(err);
+            }
+        });
+    } else {
+        if(callback) callback(0);
+    }
+}
+
 const sysSchedule = {
     clearJunkData,
-    clearFakeData
+    clearFakeData,
+    checkUserCompilationStatus,
+    sendCompilationStatusSms,
 };
 
 //export {sysSchedule as default}

+ 225 - 0
modules/users/models/sms.js

@@ -0,0 +1,225 @@
+'use strict';
+
+import Request from "request";
+
+/**
+ * 建筑短信发送相关接口
+ *
+ * @author CaiAoLin
+ * @date 2018/1/25
+ * @version
+ */
+
+const crypto = require('crypto');
+
+class SMS {
+
+    /**
+     * 构造函数
+     *
+     * @return {void}
+     */
+    constructor() {
+        this.url = 'http://www.sendcloud.net/smsapi/send';
+        this.smsUser = 'smartcost';
+        this.smskey = 'kuGmqTt10n6vBXivhxXsAuG8aoCsQ1x6';
+    }
+
+    /**
+     * 发送信息
+     *
+     * @param {String|Array} mobile - 发送的电话号码
+     * @param {String} code - 验证码
+     * @return {Boolean} - 发送结果
+     */
+    async send(mobile, code) {
+        try {
+            const formData = {
+                smsUser: this.smsUser,
+                templateId: 25595,
+                msgType: 0,
+                phone: mobile,
+                vars: '{"%code%":'+ code +'}',
+            };
+            const signature = await this.getSignature(this.sortDict(formData), this.smskey);
+            formData.signature = signature;
+
+            let postData = {
+                url: this.url,
+                form: formData,
+                encoding: 'utf8'
+            };
+
+            return new Promise(function (resolve, reject) {
+                try {
+                    // 请求接口
+                    Request.post(postData, function (err, postResponse, body) {
+                        if (err) {
+                            throw '请求错误';
+                        }
+                        if (postResponse.statusCode !== 200) {
+                            throw '短信发送失败!';
+                        }
+                        resolve(body);
+                    });
+                } catch (error) {
+                    reject([]);
+                }
+            });
+        } catch (error) {
+            console.log(error);
+        }
+    }
+
+    async sendLoginMsg(mobile, name, date, time, local, ip) {
+        console.log(mobile, name, time, local, ip);
+        try {
+            const formData = {
+                smsUser: this.smsUser,
+                templateId: 27561,
+                msgType: 0,
+                phone: mobile,
+                vars: '{"%name%": "' + name + '", "%date%": "' + date + '", "%time%": "' + time + '", "%local%": "' + local + '", "%IP%": "' + ip + '"}',
+            };
+            const signature = await this.getSignature(this.sortDict(formData), this.smskey);
+            formData.signature = signature;
+
+            let postData = {
+                url: this.url,
+                form: formData,
+                encoding: 'utf8'
+            };
+
+            return new Promise(function (resolve, reject) {
+                try {
+                    // 请求接口
+                    Request.post(postData, function (err, postResponse, body) {
+                        if (err) {
+                            throw '请求错误';
+                        }
+                        if (postResponse.statusCode !== 200) {
+                            throw '短信发送失败!';
+                        }
+                        resolve(body);
+                    });
+                } catch (error) {
+                    reject([]);
+                }
+            });
+        } catch (error) {
+            console.log(error);
+        }
+    }
+
+    async sendProductMsg(mobile, status, name, product, deadline) {
+        try {
+            let templateId = 0;
+            switch (status) {
+                case 1: templateId = 746380;break;// 产品升级通知
+                case 2: templateId = 746381;break;// 产品降级通知
+                case 3: templateId = 746379;break;// 产品延期通知
+            }
+            const formData = {
+                smsUser: this.smsUser,
+                templateId: templateId,
+                msgType: 0,
+                phone: mobile,
+            };
+            formData.vars = '{"%name%": "' + name + '", "%product%": "' + product + '"' + (status !== 2 ? ', "%deadline%": "' + deadline + '"' : '') +'}';
+            const signature = await this.getSignature(this.sortDict(formData), this.smskey);
+            formData.signature = signature;
+
+            let postData = {
+                url: this.url,
+                form: formData,
+                encoding: 'utf8'
+            };
+
+            return new Promise(function (resolve, reject) {
+                try {
+                    // 请求接口
+                    Request.post(postData, function (err, postResponse, body) {
+                        if (err) {
+                            throw '请求错误';
+                        }
+                        if (postResponse.statusCode !== 200) {
+                            throw '短信发送失败!';
+                        }
+                        resolve(body);
+                    });
+                } catch (error) {
+                    reject([]);
+                }
+            });
+        } catch (error) {
+            console.log(error);
+        }
+    }
+
+    md5(data) {
+        var str = data;
+        return crypto.createHash("md5").update(str).digest("hex");
+    }
+
+    sortDict(dict){
+        var dict2={},
+            keys = Object.keys(dict).sort();
+        for (var i = 0, n = keys.length, key; i < n; ++i) {
+            key = keys[i];
+            dict2[key] = dict[key];
+        }
+        return dict2;
+    }
+
+    async getSignature (sorted_param, smsKey) {
+        var param_str = "";
+        for(var key in sorted_param)
+            param_str += (key + '=' + sorted_param[key] + '&')
+        var param_str = smsKey + '&' + param_str + smsKey;
+        var sign = this.md5(param_str);
+        return sign.toUpperCase();
+    }
+
+    /**
+     * 生成随机字符串
+     *
+     * @param {Number} length - 需要生成字符串的长度
+     * @param {Number} type - 1为数字和字符 2为纯数字 3为纯字母
+     * @return {String} - 返回生成结果
+     */
+    generateRandomString(length, type = 1) {
+        length = parseInt(length);
+        length = isNaN(length) ? 1 : length;
+        let randSeed = [];
+        let numberSeed = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+        let stringSeed = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+            'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
+
+        switch (type) {
+            case 1:
+                randSeed = stringSeed.concat(numberSeed);
+                stringSeed = numberSeed = null;
+                break;
+            case 2:
+                randSeed = numberSeed;
+                break;
+            case 3:
+                randSeed = stringSeed;
+                break;
+            default:
+                break;
+        }
+
+        const seedLength = randSeed.length - 1;
+        let result = '';
+        for (let i = 0; i < length; i++) {
+            const index = Math.ceil(Math.random() * seedLength);
+            result += randSeed[index];
+        }
+
+        return result;
+    }
+}
+
+module.exports = SMS;

+ 22 - 0
operation.js

@@ -108,6 +108,28 @@ schedule.scheduleJob({hour: 3, minute: 30, dayOfWeek: 7}, function(){
     })
 });
 
+schedule.scheduleJob({hour: 0, minute: 1}, function(){
+    sysSchedule.checkUserCompilationStatus(function (err) {
+        if(err){
+            console.log('更新失败');
+        }
+        else{
+            console.log('更新成功');
+        }
+    })
+});
+
+schedule.scheduleJob({hour: 10, minute: 0}, function(){
+    sysSchedule.sendCompilationStatusSms(function (err) {
+        if(err){
+            console.log('短信发送失败');
+        }
+        else{
+            console.log('短信发送成功');
+        }
+    })
+});
+
 
 app.listen(2080, function(){
     console.log("server started!");

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 804 - 804
package-lock.json


+ 1 - 1
package.json

@@ -37,6 +37,6 @@
   },
   "scripts": {
     "start": "C:\\Users\\mai\\AppData\\Roaming\\npm\\babel-node.cmd operation.js",
-    "dev_server":"SET NODE_ENV=qa&& babel-node operation.js"
+    "dev_server": "SET NODE_ENV=qa&& babel-node operation.js"
   }
 }