浏览代码

Merge branch 'im-internet-hospital' of huangwenjie/im.doctor into im-internet-hospital

huangwenjie 5 年之前
父节点
当前提交
650ee2c09d

+ 8 - 3
readme.md

@ -188,9 +188,14 @@ REST API遵循REST最佳实践,规范命名URL中的每个部分。注意POST
            26、专家建议
            27、药品处方(在线复诊)
            28、服务评价
            29、视屏请求 content:{
                            answer_status:0 //0请求,1已接听
                        }
            2101、上门服务-预约信息
            2102、上门服务-修改工单卡片信息
            2103、上门服务-变更工单医生信息
            2104、上门服务-变更工单服务项信息
            2105、修改卡片消息触发刷新消息列表
    **会话类型** 
    
        sessions的type字段
@ -231,10 +236,10 @@ REST API遵循REST最佳实践,规范命名URL中的每个部分。注意POST
            j、type =11 思明区上门护理
            sessionId: 居民code+"_"+咨询code+"_"+咨询类型
            k、type =12 候诊室群聊
            sessionId: 诊室code+"_"+咨询code+"_"+咨询类型
            k、type =12 医院协同门诊
            sessionId: 家庭医生CODE+"_"+咨询code+"_"+咨询类型
            
            l、type =13 专家咨询
            l、type =13 健康咨询
            sessionId: 居民code+"_"+医生code+"_"+咨询类型

+ 57 - 0
src/server/endpoints/v2/doctor.endpoint.js

@ -0,0 +1,57 @@
/**
 * 独立的发送消息接口
 */
"use strict";
let express = require('express');
let router = express.Router();
let ModelUtil = require('../../util/model.util');
let ObjectUtil = require('../../util/object.util');
let ControllerUtil = require('../../util/controller.util');
let APIv2 = require('../../include/endpoints').APIv2;
let MODEL_EVENTS = require('../../include/commons').MODEL_EVENTS;
let Doctors = require('../../models/doctor/doctors');
let log = require('../../util/log.js');
let uuid = require('uuid')
/**
 * 新增医生
 * 参数:participants:{mobile:'',name:'',sex:'',birthdate:'',avatar:'',hospital_name:'',level:'',idcard:''}
 */
router.post(APIv2.Doctor.AddDoctor, function (req, res) {
    let payload = req.body;
    let testing = ObjectUtil.fieldsCheck(payload, "participants");
    log.info("aaaa:" + payload.participants);
    if (!testing.pass) {
        throw {httpStatus: 406, message: testing.message}
    }
   
    
    let doctors = new Doctors();
    ControllerUtil.regModelEventHandler(doctors, res);
    let participants = JSON.parse(payload.participants);
    let isAllOK = true;
    for (let j in participants) {
        log.info("aaaa:"+j + ":" + participants[j]);
        let participant = participants[j];
        // participant.id = participant.mobile;//用手机号码作为id
        participant.id = uuid.v1();//生成随机UUID
        participant.avatar = '../../../images/d-male.png';
        
        doctors.addDoctor(participant,function (err, result) {
            if(result.status==0){
                isAllOK = false;
            }
        });
    }
    let self = this;
    if(isAllOK){
        res.status(200).json({status: 200, data: {status:1,msg:"保存成功"}});    
    }
    else{
        res.status(200).json({status: 200, data: {status:0,msg:"部分成员添加失败"}});    
    }
    
});
module.exports = router;

+ 41 - 8
src/server/endpoints/v2/session.endpoint.js

