Просмотр исходного кода

Merge branch 'srx' of yeshijie/im.doctor into srx

yeshijie 7 лет назад
Родитель
Сommit
6d32e5698d

+ 3 - 3
src/server/app.js

@ -23,7 +23,7 @@ let UrlInitializer = require('./endpoints/url.initializer');
let JobInitializer = require('./models/schedule/job.initializer');
//消息订阅
let pubSub = require('./models/redis/pubSub.js');
// let pubSub = require('./models/redis/pubSub.js');
// initialize express application
let app = express();
@ -117,5 +117,5 @@ if(!server.address()){
//JobInitializer.init();
pubSub.registerHandlers(config.subChannel,msg=> console.log(msg));
pubSub.subscribe(config.subChannel);
// pubSub.registerHandlers(config.subChannel,msg=> console.log(msg));
// pubSub.subscribe(config.subChannel);

+ 1 - 1
src/server/endpoints/v2/application.endpoint.js

@ -38,7 +38,7 @@ router.get(APIv2.Application.BadgeNo, function (req, response) {
                res =  JSON.parse(res)
                if (res.status == 200) {
                    let data = res.data;
                    count = JSON.parse(data.imMsgCount).count + data.system.amount + data.healthIndex.amount + data.sign.amount;
                    count = JSON.parse(data.imMsgCount).count + data.system.amount + data.concern.amount;
                }
                response.status(200).send({"count": count});
            });

+ 1 - 1
src/server/endpoints/v2/user.endpoint.js

@ -59,7 +59,7 @@ router.put(APIv2.Users.UserStatus, function (req, res) {
    let userId = req.params.user_id;
    let payload = req.body;
    if (userId === null) {
    if (userId == null||userId=="null") {
        throw {httpStatus: 406, message: 'Validation Failed. Missing field(s): user_id.'};
    }

+ 5 - 3
src/server/include/commons.js

@ -20,7 +20,7 @@ if (process.env.IM_PROFILE === "prod") {
    wlyyDBName = "wlyy";
} else if (process.env.IM_PROFILE === "test") {
    configFile += "test";
    wlyyDBName = "wlyy";
    wlyyDBName = "wlyy_sr";
} else {
    configFile += "dev";
    wlyyDBName = "wlyy_sr";
@ -212,13 +212,15 @@ const DB_TABLES = {
    Sessions: "sessions",
    Topics: "topics",
    StickySessions: "sticky_sessions",
    WlyyConsult:"wlyy_consults",
    WlyyConsultS:"wlyy_consults",
    WlyyConsultTeam:wlyyDBName+".wlyy_consult_team",
    WlyyConsultS:wlyyDBName+".wlyy_consult",
    WlyyConsult:wlyyDBName+".wlyy_consult",
    WxAccessToken:wlyyDBName+".wx_access_token",
    WlyyWxPushLog:wlyyDBName+".wlyy_wx_push_log",
    WeixinTemplateConfig:wlyyDBName+".weixin_template_config",
    MessageNoticeSetting:wlyyDBName+".wlyy_message_notice_setting",
    WlyyPatient:wlyyDBName+".wlyy_patient",
    WlyyPatientFamilyMember:wlyyDBName+".wlyy_patient_family_member",
    SignFamily:wlyyDBName+".wlyy_sign_family",
    sessionTypeToTableName: function (sessionType) {

+ 24 - 40
src/server/models/client/app.client.js

@ -7,7 +7,6 @@ let RedisClient = require('../../repository/redis/redis.client');
let RedisModel = require('./../redis.model');
let AppStatusRepo = require('../../repository/mysql/app.status.repo');
let MessageNoticeSettingRepo = require('../../repository/mysql/message.noticeSetting.repo');
let SignFamilyRepo = require('../../repository/mysql/sign.family.repo');
let ModelUtil = require('../../util/model.util');
let clientCache = require('../socket.io/client.cache').clientCache();
let WlyySDK = require("../../util/wlyy.sdk");
@ -158,45 +157,30 @@ class AppClient extends RedisModel {
                    ModelUtil.logError("Get user app status failed", err);
                    return;
                }
                var session_type = isNaN(Number(sessionType))?sessionType:Number(sessionType);
                if(session_type==SESSION_TYPES.SYSTEM||
                    session_type==SESSION_TYPES.MUC||
                    session_type==SESSION_TYPES.P2P||
                    session_type==SESSION_TYPES.GROUP||
                    session_type==SESSION_TYPES.DISCUSSION||
                    session_type==SESSION_TYPES.PRESCRIPTION){
                    //是否发送消息
                    MessageNoticeSettingRepo.findOne(targetId,'1',function (err,res) {
                        if(res&&res.length>0){
                            let master_switch = res[0].master_switch;
                            let im_switch = res[0].im_switch;
                            let family_topic_switch = res[0].family_topic_switch;
                            if(master_switch==0||im_switch==0){
                                ModelUtil.logError(targetId+"-关闭im消息,消息id", message.id);
                            }
                            // else if(session_type==SESSION_TYPES.MUC&&family_topic_switch==1){
                            //     SignFamilyRepo.isHealthDoctor(message.session_id,targetId,function (err,res) {
                            //         if(res&&res.length==0){
                            //             ModelUtil.logError("全科医生:"+targetId+"-关闭im消息,消息id", message.id);
                            //         }else{
                            //             AppClient.sendNotice(targetId, message, sessionType,badge,userStatus)
                            //         }
                            //     })
                            // }
                            else{
                                AppClient.sendNotice(targetId, message, sessionType,badge,userStatus)
                            }
                        }
                    });
                }else{
                    AppClient.sendNotice(targetId, message, sessionType,badge,userStatus)
                }
                // let pc_doctorClient = clientCache.findByIdAndType("pc_"+targetId,SOCKET_TYPES.PC_DOCTOR);
                // if(pc_doctorClient){
                //     log.warn("User's pc is online, user id: " + targetId + ", we cannot send getui.");
                //     return;
                AppClient.sendNotice(targetId, message, sessionType,badge,userStatus);
                // var session_type = isNaN(Number(sessionType))?sessionType:Number(sessionType);
                // if(session_type==SESSION_TYPES.SYSTEM||
                //     session_type==SESSION_TYPES.MUC||
                //     session_type==SESSION_TYPES.P2P||
                //     session_type==SESSION_TYPES.GROUP||
                //     session_type==SESSION_TYPES.DISCUSSION||
                //     session_type==SESSION_TYPES.PRESCRIPTION){
                //     //是否发送消息
                //     MessageNoticeSettingRepo.findOne(targetId,'1',function (err,res) {
                //         if(res&&res.length>0){
                //             let master_switch = res[0].master_switch;
                //             let im_switch = res[0].im_switch;
                //             let family_topic_switch = res[0].family_topic_switch;
                //             if(master_switch==0||im_switch==0){
                //                 ModelUtil.logError(targetId+"-关闭im消息,消息id", message.id);
                //             }
                //             else{
                //                 AppClient.sendNotice(targetId, message, sessionType,badge,userStatus);
                //             }
                //         }
                //     });
                // }else{
                //     AppClient.sendNotice(targetId, message, sessionType,badge,userStatus);
                // }
            });

+ 0 - 391
src/server/models/migration/migration.js

@ -1,391 +0,0 @@
/**
 * 群组,即原先的行政团队数据迁移。
 *
 * @author sand
 * @since 2017/1/9
 */
'use strict';
let ImDb = require('../../repository/mysql/db/im.db');
let ObjectUtil = require("../../util/object.util.js");
let DbUtil = require("../../util/db.util.js");
let async = require("async");
let log = require("../../util/log.js");
let fs = require('fs');
let mongoose = require("mongoose");
let vprintf = require('sprintf-js').vsprintf;
const MIGRATION_SCRIPT_File_NAME = "./ichat_1.2.8_data_migration.sql";
Date.prototype.format = function (fmt) { //author: meizz
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
};
class Migration {
    constructor() {
    }
    /**
     * 迁移系统消息
     */
    static migrateSystem() {
        let data = "-- System sessions: \n";
        async.waterfall([
                function (callback) {
                    // 所有的系统会话
                    let sql = "select distinct to_uid participant_id from im_new.msg_system order by to_uid";
                    ImDb.execQuery({
                        sql: sql,
                        args: [],
                        handler: function (err, res) {
                            if (err) {
                                return callback(err, res);
                            }
                            let buffer = "insert into sessions(id, name, type, create_date) values ";
                            res.forEach(function (session) {
                                buffer += vprintf("\n('%s', '%s', 0, now()),", [
                                    DbUtil.stringArrayHash(['system', session.participant_id]),
                                    "系统消息"
                                ]);
                            });
                            data += buffer.substr(0, buffer.length - 1) + ";\n";
                            callback(null);
                        }
                    });
                },
                function (callback) {
                    // 所有的系统消息
                    let sql = "SELECT msg_id 'id', 'session_id', 'system' `sender_id`, '系统通知' `sender_name`, 1 `content_type`, DATA 'content', timestamp, `type` 'business_type', to_uid FROM im_new.msg_system ORDER BY to_uid";
                    ImDb.execQuery({
                        sql: sql,
                        args: [],
                        handler: function (err, res) {
                            if (err) {
                                return callback(err, res);
                            }
                            let buffer = "insert into system_messages(id, session_id, sender_id, sender_name, content_type, content, timestamp, business_type) values";
                            res.forEach(function (message) {
                                buffer += vprintf("\n('%s', '%s', '%s', '%s', 1, '%s', %s, '%s'),", [
                                    mongoose.Types.ObjectId().toString(),
                                    DbUtil.stringArrayHash(['system', message.to_uid]),
                                    'system',
                                    '系统',
                                    message.content.replace(/'/g, "''"),
                                    ObjectUtil.timestampToLong(message.timestamp),
                                    message.business_type]);
                            });
                            data += buffer.substr(0, buffer.length - 1) + ";\n\n";
                            callback(null, null);
                        }
                    });
                }],
            function (err, res) {
                if (err) {
                    log.error("Error occurs while migrate system sessions: ", err);
                } else {
                    fs.writeFileSync(MIGRATION_SCRIPT_File_NAME, data + "\n");
                    log.info("Migrate System sessions succeed.");
                }
            });
    }
    /**
     * 迁移MUC及其消息。将原先的P2P中与患者有关的会话全部过来出来,再将其转为会话。议题从家庭医生库中提取出来。
     */
    static migrateMUC() {
        let data = "-- MUC legacy messages: \n";
        async.waterfall([
            function (callback) {
                //
                let sql = "SELECT concat(p.id, '_consult_2') session_id, p.id sender_id, p.name sender_name, m.msg_id message_id, m.`type` content_type, m.content, m.timestamp " +
                    "FROM wlyy.msg_p2p m, patients p  " +
                    "WHERE m.`type` IN (6,7) AND ((m.from_uid IN (  " +
                    "    SELECT code  " +
                    "FROM wlyy.wlyy_patient) AND m.to_uid IN (  " +
                    "    SELECT code  " +
                    "FROM wlyy.wlyy_doctor)) OR (m.to_uid IN (  " +
                    "    SELECT code  " +
                    "FROM wlyy.wlyy_patient) AND m.from_uid IN (  " +
                    "    SELECT code  " +
                    "FROM wlyy.wlyy_doctor)))  " +
                    "AND m.from_uid = p.id  " +
                    "ORDER BY m.timestamp";
                ImDb.execQuery({
                    sql: sql,
                    args: [],
                    handler: function (err, res) {
                        if(err){
                            return callback(err, null);
                        }
                        let messageBuffer = "insert into muc_messages(id, session_id, sender_id, sender_name, content_type, content, timestamp) values ";
                        res.forEach(function (message) {
                            messageBuffer += vprintf("\n('%s', '%s', '%s', '%s', '%s', '%s', '%s'),", [
                                mongoose.Types.ObjectId().toString(),
                                message.session_id,
                                message.sender_id,
                                message.sender_name,
                                message.content_type,
                                message.content.replace(/'/g, "''"),
                                message.timestamp.format("yyyy-MM-dd hh:mm:ss")
                            ]);
                        });
                        data += messageBuffer.substr(0, messageBuffer.length -1);
                        callback(null, null);
                    }
                });
            }
        ],
        function (err, res) {
            if (err) {
                log.error("Error occurs while migrate p2p sessions: ", err);
            } else {
                fs.writeFileSync(MIGRATION_SCRIPT_File_NAME, data + "\n");
                log.info("Migrate P2P sessions succeed.");
            }
        })
    }
    /**
     * 迁移P2P及其消息,新的IM中P2P仅给医生使用,因此过滤出原先发送与接收人均是医生的会话。
     */
    static migrateP2P() {
        let data = "-- P2P sessions: \n";
        async.waterfall([
                function (callback) {
                    // 所有的P2P 会话,成员与消息
                    let sql = "SELECT a.from_uid sender_id, d.name sender_name, a.to_uid to_id, e.name to_name, a.type content_type, a.content, a.timestamp " +
                        " FROM im_new.msg_p2p a " +
                        " LEFT JOIN wlyy.wlyy_doctor d ON a.from_uid = d.code " +
                        " LEFT JOIN wlyy.wlyy_doctor e on a.to_uid = e.code " +
                        " WHERE a.from_uid IN (SELECT code FROM wlyy.wlyy_doctor d) AND a.to_uid IN (SELECT code FROM wlyy.wlyy_doctor d)";
                    ImDb.execQuery({
                        sql: sql,
                        args: [],
                        handler: function (err, res) {
                            if (err) return callback(err, null);
                            let sessionsBuffer = "insert into sessions(id, name, type, create_date) values ";
                            let participantBuffer = "insert into participants(session_id, participant_id, participant_role, last_fetch_time) values ";
                            let messageBuffer = "insert into p2p_messages(id, session_id, sender_id, sender_name, content_type, content, timestamp) values ";
                            res.forEach(function (message) {
                                let sessionId = DbUtil.stringArrayHash([message.sender_id, message.to_id]);
                                // 会话
                                sessionsBuffer += vprintf("\n('%s', '%s', %s, %s),", [
                                    sessionId,
                                    'P2P',
                                    1,
                                    new Date('2016-11-22 12:00:00').getTime()
                                ]);
                                // 成员
                                participantBuffer += vprintf("\n('%s', '%s', %s, %s),", [
                                    sessionId,
                                    message.sender_id,
                                    0,
                                    new Date().getTime()
                                ]);
                                participantBuffer += vprintf("\n('%s', '%s', %s, %s),", [
                                    sessionId,
                                    message.to_id,
                                    0,
                                    new Date().getTime()
                                ]);
                                // 消息
                                messageBuffer += vprintf("\n('%s', '%s', '%s', '%s', '%s', '%s', %s),", [
                                    mongoose.Types.ObjectId().toString(),
                                    sessionId,
                                    message.sender_id,
                                    message.sender_name,
                                    message.content_type,
                                    message.content.replace(/'/g, "''"),
                                    ObjectUtil.timestampToLong(message.timestamp)
                                ]);
                            });
                            data += sessionsBuffer.substr(0, sessionsBuffer.length - 1) + " ON DUPLICATE KEY UPDATE id = id;\n\n";
                            data += participantBuffer.substr(0, participantBuffer.length - 1) + " ON DUPLICATE KEY UPDATE session_id = session_id;\n\n";
                            data += messageBuffer.substr(0, messageBuffer.length - 1) + " ON DUPLICATE KEY UPDATE id = id;\n\n";
                            callback(null);
                        }
                    });
                }
            ],
            function (err, res) {
                if (err) {
                    log.error("Error occurs while migrate p2p sessions: ", err);
                } else {
                    fs.writeFileSync(MIGRATION_SCRIPT_File_NAME, data + "\n");
                    log.info("Migrate P2P sessions succeed.");
                }
            });
    }
    /**
     * 迁移行政团队及其消息。群聊会话规则:
     * 1 使用行政团队的ID作为会话的ID
     * 2 会话成员是医生
     * 3 原消息取出来后,需要重新生成UUID
     */
    static migrateGroups() {
        let data = "-- MUC messages: \n";
        async.waterfall([
                function (callback) {
                    // 选择出所有的行政组,作为会话
                    let sql = "select t.id, t.name, 3 `type`, t.create_time 'create_date' " +
                        "from im_new.msg_group g, wlyy.wlyy_admin_team t " +
                        "where g.to_gid = t.id group by g.to_gid order by g.to_gid";
                    ImDb.execQuery({
                        sql: sql,
                        args: [],
                        handler: function (err, sessions) {
                            if (err) {
                                return callback(err, res);
                            }
                            let buffer = "insert into sessions(id, name, type, create_date) values ";
                            sessions.forEach(function (session) {
                                buffer += vprintf("\n('%s', '%s', %s, %s),", [
                                    session.id,
                                    session.name,
                                    session.type,
                                    ObjectUtil.timestampToLong(session.create_date)
                                ]);
                            });
                            data += buffer.substr(0, buffer.length - 1) + ";\n\n";
                            callback(null);
                        }
                    });
                },
                function (callback) {
                    // 选择出所有的行政组医生,作为会话成员
                    let sql = "select t.id session_id, m.id participant_id, 0 'participant_role', 0 'last_fetch_time' " +
                        "from im_new.msg_group g, wlyy.wlyy_admin_team t, wlyy.wlyy_admin_team_member m " +
                        "where g.to_gid = t.id and t.id = m.team_id group by g.to_gid order by g.to_gid";
                    ImDb.execQuery({
                        sql: sql,
                        args: [],
                        handler: function (err, participants) {
                            if (err) {
                                return callback(err, res);
                            }
                            let buffer = "insert into participants(session_id, participant_id, participant_role, last_fetch_time) values ";
                            participants.forEach(function (participant) {
                                buffer += vprintf("\n('%s', '%s', %s, %s),", [
                                    participant.session_id,
                                    participant.participant_id,
                                    participant.participant_role,
                                    ObjectUtil.timestampToLong(participant.last_fetch_time)
                                ]);
                            });
                            data += buffer.substr(0, buffer.length - 1) + ";\n\n";
                            callback(null);
                        }
                    });
                },
                function (callback) {
                    // 选择出所有的消息
                    let sql = "SELECT g.msg_id 'id', g.to_gid 'session_id', g.from_uid 'sender_id', u.name 'sender_name', g.`type` 'content_type', g.content 'content', g.timestamp 'timestamp', g.at_uid 'at' " +
                        "FROM im_new.msg_group g, wlyy.wlyy_doctor u " +
                        "WHERE LENGTH(g.to_gid) < 20 and g.from_uid = u.code " +
                        "ORDER BY g.to_gid";
                    ImDb.execQuery({
                        sql: sql,
                        args: [],
                        handler: function (err, messages) {
                            if (err) {
                                return callback(err, res);
                            }
                            let buffer = "insert into group_messages(id, session_id, sender_id, sender_name, content_type, content, timestamp, at) values ";
                            messages.forEach(function (message) {
                                buffer += vprintf("\n('%s', '%s', '%s', '%s', '%s', '%s', %s, '%s'),", [
                                    mongoose.Types.ObjectId().toString(),
                                    message.session_id,
                                    message.sender_id,
                                    message.sender_name,
                                    message.content_type,
                                    message.content.replace(/'/g, "''"),
                                    ObjectUtil.timestampToLong(message.timestamp),
                                    message.at
                                ]);
                            });
                            data += buffer.substr(0, buffer.length - 1) + ";\n\n";
                            callback(null, null);
                        }
                    });
                }
            ],
            function (err, res) {
                if (err) {
                    log.error("Error occurs while migrate group sessions: ", err);
                } else {
                    fs.appendFileSync(MIGRATION_SCRIPT_File_NAME, data, null);
                    log.info("Migrate group sessions succeed.");
                    process.exit(err != null ? 1 : 0);
                }
            });
    }
}
async.waterfall([
        function (callback) {
            //Migration.migrateSystem();
            callback(null);
        },
        function (callback) {
            Migration.migrateMUC();
            callback(null);
        },
        function (callback) {
            //Migration.migrateP2P();
            callback(null);
        },
        function (callback) {
            //Migration.migrateGroups();
            callback(null);
        }
    ],
    function (err, res) {
    });

+ 0 - 289
src/server/models/migration/migration.redis.js

@ -1,289 +0,0 @@
'use strict';
let RedisClient = require('../../repository/redis/redis.client');
let RedisModel = require('../redis.model');
let ImDb = require('../../repository/mysql/db/im.db');
let ParticipantRepo = require('../../repository/mysql/participant.repo');
let DoctorRepo = require('../../repository/mysql/doctor.repo');
let PatientRepo = require('../../repository/mysql/patient.repo');
let SessionRepo = require('../../repository/mysql/session.repo');
let MessageRepo = require('../../repository/mysql/message.repo');
let TopicRepo = require('../../repository/mysql/topics.repo');
let AppStatusRepo = require('../../repository/mysql/app.status.repo');
let ModelUtil = require('../../util/model.util');
let ObjectUtil = require("../../util/object.util.js");
let Patient = require('../user/patient');
let Doctor = require('../user/doctor');
let redisConn = RedisClient.redisClient().connection;
let async = require('async');
let log = require('../../util/log');
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
let fs = require('fs');
let mongoose = require("mongoose");
let vprintf = require('sprintf-js').vsprintf;
const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
const PLATFORMS = require('../../include/commons').PLATFORM;
const SESSION_TYPE = require('../../include/commons').SESSION_TYPES;
class MigrateRedis extends RedisModel{
    constructor(){
        super()
    }
    updateRedisCache(){
        let self = this;
        ImDb.execQuery({
            sql: "select user_id, platform, token, client_id, app_in_bg from im.app_status",
            args: [],
            handler: function (err, res) {
                res.forEach(function (appStatus, index) {
                    log.info("Processing at " + index + " / " + res.length);
                    self.login(appStatus.user_id, appStatus.platform, appStatus.token, appStatus.client_id);
                })
            }
        })
    }
    login(userId, platform, deviceToken, clientId) {
        let self = this;
        let loginFromApp = platform !== PLATFORMS.Wechat;
        let usersKey = REDIS_KEYS.Users;
        let userKey = RedisModel.makeRedisKey(REDIS_KEYS.User, userId);
        let userStatusKey = RedisModel.makeRedisKey(loginFromApp ? REDIS_KEYS.UserAppStatus : REDIS_KEYS.UserWechatStatus, userId);
        let lastLoginTime = new Date();
        async.waterfall([
                // get user info from mysql
                function (callback) {
                    self.getUserFromMySQL(userId, function (err, userInfo) {
                        if (!userInfo) {
                            ModelUtil.emitDataNotFound(self, 'User not exists.');
                            return;
                        }
                        callback(null, userInfo);
                    })
                },
                // cache user and app/wechat status
                function (userInfo, callback) {
                    let multi = redisConn.multi()
                        .zadd(usersKey, lastLoginTime.getTime(), userId);
                    /*.hmset(userKey,
                     'avatar', userInfo.avatar ? userInfo.avatar : '',
                     'birthdate', userInfo.birthdate ? ObjectUtil.timestampToLong(userInfo.birthdate) : '',
                     'name', userInfo.name,
                     'role', loginFromApp ? 'doctor' : 'patient');*/
                    if (loginFromApp) {
                        AppStatusRepo.save(userId, deviceToken, clientId, platform, function (err, res) {
                            if (err) log.error();
                        });
                        // cache app status
                        multi = multi.hmset(userStatusKey,
                            'app_in_bg', 0,
                            'client_id', clientId,
                            'device_token', deviceToken,
                            'last_login_time', lastLoginTime.getTime(),
                            'platform', platform);
                    } else {
                        // cache wechat status
                        multi = multi.hmset(userStatusKey,
                            'last_login_time', lastLoginTime.getTime(),
                            'openid', userInfo.openid,
                            'platform', platform);
                    }
                    multi.execAsync()
                        .then(function (res) {
                            callback(null);
                        })
                        .catch(function (ex) {
                            log.error("Login failed while cache user status: ", ex);
                        });
                },
                // cache sessions, participants, topics, messages
                function (callback) {
                    SessionRepo.findAll(userId, function (err, sessions) {
                        if (err) {
                            ModelUtil.emitError(self.eventEmitter, err.message);
                            return;
                        }
                        sessions.forEach(function (session) {
                            redisConn.zscore(REDIS_KEYS.Sessions, session.id, function (err, res) {
                                (function (sessionId, userId) {
                                    let business_type = session.business_type;
                                    if (session.type == SESSION_TYPE.MUC) {
                                        business_type = 2;
                                    }
                                    let redisSession = [
                                        "id", session.id,
                                        "name", session.name,
                                        "type", session.type,
                                        "business_type", business_type,
                                        "last_sender_id", session.last_sender_id == null ? "" : session.last_sender_id,
                                        "last_sender_name", session.last_sender_name == null ? "" : session.last_sender_name,
                                        "last_content_type", session.last_content_type == null ? "" : session.last_content_type,
                                        "last_content", session.last_content == null ? "" : session.last_content,
                                        "last_message_time", session.last_message_time == null ? "" : session.last_message_time,
                                        "create_date", ObjectUtil.timestampToLong(session.create_date),
                                        "status",session.status==null?0:session.status
                                    ];
                                    // cache sessions
                                    redisConn.multi()
                                        .zadd(REDIS_KEYS.Sessions, lastLoginTime.getTime(), sessionId)                                           // 会话的最后活动时间设置为此用户的登录时间
                                        .zadd(RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, userId), lastLoginTime.getTime(), sessionId)      // 会话的最后活动时间设置为此用户的登录时间
                                        .hmset(RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId), redisSession)
                                        .execAsync()
                                        .then(function (res) {
                                            // cache participants
                                            let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                                            let sessionParticipantsRoleKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipantsRole, sessionId);
                                            ParticipantRepo.findAll(sessionId, function (err, participants) {
                                                if (err) {
                                                    ModelUtil.emitError(self.eventEmitter, err.message);
                                                    return;
                                                }
                                                let multi = redisConn.multi();
                                                participants.forEach(function (participant) {
                                                    let participantId = participant.id;
                                                    let participantRole = participant.role;
                                                    let score = ObjectUtil.timestampToLong(participant.last_fetch_time);
                                                    multi = multi.zadd(sessionParticipantsKey, score, participantId)
                                                        .hset(sessionParticipantsRoleKey, participantId, participantRole);
                                                });
                                                multi.execAsync()
                                                    .then(function (res) {
                                                    })
                                                    .catch(function (ex) {
                                                        log.error("Login failed while caching participants: ", ex);
                                                    });
                                            });
                                            // cache messages
                                            let messagesKey = RedisModel.makeRedisKey(REDIS_KEYS.Messages, sessionId);
                                            let messagesByTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                                            MessageRepo.findBySessionId(sessionId, 0, config.sessionConfig.maxMessageCount, null, function (err, messages) {
                                                if (err) {
                                                    ModelUtil.emitError(self.eventEmitter, err.message);
                                                    return;
                                                }
                                                let multi = redisConn.multi();
                                                messages.forEach(function (message) {
                                                    let msgJson = {
                                                        id: message.id,
                                                        sender_id: message.sender_id,
                                                        sender_name: message.sender_name,
                                                        timestamp: ObjectUtil.timestampToLong(message.timestamp),
                                                        content_type: message.content_type,
                                                        content: message.content
                                                    };
                                                    multi = multi.hset(messagesKey, message.id, JSON.stringify(msgJson))
                                                        .zadd(messagesByTimestampKey, ObjectUtil.timestampToLong(message.timestamp), message.id);
                                                });
                                                multi.execAsync()
                                                    .then(function (res) {
                                                    })
                                                    .catch(function (ex) {
                                                        log.error("Login failed while caching messages: ", ex);
                                                    });
                                            });
                                            // cache topics for MUC
                                            let topicsKey = RedisModel.makeRedisKey(REDIS_KEYS.Topics, sessionId);
                                            TopicRepo.findAllBySessionId(sessionId, function (err, topics) {
                                                if (err) {
                                                    ModelUtil.emitError(self.eventEmitter, err.message);
                                                    return;
                                                }
                                                topics.forEach(function (topic) {
                                                    let topicKey = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topic.id);
                                                    let topicId = topic.id;
                                                    let name = topic.name == null ? "" : topic.name;
                                                    let createTime = ObjectUtil.timestampToLong(topic.create_time);
                                                    let endBy = topic.end_by == null ? "" : topic.end_by;
                                                    let endTime = topic.end_time == null ? 0 : ObjectUtil.timestampToLong(topic.end_time);
                                                    let startMessageId = topic.start_message_id == null ? "" : topic.start_message_id;
                                                    let endMessageId = topic.end_message_id == null ? "" : topic.end_message_id;
                                                    let description = topic.description == null ? "" : topic.description;
                                                    let status = topic.status == null ? 0 : topic.status;
                                                    redisConn.multi()
                                                        .zadd(topicsKey, createTime, topicId)
                                                        .hmset(topicKey,
                                                            'name', name,
                                                            'session_id', sessionId,
                                                            'create_time', createTime,
                                                            'end_by', endBy,
                                                            'end_time', endTime,
                                                            'start_message_id', startMessageId,
                                                            'end_message_id', endMessageId,
                                                            'description', description,
                                                            'status', status)
                                                        .execAsync()
                                                        .catch(function (ex) {
                                                            log.error("Login failed while caching topics: ", ex);
                                                        });
                                                });
                                            });
                                        })
                                        .catch(function (ex) {
                                            log.error("Login failed while caching sessions: ", ex);
                                        });
                                })(session.id, userId);
                            });
                        });
                    });
                    callback(null, null);
                }
            ],
            function (err, res) {
                log.info("Update user " + userId);
            });
    }
    /**
     * 获取用户,直接从MYSQL获取,缓存是否有在不能确定。
     *
     * @param userId
     * @param outCallback
     */
    getUserFromMySQL(userId, outCallback) {
        async.waterfall([
            // get from mysql
            function (isPatientId) {
                let repoProto = isPatientId ? PatientRepo : DoctorRepo;
                repoProto.findOne(userId, function (err, res) {
                    let user = isPatientId ? new Patient() : new Doctor();
                    if (res.length > 0) {
                        user.name = res[0].name;
                        user.sex = res[0].sex;
                        user.birthdate = res[0].birthdate;
                        user.avatar = res[0].avatar;
                        if (res[0].openid) user.openid = res[0].openid;
                    }
                    outCallback(null, user);
                });
            }
        ]);
    }
}
new MigrateRedis().updateRedisCache();

+ 0 - 177
src/server/models/migration/migration.topics.js

@ -1,177 +0,0 @@
/**
 * 群组,即原先的行政团队数据迁移。
 *
 * @author sand
 * @since 2017/1/9
 */
'use strict';
let ImDb = require('../../repository/mysql/db/im.db');
let ObjectUtil = require("../../util/object.util.js");
let DbUtil = require("../../util/db.util.js");
let async = require("async");
let log = require("../../util/log.js");
let fs = require('fs');
let mongoose = require("mongoose");
let vprintf = require('sprintf-js').vsprintf;
const MIGRATION_SCRIPT_File_NAME = "./ichat_1.2.8_topics_migration.sql";
class Migration {
    constructor() {
    }
    /**
     * 迁移议题及会话。
     */
    static migrateTopicAndSession() {
        let sessionIds = [];
        let data = "-- Topics update: \n";
        async.waterfall([
                /*function (callback) {
                 // 未导入的历史咨询
                 let sql = "select t.consult id, concat(t.patient, '_consult_2') session_id, t.name name, t.czrq create_time, t.end_operator end_by, t.end_time end_time, 0 'status', t.symptoms description " +
                 "from wlyy.wlyy_consult_team t where t.consult not in (select id from im.topics)";
                 ImDb.execQuery({
                 sql: sql,
                 args: [],
                 handler: function (err, res) {
                 if (err) {
                 return callback(err, res);
                 }
                 let buffer = "insert into topics(id, session_id, name, create_time, end_by, end_time, status, description) values ";
                 res.forEach(function (topic) {
                 buffer += vprintf("\n('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'),", [
                 topic.id,
                 topic.session_id,
                 topic.name,
                 topic.create_time,
                 topic.end_by,
                 topic.end_time,
                 topic.status,
                 topic.description
                 ]);
                 topics.push(topic.id);
                 });
                 data += buffer.substr(0, buffer.length - 1) + " ON DUPLICATE KEY UPDATE id = id;\n";
                 callback(null);
                 }
                 });
                 },
                 function (callback) {
                 // 未导入的历史咨询所属会话
                 let sql = "select concat(c.patient, '_consult_2') id, c.name, 1 'type', 2 'business_type', c.czrq 'create_date' " +
                 "from wlyy.wlyy_consult_team c where concat(c.patient, '_consult_2') not in (select id from im.sessions s) group by c.patient order by c.patient";
                 ImDb.execQuery({
                 sql: sql,
                 args: [],
                 handler: function (err, res) {
                 if (err) {
                 return callback(err, res);
                 }
                 let buffer = "insert into sessions(id, name, type, business_type, create_date) values";
                 res.forEach(function (session) {
                 buffer += vprintf("\n('%s', '%s', '%s', '%s', '%s'),", [
                 session.id,
                 session.name,
                 session.type,
                 session.business_type,
                 session.create_date]);
                 });
                 data += buffer.substr(0, buffer.length - 1) + " ON DUPLICATE KEY UPDATE id = id;\n\n";
                 callback(null, null);
                 }
                 });
                 },*/
                function (callback) {
                    // 更新与未导入咨询相关的始末消息ID
                    let sql = "select t.id, t.session_id, t.name, t.create_time, t.end_by " +
                        "from topics t " +
                        "where t.start_message_id is null and t.end_message_id is null group by t.session_id " +
                        "order by session_id";
                    ImDb.execQuery({
                        sql: sql,
                        args: [],
                        handler: function (err, res) {
                            res.forEach(function (topic) {
                                let sessionId = topic.session_id;
                                sessionIds.push(sessionId);
                            });
                            callback(null);
                        }
                    });
                },
                function (callback) {
                    ImDb.execQuery({
                        sql: "select session_id, id message_id from muc_messages m where m.session_id in (?) order by session_id, m.id",
                        args: [sessionIds],
                        handler: function (err, res) {
                            let lastSessionId = null;
                            let lastMsgId = null;
                            let minMsgId = null;
                            let maxMsgId = null;
                            for(let i = 0; i < res.length; ++i){
                                console.log("Processing item " + i);
                                let item = res[i];
                                if(lastSessionId !== item.session_id){
                                    lastSessionId = item.session_id;
                                    maxMsgId = lastMsgId;
                                    if(maxMsgId !== null){
                                        let updateSQL = "update topics t set t.start_message_id = '%s', t.end_message_id = '%s' where t.session_id = '%s'; \n";
                                        updateSQL = vprintf(updateSQL, [minMsgId, maxMsgId, lastSessionId]);
                                        data += updateSQL;
                                    }
                                    minMsgId = item.message_id;
                                }
                                lastMsgId = item.message_id;
                                if(i === res.length - 1){
                                    let updateSQL = "update topics t set t.start_message_id = '%s', t.end_message_id = '%s' where t.session_id = '%s'; \n";
                                    updateSQL = vprintf(updateSQL, [minMsgId, lastMsgId, lastSessionId]);
                                    data += updateSQL;
                                    callback(null, null);
                                }
                            }
                        }
                    });
                }],
            function (err, res) {
                if (err) {
                    log.error("Error occurs while migrating topics and sessions: ", err);
                } else {
                    fs.writeFileSync(MIGRATION_SCRIPT_File_NAME, data + "\n");
                    log.info("Migrate topics and sessions succeed");
                }
            });
    }
}
async.waterfall([
        function (callback) {
            Migration.migrateTopicAndSession();
            callback(null);
        }
    ],
    function (err, res) {
    });

+ 131 - 131
src/server/models/redis/pubSub.js

@ -1,131 +1,131 @@
/*
 * redis发布订阅
 *example:
 * let channel="ryan";
 redis.pubSub.registerHandlers("ryan",msg=> console.log(msg));
 redis.pubSub.subscribe(channel);
 redis.pubSub.publish(channel,"hello from chen");
 */
"use strict";
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
let RedisModel = require('./../redis.model');
let RedisSubClient = require('./redisSubClient');
let RedisPubClient = require('./redisPubClient');
let RedisClient = require('../../repository/redis/redis.client.js');
let redisPubConn = RedisPubClient.redisClient().connection;
let redisSubConn = RedisSubClient.redisClient().connection;
let redis = RedisClient.redisClient().connection;
let Sessions = require('../../models/sessions/sessions');
let WechatClient = require("../client/wechat.client.js");
let WlyySDK = require("../../util/wlyy.sdk");
let AppClient = require("../client/app.client.js");
let Participants = require('../sessions/participants');
let Messages = require('../messages/messages');
const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
let ObjectUtil = require("../../util/object.util.js");
let logger = require('../../util/log.js');
let SessionRepo = require('../../repository/mysql/session.repo');
let ParticipantRepo = require('../../repository/mysql/participant.repo');
const SESSION_TYPES = require('../../include/commons').SESSION_TYPES;
const SESSION_BUSINESS_TYPE = require('../../include/commons').SESSION_BUSINESS_TYPE;
class PubSub{
    constructor(){
        this.sub=redisSubConn;
        this.handlers=new Map();
        this.subAction=(channle,message)=>{
            let actions= this.handlers.get(channle)||new Set();
            for(let action of actions)
            {
                console.log("接收消息:"+message);
                message = JSON.parse(message);
                if(config.pubSubSwitch){//接收订阅消息处理开关,本地运行和测试库单独运行时防止用户接收消息2次
                    //Sessions.getRedisPushNotification(message);这里不知为什么无法调用这个方法,提示getRedisPushNotification不是方法
                    if (message.targetType=='patient') {
                        if(config.environment!='local'){//pc版接收要发给居民的消息不做处理
                            WechatClient.sendMessage(message.targetUserId, message.targetUserName, message);
                        }
                    } else {
                        if(message.sessionType=="1"){
                            WechatClient.sendReadDoctorByDoctorId(message.targetUserId, message);
                        }
                        //告知医生新消息
                        WechatClient.sendSocketMessageToDoctor(message.targetUserId,message);
                        if(config.environment!='local'){//pc版不推送个推
                            WlyySDK.request(message.targetUserId, '', '', '', '/im/common/message/messages', 'POST', function (err, res) {
                                let count = 0;
                                res =  JSON.parse(res)
                                if (res.status == 200) {
                                    let data = res.data;
                                    count = parseInt(JSON.parse(data.imMsgCount).count) + parseInt(data.system.amount) + parseInt(data.healthIndex.amount) + parseInt(data.sign.amount);
                                }
                                AppClient.sendNotification(message.targetUserId, message,message.sessionType,count);
                            });
                        }
                        //外网pcim通过socket推送
                        WechatClient.sendPcImSocket(message.targetUserId,message,message.sessionType);
                    }
                }
                //action(message);
            }
        }
        this.alredyPublishs=[];
        this.subConnected=false;
    }
    publish(channel,message)
    {
        let action=()=>{
            let pub=redisPubConn;
            pub.publish(channel,message);
            console.log("发布消息:channel:"+channel+",message:"+message);
        };
        if(this.subConnected===false)
        {
            this.alredyPublishs.push(action);
        }
        else{
            action();
        }
    }
    registerHandlers(channel,action)
    {
        var actions=this.handlers.get(channel)||new Set();
        actions.add(action);
        this.handlers.set(channel,actions);
    }
    subscribe(channel)
    {
        let self=this;
        this.sub.subscribe(channel,function (err,reply) {
            if(err){
                log.error(err);
            }
            self.subConnected=true;
            for(let publish of self.alredyPublishs){
                publish();
            }
            console.log("订阅成功:"+reply);
        });
        this.sub.on("message", function (channel, message) {
            self.subAction(channel,message);
        });
    }
    tearDown()
    {
        this.sub.quit();
    }
}
// Expose class
module.exports = new PubSub();
// /*
//  * redis发布订阅
//  *example:
//  * let channel="ryan";
//  redis.pubSub.registerHandlers("ryan",msg=> console.log(msg));
//  redis.pubSub.subscribe(channel);
//
//  redis.pubSub.publish(channel,"hello from chen");
//  */
// "use strict";
//
// let configFile = require('../../include/commons').CONFIG_FILE;
// let config = require('../../resources/config/' + configFile);
//
// let RedisModel = require('./../redis.model');
// let RedisSubClient = require('./redisSubClient');
// let RedisPubClient = require('./redisPubClient');
// let RedisClient = require('../../repository/redis/redis.client.js');
// let redisPubConn = RedisPubClient.redisClient().connection;
// let redisSubConn = RedisSubClient.redisClient().connection;
// let redis = RedisClient.redisClient().connection;
// let Sessions = require('../../models/sessions/sessions');
// let WechatClient = require("../client/wechat.client.js");
// let WlyySDK = require("../../util/wlyy.sdk");
// let AppClient = require("../client/app.client.js");
// let Participants = require('../sessions/participants');
// let Messages = require('../messages/messages');
// const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
// let ObjectUtil = require("../../util/object.util.js");
// let logger = require('../../util/log.js');
// let SessionRepo = require('../../repository/mysql/session.repo');
// let ParticipantRepo = require('../../repository/mysql/participant.repo');
//
// const SESSION_TYPES = require('../../include/commons').SESSION_TYPES;
// const SESSION_BUSINESS_TYPE = require('../../include/commons').SESSION_BUSINESS_TYPE;
//
// class PubSub{
//     constructor(){
//         this.sub=redisSubConn;
//         this.handlers=new Map();
//
//         this.subAction=(channle,message)=>{
//             let actions= this.handlers.get(channle)||new Set();
//             for(let action of actions)
//             {
//                 console.log("接收消息:"+message);
//                 message = JSON.parse(message);
//
//                 if(config.pubSubSwitch){//接收订阅消息处理开关,本地运行和测试库单独运行时防止用户接收消息2次
//                     //Sessions.getRedisPushNotification(message);这里不知为什么无法调用这个方法,提示getRedisPushNotification不是方法
//                     if (message.targetType=='patient') {
//                         if(config.environment!='local'){//pc版接收要发给居民的消息不做处理
//                             WechatClient.sendMessage(message.targetUserId, message.targetUserName, message);
//                         }
//                     } else {
//                         if(message.sessionType=="1"){
//                             WechatClient.sendReadDoctorByDoctorId(message.targetUserId, message);
//                         }
//                         //告知医生新消息
//                         WechatClient.sendSocketMessageToDoctor(message.targetUserId,message);
//                         if(config.environment!='local'){//pc版不推送个推
//                             WlyySDK.request(message.targetUserId, '', '', '', '/im/common/message/messages', 'POST', function (err, res) {
//                                 let count = 0;
//                                 res =  JSON.parse(res)
//                                 if (res.status == 200) {
//                                     let data = res.data;
//                                     count = parseInt(JSON.parse(data.imMsgCount).count) + parseInt(data.system.amount) + parseInt(data.healthIndex.amount) + parseInt(data.sign.amount);
//                                 }
//
//                                 AppClient.sendNotification(message.targetUserId, message,message.sessionType,count);
//                             });
//                         }
//                         //外网pcim通过socket推送
//                         WechatClient.sendPcImSocket(message.targetUserId,message,message.sessionType);
//                     }
//                 }
//                 //action(message);
//             }
//         }
//         this.alredyPublishs=[];
//         this.subConnected=false;
//     }
//
//     publish(channel,message)
//     {
//         let action=()=>{
//             let pub=redisPubConn;
//             pub.publish(channel,message);
//             console.log("发布消息:channel:"+channel+",message:"+message);
//         };
//         if(this.subConnected===false)
//         {
//             this.alredyPublishs.push(action);
//         }
//         else{
//             action();
//         }
//     }
//     registerHandlers(channel,action)
//     {
//         var actions=this.handlers.get(channel)||new Set();
//         actions.add(action);
//         this.handlers.set(channel,actions);
//     }
//     subscribe(channel)
//     {
//         let self=this;
//         this.sub.subscribe(channel,function (err,reply) {
//             if(err){
//                 log.error(err);
//             }
//             self.subConnected=true;
//             for(let publish of self.alredyPublishs){
//                 publish();
//             }
//             console.log("订阅成功:"+reply);
//         });
//
//         this.sub.on("message", function (channel, message) {
//             self.subAction(channel,message);
//         });
//     }
//
//     tearDown()
//     {
//         this.sub.quit();
//     }
// }
//
// // Expose class
// module.exports = new PubSub();

+ 5 - 5
src/server/models/sessions/sessions.js

@ -26,7 +26,7 @@ let logger = require('../../util/log.js');
let mongoose = require('mongoose');
let async = require("async");
let log = require("../../util/log.js");
let pubSub = require("../redis/pubSub.js");
// let pubSub = require("../redis/pubSub.js");
const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
const SESSION_TYPES = require('../../include/commons').SESSION_TYPES;
@ -1643,9 +1643,9 @@ class Sessions extends RedisModel {
                message.targetType = 'doctor';
            }
            //redis发布消息
            if(config.pubSubSwitch) {//接收订阅消息处理开关,本地运行和测试库单独运行时防止用户接收消息2次
                pubSub.publish(config.pubChannel,JSON.stringify(message));
            }
            // if(config.pubSubSwitch) {//接收订阅消息处理开关,本地运行和测试库单独运行时防止用户接收消息2次
            //     pubSub.publish(config.pubChannel,JSON.stringify(message));
            // }
        });
    }
@ -1673,7 +1673,7 @@ class Sessions extends RedisModel {
                    res =  JSON.parse(res)
                    if (res.status == 200) {
                        let data = res.data;
                        count = parseInt(JSON.parse(data.imMsgCount).count) + parseInt(data.system.amount) + parseInt(data.healthIndex.amount) + parseInt(data.sign.amount);
                        count = parseInt(JSON.parse(data.imMsgCount).count) + parseInt(data.system.amount) + parseInt(data.concern.amount);
                    }
                    AppClient.sendNotification(message.targetUserId, message,message.sessionType,count);
                });

+ 0 - 19
src/server/repository/mysql/participant.repo.js

@ -96,25 +96,6 @@ class ParticipantRepo {
        });
    }
    /**
     * 获取会话的居民的家庭成员
     * @param sessionId
     * @param handler
     */
    static findFamilyIds(sessionId, handler){
        let sql =
            "SELECT u.id, u.name, true is_patient, p.participant_role,u.avatar,ps.name pname,ps.id pid " +
            "FROM sessions s, participants p, patients u ,wlyy.wlyy_patient_family_member m,patients ps " +
            "WHERE s.id = ? and s.id = p.session_id and p.participant_id = m.patient AND m.family_member = u.id and m.is_authorize = 1 and p.participant_id = ps.id ";
        //新增发送代理人
        ImDb.execQuery({
            "sql": sql,
            "args": [sessionId],
            "handler": handler
        });
    }
    /**
     * 获取会话的成员头像列表
     *

+ 3 - 12
src/server/repository/mysql/patient.repo.js

@ -9,6 +9,7 @@
"use strict";
let ImDb = require('./db/im.db');
const DB_TABLES = require('../../include/commons').DB_TABLES;
class PatientRepo {
    constructor() {
@ -38,10 +39,10 @@ class PatientRepo {
     * @param handler
     */
    static findWechatOpenIds(code, handler){
        var sql = "SELECT m.family_member code,p.name,p.openid from wlyy.wlyy_patient p,wlyy.wlyy_patient_family_member m" +
        var sql = "SELECT m.family_member code,p.name,p.openid from "+DB_TABLES.WlyyPatient+" p,"+DB_TABLES.WlyyPatientFamilyMember+" m" +
            "  WHERE m.patient = ? and m.family_member=p.code and p.openid is not null" +
            " UNION ALL" +
            "  SELECT p.code,p.name,p.openid  from wlyy.wlyy_patient p WHERE p.code = ?";
            "  SELECT p.code,p.name,p.openid  from "+DB_TABLES.WlyyPatient+" p WHERE p.code = ?";
        ImDb.execQuery({
            "sql": sql,
            "args": [code,code],
@ -49,16 +50,6 @@ class PatientRepo {
        });
    }
    // TODO: 不能直接访问三师库
    static getPatientDoctorConsult(patient, doctor, handler) {
        var sql = "select * from wlyy_consult_team where patient = ? and doctor = ? and status = 0 and del = '1' ";
        ImDb.execQuery({
            "sql": sql,
            "args": [patient, doctor],
            "handler": handler
        });
    };
}
module.exports = PatientRepo;

