doctor.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. /**
  2. * 医生模型。
  3. */
  4. "use strict";
  5. let log = require("../util/log.js");
  6. let getui = require('getui');
  7. let BaseModel = require('./base.model');
  8. let doctorRepo = require('../repository/doctor.repo.js');
  9. let gmRepo = require('../repository/group.msg.repo');
  10. let pmRepo = require('../repository/private.msg.repo');
  11. let nmRepo = require("../repository/notify.msg.repo");
  12. let smRepo = require("../repository/system.msg.repo.js");
  13. let statsRepo = require("../repository/stats.msg.repo");
  14. let objectUtil = require("../util/objectUtil.js");
  15. let modelUtil = require('../util/modelUtil');
  16. const CONTENT_TYPES = require('../include/commons').CONTENT_TYPE;
  17. const PLATFORMS = require('../include/commons').PLATFORM;
  18. class Doctor extends BaseModel {
  19. constructor() {
  20. super();
  21. }
  22. /**
  23. * 向医生发送消息。
  24. *
  25. * @param message
  26. */
  27. sendMessage(message) {
  28. let self = this;
  29. let tempContent = message.contentType === CONTENT_TYPES.Article ? JSON.stringify(message.content) : message.content;
  30. pmRepo.save(message.to, message.from, message.contentType, tempContent, function (err, result) {
  31. if (err) {
  32. modelUtil.emitDbError(self.eventEmitter, 'Save private message failed', err);
  33. return;
  34. }
  35. // 返回新插入的消息数据,并推送
  36. pmRepo.findOneMessage(result.insertId, function (err, msg) {
  37. if (err) {
  38. modelUtil.emitDbError(self.eventEmitter, 'Save private message success, but return last message failed', err);
  39. return;
  40. }
  41. // 先结束网络连接,再推送给客户端
  42. modelUtil.emitData(self.eventEmitter, Doctor.fillMessages(msg));
  43. Doctor.pushMessage(message, 'p2p_msg');
  44. });
  45. // 更新自身的聊天统计信息
  46. statsRepo.updatePrivateChatSummary(message.from, message.to, message.from, message.contentType, message.content, function (err, result) {
  47. if (err) log.error(err);
  48. });
  49. // 更新对端的聊天统计信息
  50. statsRepo.updatePrivateChatSummary(message.to, message.from, message.from, message.contentType, message.content, function (err, result) {
  51. if (err) log.error(err);
  52. });
  53. });
  54. }
  55. /**
  56. * 向医生发送系统消息。
  57. *
  58. * @param message
  59. */
  60. sendSystemMessage(message) {
  61. let self = this;
  62. smRepo.save(message.to,
  63. message.contentType,
  64. message.title,
  65. message.summary,
  66. message.content,
  67. function (err, result) {
  68. if (err) {
  69. modelUtil.emitDbError(self.eventEmitter, "Save system message failed", err);
  70. return;
  71. }
  72. // 先结束网络连接,再推送给客户端
  73. modelUtil.emitData(self.eventEmitter, {});
  74. Doctor.pushMessage(message, 'system_msg');
  75. });
  76. }
  77. /**
  78. * 推送消息。
  79. *
  80. * @param message
  81. * @param channel
  82. */
  83. static pushMessage(message, channel){
  84. doctorRepo.getUserStatus(message.to, function (err, result) {
  85. if (err) {
  86. log.error('Lookup notify message receiver failed: ' + message.to);
  87. return;
  88. }
  89. if (result.length == 0) {
  90. log.warn('Notify message receiver is not found: ', message.to);
  91. return;
  92. }
  93. let userStatus = result[0];
  94. let isOnline = result.length > 0 && userStatus.is_online === 1;
  95. // 构建通知消息
  96. let notifyMessage = {type: channel, data: message.content};
  97. if(message.from) notifyMessage.from_uid = message.from;
  98. if(message.gid) notifyMessage.gid = message.gid;
  99. let title = '新消息';
  100. let content = message.content;
  101. if (message.contentType === CONTENT_TYPES.Image) {
  102. content = '[图片]';
  103. } else if (message.contentType === CONTENT_TYPES.Audio) {
  104. content = '[语音]';
  105. } else if(message.contentType > 3) {
  106. content = '您有一条新消息';
  107. }
  108. // 保存通知消息到数据库中,并根据用户在线状态推送此消息
  109. nmRepo.save(message.to, message.contentType, title, content, JSON.stringify(notifyMessage), isOnline, function (err, result) {
  110. if (err) {
  111. log.error('Save notify message failed, ', err);
  112. return;
  113. }
  114. if (!isOnline) return;
  115. Doctor.pushToClient(message.to, userStatus.clientId, userStatus.status, userStatus.token, message.contentType,
  116. title, content, notifyMessage, userStatus.platform, function (err, result) {
  117. if (err != null) {
  118. console.log(err);
  119. } else {
  120. console.log(result);
  121. }
  122. });
  123. });
  124. });
  125. }
  126. /**
  127. * 推送消息给医生客户端。
  128. *
  129. * @param userId 用户ID
  130. * @param clientId 客户端设备ID
  131. * @param appStatus 客户端App状态
  132. * @param token
  133. * @param contentType
  134. * @param title
  135. * @param content
  136. * @param notifyMessage
  137. * @param platform
  138. * @param handler
  139. */
  140. static pushToClient(userId, clientId, appStatus, token, contentType, title, content, notifyMessage, platform, handler) {
  141. if (platform === PLATFORMS.iOS) {
  142. getui.pushAPN(userId, token, contentType, title, content, notifyMessage, handler);
  143. } else if (platform === PLATFORMS.Android) {
  144. getui.pushAndroid(clientId, contentType, title, content, notifyMessage, appStatus, handler);
  145. }
  146. }
  147. /**
  148. * 获取最近聊天的用户,组。
  149. */
  150. getRecentChatList() {
  151. let self = this;
  152. statsRepo.getRecentChats(userId, days, function (err, rows) {
  153. if (err) {
  154. modelUtil.emitDbError(self.eventEmitter, 'Get recent chat objects failed', err);
  155. return;
  156. }
  157. let data = {patients: [], doctors: [], groups: []};
  158. if (rows.length > 0) {
  159. for (let i = 0; i < rows.length; ++i) {
  160. let row = rows[i];
  161. if (row.type.indexOf('patient') > -1) {
  162. data.patients.push({
  163. code: row.code,
  164. name: row.name,
  165. birthday: row.birthday === null ? "" : row.birthday,
  166. sex: row.sex,
  167. avatar: row.photo === null ? "" : row.photo
  168. });
  169. } else if (row.type.indexOf('doctor') > -1) {
  170. data.doctors.push({
  171. code: row.code,
  172. name: row.name,
  173. birthday: row.birthday === null ? "" : row.birthday,
  174. sex: row.sex,
  175. avatar: row.photo === null ? "" : row.photo
  176. });
  177. } else if (row.type.indexOf('group') > -1) {
  178. data.groups.push({
  179. code: row.code,
  180. name: row.name
  181. });
  182. }
  183. }
  184. }
  185. modelUtil.emitData(self.eventEmitter, data);
  186. });
  187. }
  188. /**
  189. * 获取参与的聊天列表,包括:点对点,参与的讨论组,系统消息等。
  190. *
  191. * @param userId
  192. */
  193. getChatList(userId) {
  194. let self = this;
  195. // 与患者的私信
  196. pmRepo.findAllP2PWithPatient(userId, function (err, patients) {
  197. if (err) {
  198. modelUtil.emitDbError(self.eventEmitter, 'Get chat list with patient failed', err);
  199. return;
  200. }
  201. let chats = {patients: [], doctors: [], groups: []};
  202. for (let i = 0; i < patients.length; i++) {
  203. let patient = patients[i];
  204. chats.patients.push({
  205. code: patient.code,
  206. name: patient.name,
  207. birthday: patient.birthday,
  208. sex: patient.sex,
  209. avatar: patient.photo == null ? "" : patient.photo,
  210. newMessageCount: patient.new_msg_count,
  211. lastContentType: patient.last_content_type,
  212. lastContent: patient.last_content,
  213. timestamp: objectUtil.timestampToLong(patient.timestamp)
  214. });
  215. }
  216. // 含有患者的群
  217. gmRepo.findAllGroupsWithPatient(userId, function (err, groups) {
  218. if (err) {
  219. modelUtil.emitDbError(self.eventEmitter, 'Get group list with patient failed', err);
  220. return;
  221. }
  222. for (let i = 0; i < groups.length; i++) {
  223. let group = groups[i];
  224. // 过滤掉医生间的求助团队
  225. if (group.group_type === 2) continue;
  226. chats.groups.push({
  227. code: group.code,
  228. name: group.name,
  229. groupType: group.msg_type,
  230. newMessageCount: group.new_msg_count,
  231. lastContentType: group.last_content_type,
  232. lastContent: group.last_content,
  233. timestamp: objectUtil.timestampToLong(group.timestamp)
  234. });
  235. }
  236. // 医生间的私聊
  237. pmRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
  238. if (err) {
  239. modelUtil.emitDbError(self.eventEmitter, 'Get chat list with doctor failed', err);
  240. return;
  241. }
  242. for (let i = 0; i < doctors.length; i++) {
  243. let doctor = doctors[i];
  244. chats.doctors.push({
  245. code: doctor.code,
  246. name: doctor.name,
  247. sex: doctor.sex,
  248. avatar: doctor.photo === null ? "" : doctor.photo,
  249. newMessageCount: doctor.new_msg_count,
  250. lastContentType: doctor.last_content_type,
  251. lastContent: doctor.last_content,
  252. timestamp: objectUtil.timestampToLong(doctor.timestamp)
  253. });
  254. }
  255. // 获取医生间的组
  256. gmRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
  257. if (err) {
  258. modelUtil.emitDbError(self.eventEmitter, 'Get group list with doctor failed', err);
  259. return;
  260. }
  261. for (let i = 0; i < groups.length; i++) {
  262. let group = groups[i];
  263. chats.groups.push({
  264. code: group.code,
  265. name: group.name,
  266. groupType: group.group_type, // 行政团队 or 求助
  267. newMessageCount: group.new_msg_count,
  268. lastContentType: group.last_content_type,
  269. lastContent: group.last_content,
  270. timestamp: objectUtil.timestampToLong(group.timestamp)
  271. });
  272. }
  273. modelUtil.emitData(self.eventEmitter, chats);
  274. });
  275. });
  276. })
  277. });
  278. }
  279. /**
  280. * 获取与患者的聊天列表。
  281. */
  282. getChatsListWithPatient(userId) {
  283. let self = this;
  284. pmRepo.findAllP2PWithPatient(userId, function (err, patients) {
  285. if (err) {
  286. modelUtil.emitDbError(self.eventEmitter, 'Get chat list with patient failed', err);
  287. return;
  288. }
  289. let chats = {patients: [], groups: []};
  290. for (let i = 0; i < patients.length; i++) {
  291. let patient = patients[i];
  292. chats.patients.push({
  293. code: patient.code,
  294. name: patient.name,
  295. birthday: patient.birthday,
  296. sex: patient.sex,
  297. avatar: patient.photo == null ? "" : patient.photo,
  298. newMessageCount: patient.new_msg_count,
  299. lastContentType: patient.last_content_type,
  300. lastContent: patient.last_content,
  301. timestamp: objectUtil.timestampToLong(patient.timestamp)
  302. });
  303. }
  304. gmRepo.findAllGroupsWithPatient(userId, function (err, groups) {
  305. if (err) {
  306. modelUtil.emitDbError(self.eventEmitter, 'Get group list with patient failed', err);
  307. return;
  308. }
  309. for (let i = 0; i < groups.length; i++) {
  310. let group = groups[i];
  311. // 过滤掉医生间的求助团队
  312. if (group.group_type === 2) continue;
  313. chats.groups.push({
  314. code: group.code,
  315. name: group.name,
  316. groupType: group.msg_type,
  317. newMessageCount: group.new_msg_count,
  318. lastContentType: group.last_content_type,
  319. lastContent: group.last_content,
  320. timestamp: objectUtil.timestampToLong(group.timestamp)
  321. });
  322. }
  323. modelUtil.emitData(self.eventEmitter, chats);
  324. })
  325. });
  326. }
  327. /**
  328. * 获取与医生的聊天列表,包括:点对点,参与的讨论组。
  329. *
  330. * @param userId
  331. */
  332. getChatListWithDoctor(userId) {
  333. let self = this;
  334. // 先获取医生间的私聊
  335. pmRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
  336. if (err) {
  337. modelUtil.emitDbError(self.eventEmitter, 'Get chat list with doctor failed', err);
  338. return;
  339. }
  340. let chats = {doctors: [], groups: []};
  341. for (let i = 0; i < doctors.length; i++) {
  342. let doctor = doctors[i];
  343. chats.doctors.push({
  344. code: doctor.code,
  345. name: doctor.name,
  346. sex: doctor.sex,
  347. avatar: doctor.photo === null ? "" : doctor.photo,
  348. newMessageCount: doctor.new_msg_count,
  349. lastContentType: doctor.last_content_type,
  350. lastContent: doctor.last_content,
  351. timestamp: objectUtil.timestampToLong(doctor.timestamp)
  352. });
  353. }
  354. // 再获取医生间的组
  355. gmRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
  356. if (err) {
  357. modelUtil.emitDbError(self.eventEmitter, 'Get group list with doctor failed', err);
  358. return;
  359. }
  360. for (let i = 0; i < groups.length; i++) {
  361. let group = groups[i];
  362. chats.groups.push({
  363. code: group.code,
  364. name: group.name,
  365. groupType: group.group_type, // 行政团队 or 求助
  366. newMessageCount: group.new_msg_count,
  367. lastContentType: group.last_content_type,
  368. lastContent: group.last_content,
  369. timestamp: objectUtil.timestampToLong(group.timestamp)
  370. });
  371. }
  372. modelUtil.emitData(self.eventEmitter, chats);
  373. });
  374. });
  375. }
  376. /**
  377. * 获取与指定用户的聊天记录。
  378. *
  379. * @param userId
  380. * @param peerId
  381. * @param contentType
  382. * @param msgStartId
  383. * @param msgEndId
  384. * @param count
  385. * @param closedInterval
  386. */
  387. getPrivateMessages(userId, peerId, contentType, msgStartId, msgEndId, count, closedInterval) {
  388. let self = this;
  389. pmRepo.findAllMessages(userId, peerId, contentType === undefined ? "1,2,3,5,6" : contentType, msgStartId, msgEndId, count, closedInterval, function (err, rows) {
  390. if (err) {
  391. modelUtil.emitDbError(self.eventEmitter, 'Get private message failed', err);
  392. return;
  393. }
  394. let messages = self.fillMessages(rows);
  395. modelUtil.emitData(self.eventEmitter, messages);
  396. // 清空统计信息
  397. statsRepo.clearPrivateChatSummary(userId, peerId, function (err, result) {
  398. if (err) console.log(err);
  399. });
  400. });
  401. }
  402. /**
  403. * 获取与某人聊天的未读消息数。
  404. *
  405. * @param userId
  406. * @param peerId
  407. */
  408. getUnreadMessageCount(userId, peerId) {
  409. let self = this;
  410. statsRepo.getPrivateChatAllUnReadCount(userId, function (err, result) {
  411. if (err) {
  412. modelUtil.emitDbError(self.eventEmitter, "Get unread private message count failed", err);
  413. return;
  414. }
  415. let data = {userId: userId, messageType: 1, newMessageCount: 0};
  416. for (let i = 0; i < result.length; i++) {
  417. data.newMessageCount += result[i].new_msg_count;
  418. }
  419. modelUtil.emitData(self.eventEmitter, data);
  420. });
  421. }
  422. /**
  423. * 获取所有未读的消息数,包括群。
  424. *
  425. * @param userId
  426. */
  427. getAllUnreadMessageCount(userId) {
  428. let self = this;
  429. statsRepo.getChatAllUnReadCount(userId, function (err, result) {
  430. if (err) {
  431. modelUtil.emitDbError(self.eventEmitter, "Get all unread message count failed", err);
  432. return;
  433. }
  434. let data = {userId: userId, messageType: 0, newMessageCount: 0};
  435. for (let index = 0; index < result.length; index++) {
  436. data.newMessageCount += result[index].new_msg_count;
  437. }
  438. modelUtil.emitData(self.eventEmitter, data);
  439. });
  440. }
  441. /**
  442. * 获取与指定用户的未读聊天记录。
  443. *
  444. * @param userId
  445. * @param peerId
  446. */
  447. getUnreadPrivateMessages(userId, peerId) {
  448. let self = this;
  449. statsRepo.getPrivateChatSummary(userId, peerId, function (err, summary) {
  450. if (err) {
  451. modelUtil.emitDbError(self.eventEmitter, 'Get unread private messages failed', err);
  452. return;
  453. }
  454. // 没有未读消息,直接返回
  455. if (summary.length == 0 || summary[0].new_msg_count === 0) {
  456. modelUtil.emitData(self.eventEmitter, {startId: 0, count: 0, records: []});
  457. return;
  458. }
  459. pmRepo.findUnread(peerId, userId, MAX_INT, summary[0].new_msg_count, function (err, rows) {
  460. if (err) {
  461. modelUtil.emitDbError(self.eventEmitter, "Get unread private messages failed", err);
  462. return;
  463. }
  464. let messages = self.fillMessages(rows);
  465. modelUtil.emitData(self.eventEmitter, messages);
  466. });
  467. });
  468. }
  469. /**
  470. * 获取聊天统计摘要。
  471. *
  472. * @param userId
  473. * @param peerId
  474. */
  475. getChatSummary(userId, peerId) {
  476. let self = this;
  477. statsRepo.getPrivateChatSummary(userId, peerId, function (err, result) {
  478. if (err) {
  479. modelUtil.emitDbError(self.eventEmitter, "Get private messages statistic failed", err);
  480. return;
  481. }
  482. let data = {
  483. userId: userId,
  484. peerId: peerId,
  485. lastCContentType: 1,
  486. lastContent: "",
  487. newMessageCount: 0,
  488. timestamp: 0
  489. };
  490. if (result.length > 0) {
  491. let row = result[0];
  492. data.userId = row.uid;
  493. data.peerId = row.from_uid;
  494. data.lastContentType = row.last_content_type;
  495. data.lastContent = row.last_content;
  496. data.newMessageCount = row.new_msg_count;
  497. data.timestamp = objectUtil.timestampToLong(row.timestamp)
  498. }
  499. modelUtil.emitData(self.eventEmitter, data);
  500. });
  501. }
  502. getMessage(messageId, messageType) {
  503. let self = this;
  504. if (messageType == 1) {
  505. // 私信
  506. pmRepo.findOneMessage(messageId, function (err, result) {
  507. if (err) {
  508. modelUtil.emitDbError(self.eventEmitter, "Get message failed", err);
  509. return;
  510. }
  511. if (result.length == 0) {
  512. modelUtil.emitDataNotFound(self.eventEmitter, "Message not found.");
  513. return;
  514. }
  515. modelUtil.emitData(self.eventEmitter, {
  516. id: result[0].msg_id,
  517. from: result[0].from_uid,
  518. to: result[0].to_uid,
  519. contentType: result[0].type,
  520. content: result[0].content,
  521. timestamp: objectUtil.timestampToLong(result[0].timestamp)
  522. });
  523. })
  524. } else {
  525. // 群信
  526. gmRepo.findOneMessage(messageId, function (err, result) {
  527. if (err) {
  528. modelUtil.emitDbError(self.eventEmitter, "Get message failed", err);
  529. return;
  530. }
  531. if (result.length == 0) {
  532. modelUtil.emitDataNotFound(self.eventEmitter, "Message not found.");
  533. return;
  534. }
  535. modelUtil.emitData(self.eventEmitter, {
  536. id: result[0].msg_id,
  537. from: result[0].from_uid,
  538. at: result[0].at_uid,
  539. groupId: result[0].to_gid,
  540. contentType: result[0].type,
  541. content: result[0].content,
  542. timestamp: objectUtil.timestampToLong(result[0].timestamp)
  543. });
  544. });
  545. }
  546. }
  547. /**
  548. * 判断与患者的最新咨询会话是否已经结束。
  549. */
  550. isConsultFinished(doctorId, patientId) {
  551. let self = this;
  552. pmRepo.isCurrentSessionFinished(doctorId, patientId, function (err, result) {
  553. if (err) {
  554. modelUtil.emitDbError(self.eventEmitter, "Get session finish status failed: ", err);
  555. return;
  556. }
  557. let data = {finished: true, consultId: ''};
  558. if (result.length > 0) {
  559. let finishRow = result[0];
  560. data.finished = finishRow.finished === 1;
  561. if (!data.finished) {
  562. data.consultId = finishRow.consult_id;
  563. }
  564. }
  565. modelUtil.emitData(self.eventEmitter, data);
  566. })
  567. }
  568. /**
  569. * 将消息的返回结果合并成JSON。
  570. *
  571. * @param rows
  572. *
  573. * @returns {startId: 0, count: 0, records: []}
  574. */
  575. static fillMessages(rows) {
  576. let messages = {startId: rows.length > 0 ? rows[0].msg_id : '', count: rows.length, records: []};
  577. for (let i = 0; i < rows.length; i++) {
  578. let row = rows[i];
  579. let record = {
  580. id: row.msg_id,
  581. from: row.from_uid,
  582. contentType: row.type,
  583. content: row.content,
  584. timestamp: objectUtil.timestampToLong(row.timestamp)
  585. };
  586. if (row.to_uid !== undefined) record.to = row.to_uid;
  587. if (row.at_uid !== undefined) record.at = row.at_uid;
  588. messages.records.push(record);
  589. }
  590. return messages;
  591. }
  592. }
  593. // Expose class
  594. module.exports = Doctor;