chat.service.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { Inject, Provide } from '@midwayjs/decorator';
  2. import { InjectEntityModel } from '@midwayjs/typegoose';
  3. import { ReturnModelType } from '@typegoose/typegoose';
  4. import { BaseService, PageOptions, SearchBase } from 'free-midway-component';
  5. import { Chat } from '../entity/chat.entity';
  6. import { cloneDeep, get, head } from 'lodash';
  7. import { ChatMqService } from './chatMq.service';
  8. import { Types } from 'mongoose';
  9. import { JwtService } from '@midwayjs/jwt';
  10. const assert = require('assert');
  11. const ObjectId = Types.ObjectId;
  12. type modelType = ReturnModelType<typeof Chat>;
  13. @Provide()
  14. export class ChatService extends BaseService<modelType> {
  15. @InjectEntityModel(Chat)
  16. model: modelType;
  17. @Inject()
  18. chatMqService: ChatMqService;
  19. @Inject()
  20. jwtService: JwtService;
  21. // 处理已读问题
  22. async allRead(data) {
  23. const token = get(this.ctx, 'request.header.token');
  24. assert(token, '缺少token信息');
  25. const tokenInfo = await this.jwtService.decodeSync(token);
  26. const info = { ...data, not_read: 1, speaker: { $ne: get(tokenInfo, '_id') } };
  27. let result;
  28. if (get(tokenInfo, 'role') === 'Patient') result = await this.model.find({ ...info }).lean();
  29. else result = await this.model.find({ ...info, speaker_type: 'Patient' }).lean();
  30. const ids = result.map(i => new ObjectId(i._id).toString());
  31. await this.model.updateMany({ _id: ids }, { $set: { not_read: 0 } });
  32. }
  33. async sendMq(data) {
  34. // 队列: /${群组id}/${患者id}
  35. const { group, patient, _id } = data;
  36. // 没有群组&患者id直接返回,无法构成队列
  37. if (!(group && patient)) return;
  38. const routingKey = `${group}_${patient}`;
  39. const nd = await this.fetch(_id);
  40. await this.chatMqService.sendExMsg(routingKey, JSON.stringify(nd));
  41. }
  42. async query(filter: SearchBase, pageOptions: PageOptions = {}): Promise<Array<any>> {
  43. const dup = cloneDeep(filter.getFilter());
  44. const data = await this.model.find(dup, {}, { ...pageOptions, sort: { 'meta.createdAt': -1 } }).populate('speaker');
  45. return data;
  46. }
  47. lastChatRecordListItem = {
  48. group: 1,
  49. doctor: 1,
  50. patient: 1,
  51. patientName: '$pInfo.name',
  52. patientIcon: '$pInfo.icon',
  53. type: 1,
  54. time: 1,
  55. content: 1,
  56. notRead: 1,
  57. };
  58. /**
  59. * 根据医护.查找最后发送消息记录
  60. * @param doctor 医生id
  61. * @param skip 分页
  62. * @param limit 分页
  63. * @param name 患者姓名,查询用
  64. * @returns
  65. */
  66. async getLastChatRecordList(doctor: string, skip?: number, limit?: number, name?: string) {
  67. const pipes = [];
  68. const query = { doctor };
  69. pipes.push({ $match: query });
  70. pipes.push({ $sort: { 'meta.createdAt': -1 } });
  71. // 如果speaker等于patient,说明这是患者讲的话,是否未读的状态是算医护上的;如果不是患者讲的,那就不算了
  72. pipes.push({
  73. $addFields: { countDot: { $cond: { if: { $eq: ['$speaker', '$patient'] }, then: '$not_read', else: 0 } } },
  74. });
  75. pipes.push({
  76. $group: {
  77. _id: '$patient',
  78. l: { $first: '$$ROOT' },
  79. notRead: { $sum: '$countDot' },
  80. },
  81. });
  82. // 将notRead结果放到l里,之后替换根变量
  83. pipes.push({ $addFields: { 'l.gid': { $toObjectId: '$l.group' }, 'l.pid': { $toObjectId: '$l.patient' }, 'l.did': { $toObjectId: '$l.doctor' }, 'l.notRead': '$notRead' } });
  84. pipes.push({ $replaceRoot: { newRoot: '$l' } });
  85. pipes.push({
  86. $lookup: {
  87. from: 'group',
  88. localField: 'gid',
  89. foreignField: '_id',
  90. as: 'gInfo',
  91. },
  92. });
  93. pipes.push({ $unwind: '$gInfo' });
  94. pipes.push({
  95. $lookup: {
  96. from: 'patient',
  97. localField: 'pid',
  98. foreignField: '_id',
  99. as: 'pInfo',
  100. },
  101. });
  102. pipes.push({ $unwind: '$pInfo' });
  103. pipes.push({
  104. $lookup: {
  105. from: 'doctor',
  106. localField: 'did',
  107. foreignField: '_id',
  108. as: 'dInfo',
  109. },
  110. });
  111. pipes.push({ $unwind: '$dInfo' });
  112. if (name) {
  113. pipes.push({ $match: { 'pInfo.name': new RegExp(name) } });
  114. }
  115. pipes.push({ $project: this.lastChatRecordListItem });
  116. // 查询总数
  117. const totalResult = await this.model.aggregate([...pipes, { $count: 'total' }]);
  118. if (skip && skip >= 0) pipes.push({ $skip: skip });
  119. if (limit && limit > 0) pipes.push({ $limit: limit });
  120. const result = await this.model.aggregate(pipes);
  121. return { data: result, total: get(head(totalResult), 'total') };
  122. }
  123. }