+ 0 - 160
src/server/repository/mysql/private.msg.repo.js

@ -1,160 +0,0 @@
/**
 * P2P消息库。
 */
"use strict";
var ImDb = require("../mysql/db/im.db.js");
class PrivateMsgRepo {
    constructor() {
    }
    /**
     * 保存消息。
     *
     * @param to
     * @param from
     * @param type
     * @param content
     * @param handler
     */
    static save(to, from, type, content, handler) {
        ImDb.execQuery({
            "sql": "INSERT INTO msg_p2p (to_uid,from_uid,type,content) VALUES (?,?,?,?)",
            "args": [to, from, type, content],
            "handler": handler
        });
    };
    static findOneMessage(messageId, handler) {
        ImDb.execQuery({
            "sql": "SELECT msg_id, to_uid, from_uid, type, content, timestamp from msg_p2p where msg_id = ?",
            "args": [messageId],
            "handler": handler
        });
    };
    static findOnePatientMessage(messageId, handler) {
        ImDb.execQuery({
            "sql": "SELECT m.*,d.name,d.photo FROM msg_p2p m, wlyy.wlyy_doctor d, wlyy.wlyy_patient p WHERE m.from_uid = d. CODE AND m.to_uid = p. CODE AND m.msg_id =?",
            "args": [messageId],
            "handler": handler
        });
    };
    /**
     * 查找所有消息。
     *
     * @param to
     * @param from
     * @param contentType
     * @param start
     * @param end
     * @param count
     * @param closedInterval
     * @param handler
     */
    static findAllMessages(to, from, contentType, start, end, count, closedInterval, handler) {
        var sql = "SELECT msg_id, to_uid, from_uid, type, content, timestamp from msg_p2p " +
            "WHERE ((to_uid=? AND from_uid=?) OR (to_uid=? AND from_uid=?)) " +
            "   AND type in (" + contentType + ") AND msg_id between ? and ? ORDER BY msg_id DESC LIMIT ?";
        ImDb.execQuery({
            "sql": sql,
            "args": [to, from, from, to, closedInterval ? end : end + 1, closedInterval ? start : start - 1, count],
            "handler": handler
        });
    };
    /**
     * 查找用户聊天过的医生列表。
     *
     * @param userId 指定的用户
     * @param handler
     */
    static findAllP2PWithDoctor(userId, handler) {
        //var sql = "SELECT DISTINCT d.code, d.name, d.sex, d.photo, ms3.last_content_type, ms3.last_content, ms3.timestamp, ms3.new_msg_count " +
        //    "FROM (SELECT DISTINCT CASE WHEN ms1.timestamp > ms2.timestamp THEN ms1.id ELSE ms2.id END id " +
        //    "      FROM msg_statistic ms1, msg_statistic ms2 " +
        //    "      WHERE ms1.from_gid IS NULL AND ms2.from_gid IS NULL " +
        //    "            AND ms1.uid = ms2.peer_uid AND ms1.peer_uid = ms2.uid) x, msg_statistic ms3, wlyy.wlyy_doctor d " +
        //    "WHERE x.id = ms3.id AND ms3.last_content_type in (1,2,3,5,6) AND " +
        //    "(ms3.uid = ? AND ms3.peer_uid = d.code) GROUP BY d.code, d.name ORDER BY ms3.timestamp DESC";
        var sql = "SELECT d. CODE as code, d. NAME as name,  d.sex, d.photo, s.last_content_type, s.last_content, s. TIMESTAMP as timestamp, s.new_msg_count " +
            "FROM msg_p2p p, wlyy.wlyy_doctor d, msg_statistic s " +
            "WHERE (( p.from_uid = d. CODE AND p.to_uid = ? ) OR ( p.to_uid = d. CODE AND p.from_uid = ? )) " +
            "AND s.from_gid IS NULL AND s.uid = ? " +
            "AND s.peer_uid = d. CODE " +
            "GROUP BY d. NAME, d. CODE, d.hospital_name, d.job_name, d.sex, d.photo ORDER BY p.msg_id DESC"
        ImDb.execQuery({
            "sql": sql,
            "args": [userId, userId, userId],
            "handler": handler
        });
    };
    /**
     * 查找用户聊天过的患者列表。
     *
     * @param userId
     * @param handler
     */
    static findAllP2PWithPatient(userId, handler) {
        //var sql = "SELECT p.code, p.name, p.birthday, p.sex, p.photo, ms.last_content_type, ms.last_content, ms.timestamp, ms.new_msg_count " +
        //    "FROM msg_statistic ms, wlyy.wlyy_patient p " +
        //    "WHERE ms.msg_type = 1 AND ms.last_content_type in (1,2,3,5,6) " +
        //    "AND ((ms.from_uid = ? AND ms.uid = p.code) OR (ms.uid = ? AND ms.from_uid = p.code)) ORDER BY ms.timestamp";
        var sql = "SELECT p1. CODE as code , p1. NAME as name, p1.birthday, p1.sex, p1.photo, w.last_content, w.last_content_type, w. TIMESTAMP as timestamp, w.new_msg_count " +
            "FROM msg_p2p p, wlyy.wlyy_patient p1, msg_statistic w " +
            "WHERE (( p.to_uid = p1.`code` AND p.from_uid = ? ) OR ( p.from_uid = p1.`code` AND p.to_uid = ? )) " +
            "AND w.last_content_type IN (1, 2, 3, 5, 6) AND w.uid = ? AND w.peer_uid = p1.`code` AND w.from_gid IS NULL " +
            "GROUP BY p1. CODE, p1. NAME, p1.birthday, p1.sex, p1.photo " +
            "union all " +
            "SELECT p1. CODE AS code, p1. NAME AS name, p1.birthday, p1.sex, p1.photo, w.last_content, t.type, w. TIMESTAMP AS timestamp, w.new_msg_count " +
            "FROM msg_p2p p, wlyy.wlyy_patient p1, msg_statistic w, wlyy.wlyy_consult_team t " +
            "WHERE (( p.to_uid = p1.`code` AND p.from_uid = ? ) OR ( p.from_uid = p1.`code` AND p.to_uid = ? )) " +
            "AND w.last_content_type = 7 AND t.type = 6 " +
            "AND (( t.patient = p.from_uid AND t.doctor = p.to_uid ) OR ( t.patient = p.to_uid AND t.doctor = p.from_uid )) " +
            "AND w.uid = ? AND w.peer_uid = p1.`code` AND w.from_gid IS NULL GROUP BY p1. CODE, p1. NAME, p1.birthday, p1.sex, p1.photo;";
        ImDb.execQuery({
            "sql": sql,
            "args": [userId, userId, userId, userId, userId, userId],
            "handler": handler
        });
    };
    /**
     * 查找未读消息。
     *
     * @param from
     * @param to
     * @param start
     * @param count
     * @param handler
     */
    static findUnread  (from, to, start, count, handler) {
        var sql = "SELECT msg_id, to_uid, from_uid, type, content, timestamp from msg_p2p " +
            "WHERE from_uid = ? AND to_uid = ? AND msg_id < ? ORDER BY timestamp DESC LIMIT ?";
        ImDb.execQuery({
            "sql": sql,
            "args": [from, to, start, count],
            "handler": handler
        });
    };
    static isCurrentSessionFinished(doctorId, patientId, handler) {
        var sql = "SELECT c.consult consult_id, case when c.end_msg_id is not null then 1 else 0 end finished " +
            "FROM wlyy.wlyy_consult_team c where c.doctor=? and c.patient = ? ORDER BY id DESC LIMIT 1";
        ImDb.execQuery({
            "sql": sql,
            "args": [doctorId, patientId],
            "handler": handler
        });
    };
}
module.exports = PrivateMsgRepo;

