import {Injectable} from '@nestjs/common'; import {InjectRepository} from "@nestjs/typeorm"; import {ProgramEntity, ProgramGroupEntity, ProgramGroupMessageEntity, UsersEntity} from "../entity"; import {Repository} from "typeorm"; import {ResultData} from "../const/result"; import {isEmptyString} from "../utils/common"; import {RedisService} from "./redis.service"; @Injectable() export class ProgramGroupService { constructor( @InjectRepository(ProgramGroupEntity) private readonly programGroupRepository: Repository, @InjectRepository(ProgramEntity) private readonly programRepository: Repository, @InjectRepository(UsersEntity) private readonly usersRepository: Repository, private readonly redisService: RedisService, ) { } async add(programGroup: ProgramGroupEntity) { try { // 前置判断 // 判断是否为空 if (isEmptyString(programGroup.programId) || isEmptyString(programGroup.userId)) { return ResultData.fail(500, "参数不能为空") } // 查找program信息 let program = await this.programRepository.findOne({ where: { id: programGroup.programId } }) if (program == null) { return ResultData.fail(500, "未找到项目信息") } // 用户是否有权限发起群组(本人不行,系统用户不行,创建过同样会话不行) if (programGroup.userId == program.linkmanId) { return ResultData.fail(500, "不能创建自己的项目群组") } let user = await this.usersRepository.findOne({ where: { id: programGroup.userId } }) if (user?.isSystemAccount) { return ResultData.fail(500, "系统用户不能创建群组") } let groups = await this.programGroupRepository.find({ where: { programId: programGroup.programId, userId: programGroup.userId } }) if (groups.length > 0) { return ResultData.fail(500, "已经创建过群组") } // 匹配客服 let customers = await this.usersRepository.findBy({userType: "customer"}); if (customers.length == 0) { return ResultData.fail(500, "没有客服人员") } let customerList = await this.usersRepository.createQueryBuilder("users") .leftJoinAndMapMany("users.groups", "program_group", "group", "users.id = group.customer_id") .where("users.user_type = :type", {type: "customer"}) .getMany() // 客服分配任务量 var index = 0 // 任务最小值 for (let i = 0; i < customerList.length - 1; i++) { if (customerList[i].groups.length > customerList[i + 1].groups.length) { index = i + 1 } } programGroup.customerId = customerList[index].id // 创建聊天 programGroup.chargeId = program.linkmanId let result = await this.programGroupRepository.save(programGroup) return result != null ? ResultData.success(result) : ResultData.fail(500, "创建群组失败"); } catch (err) { return ResultData.fail(500, err); } } async getList(programGroup: ProgramGroupEntity) { try { programGroup.page = programGroup.page || 1; programGroup.size = programGroup.size || 10; const offset = (programGroup.page - 1) * programGroup.size; const queryBuilder = this.programGroupRepository.createQueryBuilder("group") queryBuilder.leftJoinAndMapOne( "group.program", ProgramEntity, "program", "group.program_id = program.id" ) queryBuilder.leftJoinAndMapOne( "group.chargeUser", UsersEntity, "chargeUser", "group.charge_id = chargeUser.id" ) queryBuilder.leftJoinAndMapOne( "group.user", UsersEntity, "user", "group.user_id = user.id" ) queryBuilder.addSelect(subQuery => { return subQuery .select("max(message.create_time)") .from(ProgramGroupMessageEntity, "message") .where("message.group_id = group.group_id"); }, "latest_message_time") if (programGroup.customerId != null) { queryBuilder.andWhere("group.customer_id = :customerId", {customerId: programGroup.customerId}) } if (programGroup.userId != null) { queryBuilder.orWhere("group.user_id = :userId", {userId: programGroup.userId}) queryBuilder.orWhere("group.charge_id = :charge_id", {charge_id: programGroup.userId}) } if (programGroup.keyword != null){ queryBuilder.andWhere( "(program.name LIKE :nameKeyword OR program.company LIKE :companyKeyword)", { nameKeyword: '%' + programGroup.keyword + '%', companyKeyword: '%' + programGroup.keyword + '%' } ); } queryBuilder .orderBy("latest_message_time", 'DESC') .take(programGroup.size || 10) .skip(offset || 0); // console.log(queryBuilder.getSql()) let [items, total] = await queryBuilder.getManyAndCount(); // 将未读数据(redis)塞入数据(list)中 items = await this.searchUnRead(items) let data = { list: items, total, page: programGroup.page || 1, size: programGroup.size || 10, pages: Math.ceil(total / (programGroup.size || 10)) } return ResultData.success(data); } catch (err) { return ResultData.fail(500, err); } } async getOne(programGroup: ProgramGroupEntity) { try { let result = await this.programGroupRepository.findOne({ where: { programId: programGroup.programId, userId: programGroup.userId } }) return result != null ? ResultData.success(result) : ResultData.fail(500, "未找到群组信息"); } catch (err) { return ResultData.fail(500, err); } } // 处理未读消息 // 返回用户和项目负责人的未读消息 async searchUnRead(list: ProgramGroupEntity[]) { for (let i = 0; i < list.length; i++) { let item = list[i]; let userUnreadValue = await this.redisService.getValue(`${item.groupId}_${item.userId}`) let chargeUnreadValue = await this.redisService.getValue(`${item.groupId}_${item.chargeId}`) let customerUnreadValue = await this.redisService.getValue(`${item.groupId}_${item.customerId}`) item.userUnread = userUnreadValue == null ? [] : JSON.parse(userUnreadValue) item.chargeUnread = chargeUnreadValue == null ? [] : JSON.parse(chargeUnreadValue) item.customerUnread = customerUnreadValue == null ? [] : JSON.parse(customerUnreadValue) } return list } async getGroup(groupId: number) { try { let result = await this.programGroupRepository.findOne({ where: { groupId } }) if (result != null){ result.program = await this.programRepository.createQueryBuilder("program") .leftJoinAndMapOne( "program.linkman", UsersEntity, "linkman", "program.linkman_id = linkman.id" ).where("program.id = :id", {id: result.programId}) .getOne() return ResultData.success(result) }else { throw "未找到群组信息" } } catch (err) { return ResultData.fail(500, err); } } }