@ -14,6 +14,9 @@ let ControllerUtil = require('../../util/controller.util');
let Sessions = require('../../models/sessions/sessions');
let Messages = require('../../models/messages/messages');
let Participants = require('../../models/sessions/participants');
let log = require("../../util/log.js");
let clientCache = require('../../models/socket.io/client.cache').clientCache();
const SESSION_TYPES = require('../../include/commons').SESSION_TYPES;
const APIv2 = require('../../include/endpoints').APIv2;
@ -48,29 +51,59 @@ router.post("/", function (req, res) {
    let sessionId = payload.session_id;
    let sessions = new Sessions();
    let participantArray = [];
    log.info("participants: "+participants);
    participants = JSON.parse(participants);
    ///是否视频会议的会话
    let videoconferencing = false;
    participants = JSON.parse(participants);
    /**
     *MDT 医生数据转换,根据手机号查询医生CODE
     */
    if (payload.hasOwnProperty('videoconferencing') && payload.videoconferencing == 1){
        participants = sessions.conversionAarticipant(participants);
    }
    for (let j in participants) {
        log.info("aaaa:"+j + ":" + participants[j]);
        participantArray.push(j + ":" + participants[j]);
    }
    ControllerUtil.regModelEventHandler(sessions, res);
    console.log(sessionId, sessionName, sessionType, participantArray);
    sessions.createSession(sessionId, sessionName, sessionType, participantArray);
    ///是否视频会议的会话
    let videoconferencing = false;
    // participants = JSON.parse(participants);
    // for (let j in participants) {
    //     participantArray.push(j + ":" + participants[j]);
    // }
    //视频会议的会话 szx add 20181121
    if (!payload.hasOwnProperty('videoconferencing') && payload.videoconferencing == 1){
    if (payload.hasOwnProperty('videoconferencing') && payload.videoconferencing == 1){
        let access_token = "";
        if(payload.hasOwnProperty("mobile"))access_token = payload.access_token;
        videoconferencing = true;
        //发送广播,给相关的与会人员
        for (let j in participants) {
            let participant = participants[j];
            let socketClient = ClientCache.findById(participant.userId);
            socketClient.emt("startVideoconference",{"session_id":sessionId});
            let userId = "pcim_"+j;
            let pc_doctorClient = clientCache.findById(userId);
            if(pc_doctorClient){
                log.info("videoconferencing send to "+userId);
                pc_doctorClient.socket.emit("startVideoconference",{"sessionId":sessionId,"user_id":j});
            }
            else{
                log.info("videoconferencing not find "+userId);
            }
        }
        
    }
});
/**

+ 1 - 0
src/server/include/commons.js

@ -95,6 +95,7 @@ const CONTENT_TYPES = {
    PrescriptionBloodStatus:16,//续方咨询血糖血压咨询消息
    PrescriptionFollowupContent:17,//续方咨询随访问卷消息
    Rehabilitation: 20, //康复计划发送
    VideoAnswerStatus: 29, //视屏请求
    ReservationDoorCardInfo: 2101,//上门服务-预约工单卡片信息
    ChangeDoorCardInfo: 2102,//上门服务-修改工单卡片信息
    ChangeDoorDoctor: 2103,//上门服务-变更工单医生信息

+ 5 - 0
src/server/include/endpoints.js

@ -74,6 +74,11 @@ const APIv2 = {
    },
    Demo:{
        Base:'/api/v2/demo'
    },
    Doctor: {//szx add ,针对中山医院视频通信
        Base: '/api/v2/doctor',
        AddDoctor: '/addDoctor'                                                  //新增医生
    }
};

+ 61 - 1
src/server/models/client/wechat.client.js

@ -66,7 +66,9 @@ class WechatClient extends RedisModel {
            message.content_type == CONTENT_TYPES.ReservationDoorCardInfo ||
            message.content_type == CONTENT_TYPES.ChangeDoorCardInfo ||
            message.content_type == CONTENT_TYPES.ChangeDoorDoctor ||
            message.content_type == CONTENT_TYPES.ChangeDoorPackageItems)) {
            message.content_type == CONTENT_TYPES.ChangeDoorPackageItems ||
            message.content_type == CONTENT_TYPES.VideoAnswerStatus
            )) {
            let patientClient = clientCache.findById(targetUserId);
            let pc_patientClient = clientCache.findById("pcpatient_"+targetUserId);
            let doctorClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);
@ -382,6 +384,64 @@ class WechatClient extends RedisModel {
        }
    }
    static sendSocketMessageToPatient(patientId, message) {
        let patientClient = clientCache.findByIdAndType(patientId,SOCKET_TYPES.PATIENT);
        let pc_patientClient = clientCache.findByIdAndType("pcpatient_"+patientId,SOCKET_TYPES.PC_PATIENT);
        if(!patientClient&&!pc_patientClient){
            log.warn("target patient is not online!");
            return;
        }
        // let sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);//app医生发送的消息
        // if(!sendClient){//pc医生发送的消息
        //     sendClient = clientCache.findByIdAndType("pc_"+message.sender_id,SOCKET_TYPES.PC_DOCTOR);
        // }
        // if(!sendClient){//居民发送的消息
        //     sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.PATIENT);
        // }
        var count = 0;
        if(patientClient&&message.session_id==patientClient.sessionId){
            WechatClient.updateParticipantLastFetchTime(patientClient.sessionId, patientId, ObjectUtil.timestampToLong(message.timestamp));
            patientClient.socket.emit('message', {
                id: message.id,
                session_id: message.session_id,
                sender_id: message.sender_id,
                sender_name: message.sender_name,
                content_type: message.content_type,
                content: message.content,
                timestamp: ObjectUtil.timestampToLong(message.timestamp),
                type: message.content_type,          // legacy support
                name: message.sender_name,
            });
        }else{
            count++;
        }
        //发送pc端
        if(pc_patientClient&&message.session_id==pc_patientClient.sessionId){
            WechatClient.updateParticipantLastFetchTime(pc_patientClient.sessionId, patientId, ObjectUtil.timestampToLong(message.timestamp));
            pc_patientClient.socket.emit('message', {
                id: message.id,
                session_id: message.session_id,
                sender_id: message.sender_id,
                sender_name: message.sender_name,
                content_type: message.content_type,
                content: message.content,
                timestamp: ObjectUtil.timestampToLong(message.timestamp),
                type: message.content_type,          // legacy support
                name: message.sender_name,
            });
        }else{
            count++;
        }
        if(count==2){
            log.warn("patient is not in the same session or is not online");
        }
    }
    /**
     *
     * 发送微信模板消息给居民

+ 111 - 0
src/server/models/doctor/doctors.js

@ -0,0 +1,111 @@
/**
 * 医生相关操作。
 *
 * author: shenzaixin
 * since: 12/27/2018
 */
"use strict";
let BaseModel = require('../base.model');
let ImDb = require('../../repository/mysql/db/im.db');
let ParticipantRepo = require('../../repository/mysql/participant.repo');
let DoctorRepo = require('../../repository/mysql/doctor.repo');
let SessionRepo = require('../../repository/mysql/session.repo');
let ModelUtil = require('../../util/model.util');
let ObjectUtil = require("../../util/object.util.js");
let async = require('async');
let log = require('../../util/log');
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
const PLATFORMS = require('../../include/commons').PLATFORM;
class Dortors extends BaseModel {
    constructor() {
        super();
    }
    /**
     * 新增医生信息
     *
     * @param participant
     * @param outCallback
     */
    addDoctor(participant, outCallback) {
        let self = this;
        async.waterfall([
            // 检查是否已存在
            function (callback) {
                let repoProto = DoctorRepo;
                let mobile = participant.mobile;
                repoProto.findByMobile(mobile, function (err, oDoctor) {
                    callback(null, oDoctor);
                });
            },
            // 保存医生信息
            function (oDoctor) {
                let repoProto = DoctorRepo;
                if(oDoctor.length>0){
                    outCallback(null, {status:0,msg:"医生已存在"});
                }
                let id = participant.id;
                let name = participant.name;
                let sex = participant.sex;
                let birthdate = participant.birthdate;
                let avatar = participant.avatar;
                let hospital_name = participant.hospital_name;
                let level = participant.level;
                let idcard = participant.idcard;
                let mobile = participant.mobile;
                repoProto.addDoctor(id,name,mobile,sex,birthdate,avatar,hospital_name,level,idcard, function (err, res) {                        
                    outCallback(null, {status:1,msg:"保存成功"});
                });
            }
        ]);
    }
    /**
     * 用户ID是否属于患者。
     *
     * @param userId
     * @param callback
     */
    static isPatientId(userId, callback) {
        async.waterfall([
                function (callback) {
                    ImDb.execQuery({
                        "sql": "select case when count(*) > 0 then true else false end 'is_patient' from patients where id = ?",
                        "args": [userId],
                        "handler": function (err, res) {
                            if (err) {
                                callback(err, res);
                                return;
                            }
                            callback(null, res);
                        }
                    });
                },
                function (res, callback) {
                    if (res.length === 0) return false;
                    callback(null, res[0].is_patient);
                }
            ],
            function (err, res) {
                if (err) {
                    log.error("User id check failed: ", err);
                    callback(null, false);
                    return;
                }
                callback(null, res !== 0);
            });
    }
}
let Promises = require('bluebird');
Promises.promisifyAll(Dortors.prototype);
module.exports = Dortors;

+ 3 - 0
src/server/models/messages/messages.js

@ -188,6 +188,9 @@ class Messages extends RedisModel {
                //外网pcim通过socket推送
                WechatClient.sendPcImSocket(targetUserId,message,sessionType);
                //告知居民新消息
                WechatClient.sendSocketMessageToPatient(targetUserId,message,sessionType);
                //redis发布消息
                if(config.pubSubSwitch) {//接收订阅消息处理开关,本地运行和测试库单独运行时防止用户接收消息2次
                    pubSub.publish(config.pubChannel,JSON.stringify(message));

+ 46 - 7
src/server/models/sessions/sessions.js

@ -8,6 +8,7 @@ let RedisModel = require('./../redis.model.js');
let ModelUtil = require('../../util/model.util');
let Messages = require('../messages/messages');
let Users = require('../user/users');
let DoctorRepo = require('../../repository/mysql/doctor.repo');
let Participants = require('./participants');
let SessionRepo = require('../../repository/mysql/session.repo');
let TopicRepo = require('../../repository/mysql/topics.repo');
@ -87,6 +88,23 @@ class Sessions extends RedisModel {
        });
    }
    /**
     *MDT 医生数据转换,根据手机号查询医生CODE
     */
    conversionAarticipant(participants) {
        let doctorProto = DoctorRepo;
        for (let j in participants) {
            doctorProto.findByMobile(participants[j][0], function (err, oDoctor) {
                if(oDoctor.length>0){
                    participants[j][0] = oDoctor.id;
                }
            });
        }
        return participants;
    }
    /**
     * 创建会话。REDIS
     * @param sessionId
@ -384,7 +402,7 @@ class Sessions extends RedisModel {
        })
    }
    /**
     /**
     * 根据用户ID获取用户的session列表
     * @param userId
     * @param page
@ -393,7 +411,6 @@ class Sessions extends RedisModel {
     */
    getUserSessions(userId, page, size, businessType) {
        let userSessionKey = RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, userId);
        logger.info(userId);
        let self = this;
        if (page > 0) {
            if (page == 1) {
@ -415,7 +432,7 @@ class Sessions extends RedisModel {
            // },
            function (callback) {
                SessionRepo.findAllByType(userId,businessType,page,size,function(err,res){
                    if (res && res.length == 0) {
                    if (res.length == 0) {
                        ModelUtil.emitOK(self.eventEmitter, []);
                        return;
                    }
@ -430,14 +447,18 @@ class Sessions extends RedisModel {
            function (sessionIds) {
                let sessionList = [];
                let functionList = [];
                log.info("sessionIds.length:" + sessionIds.length);
                for (let j = 0; j < sessionIds.length; j++) {
                    log.info("遍历会话 :" + sessionIds);
                    let fun = function (index, callback) {
                        log.info("!callback:" + !callback);
                        if (!callback) {
                            callback = index, index = 0
                        }
                        let sessionId = sessionIds[index];
                        let sessionKey = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId);
                        log.info("sessionKey:" + sessionKey);
                        let participantsRoleKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipantsRole, sessionId);
                        let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                        redis.multi()
@ -450,6 +471,9 @@ class Sessions extends RedisModel {
                            .execAsync()
                            .then(function (res) {
                                let session = res[0];
                                log.info("top.session.id:" + session.id);
                                log.info("top.session.name:" + session.name);
                                log.info("tope.session.business_type:" + session.business_type);
                                let role = res[1];
                                let lastFetchTime = res[2];
                                let users = res[3];
@ -459,11 +483,19 @@ class Sessions extends RedisModel {
                                let isInvite = true;
                                //处理session未加入redis的bug
                                log.info("1.session==null:" + session==null);
                                if(session==null){
                                    let lastLoginTime = new Date();
                                    SessionRepo.findOne(sessionId, function (err, res) {
                                        if(res){
                                            session = res;
                                            log.info("1.session.id:" + session.id);
                                            log.info("1.session.name:" + session.name);
                                            log.info("1.session.business_type:" + session.business_type);
                                            let redisSession = [
                                                "id", session.id,
                                                "name", session.name,
@ -625,14 +657,19 @@ class Sessions extends RedisModel {
                                                sessionName = res[0].name;
                                            }
                                            var bir = new Date().getTime();
                                            if (res && res.length != 0 && res[0].birthdate) {
                                            if (res.length != 0 && res[0].birthdate) {
                                                bir = res[0].birthdate.getTime();
                                            }
                                            var sex = 1;
                                            if (res && res.length != 0 && res[0].sex) {
                                            if (res.length != 0 && res[0].sex) {
                                                sex = res[0].sex;
                                            }
                                            //end
                                            log.info("2.session.id:" + sessionId);
                                            log.info("2.session.name:" + sessionName);
                                            log.info("2.session.business_type:" + session.business_type);
                                            sessionList.push({
                                                id: sessionId,
                                                name: sessionName,
@ -643,7 +680,8 @@ class Sessions extends RedisModel {
                                                type: session.type,
                                                sender_name: session.last_sender_name||"",
                                                unread_count: count,
                                                business_type: session.business_type,
                                                // business_type: session.business_type,
                                                business_type: businessType,
                                                my_role: role,
                                                sender_sex: sex,
                                                sender_birthday: bir,
@ -2007,6 +2045,7 @@ class Sessions extends RedisModel {
    }
}
// Expose class

+ 16 - 0
src/server/repository/mysql/doctor.repo.js

@ -19,6 +19,22 @@ class DoctorRepo {
            "handler": handler
        });
    };
    static findByMobile(mobile, handler) {
        ImDb.execQuery({
            "sql": "select id, name, sex, birthdate, photo from doctors where mobile = ? ",
            "args": [mobile],
            "handler": handler
        });
    };
    static addDoctor(id,name,mobile,sex,birthdate,avatar,hospital_name,level,idcard, handler) {
        ImDb.execQuery({
            "sql": "insert into base.base_doctor (id,name,mobile,sex,birthdate,photo,idcard,del) values (?,?,?,?,?,?,?,1)",
            "args": [id,name,mobile,sex,birthdate,avatar,idcard],
            "handler": handler
        });
    };
}
module.exports = DoctorRepo;

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

@ -240,7 +240,9 @@ class SessionRepo {
        }
        let sessionSQL ="";
        let sql ="";
        sql = "select session_id from " + DB_TABLES.Participants + " w where w.participant_id = ? and participant_role ="+PARTICIPANT_ROLES.HOST+" group by w.session_id";
        //sql = "select session_id from " + DB_TABLES.Participants + " w where w.participant_id = ? and participant_role ="+PARTICIPANT_ROLES.HOST+" group by w.session_id";
        //中山医院无法查询到所有会话记录,暂时取消participant_role的判断条件 20190619
        sql = "select session_id from " + DB_TABLES.Participants + " w where w.participant_id = ? group by w.session_id";
        sessionSQL =  "select * from "
            + DB_TABLES.Sessions + " s where s.id in(" + sql + ") and s.business_type = ? and s.type!=0 limit "+page+","+pagesize;
        ImDb.execQuery({