fix: 修复未报备签名统计的中文编码兼容性
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { startOfDay, addDays } from './analytics-date';
|
||||
import { leadingSignatureSql } from './signature-extraction';
|
||||
|
||||
export type ActivityDimension = {
|
||||
dimensionKey: string;
|
||||
@@ -114,7 +115,7 @@ export async function unreportedRows(db: PrismaService, date: string) {
|
||||
}>
|
||||
>(Prisma.sql`
|
||||
WITH extracted AS (
|
||||
SELECT m."tenantId",m."applicationId",SUBSTRING(m.content FROM '^【[^【】]+】') AS name
|
||||
SELECT m."tenantId",m."applicationId",${leadingSignatureSql(Prisma.sql`m.content`)} AS name
|
||||
FROM "SmsMessageRecord" m WHERE m."queuedAt">=${startOfDay(date)} AND m."queuedAt"<${startOfDay(addDays(date, 1))} AND m."signatureId" IS NULL
|
||||
) SELECT jsonb_build_array(e."tenantId",e."applicationId",e.name)::text AS "dimensionKey",
|
||||
e."tenantId",e."applicationId",e.name AS "signatureName",t.name AS "tenantName",a.name AS "applicationName",COUNT(*)::int AS "messageCount"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
/** Keep delimiters as whole strings: SQL_ASCII treats a Chinese character class as bytes. */
|
||||
export function leadingSignatureSql(content: Prisma.Sql): Prisma.Sql {
|
||||
// The lookahead excludes complete brackets without rejecting bytes shared by other Chinese characters.
|
||||
// Noncapturing groups keep SUBSTRING returning the complete signature, including its brackets.
|
||||
return Prisma.sql`SUBSTRING(${content} FROM '^【(?:(?!【|】).)+】')`;
|
||||
}
|
||||
@@ -139,7 +139,7 @@ describe('SignatureRetirementService dimensions', () => {
|
||||
});
|
||||
const query = prisma.$queryRaw.mock.calls[0]?.[0] as { strings?: readonly string[] };
|
||||
const sql = query.strings?.join('?') ?? '';
|
||||
expect(sql).toContain("SUBSTRING(message.content FROM '^【[^【】]+】')");
|
||||
expect(sql).toContain("SUBSTRING(message.content FROM '^【(?:(?!【|】).)+】')");
|
||||
expect(sql).toContain('message."signatureId" IS NULL');
|
||||
expect(sql).toContain('FROM "SmsSignature" signature');
|
||||
expect(sql).toContain('signature."applicationId" = extracted.application_id');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { SignatureAnalyticsRead } from '../signature-analytics/analytics-read';
|
||||
import { analyticsDate, analyticsPage, todayKey } from '../signature-analytics/analytics-date';
|
||||
import { detectRetirement } from '../signature-analytics/retirement-batch';
|
||||
import { leadingSignatureSql } from '../signature-analytics/signature-extraction';
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
@@ -568,7 +569,7 @@ export class SignatureRetirementService implements OnModuleInit, OnModuleDestroy
|
||||
SELECT
|
||||
message."tenantId" AS tenant_id,
|
||||
message."applicationId" AS application_id,
|
||||
SUBSTRING(message.content FROM '^【[^【】]+】') AS signature_name
|
||||
${leadingSignatureSql(Prisma.sql`message.content`)} AS signature_name
|
||||
FROM "SmsMessageRecord" message
|
||||
WHERE message."queuedAt" >= ${shanghaiStart(date)}
|
||||
AND message."queuedAt" < ${shanghaiStart(addDays(date, 1))}
|
||||
|
||||
Reference in New Issue
Block a user