feat: 装配线看板修正、统一密钥Hardman_2026、操作日志追溯、日志按天存储
Dashboard 移除 CNC/清洗机等不存在设备,改为纯装配线看板(扫码枪+拧紧枪+人工);JWT/内部token统一为 Hardman_2026 写入各 etc/*.yaml,MES 建表 DSN 改读 yaml;event_log 增加 workOrderNo/operator,BOM/备料/PLC下发/拧紧/扫码报工/半成品/AGV 全链路埋点,日志页支持工单号/操作人筛选;MES/WMS 日志按天存储(dailyWriter),WMS SetWriter 用 logx.NewWriter 适配
This commit is contained in:
@@ -127,6 +127,8 @@ export interface EventLog {
|
||||
jobId?: number
|
||||
workOrderId?: number
|
||||
workpieceNo?: string
|
||||
workOrderNo?: string
|
||||
operator?: string
|
||||
equipmentId?: number
|
||||
equipmentName?: string
|
||||
tempSlotNo?: number
|
||||
@@ -326,6 +328,8 @@ export function useWorkOrderApi() {
|
||||
startTime?: string
|
||||
endTime?: string
|
||||
workpieceNo?: string
|
||||
workOrderNo?: string
|
||||
operator?: string
|
||||
jobId?: number
|
||||
}): Promise<PageResult<EventLog>> => {
|
||||
return get({url: `/api/v1/event-logs`, params})
|
||||
|
||||
@@ -8,4 +8,20 @@ export const EVENT_TYPE_LABELS: Record<string, string> = {
|
||||
ORDER_CANCELLED: '取消', ORDER_COMPLETED: '工单完工',
|
||||
ALARM_RAISED: '报警', ALARM_ACKED: '确认',
|
||||
MANUAL_ACTION_CREATED: '人工处理', MANUAL_ACTION_RESOLVED: '已解决',
|
||||
}
|
||||
TEMP_SLOT_CHANGED: '暂存台',
|
||||
EQUIPMENT_AVAILABILITY_CHANGED: '设备启停',
|
||||
// 装配线操作日志
|
||||
BOM_SAVED: 'BOM维护',
|
||||
MATERIAL_REQUESTED: '备料',
|
||||
PLC_PROCESS_SENT: 'PLC下发',
|
||||
TORQUE_REPORTED: '拧紧',
|
||||
SCAN_REPORTED: '扫码报工',
|
||||
SEMI_FLOW: '半成品',
|
||||
AGV_TASK_CREATED: 'AGV任务',
|
||||
}
|
||||
|
||||
// 装配线操作日志事件(工序/备料/拧紧/扫码/流转/搬运)
|
||||
export const ASSEMBLY_EVENT_TYPES = [
|
||||
'BOM_SAVED', 'MATERIAL_REQUESTED', 'PLC_PROCESS_SENT',
|
||||
'TORQUE_REPORTED', 'SCAN_REPORTED', 'SEMI_FLOW', 'AGV_TASK_CREATED',
|
||||
]
|
||||
|
||||
@@ -8,7 +8,7 @@ import {TagColor} from '@douyinfe/semi-ui/lib/es/tag'
|
||||
import {EVENT_TYPE_LABELS} from '@/constants/event'
|
||||
|
||||
// 事件类别分组
|
||||
type EventCategory = 'material' | 'process' | 'lifecycle' | 'alarm' | 'manual'
|
||||
type EventCategory = 'material' | 'process' | 'lifecycle' | 'alarm' | 'manual' | 'assembly'
|
||||
|
||||
const EVENT_CATEGORY: Record<string, EventCategory> = {
|
||||
LOAD: 'material', UNLOAD: 'material', EXCHANGE: 'material', REPLENISH: 'material',
|
||||
@@ -19,6 +19,9 @@ const EVENT_CATEGORY: Record<string, EventCategory> = {
|
||||
ORDER_CANCELLED: 'lifecycle', ORDER_COMPLETED: 'lifecycle',
|
||||
ALARM_RAISED: 'alarm', ALARM_ACKED: 'alarm',
|
||||
MANUAL_ACTION_CREATED: 'manual', MANUAL_ACTION_RESOLVED: 'manual',
|
||||
BOM_SAVED: 'assembly', MATERIAL_REQUESTED: 'assembly', PLC_PROCESS_SENT: 'assembly',
|
||||
TORQUE_REPORTED: 'assembly', SCAN_REPORTED: 'assembly', SEMI_FLOW: 'assembly',
|
||||
AGV_TASK_CREATED: 'assembly',
|
||||
}
|
||||
|
||||
const CATEGORY_COLOR: Record<EventCategory, TagColor> = {
|
||||
@@ -27,6 +30,7 @@ const CATEGORY_COLOR: Record<EventCategory, TagColor> = {
|
||||
lifecycle: 'grey',
|
||||
alarm: 'red',
|
||||
manual: 'orange',
|
||||
assembly: 'cyan',
|
||||
}
|
||||
|
||||
const EVENT_TYPE_OPTIONS = [
|
||||
@@ -35,6 +39,10 @@ const EVENT_TYPE_OPTIONS = [
|
||||
{label: '加工', value: 'MACHINE_START'}, {label: '完工', value: 'MACHINE_DONE'},
|
||||
{label: '完成', value: 'JOB_COMPLETED'}, {label: '报废', value: 'JOB_SCRAPPED'}, {label: '下线', value: 'JOB_DISCHARGED'},
|
||||
{label: '报警', value: 'ALARM_RAISED'}, {label: '确认', value: 'ALARM_ACKED'},
|
||||
{label: 'BOM维护', value: 'BOM_SAVED'}, {label: '备料', value: 'MATERIAL_REQUESTED'},
|
||||
{label: 'PLC下发', value: 'PLC_PROCESS_SENT'}, {label: '拧紧上报', value: 'TORQUE_REPORTED'},
|
||||
{label: '扫码报工', value: 'SCAN_REPORTED'}, {label: '半成品流转', value: 'SEMI_FLOW'},
|
||||
{label: 'AGV任务', value: 'AGV_TASK_CREATED'},
|
||||
]
|
||||
|
||||
const ENTITY_TYPE_OPTIONS = [
|
||||
@@ -54,6 +62,8 @@ export default function WorkOrderLogPage() {
|
||||
const [entityType, setEntityType] = useState<string>()
|
||||
const [dateRange, setDateRange] = useState<[Date, Date]>()
|
||||
const [workpieceNo, setWorkpieceNo] = useState<string>()
|
||||
const [workOrderNo, setWorkOrderNo] = useState<string>()
|
||||
const [operator, setOperator] = useState<string>()
|
||||
const [panelVisible, setPanelVisible] = useState(false)
|
||||
const [selectedOrderId, setSelectedOrderId] = useState<number>()
|
||||
const [workpiecePanelVisible, setWorkpiecePanelVisible] = useState(false)
|
||||
@@ -65,16 +75,18 @@ export default function WorkOrderLogPage() {
|
||||
setPanelVisible(true)
|
||||
}, [])
|
||||
|
||||
const fetchLogs = useCallback(async (page: number, filters?: {eventType?: string; entityType?: string; dateRange?: [Date, Date]; workpieceNo?: string}) => {
|
||||
const fetchLogs = useCallback(async (page: number, filters?: {eventType?: string; entityType?: string; dateRange?: [Date, Date]; workpieceNo?: string; workOrderNo?: string; operator?: string}) => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const f = filters ?? {eventType, entityType, dateRange, workpieceNo}
|
||||
const f = filters ?? {eventType, entityType, dateRange, workpieceNo, workOrderNo, operator}
|
||||
const params: Record<string, unknown> = {page, limit: PAGE_SIZE}
|
||||
if (f.eventType) params.eventType = f.eventType
|
||||
if (f.entityType) params.entityType = f.entityType
|
||||
if (f.dateRange?.[0]) params.startTime = moment(f.dateRange[0]).format('YYYY-MM-DD')
|
||||
if (f.dateRange?.[1]) params.endTime = moment(f.dateRange[1]).format('YYYY-MM-DD')
|
||||
if (f.workpieceNo) params.workpieceNo = f.workpieceNo
|
||||
if (f.workOrderNo) params.workOrderNo = f.workOrderNo
|
||||
if (f.operator) params.operator = f.operator
|
||||
|
||||
const result = await orderApi.queryEventLogs(params as Parameters<typeof orderApi.queryEventLogs>[0])
|
||||
setLogs(result.data)
|
||||
@@ -87,7 +99,7 @@ export default function WorkOrderLogPage() {
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [orderApi])
|
||||
}, [orderApi, eventType, entityType, dateRange, workpieceNo, workOrderNo, operator])
|
||||
|
||||
useEffect(() => {
|
||||
fetchLogs(1)
|
||||
@@ -130,6 +142,18 @@ export default function WorkOrderLogPage() {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '工单号',
|
||||
dataIndex: 'workOrderNo',
|
||||
width: 130,
|
||||
render: (text: string) => text || '-',
|
||||
},
|
||||
{
|
||||
title: '操作人',
|
||||
dataIndex: 'operator',
|
||||
width: 100,
|
||||
render: (text: string) => text || '-',
|
||||
},
|
||||
{
|
||||
title: '设备',
|
||||
dataIndex: 'equipmentName',
|
||||
@@ -182,7 +206,23 @@ export default function WorkOrderLogPage() {
|
||||
showClear
|
||||
onClear={() => setWorkpieceNo(undefined)}
|
||||
/>
|
||||
<Button theme="solid" onClick={() => fetchLogs(1, {eventType, entityType, dateRange, workpieceNo})}>查询</Button>
|
||||
<Input
|
||||
placeholder="工单号"
|
||||
value={workOrderNo}
|
||||
onChange={setWorkOrderNo}
|
||||
style={{width: 160}}
|
||||
showClear
|
||||
onClear={() => setWorkOrderNo(undefined)}
|
||||
/>
|
||||
<Input
|
||||
placeholder="操作人"
|
||||
value={operator}
|
||||
onChange={setOperator}
|
||||
style={{width: 120}}
|
||||
showClear
|
||||
onClear={() => setOperator(undefined)}
|
||||
/>
|
||||
<Button theme="solid" onClick={() => fetchLogs(1, {eventType, entityType, dateRange, workpieceNo, workOrderNo, operator})}>查询</Button>
|
||||
</div>
|
||||
<Table
|
||||
dataSource={logs}
|
||||
@@ -194,7 +234,7 @@ export default function WorkOrderLogPage() {
|
||||
currentPage,
|
||||
pageSize: PAGE_SIZE,
|
||||
total,
|
||||
onPageChange: (page: number) => fetchLogs(page, {eventType, entityType, dateRange, workpieceNo}),
|
||||
onPageChange: (page: number) => fetchLogs(page, {eventType, entityType, dateRange, workpieceNo, workOrderNo, operator}),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user