123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import { Inject, Provide } from '@midwayjs/decorator';
- import { InjectEntityModel } from '@midwayjs/typegoose';
- import { ReturnModelType } from '@typegoose/typegoose';
- import { BaseService, PageOptions, SearchBase } from 'free-midway-component';
- import { Chat } from '../entity/chat.entity';
- import { cloneDeep, get, head } from 'lodash';
- import { ChatMqService } from './chatMq.service';
- import { Types } from 'mongoose';
- import { JwtService } from '@midwayjs/jwt';
- const assert = require('assert');
- const ObjectId = Types.ObjectId;
- type modelType = ReturnModelType<typeof Chat>;
- @Provide()
- export class ChatService extends BaseService<modelType> {
- @InjectEntityModel(Chat)
- model: modelType;
- @Inject()
- chatMqService: ChatMqService;
- @Inject()
- jwtService: JwtService;
- // 处理已读问题
- async allRead(data) {
- const token = get(this.ctx, 'request.header.token');
- assert(token, '缺少token信息');
- const tokenInfo = await this.jwtService.decodeSync(token);
- const info = { ...data, not_read: 1, speaker: { $ne: get(tokenInfo, '_id') } };
- let result;
- if (get(tokenInfo, 'role') === 'Patient') result = await this.model.find({ ...info }).lean();
- else result = await this.model.find({ ...info, speaker_type: 'Patient' }).lean();
- const ids = result.map(i => new ObjectId(i._id).toString());
- await this.model.updateMany({ _id: ids }, { $set: { not_read: 0 } });
- }
- async sendMq(data) {
- // 队列: /${群组id}/${患者id}
- const { group, patient, _id } = data;
- // 没有群组&患者id直接返回,无法构成队列
- if (!(group && patient)) return;
- const routingKey = `${group}_${patient}`;
- const nd = await this.fetch(_id);
- await this.chatMqService.sendExMsg(routingKey, JSON.stringify(nd));
- }
- async query(filter: SearchBase, pageOptions: PageOptions = {}): Promise<Array<any>> {
- const dup = cloneDeep(filter.getFilter());
- const data = await this.model.find(dup, {}, { ...pageOptions, sort: { 'meta.createdAt': -1 } }).populate('speaker');
- return data;
- }
- lastChatRecordListItem = {
- group: 1,
- doctor: 1,
- patient: 1,
- patientName: '$pInfo.name',
- patientIcon: '$pInfo.icon',
- type: 1,
- time: 1,
- content: 1,
- notRead: 1,
- };
- /**
- * 根据医护.查找最后发送消息记录
- * @param doctor 医生id
- * @param skip 分页
- * @param limit 分页
- * @param name 患者姓名,查询用
- * @returns
- */
- async getLastChatRecordList(doctor: string, skip?: number, limit?: number, name?: string) {
- const pipes = [];
- const query = { doctor };
- pipes.push({ $match: query });
- pipes.push({ $sort: { 'meta.createdAt': -1 } });
- // 如果speaker等于patient,说明这是患者讲的话,是否未读的状态是算医护上的;如果不是患者讲的,那就不算了
- pipes.push({
- $addFields: { countDot: { $cond: { if: { $eq: ['$speaker', '$patient'] }, then: '$not_read', else: 0 } } },
- });
- pipes.push({
- $group: {
- _id: '$patient',
- l: { $first: '$$ROOT' },
- notRead: { $sum: '$countDot' },
- },
- });
- // 将notRead结果放到l里,之后替换根变量
- pipes.push({ $addFields: { 'l.gid': { $toObjectId: '$l.group' }, 'l.pid': { $toObjectId: '$l.patient' }, 'l.did': { $toObjectId: '$l.doctor' }, 'l.notRead': '$notRead' } });
- pipes.push({ $replaceRoot: { newRoot: '$l' } });
- pipes.push({
- $lookup: {
- from: 'group',
- localField: 'gid',
- foreignField: '_id',
- as: 'gInfo',
- },
- });
- pipes.push({ $unwind: '$gInfo' });
- pipes.push({
- $lookup: {
- from: 'patient',
- localField: 'pid',
- foreignField: '_id',
- as: 'pInfo',
- },
- });
- pipes.push({ $unwind: '$pInfo' });
- pipes.push({
- $lookup: {
- from: 'doctor',
- localField: 'did',
- foreignField: '_id',
- as: 'dInfo',
- },
- });
- pipes.push({ $unwind: '$dInfo' });
- if (name) {
- pipes.push({ $match: { 'pInfo.name': new RegExp(name) } });
- }
- pipes.push({ $project: this.lastChatRecordListItem });
- // 查询总数
- const totalResult = await this.model.aggregate([...pipes, { $count: 'total' }]);
- if (skip && skip >= 0) pipes.push({ $skip: skip });
- if (limit && limit > 0) pipes.push({ $limit: limit });
- const result = await this.model.aggregate(pipes);
- return { data: result, total: get(head(totalResult), 'total') };
- }
- }
|