fix: hide deleted signatures and fit uplink table
This commit is contained in:
@@ -142,6 +142,19 @@ describe('SignatureRetirementService dimensions', () => {
|
|||||||
page: 2,
|
page: 2,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
});
|
});
|
||||||
|
const query = prisma.$queryRaw.mock.calls[0]?.[0] as { strings?: readonly string[] };
|
||||||
|
expect(query.strings?.join('?')).toContain('signature."auditStatus" <> \'deleted\'');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not count deleted signatures as unread retirement warnings', async () => {
|
||||||
|
const prisma = { $queryRaw: jest.fn().mockResolvedValue([{ count: 2 }]) };
|
||||||
|
const unreadService = new SignatureRetirementService(prisma as never);
|
||||||
|
|
||||||
|
await expect(unreadService.unreadCount()).resolves.toEqual({ count: 2 });
|
||||||
|
const query = prisma.$queryRaw.mock.calls[0]?.[0] as { strings?: readonly string[] };
|
||||||
|
const sql = query.strings?.join('?') ?? '';
|
||||||
|
expect(sql).toContain('JOIN "SmsSignature" signature ON signature.id = detection."signatureId"');
|
||||||
|
expect(sql).toContain('signature."auditStatus" <> \'deleted\'');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('requires a reason for temporary and permanent suppression', async () => {
|
it('requires a reason for temporary and permanent suppression', async () => {
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ export class SignatureRetirementService implements OnModuleInit, OnModuleDestroy
|
|||||||
LEFT JOIN "SmsApplication" application ON application.id = detection."applicationId"
|
LEFT JOIN "SmsApplication" application ON application.id = detection."applicationId"
|
||||||
WHERE message."createdAt" >= ${range?.gte}
|
WHERE message."createdAt" >= ${range?.gte}
|
||||||
AND message."createdAt" <= ${range?.lte}
|
AND message."createdAt" <= ${range?.lte}
|
||||||
|
AND signature."auditStatus" <> 'deleted'
|
||||||
AND (${dimensionType}::text IS NULL OR detection."dimensionType" = ${dimensionType})
|
AND (${dimensionType}::text IS NULL OR detection."dimensionType" = ${dimensionType})
|
||||||
AND (${tenantId}::text IS NULL OR detection."tenantId" = ${tenantId})
|
AND (${tenantId}::text IS NULL OR detection."tenantId" = ${tenantId})
|
||||||
AND (${applicationId}::text IS NULL OR application.id = ${applicationId})
|
AND (${applicationId}::text IS NULL OR application.id = ${applicationId})
|
||||||
@@ -167,8 +168,18 @@ export class SignatureRetirementService implements OnModuleInit, OnModuleDestroy
|
|||||||
|
|
||||||
async unreadCount() {
|
async unreadCount() {
|
||||||
const range = shanghaiDateRange(shanghaiDateKey(), shanghaiDateKey());
|
const range = shanghaiDateRange(shanghaiDateKey(), shanghaiDateKey());
|
||||||
const count = await this.prisma.signatureRetirementMessage.count({ where: { createdAt: range, isRead: false, suppressed: false } });
|
const rows = await this.prisma.$queryRaw<Array<{ count: number }>>(Prisma.sql`
|
||||||
return { count };
|
SELECT COUNT(*)::integer AS count
|
||||||
|
FROM "SignatureRetirementMessage" message
|
||||||
|
JOIN "SignatureRetirementDetection" detection ON detection.id = message."detectionId"
|
||||||
|
JOIN "SmsSignature" signature ON signature.id = detection."signatureId"
|
||||||
|
WHERE message."createdAt" >= ${range?.gte}
|
||||||
|
AND message."createdAt" <= ${range?.lte}
|
||||||
|
AND message."isRead" = FALSE
|
||||||
|
AND message.suppressed = FALSE
|
||||||
|
AND signature."auditStatus" <> 'deleted'
|
||||||
|
`);
|
||||||
|
return { count: rows[0]?.count ?? 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
async markRead(id: string) {
|
async markRead(id: string) {
|
||||||
|
|||||||
@@ -283,20 +283,20 @@ export function AdminSmsUplinkRecordsPage() {
|
|||||||
{
|
{
|
||||||
key: 'select',
|
key: 'select',
|
||||||
title: '',
|
title: '',
|
||||||
width: '72px',
|
width: '48px',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: () => <input aria-label="选择上行记录" className="admin-uplink-checkbox" type="checkbox" />,
|
render: () => <input aria-label="选择上行记录" className="admin-uplink-checkbox" type="checkbox" />,
|
||||||
},
|
},
|
||||||
{ key: 'phoneNumber', title: '手机号码', width: '170px', render: (record) => <strong>{record.phoneNumber}</strong> },
|
{ key: 'phoneNumber', title: '手机号码', width: '120px', render: (record) => <strong>{record.phoneNumber}</strong> },
|
||||||
{ key: 'receivedAt', title: '上行时间', width: '220px', render: (record) => <strong>{getTime(record.receivedAt)}</strong> },
|
{ key: 'receivedAt', title: '上行时间', width: '156px', render: (record) => <strong>{getTime(record.receivedAt)}</strong> },
|
||||||
{ key: 'content', title: '上行内容', width: '360px', render: (record) => <span className="uplink-content" title={record.content}>{record.content}</span> },
|
{ key: 'content', title: '上行内容', width: '260px', render: (record) => <span className="uplink-content" title={record.content}>{record.content}</span> },
|
||||||
{ key: 'channel', title: '上行通道', width: '260px', render: (record) => <strong>{record.channel?.name ?? record.channelId}</strong> },
|
{ key: 'channel', title: '上行通道', width: '160px', render: (record) => <strong>{record.channel?.name ?? record.channelId}</strong> },
|
||||||
{ key: 'accessNo', title: '上行接入号', width: '180px', render: (record) => <strong>{record.destId}</strong> },
|
{ key: 'accessNo', title: '上行接入号', width: '120px', render: (record) => <strong>{record.destId}</strong> },
|
||||||
{ key: 'matchStatus', title: '匹配状态', width: '140px', render: (record) => <strong>{matchStatusText(record.matchStatus)}</strong> },
|
{ key: 'matchStatus', title: '匹配状态', width: '100px', render: (record) => <strong>{matchStatusText(record.matchStatus)}</strong> },
|
||||||
{
|
{
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: '140px',
|
width: '88px',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (record) => (
|
render: (record) => (
|
||||||
<button className="admin-uplink-detail-link" onClick={() => openDetail(record)} type="button">查看详情</button>
|
<button className="admin-uplink-detail-link" onClick={() => openDetail(record)} type="button">查看详情</button>
|
||||||
|
|||||||
+11
-1
@@ -7791,7 +7791,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.admin-uplink-table-card .ui-table {
|
.admin-uplink-table-card .ui-table {
|
||||||
min-width: 1500px;
|
min-width: 1052px;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-uplink-table-card .uplink-content {
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-uplink-table-card .ui-table td strong {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gateway-exception-list-heading {
|
.gateway-exception-list-heading {
|
||||||
|
|||||||
Reference in New Issue
Block a user