+ 6 - 6
src/server/repository/mysql/search.repo.js

@ -20,11 +20,11 @@ class SearchRepo {
    static findTopicEndedSessionIdList(userId, handler) {
        let sql = "SELECT s.id " +
            "FROM sessions s, topics t, participants p " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NOT NULL AND s.`type` IN (1,2,8) " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NOT NULL AND s.`type` IN (1) " +
            " UNION " +
            "SELECT s.id " +
            "FROM sessions s, participants p " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.`type` IN (2, 3)";
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.`type` IN (1, 3)";
        ImDb.execQuery({
            sql: sql,
@ -42,11 +42,11 @@ class SearchRepo {
    static findTopicActiveSessionIdList(userId, handler) {
        let sql = "SELECT s.id " +
            "FROM sessions s, topics t, participants p " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NULL  AND s.`type` IN (1,2,8) " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NULL  AND s.`type` IN (1) " +
            " UNION " +
            "SELECT s.id " +
            "FROM sessions s, participants p " +
            "WHERE p.participant_id = ? AND p.session_id = s.id  AND s.`type` IN (2,3)  and s.id not in(" +
            "WHERE p.participant_id = ? AND p.session_id = s.id  AND s.`type` IN (1,3)  and s.id not in(" +
            " select DISTINCT p1.session_id from  participants p1 ,topics t where p1.participant_id = ? and  t.session_id = p1.session_id  " +
            ") ";
        ImDb.execQuery({
@ -115,9 +115,9 @@ class SearchRepo {
            " u,sessions s WHERE s.id in (?) AND s.id = p.session_id AND p.participant_id = u.id and p.participant_id<>? AND (u.name like ? or u.idcard like ?) ";
        if (userTable === DB_TABLES.Doctors) {
            sql += " AND s.type in (2) and s.business_type = 1 ";
            sql += " AND s.type in (1) and s.business_type = 1 ";
        }else{
            sql += " AND s.type in (1,2,8)  and s.business_type = 2 ";
            sql += " AND s.type in (1)  and s.business_type = 2 ";
        }
        sql += " limit ?, ? ";
        sql = vsprintf(sql, [userTable == DB_TABLES.Doctors ? ', hospital_name' : '']);

+ 1 - 1
src/server/repository/mysql/session.repo.js

@ -203,7 +203,7 @@ class SessionRepo {
     * @param handler
     */
    static findAllByTimestampAndType(userId, dateSpan, handler) {
        let sql = "SELECT DISTINCT s.id, CASE WHEN TYPE = 2 THEN d.name ELSE s.name END 'name',s.last_content_type, s.type, s.create_date, s.business_type " +
        let sql = "SELECT DISTINCT s.id, CASE WHEN TYPE = 1 THEN d.name ELSE s.name END 'name',s.last_content_type, s.type, s.create_date, s.business_type " +
        "FROM sessions s, participants p " +
        "LEFT JOIN doctors d ON p.participant_id = d.id " +
        "WHERE s.id = p.session_id AND s.last_sender_id <> 'system' " +

+ 0 - 51
src/server/repository/mysql/sign.family.repo.js

@ -1,51 +0,0 @@
/**
 * Created by ysj on 2017/12/4.
 */
"use strict";
let log = require('../../util/log');
let ImDb = require('../mysql/db/im.db');
const DB_TABLES = require('../../include/commons').DB_TABLES;
class SignFamilyRepo{
    constructor(){
    }
    /**
     * 获取单个MessageNoticeSetting对象
     *
     * @param session_id
     * @param handler
     */
    static findDoctor(session_id, handler) {
        let sql = "SELECT s.doctor,s.doctor_health from "+DB_TABLES.Participants+" p,"+DB_TABLES.SignFamily+" s WHERE p.session_id = ? and p.participant_id = s.patient and s.`status`>0";
        ImDb.execQuery({
            "sql": sql,
            "args": [session_id],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
    /**
     * 判断医生在会话中是否是健管师
     * @param session_id
     * @param doctor
     * @param handler
     */
    static isHealthDoctor(session_id,doctor, handler) {
        let sql = "SELECT s.doctor_health from "+DB_TABLES.Participants+" p,"+DB_TABLES.SignFamily+" s WHERE p.session_id = ? and p.participant_id = s.patient and s.doctor_health=? and s.`status`>0";
        ImDb.execQuery({
            "sql": sql,
            "args": [session_id,doctor],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
}
module.exports = SignFamilyRepo;

+ 7 - 7
src/server/repository/mysql/topics.repo.js

@ -243,23 +243,23 @@ class TopicRepo {
        let sql = "";
        var args =[];
        if(status==10){
            args.push(adminTeamCode,userId,status);
            args.push(userId,status);
            sql =  "SELECT count(1)  as count FROM "+
                DB_TABLES.Topics+" t,"+DB_TABLES.Participants+" p,"+DB_TABLES.Doctors+" d,"+DB_TABLES.WlyyConsultTeam+" c,"+DB_TABLES.Patients+" s "+
                "WHERE d.id = p.participant_id AND c.consult = t.id AND c.patient = s.id AND p.session_id = t.session_id "+
                "AND c.admin_team_code=? AND c.type!=8 AND d.id in (?) AND t. STATUS = ? ";
                " AND c.type=1 AND d.id in (?) AND t. STATUS = ? ";
        }else if(status){
            args.push(adminTeamCode,userId,status,reply);
            args.push(userId,status,reply);
            sql =  "SELECT count(1) as count FROM "+
                DB_TABLES.Topics+" t,"+DB_TABLES.Participants+" p,"+DB_TABLES.Doctors+" d,"+DB_TABLES.WlyyConsultTeam+" c,"+DB_TABLES.Patients+" s "+
                "WHERE d.id = p.participant_id AND c.consult = t.id AND c.patient = s.id AND p.session_id = t.session_id "+
                "AND c.admin_team_code=? AND c.type!=8 AND d.id in (?) AND t. STATUS = ? and t.reply=? ";
                " AND c.type=1 AND d.id in (?) AND t. STATUS = ? and t.reply=? ";
        }else{
            args.push(adminTeamCode,userId);
            args.push(userId);
            sql =  "SELECT count(1) as count FROM "+
                DB_TABLES.Topics+" t,"+DB_TABLES.Participants+" p,"+DB_TABLES.Doctors+" d,"+DB_TABLES.WlyyConsultTeam+" c,"+DB_TABLES.Patients+" s "+
                "WHERE d.id = p.participant_id AND c.consult = t.id AND c.patient = s.id AND p.session_id = t.session_id "+
                "AND c.admin_team_code=? AND c.type!=8 AND d.id in (?)";
                " AND c.type=1 AND d.id in (?)";
        }
        ImDb.execQuery({
            sql: sql,
@ -304,7 +304,7 @@ class TopicRepo {
    }
    static findTopicStatusAndType(topicId, handler) {
        let sql = "select t.id, t.name, t.description, t.status,t.agent,c.type from topics t,wlyy.wlyy_consult c where t.id = ? and t.id = c.code";
        let sql = "select t.id, t.name, t.description, t.status,t.agent,c.type from topics t," + DB_TABLES.WlyyConsult + " c where t.id = ? and t.id = c.code";
        ImDb.execQuery({
            sql: sql,

+ 4 - 3
src/server/repository/mysql/wechat.token.repo.js

@ -8,6 +8,7 @@
let log = require('../../util/log');
let ImDb = require('../mysql/db/im.db');
const DB_TABLES = require('../../include/commons').DB_TABLES;
class WeChatTokenRepo {
    constructor() {
@ -20,7 +21,7 @@ class WeChatTokenRepo {
     */
    static findOne(handler) {
        ImDb.execQuery({
            "sql": "select access_token, expires_in, add_timestamp from wlyy.wx_access_token where acc_id = 'gh_ffd64560fb21' order by add_timestamp desc limit 0, 1"
            "sql": "select access_token, expires_in, add_timestamp from "+DB_TABLES.WxAccessToken+" where acc_id = 'gh_733f975e0bed' order by add_timestamp desc limit 0, 1"
            , "handler": handler
        });
    };
@ -35,7 +36,7 @@ class WeChatTokenRepo {
     */
    static save(accessToken, expireIn, createTime, handler) {
        ImDb.execQuery({
            "sql": "insert into wlyy.wx_access_token (acc_id,access_token, expires_in, add_timestamp) values ('gh_ffd64560fb21',?,?,?)"
            "sql": "insert into "+DB_TABLES.WxAccessToken+" (acc_id,access_token, expires_in, add_timestamp) values ('gh_733f975e0bed',?,?,?)"
            , "args": [accessToken, expireIn, createTime.getTime()]
            , "handler": handler
        });
@ -53,7 +54,7 @@ class WeChatTokenRepo {
     */
    static saveLog(openid,patient,name,request,response,status,createTime,handler){
        ImDb.execQuery({
            "sql": "insert into wlyy.wlyy_wx_push_log (type,openid, patient,name,request,response,status, create_time) values (3,?,?,?,?,?,?,?)"
            "sql": "insert into "+DB_TABLES.WlyyWxPushLog+" (type,openid, patient,name,request,response,status, create_time) values (3,?,?,?,?,?,?,?)"
            , "args": [openid,patient,name,request,response,status, createTime]
            , "handler": handler
        });

+ 4 - 4
src/server/resources/config/config.dev.js

@ -53,11 +53,11 @@ let getTuiConfig = {
// 微信配置
let wechatConfig = {
    appId: 'wxd03f859efdf0873d',
    appSecret: '2935b54b53a957d9516c920a544f2537',
    appId: 'wxe627ffaee2d05a40',
    appSecret: '7c29f6b28be7e54b742883a47ff39767',
    token: '27eb3bb24f149a7760cf1bb154b08040',
    accId: 'gh_ffd64560fb21',
    baseUrl: 'ehr.yihu.com/wlyy',
    accId: 'gh_733f975e0bed',
    baseUrl: 'srijk.yihu.com/wlyy',
    template: {
        consultTemplate: '-dr4QNyFoRvVsf8uWxXMC1dRyjwnbUuJwJ21vBLhf18'  // 咨询回复模板
    }

+ 30 - 22
src/server/resources/config/config.local.js

@ -1,10 +1,10 @@
"use strict";
let imDbConfig = {
    host: '10.95.22.143',
    user: 'im',
    host: '11.1.2.5',
    user: 'wlyy_sr',
    port:3306,
    password: 'im!)123',
    password: '123456',
    database: 'im',
    connectionLimit: '100',
    charset : 'utf8mb4'
@ -12,41 +12,49 @@ let imDbConfig = {
// Redis
let redisConfig = {
    host: '10.95.22.142',
    port: 6380,
    host: '11.1.2.22',
    port: 6390,
    db: 1,
    password:'jkzlehr'
    password:'Kb6wKDQP1W4'
};
// let redisConfig = {
//     host: '192.168.120.14',
//     port: 6380,
//     db: 1,
//     password:'jkzl_ehr'
// };
// 内网Redis
let innerRedisConfig = {
    host: '10.95.22.142',
    port: 6380,
    host: '11.1.2.22',
    port: 6390,
    db: 1,
    password:'jkzlehr'
    password:'Kb6wKDQP1W4'
};
// 三师后台
let wlyyServerConfig = {
    host: '10.95.22.137',
    port: 9660,
    host: 'srijk.yihu.com',
    port: 80,
    model:"/wlyy"
};
// 个推AppStore版参数
let getTuiConfig = {
    HOST: 'https://api.getui.com/apiex.htm',
    APPID: 'qWmRh2X88l7HuE36z3qBe8',
    APPKEY: 'EzERfV8c849lBkZqHWzQG1',
    MASTERSECRET: 'veXiajQrId6iojy7Qv8kZ2'
    APPID: 'NamoCLe9no9pIihdoZ930A',
    APPKEY: 'db7PZsd7TX6JAsLKmWuAT8',
    MASTERSECRET: '5IFJjgxRiI7QpuArMMT3E5'
};
// 微信配置
let wechatConfig = {
    appId: 'wxad04e9c4c5255acf',
    appSecret: 'ae77c48ccf1af5d07069f5153d1ac8d3',
    appId: 'wxe627ffaee2d05a40',
    appSecret: '7c29f6b28be7e54b742883a47ff39767',
    token: '27eb3bb24f149a7760cf1bb154b08040',
    baseUrl: 'www.xmtyw.cn/wlyy',
    accId: 'gh_733f975e0bed',
    baseUrl: 'srijk.yihu.com/wlyy',
    template: {
        consultTemplate: '0mF_vHj-ILx8EH8DwzmAi7LqzjqYiU9IrSRRmziTZyc'  // 咨询回复模板
        consultTemplate: 'a3PCZJetJ02MI0Xs5pkZKUNZo6UkdC9xdR4GqEjlsNA'  // 咨询回复模板
    }
};
@ -65,10 +73,10 @@ let topicConfig = {
    TERMINATING_CRON: "* 59 * * * *"        // 议题自动关闭的任务执行时间间隔
};
exports.environment = 'local';
exports.pubChannel = 'pc_to_phone';
exports.subChannel = 'phone_to_pc';
exports.pubSubSwitch = true;
exports.environment = 'prod';
exports.pubChannel = 'phone_to_pc';
exports.subChannel = 'pc_to_phone';
exports.pubSubSwitch = false;
exports.app = 'im.server';
exports.version = '2.0.0';

+ 6 - 6
src/server/resources/config/config.prod.js

@ -3,7 +3,7 @@
let imDbConfig = {
    host: '11.1.2.5',
    user: 'wlyy_sr',
    port:9069,
    port:3306,
    password: '123456',
    database: 'im',
    connectionLimit: '100',
@ -48,13 +48,13 @@ let getTuiConfig = {
// 微信配置
let wechatConfig = {
    appId: 'wxe627ffaee2d05a40',
    appSecret: '7c29f6b28be7e54b742883a47ff39767',
    appId: 'wx0a06b75a40b28f2a',
    appSecret: 'd46ecfb0fc6fc8bc699b77f93b2a1e20',
    token: '27eb3bb24f149a7760cf1bb154b08040',
    accId: 'gh_ffd64560fb21',
    accId: 'gh_9386c9ab884f',
    baseUrl: 'srijk.yihu.com/wlyy',
    template: {
        consultTemplate: '-dr4QNyFoRvVsf8uWxXMC1dRyjwnbUuJwJ21vBLhf18'  // 咨询回复模板
        consultTemplate: 'fadxatOcyNG3ihvJg-OZsq8EzQyLDNljogv6V-Hxshc'  // 咨询回复模板
    }
};
@ -76,7 +76,7 @@ let topicConfig = {
exports.environment = 'prod';
exports.pubChannel = 'phone_to_pc';
exports.subChannel = 'pc_to_phone';
exports.pubSubSwitch = true;
exports.pubSubSwitch = false;
exports.app = 'im.server';
exports.version = '2.0.0';

+ 17 - 16
src/server/resources/config/config.test.js

@ -1,11 +1,11 @@
"use strict";
let imDbConfig = {
    host: '172.17.110.160',
    user: 'ssgg',
    password: 'ssgg',
    database: 'im_new',
    connectionLimit: '100',
    host: '172.19.103.77',
    user: 'root',
    password: '123456',
    database: 'im_sr',
    connectionLimit: '50',
    charset: 'utf8mb4'
};
@ -13,7 +13,7 @@ let imDbConfig = {
let redisConfig = {
    host: '172.19.103.88',
    port: 6379,
    db: 1
    db: 2
};
// let redisConfig = {
//     host: '192.168.1.220',
@ -24,29 +24,30 @@ let redisConfig = {
let innerRedisConfig = {
    host: '172.19.103.88',
    port: 6379,
    db: 1
    db: 2
};
// 三师后台
let wlyyServerConfig = {
    host: '172.19.103.88',
    port: 9092,
    host: '172.19.103.72',
    port: 9096,
    model:"/wlyy"
};
// 个推AppStore版参数
let getTuiConfig = {
    HOST: 'https://api.getui.com/apiex.htm',
    APPID: 'H6FYbDejks6VjMmW3uH7V6',
    APPKEY: '0PFWlKmLBN9YzhCfFWVgYA',
    MASTERSECRET: 'pvjCGtRZJx9SRVODkxc816'
    APPID: 'NamoCLe9no9pIihdoZ930A',
    APPKEY: 'db7PZsd7TX6JAsLKmWuAT8',
    MASTERSECRET: '5IFJjgxRiI7QpuArMMT3E5'
};
// 微信配置
let wechatConfig = {
    appId: 'wx1f129f7b51701428',
    appSecret: '988f005d8309ed1795939e0f042431fb',
    appId: 'wxe627ffaee2d05a40',
    appSecret: '7c29f6b28be7e54b742883a47ff39767',
    token: '27eb3bb24f149a7760cf1bb154b08040',
    baseUrl: 'ehr.yihu.com/wlyy',
    accId: 'gh_733f975e0bed',
    baseUrl: 'srijk.yihu.com/wlyy',
    template: {
        consultTemplate: '-dr4QNyFoRvVsf8uWxXMC1dRyjwnbUuJwJ21vBLhf18'  // 咨询回复模板
    }
@ -69,7 +70,7 @@ let topicConfig = {
exports.environment = 'test';
exports.pubChannel = 'test';
exports.subChannel = 'dev';
exports.pubSubSwitch = true;
exports.pubSubSwitch = false;
exports.app = 'im.server';
exports.version = '2.0.0';