import type { AuditEventListDTO, AuditOperation, AuditPageQuery } from './types';
|
|
const actionCodeLabels: Record<string, string> = {
|
CREATE: '新增',
|
DELETE: '删除',
|
READ: '查询',
|
SIGN: '电子签名',
|
UPDATE: '修改',
|
};
|
|
const eventTypeLabels: Record<string, string> = {
|
BIZ_ACTION: '业务动作',
|
DATA_CHANGE: '数据变更',
|
E_SIGNATURE: '电子签名',
|
};
|
|
const sourceLayerLabels: Record<number, string> = {
|
0: '在线表单',
|
1: '数据库变更',
|
2: '业务动作',
|
3: '电子签名',
|
};
|
|
/** Normalize one BUSINESS row and its related physical signature events. */
|
export function normalizeOperation(main: AuditEventListDTO): AuditOperation {
|
const subEvents = Array.isArray(main.subEvents) ? main.subEvents : [];
|
const eventIds = [main.id, ...subEvents.map((event) => event.id)];
|
const layers = [...new Set([main, ...subEvents].flatMap((event) => (typeof event.sourceLayer === 'number' ? [event.sourceLayer] : [])))];
|
const diffCount = toDiffCount(main.diffCount);
|
|
return {
|
...main,
|
correlationKey: main.operationId ?? main.clientEventId ?? `event:${main.id}`,
|
diffCount,
|
eventIds,
|
layers,
|
sourceSummary: getSourceSummary(layers, diffCount),
|
subEvents,
|
};
|
}
|
|
/** Timeline uses the same operation-level display contract as the page endpoint. */
|
export function groupTimelineOperations(events: AuditEventListDTO[]): AuditOperation[] {
|
return events.map((event) => normalizeOperation(event));
|
}
|
|
/**
|
* 动作名优先按 actionCode 映射:层 0 的基础三动作有稳定语义,映射后历史数据
|
* (actionLabel 是 "LIMS-请验单 新建" 这种旧格式)也立刻显示对。
|
* 层 2 事件的动作词是业务自定义的("请验单 撤回"),映射表命不中,回落 actionLabel。
|
*/
|
export function getAuditActionLabel(event: Pick<AuditEventListDTO, 'actionCode' | 'actionLabel'>): string {
|
const mapped = event.actionCode ? actionCodeLabels[event.actionCode] : undefined;
|
return mapped || event.actionLabel || event.actionCode || '未标记操作';
|
}
|
|
export function getAuditEventTypeLabel(eventType?: string): string {
|
if (!eventType) return '未标记类型';
|
return eventTypeLabels[eventType] || eventType;
|
}
|
|
export function getSourceLayerLabel(sourceLayer?: number): string {
|
if (sourceLayer === undefined) return '未知来源';
|
return sourceLayerLabels[sourceLayer] || `采集层 ${sourceLayer}`;
|
}
|
|
export function getSourceSummary(layers: number[], diffCount: number): string {
|
const hasBusinessAction = layers.includes(2);
|
const hasElectronicSignature = layers.includes(3);
|
if (hasBusinessAction) {
|
return ['业务动作', hasElectronicSignature ? '电子签名' : '', diffCount > 0 ? '字段变更' : ''].filter(Boolean).join(' + ');
|
}
|
if (hasElectronicSignature && diffCount > 0) return '电子签名 + 字段变更';
|
if (hasElectronicSignature) return '电子签名';
|
if (layers.length === 1 && layers[0] === 0) return '在线表单';
|
if (layers.length === 1 && layers[0] === 1) return '数据库变更';
|
if (layers.includes(0) && layers.includes(1)) return '在线表单 + 数据库变更';
|
return '未知来源';
|
}
|
|
export function normalizeAuditPageQuery(query: Record<string, unknown>): AuditPageQuery {
|
const normalized: Record<string, unknown> = {};
|
for (const [key, value] of Object.entries(query)) {
|
const nextValue = typeof value === 'string' ? value.trim() : value;
|
if (nextValue !== '' && nextValue !== undefined && nextValue !== null) normalized[key] = nextValue;
|
}
|
return normalized as unknown as AuditPageQuery;
|
}
|
|
function toDiffCount(value?: number): number {
|
return Number.isFinite(value) && Number(value) > 0 ? Number(value) : 0;
|
}
|