/** * 消息端点。 * * 此控制器处理点对点,组及消息消息。为三类消息提供发送及查询功能。 */ "use strict"; let express = require('express'); let router = express.Router(); let http = require('http'); let log = require('../util/log.js'); let objectUtil = require("../util/objectUtil.js"); let controllerUtil = require('../util/controllerUtil'); let Patient = new require("../models/patient"); let Doctor = new require('../models/doctor'); let Group = new require('../models/group'); let Search = require('../models/search'); const APIv1 = require('../include/endpoints').APIv1; const CONTENT_TYPES = require('../include/commons').CONTENT_TYPE; const GROUP_TYPE = require('../include/commons').GROUP_TYPE; const MAX_INT = 9007199254740992; const DEFAULT_PAGE_SIZE = 100; //--------------------------------------------------------------// //----------------------------消息发送----------------------------// //--------------------------------------------------------------// /** * 发送System消息。 * * 请求URL: * /chats/sm * * 消息格式: * { * to: "Rose", * title: "System Message", * summary: "You have new job", * contentType: "1", * content: "The patient has been followed in the scheduler, please make new follow plan as soon as possible." * } * * @param message */ router.post(APIv1.Chats.SM, function (req, res) { // 检查消息体及消息格式是否正确 let message = req.body; if (!objectUtil.isJsonObject(message)) { throw {httpStatus: 406, message: 'Problems parsing JSON.'} } // 字段判断 let testing = objectUtil.fieldsCheck(message, "to", "title", "summary", "contentType", "content"); if (!testing.pass) { throw {httpStatus: 406, message: testing.message} } // 消息处理 let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.sendSystemMessage(message); }); /** * 处理Private消息。处理流程分: * 1 解析消息,并保存到数据库 * 2 更新消息统计数据 * 3 获取目标的状态并构建通知消息,如果用户在线就推送通知消息 * * 请求URL: * /chats/pm * * 消息格式: * { * from: sand, * to: Rose, * contentType: "1,2,3,4", * content: "Please follow the patient as soon as possible." * } * * @param message */ router.post(APIv1.Chats.PM, function (req, res) { // 检查消息体及消息格式是否正确 let message = req.body; if (!objectUtil.isJsonObject(message)) { throw {httpStatus: 406, message: 'Problems parsing JSON.'} } // 字段判断 let testing = objectUtil.fieldsCheck(message, "from", "to", "contentType", "content"); if (!testing.pass) { throw {httpStatus: 406, message: testing.message}; } // 消息处理,患者与医生分开发送 Patient.isPatientCode(message.to, function () { let patient = new Patient(); controllerUtil.regModelEventHandler(patient, res); patient.sendMessage(message); }, function () { let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.sendMessage(message); }); }); /** * 处理讨论组消息。 * * 请求URL: * /chats/gm * * 消息格式: * { * from: "sand", // 发送者id * at: "Rose", // @人 * group: "DiscussionGroupId", // 所在组 * groupType: "1 or 2", // 组类型:行政团队或讨论组 * contentType: "1,2,3", // 内容类型 * content: "The patient mess me up" // 内容 * } * * @param message */ router.post(APIv1.Chats.GM, function (req, res) { // 检查消息体及消息格式是否正确 let message = req.body; if (!objectUtil.isJsonObject(message)) { throw {httpStatus: 406, message: 'Problems parsing JSON.'}; } // 字段判断 let testing = objectUtil.fieldsCheck(message, 'from', 'at', 'group', 'groupType', 'contentType', 'content'); if (!testing.pass) { throw {httpStatus: 406, message: testing.message} } // 消息处理 let group = new Group(); controllerUtil.regModelEventHandler(group, res); group.sendMessage(message); }); //--------------------------------------------------------------// //----------------------------消息提取----------------------------// //--------------------------------------------------------------// /** * 获取参与的聊天列表,包括:点对点,@我,参与的讨论组,系统消息等。 * * 请求URL: * /chats/list?user_id=sand */ router.get(APIv1.Chats.List, function (req, res) { let userId = req.query.user_id; if (userId === null) { throw {httpStatus: 406, message: 'Missing fields.'}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getChatList(userId); }); /** * 获取与患者的聊天列表,包括:P2P,参与的讨论组和行政团队。 * * 请求URL: * /chats/list/patient */ router.get(APIv1.Chats.ListWithPatient, function (req, res) { let userId = req.query.user_id; if (userId === null) { throw {httpStatus: 406, message: 'Missing fields.'}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getChatsListWithPatient(userId); }); /** * 获取与医生的聊天列表,包括:点对点,参与的讨论组。 * * 请求URL: * /chats/list/doctor */ router.get(APIv1.Chats.ListWithDoctor, function (req, res) { let userId = req.query.user_id; if (userId === null) { throw {httpStatus: 406, message: 'Missing fields.'}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getChatListWithDoctor(userId); }); /** * 获取最近聊天对象:包括患者,医生与讨论组。客户端自行根据需要提取患者、医生或讨论组数据。 * * 请求URL: * /chats/recent?user_id=0de7295862dd11e69faffa163e8aee56&days=7 * * 参数: * user_id: 用户ID * target_type: 对象类型,1患者,2医生,3讨论组 * days: 最近天数 */ router.get(APIv1.Chats.Recent, function (req, res) { let userId = req.query.user_id; let days = req.query.days; if (userId === null) { throw {httpStatus: 406, message: 'Missing field: user_id'}; } if (days === null) { throw {httpStatus: 406, message: 'Missing field: days'}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getRecentChatList(userId); }); /** * 获取私信。倒序排列。 * * 参数: * user_id 必须,医生ID * peer_id 必须,对方医生ID * content_type 必须,消息类型 * message_start_id 可选,消息的起始ID,如果为空从最新的一条开始获取 * message_end_id 可选,消息的结束ID,如果为空从第一条开始获取 * count 可选,消息数量,如果不指定、小于零或大于50,默认为100条。若message_start_id与message_end_id均不为空,则此参数无效,方法是设置为10000条 * closed_interval 消息范围是否使用闭区间 * * 请求URL: * /chats/pm?user_id=sand&peer_id=Rose&content_type=2&message_start_id=10000&message_end_id=0&count=20&closed_interval=false */ router.get(APIv1.Chats.PM, function (req, res) { let userId = req.query.user_id; let peerId = req.query.peer_id; let contentType = req.query.content_type; let msgStartId = !req.query.message_start_id ? MAX_INT : parseInt(req.query.message_start_id); let msgEndId = !req.query.message_end_id ? 0 : parseInt(req.query.message_end_id); let count = req.query.count === undefined ? DEFAULT_PAGE_SIZE : parseInt(req.query.count); let closedInterval = (req.query.closed_interval != false && req.query.closed_interval === "true"); if (contentType !== undefined && parseInt(contentType) === CONTENT_TYPES.Image) count = DEFAULT_PAGE_SIZE; if (req.query.message_start_id && req.query.message_end_id) count = 10000; if (!userId) { throw {httpStatus: 400, message: "Missing field: user_id."}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getPrivateMessages(userId, peerId, contentType, msgStartId, msgEndId, count, closedInterval); }); /** * 获取未读私信。倒序排列。 * * 参数: * user_id 必须,医生ID * peer_id 必须,对方医生ID * * 请求URL: * /chats/pm/unread?user_id=sand&peer_id=Rose */ router.get(APIv1.Chats.PMUnread, function (req, res) { let userId = req.query.user_id; let peerId = req.query.peer_id; if (userId === undefined) { throw {httpStatus: 400, message: "Missing field: user_id."}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getUnreadPrivateMessages(userId, peerId); }); /** * 按时间倒序获取群消息。 * * 参数: * user_id 必须,医生ID * group_id 必须,组ID * message_start_id 可选,消息的起始ID,如果为空从最新的一条开始获取 * count 可选,消息数量,如果不指定、小于零或大于50,默认为50条 * * 请求URL: * /chats/gm?user_id=D2016008240002&group_id=494&content_type=2&message_start_id=0&message_end_id=0&count=20 */ router.get(APIv1.Chats.GM, function (req, res) { let groupId = req.query.group_id; let memberId = req.query.user_id; let contentType = req.query.content_type; let msgStartId = !req.query.message_start_id ? MAX_INT : parseInt(req.query.message_start_id); let msgEndId = !req.query.message_end_id ? 0 : parseInt(req.query.message_end_id); let count = req.query.count === undefined ? DEFAULT_PAGE_SIZE : parseInt(req.query.count); if (groupId === undefined) { throw {httpStatus: 400, message: "Missing field: group_id."}; } if (contentType !== undefined && parseInt(contentType) === CONTENT_TYPES.Image) count = DEFAULT_PAGE_SIZE; if (req.query.message_start_id && req.query.message_end_id) count = 100000; let group = new Group(); controllerUtil.regModelEventHandler(group, res); group.getMessages(groupId, memberId, contentType, msgStartId, msgEndId, count); }); /** * 获取未读群消息。 * * 请求URL: * /chats/gm/unread?group_id=discussionGroupId&user_id=sand */ router.get(APIv1.Chats.GMUnread, function (req, res) { let memberId = req.query.user_id; let groupId = req.query.group_id; if (memberId === undefined) { throw {httpStatus: 400, message: "Missing field: user_id."}; } if (groupId === undefined) { throw {httpStatus: 400, message: "Missing field: group_id."}; } let group = new Group(); controllerUtil.regModelEventHandler(group, res); group.getUnreadMessages(groupId, memberId); }); //--------------------------------------------------------------// //----------------------------消息统计----------------------------// //--------------------------------------------------------------// /** * 获取所有群组未读消息总数。 * * 请求URL: * /chats/gm/unread_count?user_id=sand * * 参数: * user_id:医生ID */ router.get(APIv1.Chats.GMUnreadCount, function (req, res) { let memberId = req.query.user_id; if (memberId === null) { throw {httpStatus: 406, message: 'Missing fields.'}; } let group = new Group(); controllerUtil.regModelEventHandler(group, res); group.getUnreadMessageCount(memberId); }); /** * 获取特定群组消息统计情况。 * * /chats/gm/statistic?group_id=GGG&&user_id=sand * * 参数: * user_id:信息所有者id * group_id:群组id */ router.get(APIv1.Chats.GMStats, function (req, res) { let memberId = req.query.user_id; let groupId = req.query.group_id; if (memberId === null || groupId === null) { throw {httpStatus: 406, message: 'Miss fields.'}; } let group = new Group(); controllerUtil.regModelEventHandler(group, res); group.getChatSummary(groupId, memberId); }); /** * 获取与某人的私信统计。 * * /chats/pm/statistic?user_id=sand&&peer_id=rose * * 参数: * user_id:信息所有者id * peer_id:聊天对端id */ router.get(APIv1.Chats.PMStats, function (req, res) { let userId = req.query.user_id; let peerId = req.query.peer_id; if (userId == null || peerId == null) { throw {httpStatus: 406, message: "Missing fields."}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getChatSummary(userId, peerId); }); /** * 获取所有未读私信总数。 * * /chats/pm/unread_count?user_id=sand * * 参数: * uid:信息所有者id */ router.get(APIv1.Chats.PMUnreadCount, function (req, res) { let userId = req.query.user_id; let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getUnreadPrivateMessages(userId); }); /** * 所有聊天消息未读数。 * * 请求URL: * /chats/chats/unread_count?user_id=sand * * 参数: * user_id:信息所有者id */ router.get(APIv1.Chats.UnreadMsgCount, function (req, res) { let userId = req.query.user_id; if (userId === null) { throw {httpStatus: 406, message: "Missing fields."}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getAllUnreadMessageCount(userId); }); /** * 搜索患者相关的数据,包括患者信息与相关的私信记录。关键词不支持空格拆分。 * * 请求URL: * /search/patient?user_id=3b723bb8699a11e69f7c005056850d66&user_role=1&keyword=庄 * * 参数: * keywords: 关键词 */ router.get(APIv1.Chats.SearchAboutPatient, function (req, res) { let userId = req.query.user_id; let userRole = req.query.user_role; let keyword = req.query.keyword; if (!userId) throw {httpStatus: 406, message: "Missing fields: user_id."}; if (!userRole) throw {httpStatus: 406, message: "Missing fields: user_role."}; if (!keyword) throw {httpStatus: 406, message: "Missing fields: keyword."}; let search = new Search(); controllerUtil.regModelEventHandler(search, res); search.searchAboutPatient(userId, userRole, keyword); }); /** * 搜索医生相关的数据,包括医生信息与相关的聊天记录,包括私信与群信。 * * 请求URL: * /search/doctor?user_id=5fa5e88f7a4111e69f7c005056850d66&keyword=丘 * * 参数: * keywords: 关键词 */ router.get(APIv1.Chats.SearchAboutDoctor, function (req, res) { let userId = req.query.user_id; let keyword = req.query.keyword; if (!userId) throw {httpStatus: 406, message: "Missing fields: user_id."}; if (!keyword) throw {httpStatus: 406, message: "Missing fields: keyword."}; let search = new Search(); controllerUtil.regModelEventHandler(search, res); search.searchAboutDoctor(userId, keyword); }); /** * 获取单条消息。 * * URL: * /chats/message?id=1234&type=1 */ router.get(APIv1.Chats.Message, function (req, res) { let messageId = req.query.id; let messageType = req.query.type; let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.getMessage(messageId, messageType); }); /** * 判断当前会话是否已经结束。 * * 请求URL: * /chats/pm/finished?user_id=sand&peer_id=rose */ router.get(APIv1.Chats.PMFinished, function (req, res) { let doctorId = req.query.doctor_id; let patientId = req.query.patient_id; if (!doctorId) { throw {httpStatus: 406, message: "Missing field: doctor_id"}; } if (!patientId) { throw {httpStatus: 406, message: "Missing field: patient_id"}; } let doctor = new Doctor(); controllerUtil.regModelEventHandler(doctor, res); doctor.isConsultFinished(doctorId, patientId); }); module.exports = router;