fix(analysis): 统一方案名与接口错误提示
Generic Container CI/CD / test-build-publish (push) Successful in 1m2s
Frontend CI/CD v2 / build-test-publish-and-deploy (push) Successful in 1m2s

This commit is contained in:
2026-08-17 18:54:29 +08:00
parent 9e79d52dc8
commit 45def5bba3
12 changed files with 720 additions and 55 deletions
+40
View File
@@ -0,0 +1,40 @@
import {
createSchemeName,
isSchemeNameValid,
normalizeSchemeName,
SCHEME_NAME_PREFIXES,
} from "./schemeName";
describe("createSchemeName", () => {
it("combines the scheme type with a readable local timestamp", () => {
const date = new Date(2026, 7, 17, 15, 30, 45, 123);
expect(createSchemeName(SCHEME_NAME_PREFIXES.flushingAnalysis, date)).toBe(
"flush_260817_153045123",
);
});
it("pads single-digit date and time values", () => {
const date = new Date(2026, 0, 2, 3, 4, 5, 6);
expect(createSchemeName(SCHEME_NAME_PREFIXES.burstAnalysis, date)).toBe(
"burst_sim_260102_030405006",
);
});
it("keeps names distinct within the same second", () => {
const first = new Date(2026, 7, 17, 15, 30, 45, 123);
const second = new Date(2026, 7, 17, 15, 30, 45, 124);
expect(createSchemeName(SCHEME_NAME_PREFIXES.flushingAnalysis, first)).not.toBe(
createSchemeName(SCHEME_NAME_PREFIXES.flushingAnalysis, second),
);
});
it("normalizes and validates manually entered names", () => {
expect(normalizeSchemeName(" cafe\u0301 ")).toBe("café");
expect(normalizeSchemeName("方案\u200bA\u2060")).toBe("方案A");
expect(isSchemeNameValid("x".repeat(32))).toBe(true);
expect(isSchemeNameValid("x".repeat(33))).toBe(false);
});
});
+47
View File
@@ -0,0 +1,47 @@
export const SCHEME_NAME_PREFIXES = {
dmaLeakIdentification: "dma_leak",
flushingAnalysis: "flush",
burstDetection: "burst_detect",
burstAnalysis: "burst_sim",
burstLocation: "burst_locate",
contaminantAnalysis: "water_quality",
sensorPlacement: "sensor_place",
} as const;
export type SchemeNamePrefix =
(typeof SCHEME_NAME_PREFIXES)[keyof typeof SCHEME_NAME_PREFIXES];
export const SCHEME_NAME_MAX_LENGTH = 32;
export const normalizeSchemeName = (value: string) =>
value
.normalize("NFC")
.replace(/\p{Default_Ignorable_Code_Point}/gu, "")
.trim();
export const isSchemeNameValid = (value: string) => {
const normalized = normalizeSchemeName(value);
return normalized.length > 0 && normalized.length <= SCHEME_NAME_MAX_LENGTH;
};
const padNumber = (value: number, length = 2) =>
String(value).padStart(length, "0");
export const createSchemeName = (
prefix: SchemeNamePrefix,
date = new Date(),
) => {
const timestamp = [
padNumber(date.getFullYear() % 100),
padNumber(date.getMonth() + 1),
padNumber(date.getDate()),
].join("");
const time = [
padNumber(date.getHours()),
padNumber(date.getMinutes()),
padNumber(date.getSeconds()),
padNumber(date.getMilliseconds(), 3),
].join("");
return `${prefix}_${timestamp}_${time}`;
};