import type { AddLedger } from '@/api/tools/addLedger/interface' export type LedgerContextIds = { engineeringId: string projectId: string deviceId: string } export function generateGuidText() { return window.crypto.randomUUID().replace(/-/g, '') } export function createEmptyEngineeringForm(): AddLedger.EngineeringForm { return { id: '', name: '', province: '', city: '', description: '' } } export function createEmptyProjectForm(parentEngineeringId = ''): AddLedger.ProjectForm { return { id: '', engineeringId: parentEngineeringId, parentId: parentEngineeringId, name: '', area: '', description: '' } } export function createEmptyEquipmentForm(parentProjectId = '', parentEngineeringId = ''): AddLedger.EquipmentForm { return { id: '', engineeringId: parentEngineeringId, projectId: parentProjectId, parentId: parentProjectId, name: '', ndid: '', mac: '', dev_type: '', dev_model: '', dev_access_method: '', node_id: '', node_process: '', upgrade: 0 } } export function createEmptyLineForm(parentDeviceId = ''): AddLedger.LineForm { return { id: '', line_id: generateGuidText(), deviceId: parentDeviceId, parentId: parentDeviceId, name: '', line_no: undefined, conType: undefined, vol_grade: undefined, position: '', ct_ratio: undefined, ct2_ratio: undefined, pt_ratio: undefined, pt2_ratio: undefined, short_circuit_capacity: undefined, basic_capacity: undefined, protocol_capacity: undefined, dev_capacity: undefined, monitor_obj: '', is_govern: 0, monitor_user: '', is_important: 0 } } const resolveString = (data: Record, ...keys: string[]) => { for (const key of keys) { const value = data[key] if (value === null || value === undefined) continue const text = String(value).trim() if (text) return text } return '' } const resolveNumber = (data: Record, ...keys: string[]) => { for (const key of keys) { const value = data[key] if (value === null || value === undefined || value === '') continue const parsed = Number(value) if (Number.isFinite(parsed)) return parsed } return undefined } const normalizeLevel = (value: unknown): AddLedger.NodeLevel => { const level = Number(value) if (level === 0 || level === 1 || level === 2 || level === 3) { return level } return 0 } export const normalizeTreeNode = (node: AddLedger.LedgerTreeNode): AddLedger.NormalizedTreeNode => { const rawNode = node as Record const id = resolveString(rawNode, 'id', 'Id') const children = Array.isArray(node.children) ? node.children.map(normalizeTreeNode).filter(item => item.id) : [] return { id, pid: resolveString(rawNode, 'parentId', 'pid', 'Pid'), pids: resolveString(rawNode, 'parentIds', 'pids', 'Pids'), name: resolveString(rawNode, 'name', 'Name') || id || '--', level: normalizeLevel(rawNode.level ?? rawNode.Level), children, raw: node } } export const findNodePath = ( nodes: AddLedger.NormalizedTreeNode[], id: string, path: AddLedger.NormalizedTreeNode[] = [] ): AddLedger.NormalizedTreeNode[] => { for (const node of nodes) { const nextPath = [...path, node] if (node.id === id) return nextPath const matchedPath = findNodePath(node.children, id, nextPath) if (matchedPath.length) return matchedPath } return [] } export const resolveContextFromPath = (path: AddLedger.NormalizedTreeNode[]): LedgerContextIds => { return { engineeringId: path.find(item => item.level === 0)?.id || '', projectId: path.find(item => item.level === 1)?.id || '', deviceId: path.find(item => item.level === 2)?.id || '' } } export const normalizeEngineeringDetail = ( detail: AddLedger.NodeDetail | null, node?: AddLedger.NormalizedTreeNode ): AddLedger.EngineeringForm => { const data = (detail || {}) as Record return { id: resolveString(data, 'id', 'engineeringId') || node?.id || '', name: resolveString(data, 'name') || node?.name || '', province: resolveString(data, 'province'), city: resolveString(data, 'city'), description: resolveString(data, 'description') } } export const normalizeProjectDetail = ( detail: AddLedger.NodeDetail | null, node?: AddLedger.NormalizedTreeNode, context: LedgerContextIds = { engineeringId: '', projectId: '', deviceId: '' } ): AddLedger.ProjectForm => { const data = (detail || {}) as Record return { id: resolveString(data, 'id', 'projectId') || node?.id || '', engineeringId: resolveString(data, 'engineeringId', 'associated_engineering') || context.engineeringId, parentId: context.engineeringId, name: resolveString(data, 'name') || node?.name || '', area: resolveString(data, 'area'), description: resolveString(data, 'description') } } export const normalizeEquipmentDetail = ( detail: AddLedger.NodeDetail | null, node?: AddLedger.NormalizedTreeNode, context: LedgerContextIds = { engineeringId: '', projectId: '', deviceId: '' } ): AddLedger.EquipmentForm => { const data = (detail || {}) as Record return { id: resolveString(data, 'id', 'equipmentId') || node?.id || '', engineeringId: resolveString(data, 'engineeringId', 'associated_engineering') || context.engineeringId, projectId: resolveString(data, 'projectId', 'associated_project') || context.projectId, parentId: context.projectId, name: resolveString(data, 'name') || node?.name || '', ndid: resolveString(data, 'ndid'), mac: resolveString(data, 'mac'), dev_type: resolveString(data, 'dev_type', 'devType'), dev_model: resolveString(data, 'dev_model', 'devModel'), dev_access_method: resolveString(data, 'dev_access_method', 'devAccessMethod'), node_id: resolveString(data, 'node_id', 'nodeId'), node_process: resolveString(data, 'node_process', 'nodeProcess'), upgrade: resolveNumber(data, 'upgrade') ?? 0 } } export const normalizeLineDetail = ( detail: AddLedger.NodeDetail | null, node?: AddLedger.NormalizedTreeNode, context: LedgerContextIds = { engineeringId: '', projectId: '', deviceId: '' } ): AddLedger.LineForm => { const data = (detail || {}) as Record const lineId = resolveString(data, 'line_id', 'lineId', 'id') || node?.id || generateGuidText() return { id: resolveString(data, 'id') || lineId, line_id: lineId, deviceId: resolveString(data, 'deviceId', 'device_id') || context.deviceId, parentId: context.deviceId, name: resolveString(data, 'name') || node?.name || '', line_no: resolveNumber(data, 'line_no', 'lineNo'), conType: resolveNumber(data, 'conType'), vol_grade: resolveNumber(data, 'vol_grade', 'volGrade'), position: resolveString(data, 'position'), ct_ratio: resolveNumber(data, 'ct_ratio', 'ctRatio'), ct2_ratio: resolveNumber(data, 'ct2_ratio', 'ct2Ratio'), pt_ratio: resolveNumber(data, 'pt_ratio', 'ptRatio'), pt2_ratio: resolveNumber(data, 'pt2_ratio', 'pt2Ratio'), short_circuit_capacity: resolveNumber(data, 'short_circuit_capacity', 'shortCircuitCapacity'), basic_capacity: resolveNumber(data, 'basic_capacity', 'basicCapacity'), protocol_capacity: resolveNumber(data, 'protocol_capacity', 'protocolCapacity'), dev_capacity: resolveNumber(data, 'dev_capacity', 'devCapacity'), monitor_obj: resolveString(data, 'monitor_obj', 'monitorObj'), is_govern: resolveNumber(data, 'is_govern', 'isGovern') ?? 0, monitor_user: resolveString(data, 'monitor_user', 'monitorUser'), is_important: resolveNumber(data, 'is_important', 'isImportant') ?? 0 } } export const buildLineNoOptions = (lineNos: number[], currentLineNo?: number) => { const values = new Set(lineNos.filter(item => Number.isInteger(item) && item >= 1 && item <= 20)) if (currentLineNo && currentLineNo >= 1 && currentLineNo <= 20) { values.add(currentLineNo) } return Array.from(values) .sort((left, right) => left - right) .map(item => ({ label: `${item} 号线路`, value: item })) }