123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545 |
- /**
- * 消息端点。
- *
- * 此控制器处理点对点,组及消息消息。为三类消息提供发送及查询功能。
- */
- "use strict";
- let express = require('express');
- let router = express.Router();
- let http = require('http');
- let getui = require('getui');
- let log = require('../util/log.js');
- let objectUtil = require("../util/objectUtil.js");
- let Patient = new require("../models/patient");
- let patient = new Patient();
- let smRepo = require("../repository/system.msg.repo.js");
- let pmRepo = require('../repository/private.msg.repo.js');
- let gmRepo = require("../repository/group.msg.repo.js");
- let nmRepo = require("../repository/notify.msg.repo.js");
- let statsRepo = require("../repository/stats.msg.repo.js");
- let doctorRepo = require("../repository/doctor.repo.js");
- let groupRepo = require("../repository/group.repo.js");
- let searchRepo = require('../repository/search.repo.js');
- let APIv1 = require('../include/endpoints').APIv1;
- let CONTENT_TYPES = require('../include/commons').CONTENT_TYPE;
- let GROUP_TYPE = require('../include/commons').GROUP_TYPE;
- let PLATFORMS = require('../include/commons').PLATFORM;
- let MAX_INT = 9007199254740992;
- let 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}
- }
- // 消息处理
- doctorRepo.getUserStatus(message.to, function (err, rows) {
- if (err) {
- console.log("Lookup system message receiver failed: ", err);
- res.status(500).send({message: "Lookup system message receiver failed."});
- return;
- }
- if (rows.length == 0) {
- res.status(404).send({message: "User not found: " + message.to});
- return;
- }
- let pushable = rows.length > 0 && rows[0].is_online;
- let notifyMessage = JSON.stringify({type: 'system_msg', data: message.content});
- let userStatus = rows[0];
- // 保存该条推送信息
- smRepo.save(message.to,
- message.contentType,
- message.title,
- message.summary,
- message.content,
- function (err, result) {
- if (err) {
- log.error("Save system notify message failed, ", err);
- res.status(500).send({message: "Save system notify message failed."});
- } else {
- // 先结束网络连接,再处理后续操作,减少客户端等待
- res.status(200).send();
- // 保存通知到数据库中
- nmRepo.save(message.to,
- message.contentType,
- message.title,
- message.summary,
- notifyMessage,
- pushable,
- function (err, result) {
- if (err) {
- log.error("Save system notify message failed, ", err);
- res.status(500).send({message: "Save system notify message failed."});
- } else {
- if (pushable) {
- if (userStatus.platform === PLATFORMS.iOS) {
- getui.pushAPN(message.to, userStatus.token, message.contentType, message.title, message.content, notifyMessage,
- function (err, result) {
- err != null ? console.log(err) : console.log(result);
- });
- } else if (userStatus.platform === PLATFORMS.Android) {
- getui.pushAndroid(userStatus.client_id, message.contentType, message.title, message.content, notifyMessage, userStatus.status,
- function (err, result) {
- err != null ? console.log(err) : console.log(result);
- });
- }
- }
- }
- });
- }
- });
- });
- });
- /**
- * 处理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.sendMessage(message.to, message);
- res.status(200).send({});
- return;
- // 保存消息
- let tempContent = message.contentType === CONTENT_TYPES.Article ? JSON.stringify(message.content) : message.content;
- pmRepo.save(message.to, message.from, message.contentType, tempContent, function (err, result) {
- if (err) {
- res.status(500).send({message: 'Save private message failed.'});
- return;
- }
- // 结束网络连接,后续操作继续执行
- pmRepo.findOneMessage(result.insertId, function (err, msg) {
- if (err) {
- res.status(500).send({message: "Save private message success, but return last message failed."});
- return;
- }
- let feedback = fillMessages(msg);
- res.status(200).send(feedback);
- patient.isPatientCode(
- message.to,
- function () {
- // 推送给患者
- patient.sendMessage(message.to, 1, feedback);
- },
- function () {
- // 推送给医生。获取对方状态,即对端的系统平台,token等信息,并推送通知消息给对端
- doctorRepo.isExist(message.to, function (err, rows) {
- if (err) {
- console.log('Lookup receiving users failed or user not found: ', err);
- return;
- }
- doctorRepo.getUserStatus(message.to, function (err, result) {
- if (err) {
- log.error('Get target user status for private message failed: ' + message.to);
- return;
- }
- // 构建通知消息
- let title = '新消息';
- let content = '';
- if (message.contentType === CONTENT_TYPES.PlainText) {
- content = message.content;
- } else if (message.contentType === CONTENT_TYPES.Image) {
- content = '[图片]';
- } else if (message.contentType === CONTENT_TYPES.Audio) {
- content = '[语音]';
- } else {
- content = '接收到一条新消息';
- }
- let target = result[0];
- let isOnline = result.length > 0 && target.is_online === 1;
- let notifyMessage = JSON.stringify({type: 'p2p_msg', from_uid: message.from});
- // 保存通知消息到数据库中并根据用户在线状态推送此消息
- nmRepo.save(message.to, message.contentType, title, content, notifyMessage, isOnline, function (err, result) {
- if (err) {
- log.error('Save private notify message failed, ', err);
- return;
- }
- if (!isOnline) return;
- if (target.platform === PLATFORMS.iOS) {
- getui.pushAPN(message.to,
- target.token,
- message.contentType,
- title,
- content,
- notifyMessage,
- function (err, result) {
- if (err != null) {
- console.log(err);
- } else {
- console.log(result);
- }
- });
- } else if (target.platform === PLATFORMS.Android) {
- getui.pushAndroid(target.client_id,
- message.contentType,
- title,
- content,
- notifyMessage,
- target.status,
- function (err, result) {
- if (err != null) {
- console.log(err);
- } else {
- console.log(result);
- }
- });
- }
- });
- });
- });
- });
- });
- // 更新自身的聊天统计信息
- statsRepo.updatePrivateChatSummary(message.from, message.to, message.from, message.contentType, message.content, function (err, result) {
- if (err) log.error(err);
- });
- // 更新对端的聊天统计信息
- statsRepo.updatePrivateChatSummary(message.to, message.from, message.from, message.contentType, message.content, function (err, result) {
- if (err) log.error(err);
- });
- });
- });
- /**
- * 处理讨论组消息。
- *
- * 请求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}
- }
- // 消息处理
- groupRepo.isGroupMember(message.group, message.groupType, message.from, function (err, result) {
- if (err) {
- log.error('Check group member failed: ', err);
- res.status(500).send({message: 'Check group member failed.'});
- return;
- }
- if (result.length == 0) {
- res.status(404).send({message: 'Member with id "' + message.from + '" is not in group "' + message.group + '"'});
- return;
- }
- // 保存群组消息
- gmRepo.save(message.from, message.group, message.at, message.contentType, message.content, function (err, insertedRow) {
- if (err) {
- log.error('Save group message failed: ', err);
- res.status(500).send({message: 'Save group message failed.'});
- return;
- }
- gmRepo.findOneMessage(insertedRow.insertId, function (err, groupMsg) {
- if (err) {
- log.error("Save group message success, but return this message failed.");
- res.status(500).send({message: "Save group message success, but return this message failed."});
- }
- // 关闭网络连接后执行后续操作
- let feedback = fillMessages(groupMsg);
- res.status(200).send(feedback);
- // 推送通知消息给群组成员
- groupRepo.getMembers(message.group, message.groupType, function (err, members) {
- if (err) {
- log.error('Get group members failed: ', err);
- return;
- }
- if (members.length == 0) {
- log.warn('No members in group ', message.group,
- message.groupType === GROUP_TYPE.AdminTeam ? " of admin team." : "of discussion group.");
- return;
- }
- // 逐个推送通知,患者与医生推送方式不一样
- for (let i = 0; i < members.length; i++) {
- let member = members[i];
- if (member.user_id === message.from) continue;
- (function (user_id) {
- patient.isPatientCode(user_id,
- function () {
- patient.sendMessage(user_id, 2, feedback);
- },
- function () {
- doctorRepo.getUserStatus(user_id, function (err, result) {
- if (err) {
- console.error('Get group member status failed: ', err);
- return;
- }
- let title = '';
- let content = '';
- if (message.contentType === CONTENT_TYPES.PlainText) {
- title = '群组消息';
- content = message.content;
- } else if (message.contentType === CONTENT_TYPES.Image) {
- title = '群组消息';
- content = '[图片]';
- } else if (message.contentType === CONTENT_TYPES.Audio) {
- title = '群组消息';
- content = '[语音]';
- } else {
- title = '群组消息';
- content = '接收到一条新消息';
- }
- let pushable = result.length > 0 && result[0].is_online === 1;
- let notifyMessage = JSON.stringify({type: 'group_msg', gid: message.group});
- // 发送并保存通知到数据库中
- if (pushable) {
- let userStatus = result[0];
- if (userStatus.platform === PLATFORMS.iOS) {
- getui.pushAPN(user_id,
- userStatus.token,
- message.contentType,
- title,
- content,
- notifyMessage,
- function (err, result) {
- err != null ? console.error(err) : console.log(result);
- // 这段代码重复
- nmRepo.save(user_id,
- message.contentType,
- title,
- content,
- notifyMessage,
- err != null ? 0 : 1,
- function (err, result) {
- if (err) {
- console.log('Save group notify message failed: ', err);
- } else {
- }
- });
- });
- } else if (userStatus.platform === PLATFORMS.Android) {
- getui.pushAndroid(data.client_id,
- message.contentType,
- title,
- content,
- notifyMessage,
- userStatus.status,
- function (err, result) {
- err != null ? console.error(err) : console.log(result);
- // 这段代码重复
- nmRepo.save(user_id,
- message.contentType,
- title,
- content,
- notifyMessage,
- err != null ? 0 : 1,
- function (err, result) {
- if (err) {
- console.log('Save group notify message failed: ', err);
- } else {
- }
- });
- });
- }
- } else {
- // 这段代码重复
- nmRepo.save(user_id,
- message.contentType,
- title,
- content,
- notifyMessage,
- 0,
- function (err, result) {
- if (err) {
- console.log('Save group notify message failed: ', err);
- } else {
- }
- });
- }
- });
- // 统计'@'信息
- let at = message.at == user_id ? 1 : 0;
- statsRepo.updateGroupChatSummary(user_id,
- message.group,
- message.from,
- at,
- message.contentType,
- message.content,
- true,
- function (err, result) {
- if (err) console.log(err);
- });
- });
- })(member.user_id);
- }
- });
- });
- // 更新组内统计信息
- statsRepo.updateGroupChatSummary(message.from, message.group, message.from, 0, message.contentType, message.content, false, function (err, result) {
- if (err) log.error(err);
- });
- });
- });
- });
- //--------------------------------------------------------------//
- //----------------------------消息提取----------------------------//
- //--------------------------------------------------------------//
- /**
- * 获取参与的聊天列表,包括:点对点,@我,参与的讨论组,系统消息等。
- *
- * 请求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.'};
- }
- // 与患者的私信
- pmRepo.findAllP2PWithPatient(userId, function (err, patients) {
- if (err) {
- log.error('Get chat list with patient failed: ', err);
- res.status(500).send({message: 'Get chat list with patient failed.'});
- return;
- }
- let chats = {patients: [], doctors: [], groups: []};
- for (let i = 0; i < patients.length; i++) {
- let patient = patients[i];
- chats.patients.push({
- code: patient.code,
- name: patient.name,
- birthday: patient.birthday,
- sex: patient.sex,
- avatar: patient.photo == null ? "" : patient.photo,
- newMessageCount: patient.new_msg_count,
- lastContentType: patient.last_content_type,
- lastContent: patient.last_content,
- timestamp: objectUtil.timestampToLong(patient.timestamp)
- });
- }
- // 含有患者的群
- gmRepo.findAllGroupsWithPatient(userId, function (err, groups) {
- if (err) {
- log.error('Get group list with patient failed: ', err);
- res.status(500).send({message: 'Get group list with patient failed.'});
- return;
- }
- for (let i = 0; i < groups.length; i++) {
- let group = groups[i];
- // 过滤掉医生间的求助团队
- if (group.group_type === 2) continue;
- //查找医生在讨论组的最新的消息记录数
- chats.groups.push({
- code: group.code,
- name: group.name,
- groupType: group.msg_type,
- newMessageCount: group.new_msg_count,
- lastContentType: group.last_content_type,
- lastContent: group.last_content,
- timestamp: objectUtil.timestampToLong(group.timestamp)
- });
- }
- // 医生间的私聊
- pmRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
- if (err) {
- log.error('Get chat list with doctor failed: ', err);
- res.status(500).send({message: 'Get chat list with doctor failed.'});
- return;
- }
- for (let i = 0; i < doctors.length; i++) {
- let doctor = doctors[i];
- chats.doctors.push({
- code: doctor.code,
- name: doctor.name,
- sex: doctor.sex,
- avatar: doctor.photo === null ? "" : doctor.photo,
- newMessageCount: doctor.new_msg_count,
- lastContentType: doctor.last_content_type,
- lastContent: doctor.last_content,
- timestamp: objectUtil.timestampToLong(doctor.timestamp)
- });
- }
- // 获取医生间的组
- gmRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
- if (err) {
- log.error('Get group list with doctor failed: ', err);
- res.status(500).send({message: 'Get group list with doctor failed.'});
- return;
- }
- for (let i = 0; i < groups.length; i++) {
- let group = groups[i];
- chats.groups.push({
- code: group.code,
- name: group.name,
- groupType: group.group_type, // 行政团队 or 求助
- newMessageCount: group.new_msg_count,
- lastContentType: group.last_content_type,
- lastContent: group.last_content,
- timestamp: objectUtil.timestampToLong(group.timestamp)
- });
- }
- res.status(200).send(chats);
- });
- });
- })
- });
- });
- /**
- * 获取与患者的聊天列表,包括: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.'};
- }
- pmRepo.findAllP2PWithPatient(userId, function (err, patients) {
- if (err) {
- log.error('Get chat list with patient failed: ', err);
- res.status(500).send({message: 'Get chat list with patient failed.'});
- return;
- }
- let chats = {patients: [], groups: []};
- for (let i = 0; i < patients.length; i++) {
- let patient = patients[i];
- chats.patients.push({
- code: patient.code,
- name: patient.name,
- birthday: patient.birthday,
- sex: patient.sex,
- avatar: patient.photo == null ? "" : patient.photo,
- newMessageCount: patient.new_msg_count,
- lastContentType: patient.last_content_type,
- lastContent: patient.last_content,
- timestamp: objectUtil.timestampToLong(patient.timestamp)
- });
- }
- gmRepo.findAllGroupsWithPatient(userId, function (err, groups) {
- if (err) {
- log.error('Get group list with patient failed: ', err);
- res.status(500).send({message: 'Get group list with patient failed.'});
- return;
- }
- for (let i = 0; i < groups.length; i++) {
- let group = groups[i];
- // 过滤掉医生间的求助团队
- if (group.group_type === 2) continue;
- chats.groups.push({
- code: group.code,
- name: group.name,
- groupType: group.msg_type,
- newMessageCount: group.new_msg_count,
- lastContentType: group.last_content_type,
- lastContent: group.last_content,
- timestamp: objectUtil.timestampToLong(group.timestamp)
- });
- }
- res.status(200).send(chats);
- })
- });
- });
- /**
- * 获取与医生的聊天列表,包括:点对点,参与的讨论组。
- *
- * 请求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.'};
- }
- // 先获取医生间的私聊
- pmRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
- if (err) {
- log.error('Get chat list with doctor failed: ', err);
- res.status(500).send({message: 'Get chat list with doctor failed.'});
- return;
- }
- let chats = {doctors: [], groups: []};
- for (let i = 0; i < doctors.length; i++) {
- let doctor = doctors[i];
- chats.doctors.push({
- code: doctor.code,
- name: doctor.name,
- sex: doctor.sex,
- avatar: doctor.photo === null ? "" : doctor.photo,
- newMessageCount: doctor.new_msg_count,
- lastContentType: doctor.last_content_type,
- lastContent: doctor.last_content,
- timestamp: objectUtil.timestampToLong(doctor.timestamp)
- });
- }
- // 再获取医生间的组
- gmRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
- if (err) {
- log.error('Get group list with doctor failed: ', err);
- res.status(500).send({message: 'Get group list with doctor failed.'});
- return;
- }
- for (let i = 0; i < groups.length; i++) {
- let group = groups[i];
- chats.groups.push({
- code: group.code,
- name: group.name,
- groupType: group.group_type, // 行政团队 or 求助
- newMessageCount: group.new_msg_count,
- lastContentType: group.last_content_type,
- lastContent: group.last_content,
- timestamp: objectUtil.timestampToLong(group.timestamp)
- });
- }
- res.status(200).send(chats);
- });
- });
- });
- /**
- * 获取最近聊天对象:包括患者,医生与讨论组。客户端自行根据需要提取患者、医生或讨论组数据。
- *
- * 请求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) {
- var userId = req.query.user_id;
- var 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'};
- }
- statsRepo.getRecentChats(userId, days, function (err, result) {
- if (err) {
- log.error('Get recent chat objects failed: ', err);
- res.status(500).send({message: 'Get recent chat objects failed.'});
- return;
- }
- var data = {patients: [], doctors: [], groups: []};
- if (result.length === 0) {
- res.status(200).send(data);
- return;
- }
- for (var i = 0; i < result.length; ++i) {
- var row = result[i];
- if (row.type.indexOf('patient') > -1) {
- data.patients.push({
- code: row.code,
- name: row.name,
- birthday: row.birthday === null ? "" : row.birthday,
- sex: row.sex,
- avatar: row.photo === null ? "" : row.photo
- });
- } else if (row.type.indexOf('doctor') > -1) {
- data.doctors.push({
- code: row.code,
- name: row.name,
- birthday: row.birthday === null ? "" : row.birthday,
- sex: row.sex,
- avatar: row.photo === null ? "" : row.photo
- });
- } else if (row.type.indexOf('group') > -1) {
- data.groups.push({
- code: row.code,
- name: row.name
- });
- }
- }
- res.status(200).send(data);
- });
- });
- /**
- * 获取私信。倒序排列。
- *
- * 参数:
- * 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) {
- var userId = req.query.user_id;
- var peerId = req.query.peer_id;
- var contentType = req.query.content_type;
- var msgStartId = !req.query.message_start_id ? MAX_INT : parseInt(req.query.message_start_id);
- var msgEndId = !req.query.message_end_id ? 0 : parseInt(req.query.message_end_id);
- var count = req.query.count === undefined ? DEFAULT_PAGE_SIZE : parseInt(req.query.count);
- var 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."};
- }
- pmRepo.findAllMessages(userId, peerId, contentType === undefined ? "1,2,3,5,6" : contentType, msgStartId, msgEndId, count, closedInterval, function (err, rows) {
- if (err) {
- log.error("Get private message failed, ", err);
- res.status(500).send({message: "Get private messages failed."});
- return;
- }
- var messages = fillMessages(rows);
- // 清空统计信息
- statsRepo.clearPrivateChatSummary(userId, peerId, function (err, result) {
- if (err) console.log(err);
- });
- res.status(200).send(messages);
- });
- });
- /**
- * 获取未读私信。倒序排列。
- *
- * 参数:
- * user_id 必须,医生ID
- * peer_id 必须,对方医生ID
- *
- * 请求URL:
- * /chats/pm/unread?user_id=sand&peer_id=Rose
- */
- router.get(APIv1.Chats.PMUnread, function (req, res) {
- var userId = req.query.user_id;
- var peerId = req.query.peer_id;
- if (userId === undefined) {
- throw {httpStatus: 400, message: "Missing field: user_id."};
- }
- statsRepo.getPrivateChatSummary(userId, peerId, function (err, summary) {
- if (err) {
- log.error("Get unread private messages failed: ", err);
- res.status(500).send({message: "Get unread private messages failed."});
- return;
- }
- // 没有未读消息,直接返回
- if (summary.length == 0 || summary[0].new_msg_count === 0) {
- res.status(200).send({startId: 0, count: 0, records: []});
- return;
- }
- pmRepo.findUnread(peerId, userId, MAX_INT, summary[0].new_msg_count, function (err, rows) {
- if (err) {
- log.error("Get unread private messages failed: ", err);
- res.status(500).send({message: "Get unread private messages failed."});
- return;
- }
- var messages = fillMessages(rows);
- res.status(200).send(messages);
- });
- });
- });
- /**
- * 按时间倒序获取群消息。
- *
- * 参数:
- * 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) {
- var groupId = req.query.group_id;
- var userId = req.query.user_id;
- var contentType = req.query.content_type;
- var msgStartId = !req.query.message_start_id ? MAX_INT : parseInt(req.query.message_start_id);
- var msgEndId = !req.query.message_end_id ? 0 : parseInt(req.query.message_end_id);
- var 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;
- gmRepo.findAllMessages(groupId, !contentType ? "1,2,3,5,6" : contentType, msgStartId, msgEndId, count, function (err, rows) {
- if (err) {
- console.log('Get group message failed: ', err);
- res.status(500).send({message: 'Get group message failed.'});
- return;
- }
- var messages = fillMessages(rows);
- // 清空统计信息
- statsRepo.clearGroupChatSummary(userId, groupId, function (err, result) {
- if (err) console.log(err);
- });
- res.status(200).send(messages);
- });
- });
- /**
- * 获取未读群消息。
- *
- * 请求URL:
- * /chats/gm/unread?group_id=discussionGroupId&user_id=sand
- */
- router.get(APIv1.Chats.GMUnread, function (req, res) {
- var userId = req.query.user_id;
- var groupId = req.query.group_id;
- if (userId === undefined) {
- throw {httpStatus: 400, message: "Missing field: user_id."};
- }
- if (groupId === undefined) {
- throw {httpStatus: 400, message: "Missing field: group_id."};
- }
- statsRepo.getGroupChatSummary(userId, groupId, function (err, summary) {
- if (err) {
- log.error("Get unread group messages failed: ", err);
- res.status(500).send({message: "Get unread group messages failed."});
- return;
- }
- var messages = {startId: 0, count: 0, records: []};
- if (summary.length == 0 || summary[0].new_msg_count === 0) {
- res.status(200).send(messages);
- return;
- }
- messages.count = summary[0].new_msg_count;
- gmRepo.findUnread(groupId, MAX_INT, messages.count, function (err, rows) {
- if (err) {
- log.error("Get unread group messages failed: ", err);
- res.status(500).send({message: "Get unread group messages failed."});
- return;
- }
- var messages = fillMessages(rows);
- res.status(200).send(messages);
- });
- });
- });
- /**
- * 将消息的返回结果合并成JSON。
- *
- * @param rows
- *
- * @returns {startId: 0, count: 0, records: []}
- */
- function fillMessages(rows) {
- var messages = {startId: rows.length > 0 ? rows[0].msg_id : '', count: rows.length, records: []};
- for (var i = 0; i < rows.length; i++) {
- var row = rows[i];
- var record = {
- id: row.msg_id,
- from: row.from_uid,
- contentType: row.type,
- content: row.content,
- timestamp: objectUtil.timestampToLong(row.timestamp)
- };
- if (row.to_uid !== undefined) record.to = row.to_uid;
- if (row.at_uid !== undefined) record.at = row.at_uid;
- messages.records.push(record);
- }
- return messages;
- }
- //--------------------------------------------------------------//
- //----------------------------消息统计----------------------------//
- //--------------------------------------------------------------//
- /**
- * 获取所有群组未读消息总数。
- *
- * 请求URL:
- * /chats/gm/unread_count?user_id=sand
- *
- * 参数:
- * user_id:医生ID
- */
- router.get(APIv1.Chats.GMUnreadCount, function (req, res) {
- var userId = req.query.user_id;
- if (userId === null) {
- throw {httpStatus: 406, message: 'Missing fields.'};
- }
- statsRepo.getGroupChatAllUnReadCount(userId, function (err, result) {
- if (err) {
- console.log('Get all unread messages failed: ', err);
- res.status(500).send({message: 'Get all unread messages failed.'});
- }
- var data = {
- userId: userId,
- messageType: 2,
- newMessageCount: 0
- };
- if (result.length > 0) {
- for (var index = 0; index < result.length; index++) {
- data.newMessageCount += result[index].new_msg_count;
- }
- }
- res.send(data);
- });
- });
- /**
- * 获取特定群组消息统计情况。
- *
- * /chats/gm/statistic?group_id=GGG&&user_id=sand
- *
- * 参数:
- * user_id:信息所有者id
- * group_id:群组id
- */
- router.get(APIv1.Chats.GMStats, function (req, res) {
- var userId = req.query.user_id;
- var groupId = req.query.group_id;
- if (userId === null || groupId === null) {
- throw {httpStatus: 406, message: 'Miss fields.'};
- }
- statsRepo.getGroupChatSummary(userId, groupId, function (err, result) {
- if (err) {
- console.log('Get group stats failed: ', err);
- res.status(500).send({message: 'Get group stats failed.'});
- return;
- }
- var data = {
- userId: userId,
- from: "",
- groupId: groupId,
- atMe: 0,
- lastContentType: 1,
- lastContent: "",
- newMessageCount: 0,
- timestamp: 0
- };
- if (result.length > 0) {
- var row = result[0];
- data.from = row.from_uid;
- data.groupId = row.gid;
- data.atMe = row.at_me;
- data.lastContentType = row.last_content_type;
- data.lastContent = row.lastContent;
- data.newMessageCount = row.new_msg_count;
- data.timestamp = objectUtil.timestampToLong(row.timestamp)
- }
- res.status(200).send(data);
- });
- });
- /**
- * 获取与某人的私信统计。
- *
- * /chats/pm/statistic?user_id=sand&&peer_id=rose
- *
- * 参数:
- * user_id:信息所有者id
- * peer_id:聊天对端id
- */
- router.get(APIv1.Chats.PMStats, function (req, res) {
- var userId = req.query.user_id;
- var peerId = req.query.peer_id;
- if (userId == null || peerId == null) {
- throw {httpStatus: 406, message: "Missing fields."};
- }
- statsRepo.getPrivateChatSummary(userId, peerId, function (err, result) {
- if (err) {
- console.log("Get private messages stats failed: ", err);
- res.status(500).send({message: "Get private messages stats failed."});
- }
- var data = {
- userId: userId,
- peerId: peerId,
- lastCContentType: 1,
- lastContent: "",
- newMessageCount: 0,
- timestamp: 0
- };
- if (result.length > 0) {
- var row = result[0];
- data.userId = row.uid;
- data.peerId = row.from_uid;
- data.lastContentType = row.last_content_type;
- data.lastContent = row.last_content;
- data.newMessageCount = row.new_msg_count;
- data.timestamp = objectUtil.timestampToLong(row.timestamp)
- }
- res.status(0).send(data);
- });
- });
- /**
- * 获取所有未读私信总数。
- *
- * /chats/pm/unread_count?user_id=sand
- *
- * 参数:
- * uid:信息所有者id
- */
- router.get(APIv1.Chats.PMUnreadCount, function (req, res) {
- var userId = req.query.user_id;
- statsRepo.getPrivateChatAllUnReadCount(userId, function (err, result) {
- if (err) {
- console.log("Get unread private message count failed: ", err);
- res.status(500).send({message: "Get unread private message count failed."});
- }
- var data = {userId: userId, messageType: 1, newMessageCount: 0};
- if (result.length > 0) {
- for (var i = 0; i < result.length; i++) {
- data.newMessageCount += result[i].new_msg_count;
- }
- }
- res.send(data);
- });
- });
- /**
- * 所有聊天消息未读数。
- *
- * 请求URL:
- * /chats/chats/unread_count?user_id=sand
- *
- * 参数:
- * user_id:信息所有者id
- */
- router.get(APIv1.Chats.UnreadMsgCount, function (req, res) {
- var userId = req.query.user_id;
- if (userId === null) {
- throw {httpStatus: 406, message: "Missing fields."};
- }
- statsRepo.getChatAllUnReadCount(userId, function (err, result) {
- if (err) {
- console.error("Get all unread message count failed: ", err);
- res.status(500).send({message: "Get all unread message count failed."});
- }
- var data = {userId: userId, messageType: 0, newMessageCount: 0};
- if (result.length > 0) {
- for (var index = 0; index < result.length; index++) {
- data.newMessageCount += result[index].new_msg_count;
- }
- }
- res.send(data);
- });
- });
- /**
- * 搜索患者相关的数据,包括患者信息与相关的私信记录。关键词不支持空格拆分。
- *
- * 请求URL:
- * /search/patient?user_id=3b723bb8699a11e69f7c005056850d66&user_role=1&keyword=庄
- *
- * 参数:
- * keywords: 关键词
- */
- router.get(APIv1.Chats.SearchAboutPatient, function (req, res) {
- var userId = req.query.user_id;
- var userRole = req.query.user_role;
- var 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."};
- searchRepo.searchPatients(userId, userRole, keyword, function (err, patients) {
- if (err) {
- log.error("Search patient on basic information failed: ", err);
- res.status(500).send({message: "Search patient on basic information failed."});
- return;
- }
- var data = {patients: [], chats: []};
- for (var i = 0; i < patients.length; ++i) {
- var patient = patients[i];
- data.patients.push({
- code: patient.code,
- name: patient.name,
- sex: patient.sex,
- birthday: objectUtil.timestampToLong(patient.birthday),
- avatar: patient.photo === null ? "" : patient.photo
- });
- }
- searchRepo.searchPatientPM(userId, keyword, function (err, chats) {
- if (err) {
- log.error("Search patient on private messages failed: ", err);
- res.status(500).send({message: "Search patient on private messages failed."});
- return;
- }
- var lastPatientCode = '';
- var lastPatient = {code: '', name: '', sex: '', avatar: '', messages: []};
- for (var i = 0; i < chats.length; ++i) {
- var chat = chats[i];
- if (lastPatientCode !== chat.code) {
- lastPatientCode = chat.code;
- lastPatient.code = chat.code;
- lastPatient.name = chat.name;
- lastPatient.sex = chat.sex;
- lastPatient.birthday = objectUtil.timestampToLong(patient.birthday);
- lastPatient.avatar = chat.photo === null ? "" : chat.photo;
- data.chats.push(lastPatient);
- }
- lastPatient.messages.push({
- id: chat.msg_id,
- content: chat.content
- });
- }
- res.status(200).send(data);
- });
- });
- });
- /**
- * 搜索医生相关的数据,包括医生信息与相关的聊天记录,包括私信与群信。
- *
- * 请求URL:
- * /search/doctor?user_id=5fa5e88f7a4111e69f7c005056850d66&keyword=丘
- *
- * 参数:
- * keywords: 关键词
- */
- router.get(APIv1.Chats.SearchAboutDoctor, function (req, res) {
- var userId = req.query.user_id;
- var keyword = req.query.keyword;
- if (!userId) throw {httpStatus: 406, message: "Missing fields: user_id."};
- if (!keyword) throw {httpStatus: 406, message: "Missing fields: keyword."};
- // 搜索医生
- searchRepo.searchDoctors(userId, keyword, function (err, doctors) {
- if (err) {
- log.error("Search doctor on basic information failed: ", err);
- res.status(500).send({message: "Search doctor on basic information failed."});
- return;
- }
- var data = {doctors: [], groups: [], chats: {doctors: [], groups: []}};
- for (var i = 0; i < doctors.length; ++i) {
- var doctor = doctors[i];
- data.doctors.push({
- code: doctor.code,
- name: doctor.name,
- sex: doctor.sex,
- avatar: doctor.photo === null ? "" : doctor.photo
- });
- }
- // 搜索讨论组名称及成员名称
- searchRepo.searchGroups(userId, keyword, function (err, groups) {
- if (err) {
- log.error("Search talk group failed: ", err);
- res.status(500).send({message: "Search talk group failed."});
- return;
- }
- var lastGroupCode = '';
- var lastGroup = null;
- for (var i = 0; i < groups.length; ++i) {
- var group = groups[i];
- if (lastGroupCode !== group.code) {
- lastGroupCode = group.code;
- lastGroup = {
- code: group.code,
- name: group.name,
- type: GROUP_TYPE.DiscussionGroup,
- members: []
- };
- data.groups.push(lastGroup);
- }
- lastGroup.members.push({
- code: group.member_code,
- name: group.member_name
- });
- }
- // 搜索医生间的私信
- searchRepo.searchDoctorMessages(userId, keyword, function (err, messages) {
- if (err) {
- log.error("Search doctor private messages failed: ", err);
- res.status(500).send({message: "Search doctor private messages failed."});
- return;
- }
- var lastDoctor;
- var lastDoctorCode = '';
- for (var i = 0; i < messages.length; ++i) {
- var message = messages[i];
- if (lastDoctorCode !== message.code) {
- lastDoctorCode = message.code;
- lastDoctor = {
- code: message.code,
- name: message.name,
- photo: message.photo === null ? "" : message.photo,
- messages: []
- };
- data.chats.doctors.push(lastDoctor);
- }
- lastDoctor.messages.push({
- id: message.msg_id,
- content: message.content
- });
- }
- // 搜索医生间的讨论组消息
- searchRepo.searchGroupMessages(userId, keyword, function (err, messages) {
- if (err) {
- log.error("Search doctor group messages failed: ", err);
- res.status(500).send({message: "Search doctor group messages failed."});
- return;
- }
- // g.code, g.name, gm.msg_id, gm.content
- var lastGroup;
- var lastGroupCode = '';
- for (var i = 0; i < messages.length; ++i) {
- var message = messages[i];
- if (lastGroupCode !== message.code) {
- lastGroupCode = message.code;
- lastGroup = {
- code: message.code,
- name: message.name,
- messages: []
- };
- data.chats.groups.push(lastGroup);
- }
- lastGroup.messages.push({
- id: message.msg_id,
- content: message.content
- });
- }
- res.status(200).send(data);
- });
- });
- });
- });
- });
- /**
- * 获取单条消息。
- *
- * URL:
- * /chats/message?id=1234&type=1
- */
- router.get(APIv1.Chats.Message, function (req, res) {
- var messageId = req.query.id;
- var messageType = req.query.type;
- // 私信
- if (messageType == 1) {
- pmRepo.findOneMessage(messageId, function (err, result) {
- if (err) {
- log.error("Get message failed: ", err);
- res.status(500).send({message: "Get message failed."});
- return;
- }
- if (result.length == 0) {
- res.status(404).send({message: "Message not found."});
- return;
- }
- res.status(200).send({
- id: result[0].msg_id,
- from: result[0].from_uid,
- to: result[0].to_uid,
- contentType: result[0].type,
- content: result[0].content,
- timestamp: objectUtil.timestampToLong(result[0].timestamp)
- });
- })
- } else {
- gmRepo.findOneMessage(messageId, function (err, result) {
- if (err) {
- log.error("Get message failed: ", err);
- res.status(500).send({message: "Get message failed."});
- return;
- }
- if (result.length == 0) {
- res.status(404).send({message: "Message not found."});
- return;
- }
- res.status(200).send({
- id: result[0].msg_id,
- from: result[0].from_uid,
- at: result[0].at_uid,
- groupId: result[0].to_gid,
- contentType: result[0].type,
- content: result[0].content,
- timestamp: objectUtil.timestampToLong(result[0].timestamp)
- });
- });
- }
- });
- /**
- * 判断当前会话是否已经结束。
- *
- * 请求URL:
- * /chats/pm/finished?user_id=sand&peer_id=rose
- */
- router.get(APIv1.Chats.PMFinished, function (req, res) {
- var doctorId = req.query.doctor_id;
- var 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"};
- }
- pmRepo.isCurrentSessionFinished(doctorId, patientId, function (err, result) {
- if (err) {
- log.error("Get session finish status failed: ", err);
- throw {httpStatus: 500, message: "Get session finish status failed."};
- }
- var data = {finished: true, consultId: ''};
- if (result.length > 0) {
- var finishRow = result[0];
- data.finished = finishRow.finished === 1;
- if (!data.finished) {
- data.consultId = finishRow.consult_id;
- }
- }
- res.status(200).send(data);
- })
- });
- module.exports = router;
|