feat(admin): v3.5.18 用户详情明文手机、任务关联版本与核销快链

HQ 后台:用户/核销记录展示完整手机号;任务列表与编辑可关联版本;账单核销单号与券号/用户可快链;门店账单日标明为出账自然日;技术支持操作按钮右对齐。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-28 13:58:08 +08:00
parent b226af2adc
commit da19c39965
11 changed files with 302 additions and 88 deletions
@@ -156,10 +156,16 @@ export class DevPlanService {
},
extras?: { creatorName?: string | null; supportTicketNo?: string | null },
extras?: {
creatorName?: string | null;
supportTicketNo?: string | null;
versions?: Array<{ id: string; versionNo: string }>;
},
): DevPlanTaskDto {
const versions = extras?.versions ?? [];
return {
id: String(row.id),
@@ -188,6 +194,10 @@ export class DevPlanService {
attachmentUrls: parseAttachmentUrls(row.attachmentUrls),
versions,
versionIds: versions.map((v) => v.id),
};
}
@@ -306,7 +316,7 @@ export class DevPlanService {
const ticketIds = rows.map((r) => r.supportTicketId).filter((id): id is bigint => id != null);
const [names, tickets] = await Promise.all([
const [names, tickets, versionMap] = await Promise.all([
this.loadHqNames(creatorIds),
@@ -322,6 +332,8 @@ export class DevPlanService {
: Promise.resolve([]),
this.loadTaskVersionMap(rows.map((r) => r.id)),
]);
const ticketMap = new Map<string, string>(
@@ -340,6 +352,8 @@ export class DevPlanService {
supportTicketNo: r.supportTicketId != null ? ticketMap.get(String(r.supportTicketId)) ?? null : null,
versions: versionMap.get(String(r.id)) ?? [],
}),
);
@@ -374,12 +388,16 @@ export class DevPlanService {
}
const versionMap = await this.loadTaskVersionMap([row.id]);
return this.mapTask(row, {
creatorName: names.get(String(row.creatorHqAccountId)) ?? null,
supportTicketNo,
versions: versionMap.get(String(row.id)) ?? [],
});
}
@@ -508,6 +526,10 @@ export class DevPlanService {
await this.prisma.devPlanTask.update({ where: { id }, data });
if (dto.versionIds !== undefined) {
await this.replaceTaskVersions(id, dto.versionIds);
}
return this.getTask(id);
}
@@ -606,6 +628,41 @@ export class DevPlanService {
private async loadTaskVersionMap(
taskIds: bigint[],
): Promise<Map<string, Array<{ id: string; versionNo: string }>>> {
const map = new Map<string, Array<{ id: string; versionNo: string }>>();
if (!taskIds.length) return map;
const links = await this.prisma.devPlanVersionTask.findMany({
where: { taskId: { in: taskIds } },
include: { version: { select: { id: true, versionNo: true } } },
orderBy: { versionId: 'asc' },
});
for (const link of links) {
const key = String(link.taskId);
const list = map.get(key) ?? [];
list.push({ id: String(link.version.id), versionNo: link.version.versionNo });
map.set(key, list);
}
return map;
}
private async replaceTaskVersions(taskId: bigint, versionIds: string[]) {
const unique = [...new Set(versionIds.map((id) => id.trim()).filter(Boolean))];
const ids = unique.map(BigInt);
if (ids.length) {
const versions = await this.prisma.devPlanVersion.findMany({
where: { id: { in: ids } },
select: { id: true },
});
if (versions.length !== ids.length) throw new BadRequestException('部分版本不存在');
}
await this.prisma.devPlanVersionTask.deleteMany({ where: { taskId } });
for (const versionId of ids) {
await this.appendVersionTasks(versionId, [String(taskId)]);
}
}
private async loadVersionTasks(versionId: bigint): Promise<{ tasks: DevPlanTaskDto[]; taskIds: string[] }> {
const links = await this.prisma.devPlanVersionTask.findMany({
@@ -62,6 +62,11 @@ export class UpdateDevPlanTaskDto {
@IsArray()
@IsString({ each: true })
attachmentUrls?: string[];
@IsOptional()
@IsArray()
@IsString({ each: true })
versionIds?: string[];
}
export class CreateDevPlanVersionDto {
@@ -54,7 +54,7 @@ export class AdminRedeemService {
skip: (page - 1) * pageSize,
take: pageSize,
include: {
user: { select: { id: true, userNo: true, phone: true, nickname: true } },
user: { select: { id: true, userNo: true, phone: true, nickname: true, hqRemark: true } },
store: { select: { id: true, name: true, cityName: true } },
coupon: { select: { id: true, couponNo: true, balance: true } },
},
@@ -77,7 +77,7 @@ export class AdminRedeemService {
const record = await this.prisma.redeemRecord.findUnique({
where: { id },
include: {
user: { select: { id: true, userNo: true, phone: true, nickname: true } },
user: { select: { id: true, userNo: true, phone: true, nickname: true, hqRemark: true } },
store: {
select: {
id: true,