刘光辉
8 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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;
}