2025-09-30
未读变已读 查询列表排序
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
export * from './programGroup.controller';
|
||||
export * from './file.controller';
|
||||
export * from './file.controller';
|
||||
export * from './message.controller'
|
||||
23
src/controller/message.controller.ts
Normal file
23
src/controller/message.controller.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import {Body, Controller, Get, Post, Query} from "@nestjs/common";
|
||||
import {MessageService} from "../service";
|
||||
import {ProgramGroupMessageEntity, ReadDto} from "../entity";
|
||||
|
||||
@Controller('message')
|
||||
export class MessageController {
|
||||
|
||||
constructor(private messageService: MessageService) {
|
||||
}
|
||||
|
||||
// 获取未读消息
|
||||
@Get("unread")
|
||||
async getUnread(@Query() readDto: ReadDto) {
|
||||
return await this.messageService.getUnread(readDto)
|
||||
}
|
||||
|
||||
// 将未读消息置为已读
|
||||
@Post('read')
|
||||
async read(@Body() readDto: ReadDto) {
|
||||
return await this.messageService.read(readDto)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,5 +26,4 @@ export class ProgramGroupController {
|
||||
async getOne(@Param() programGroup: ProgramGroupEntity) {
|
||||
return await this.programGroupService.getOne(programGroup);
|
||||
}
|
||||
|
||||
}
|
||||
4
src/entity/dto/read.dto.ts
Normal file
4
src/entity/dto/read.dto.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export class ReadDto {
|
||||
groupId: number;
|
||||
userId: number;
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from './program.entity';
|
||||
export * from './users.entity';
|
||||
export * from './programGroup.entity';
|
||||
export * from './programGroupMessage.entity';
|
||||
export * from './programGroupMessage.entity';
|
||||
|
||||
export * from './dto/read.dto'
|
||||
@@ -1,32 +1,36 @@
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
||||
import {Column, Entity, PrimaryGeneratedColumn} from "typeorm";
|
||||
import {ProgramEntity} from "./program.entity";
|
||||
|
||||
@Entity("program_group", { schema: "test" })
|
||||
@Entity("program_group", {schema: "test"})
|
||||
export class ProgramGroupEntity {
|
||||
@PrimaryGeneratedColumn({ type: "int", name: "group_id", comment: "群组ID" })
|
||||
groupId: number;
|
||||
@PrimaryGeneratedColumn({type: "int", name: "group_id", comment: "群组ID"})
|
||||
groupId: number;
|
||||
|
||||
@Column("int", { name: "program_id", comment: "项目ID" })
|
||||
programId: number;
|
||||
@Column("int", {name: "program_id", comment: "项目ID"})
|
||||
programId: number;
|
||||
|
||||
@Column("int", { name: "charge_id", comment: "负责人ID" })
|
||||
chargeId: number;
|
||||
@Column("int", {name: "charge_id", comment: "负责人ID"})
|
||||
chargeId: number;
|
||||
|
||||
@Column("int", { name: "customer_id", comment: "客服ID" })
|
||||
customerId: number;
|
||||
@Column("int", {name: "customer_id", comment: "客服ID"})
|
||||
customerId: number;
|
||||
|
||||
@Column("int", { name: "user_id", comment: "用户ID" })
|
||||
userId: number;
|
||||
@Column("int", {name: "user_id", comment: "用户ID"})
|
||||
userId: number;
|
||||
|
||||
@Column("datetime", {
|
||||
name: "create_time",
|
||||
comment: "创建时间",
|
||||
default: () => "CURRENT_TIMESTAMP",
|
||||
})
|
||||
createTime: Date;
|
||||
@Column("datetime", {
|
||||
name: "create_time",
|
||||
comment: "创建时间",
|
||||
default: () => "CURRENT_TIMESTAMP",
|
||||
})
|
||||
createTime: Date;
|
||||
|
||||
program: ProgramEntity;
|
||||
// 虚拟字段
|
||||
program: ProgramEntity;
|
||||
|
||||
page: number = 1;
|
||||
size: number = 10;
|
||||
page: number = 1;
|
||||
size: number = 10;
|
||||
|
||||
userUnread: any
|
||||
chargeUnread: any
|
||||
}
|
||||
|
||||
@@ -58,28 +58,6 @@ export class ChatGateway implements OnGatewayInit {
|
||||
*/
|
||||
@SubscribeMessage('clientMsg')
|
||||
async clientMessage(@MessageBody() data: ProgramGroupMessageEntity): Promise<any> {
|
||||
|
||||
// 不在线用户
|
||||
let userIds = await this.activeUser(data.groupId)
|
||||
|
||||
if (userIds.length != 0) {
|
||||
// 保存未读消息 redis
|
||||
console.log(userIds)
|
||||
for (let i = 0; i < userIds.length; i++) {
|
||||
let item = userIds[i]
|
||||
// 先取再存
|
||||
let redisData = await this.redisService.getValue(`${data.groupId}_${item}`)
|
||||
if (redisData == null) {
|
||||
this.redisService.setValue(`${data.groupId}_${item}`, JSON.stringify([data]))
|
||||
} else {
|
||||
let arr: any = []
|
||||
arr = JSON.parse(redisData)
|
||||
arr.push(data)
|
||||
this.redisService.setValue(`${data.groupId}_${item}`, JSON.stringify(arr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存记录
|
||||
let saveMessage = await this.messageRepository.save(data)
|
||||
|
||||
@@ -89,6 +67,28 @@ export class ChatGateway implements OnGatewayInit {
|
||||
}
|
||||
})
|
||||
|
||||
// 不在线用户
|
||||
let userIds = await this.activeUser(data.groupId)
|
||||
|
||||
// 存储未读消息
|
||||
if (userIds.length != 0) {
|
||||
// 保存未读消息 redis
|
||||
console.log(userIds)
|
||||
for (let i = 0; i < userIds.length; i++) {
|
||||
let item = userIds[i]
|
||||
// 先取再存
|
||||
let redisData = await this.redisService.getValue(`${data.groupId}_${item}`)
|
||||
if (redisData == null) {
|
||||
this.redisService.setValue(`${data.groupId}_${item}`, JSON.stringify([saveMessage]))
|
||||
} else {
|
||||
let arr: any = []
|
||||
arr = JSON.parse(redisData)
|
||||
arr.push(saveMessage)
|
||||
this.redisService.setValue(`${data.groupId}_${item}`, JSON.stringify(arr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.server.to(data.groupId.toString()).emit('serverMsg', saveMessage)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './programGroupService.service';
|
||||
export * from './programGroup.service';
|
||||
export * from './chat.gateway';
|
||||
export * from './file.service';
|
||||
export * from './redis.service'
|
||||
export * from './redis.service'
|
||||
export * from './message.service'
|
||||
23
src/service/message.service.ts
Normal file
23
src/service/message.service.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import {Injectable} from "@nestjs/common";
|
||||
import {ReadDto} from "../entity";
|
||||
import {RedisService} from "./redis.service";
|
||||
import {ResultData} from "../const/result";
|
||||
|
||||
@Injectable()
|
||||
export class MessageService {
|
||||
constructor(private readonly redisService: RedisService) {
|
||||
}
|
||||
|
||||
// 获取未读消息
|
||||
async getUnread(readDto: ReadDto) {
|
||||
let data = await this.redisService.getValue(`${readDto.groupId}_${readDto.userId}`)
|
||||
data = data == null ? [] : JSON.parse(data)
|
||||
return ResultData.success(data)
|
||||
}
|
||||
|
||||
// 未读 -> 已读
|
||||
async read(readDto: ReadDto) {
|
||||
this.redisService.delValue(`${readDto.groupId}_${readDto.userId}`)
|
||||
return ResultData.success()
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import {Injectable} from '@nestjs/common';
|
||||
import {InjectRepository} from "@nestjs/typeorm";
|
||||
import {ProgramEntity, ProgramGroupEntity, UsersEntity} from "../entity";
|
||||
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 {
|
||||
@@ -12,6 +13,7 @@ export class ProgramGroupService {
|
||||
@InjectRepository(ProgramGroupEntity) private readonly programGroupRepository: Repository<ProgramGroupEntity>,
|
||||
@InjectRepository(ProgramEntity) private readonly programRepository: Repository<ProgramEntity>,
|
||||
@InjectRepository(UsersEntity) private readonly usersRepository: Repository<UsersEntity>,
|
||||
private readonly redisService: RedisService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -105,21 +107,45 @@ export class ProgramGroupService {
|
||||
"group.user_id = user.id"
|
||||
)
|
||||
|
||||
if (programGroup.customerId != null){
|
||||
// 查询最新消息
|
||||
// queryBuilder.leftJoinAndMapOne(
|
||||
// "group.latest_message",
|
||||
// ProgramGroupMessageEntity,
|
||||
// "message",
|
||||
// `
|
||||
// message.group_id = group.group_id and
|
||||
// group.group_id = (
|
||||
// select group_id from program_group_message
|
||||
// where program_group_message.group_id = group.group_id
|
||||
// order by create_time desc
|
||||
// limit 1
|
||||
// )
|
||||
// `)
|
||||
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){
|
||||
if (programGroup.userId != null) {
|
||||
queryBuilder.orWhere("group.user_id = :userId", {userId: programGroup.userId})
|
||||
queryBuilder.orWhere("group.charge_id = :charge_id", {charge_id: programGroup.userId})
|
||||
}
|
||||
|
||||
queryBuilder
|
||||
.orderBy('program.id', 'DESC')
|
||||
.orderBy("latest_message_time", 'DESC')
|
||||
.take(programGroup.size || 10)
|
||||
.skip(offset || 0);
|
||||
|
||||
const [items, total] = await queryBuilder.getManyAndCount();
|
||||
let [items, total] = await queryBuilder.getManyAndCount();
|
||||
|
||||
// 将未读数据(redis)塞入数据(list)中
|
||||
items = await this.searchUnRead(items)
|
||||
|
||||
let data = {
|
||||
list: items,
|
||||
@@ -147,4 +173,17 @@ export class ProgramGroupService {
|
||||
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}`)
|
||||
item.userUnread = userUnreadValue == null ? [] : JSON.parse(userUnreadValue)
|
||||
item.chargeUnread = chargeUnreadValue == null ? [] : JSON.parse(chargeUnreadValue)
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
@@ -22,4 +22,8 @@ export class RedisService {
|
||||
getValue(key: string) {
|
||||
return this.redisClient.get(key);
|
||||
}
|
||||
|
||||
delValue(key: string) {
|
||||
return this.redisClient.del(key);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user