This commit is contained in:
zlwu committed 2026-05-21 20:56:57 +08:00
1 parent 7541a167c0
commit b0eb80a2d4
37 files changed
+6279 -4732

No files matched your search

+4 -4
View File
@@ -44,21 +44,21 @@ export function fetchDeleteTaskStep(taskId: string, stepId: string) {
return request.del({ url: `/web/admin/production-tasks/${taskId}/steps/${stepId}` })
}
export function fetchReplaceStepReagents(taskId: string, stepId: string, data: Record<string, any>) {
export function fetchReplaceStepReagents(taskId: string, stepId: string, data: any[]) {
return request.put({
url: `/web/admin/production-tasks/${taskId}/steps/${stepId}/reagents`,
params: data
})
}
export function fetchReplaceStepConsumables(taskId: string, stepId: string, data: Record<string, any>) {
export function fetchReplaceStepConsumables(taskId: string, stepId: string, data: any[]) {
return request.put({
url: `/web/admin/production-tasks/${taskId}/steps/${stepId}/consumables`,
params: data
})
}
export function fetchReplaceStepDataCollection(taskId: string, stepId: string, data: Record<string, any>) {
export function fetchReplaceStepDataCollection(taskId: string, stepId: string, data: any[]) {
return request.put({
url: `/web/admin/production-tasks/${taskId}/steps/${stepId}/data-collection`,
params: data
@@ -84,7 +84,7 @@ export function fetchCopyTaskStep(data: { taskId: string; stepId: string }) {
})
}
export function fetchReplaceStepOutputs(taskId: string, stepId: string, data: Record<string, any>) {
export function fetchReplaceStepOutputs(taskId: string, stepId: string, data: any[]) {
return request.put({
url: `/web/admin/production-tasks/${taskId}/steps/${stepId}/outputs`,
params: data
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_stepdetailpanel_vue", "label": "StepDetailPanel.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_stepdetailpanel_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue", "source_location": "L265", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_config_index_ts", "label": "index.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/config/index.ts", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_config_index_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_enums_appenum", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/config/index.ts", "source_location": "L32", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_config_index_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_types_config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/config/index.ts", "source_location": "L33", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_config_index_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_config_assets_images", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/config/index.ts", "source_location": "L34", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_config_index_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_config_modules_fastenter", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/config/index.ts", "source_location": "L35", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_config_index_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_config_modules_headerbar", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/config/index.ts", "source_location": "L36", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_dispatchtaskdialog_vue", "label": "DispatchTaskDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L1"}, {"id": "production_work_order_dispatchtaskdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L205"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_dispatchtaskdialog_vue", "target": "production_work_order_dispatchtaskdialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L205", "weight": 1.0}], "raw_calls": [{"caller_nid": "production_work_order_dispatchtaskdialog_if", "callee": "initEditor", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L209"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "label": "ProtocolViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolviewdialog_dash", "label": "dash()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L329"}, {"id": "protocol_protocolviewdialog_handleclosed", "label": "handleClosed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1648"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "target": "protocol_protocolviewdialog_dash", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L329", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "target": "protocol_protocolviewdialog_handleclosed", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1648", "weight": 1.0}], "raw_calls": [{"caller_nid": "protocol_protocolviewdialog_dash", "callee": "unitName", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L329"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "label": "production-task.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L1"}, {"id": "api_production_task_fetchcreateproductiontask", "label": "fetchCreateProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L3"}, {"id": "api_production_task_fetchproductiontasklist", "label": "fetchProductionTaskList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L7"}, {"id": "api_production_task_fetchproductiontaskdetail", "label": "fetchProductionTaskDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L23"}, {"id": "api_production_task_fetchupdateproductiontask", "label": "fetchUpdateProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L27"}, {"id": "api_production_task_fetchupdateproductiontaskstatus", "label": "fetchUpdateProductionTaskStatus()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L31"}, {"id": "api_production_task_fetchaddtaskstep", "label": "fetchAddTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L35"}, {"id": "api_production_task_fetchupdatetaskstep", "label": "fetchUpdateTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L39"}, {"id": "api_production_task_fetchdeletetaskstep", "label": "fetchDeleteTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L43"}, {"id": "api_production_task_fetchreplacestepreagents", "label": "fetchReplaceStepReagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L47"}, {"id": "api_production_task_fetchreplacestepconsumables", "label": "fetchReplaceStepConsumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L54"}, {"id": "api_production_task_fetchreplacestepdatacollection", "label": "fetchReplaceStepDataCollection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L61"}, {"id": "api_production_task_fetchsettaskinputs", "label": "fetchSetTaskInputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L68"}, {"id": "api_production_task_fetchsettaskoutputs", "label": "fetchSetTaskOutputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L72"}, {"id": "api_production_task_fetchreordertasksteps", "label": "fetchReorderTaskSteps()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L76"}, {"id": "api_production_task_fetchcopytaskstep", "label": "fetchCopyTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L80"}, {"id": "api_production_task_fetchreplacestepoutputs", "label": "fetchReplaceStepOutputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L87"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "target": "api_production_task_fetchcreateproductiontask", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "target": "api_production_task_fetchproductiontasklist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "target": "api_production_task_fetchLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "label": "useTaskStepEditor.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L1"}, {"id": "production_work_order_usetaskstepeditor_toapiflag", "label": "toApiFlag()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L24"}, {"id": "production_work_order_usetaskstepeditor_fromapiflag", "label": "fromApiFlag()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L28"}, {"id": "production_work_order_usetaskstepeditor_normalizestepsubtables", "label": "normalizeStepSubTables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L31"}, {"id": "production_work_order_usetaskstepeditor_parseordernum", "label": "parseOrderNum()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L46"}, {"id": "production_work_order_usetaskstepeditor_usetaskstepeditor", "label": "useTaskStepEditor()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L53"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L13", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L21", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "production_work_order_usetaskstepeditor_toapiflag", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L24", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "production_work_order_usetaskstepeditor_fromapiflag", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L28", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "production_work_order_usetaskstepeditor_normalizestepsubtables", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L31", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "production_work_order_usetaskstepeditor_parseordernum", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L46", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "production_work_order_usetaskstepeditor_usetaskstepeditor", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L53", "weight": 1.0}], "raw_calls": [{"caller_nid": "productLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L1"}, {"id": "art_sidebar_menu_index_logsidebarmenu", "label": "logSidebarMenu()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L165"}, {"id": "art_sidebar_menu_index_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L256"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "pinia", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L142", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_setting", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L143", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_enums_appenum", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L144", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_menu", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L145", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_navigation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L146", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_navigation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L147", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_sidebar_menu_filter", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L148", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_widget_sidebarsubmenu_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L149", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_hooks_core_usecommon", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L150", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_core_layouts_art_menus_art_sidebar_menu_index_vue", "target": "core", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue", "source_location": "L151", "weight": 1.0}, {"sourLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
+7
View File
@@ -248,6 +248,13 @@
overflow-y: auto;
padding: 16px;
}
.route-config-right-footer {
padding: 12px 16px;
border-top: 1px solid #e5e7eb;
display: flex;
justify-content: flex-end;
flex-shrink: 0;
}
.route-config-right-empty {
display: flex;
flex-direction: column;
@@ -678,16 +678,6 @@
</el-select>
</template>
</el-table-column>
<el-table-column label="排序号" min-width="100" align="center" header-align="center">
<template #default="{ row }">
<el-input
v-model="row.orderNum"
placeholder="排序号"
class="inner-cell-input"
@change="saveDataCollections"
/>
</template>
</el-table-column>
<el-table-column label="备注" min-width="120" align="center" header-align="center">
<template #default="{ row }">
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" @change="saveDataCollections" />
@@ -703,6 +693,12 @@
</el-tab-pane>
</el-tabs>
</div>
<div class="route-config-right-footer">
<el-button class="btn-main" type="primary" :loading="manualSaveLoading" @click="handleManualSave">
<el-icon><Check /></el-icon>
保存
</el-button>
</div>
</template>
<template v-else>
<div class="route-config-right-empty">
@@ -1021,6 +1017,16 @@
reagentMasterById.value = next
}
/** 通过 reagentCode 在已缓存的主表数据中反查 masterId */
function resolveReagentMasterId(row: Record<string, any>): string | null {
const code = (row.reagentCode || '').trim()
if (!code) return null
for (const master of Object.values(reagentMasterById.value)) {
if ((master.reagentCode || '').trim() === code) return master.id
}
return null
}
async function searchReagentOptions(query: string) {
reagentOptionsLoading.value = true
try {
@@ -1054,6 +1060,14 @@
}
return
}
// reagentId 为空(后端不存储该字段)— 通过 reagentCode 反查主表真实 ID
const masterId = resolveReagentMasterId(row)
if (masterId) {
row.reagentId = masterId
// 主表选项已在 searchReagentOptions 中加载,无需重复添加
return
}
// 实在找不到主表记录才走 legacy 兜底
const code = (row.reagentCode || '').trim()
const name = (row.reagentName || '').trim()
if (!code && !name) return
@@ -1080,6 +1094,16 @@
saveReagents()
return
}
// 重复校验:同一试剂 ID 不可出现多次
const reagents = selectedStep.value?.reagents || []
const duplicate = reagents.find(
(r: Record<string, any>) => r !== row && r.reagentId === reagentId
)
if (duplicate) {
ElMessage.warning('该试剂已添加,不可重复选择')
row.reagentId = ''
return
}
const master = reagentMasterById.value[reagentId]
if (!master) {
saveReagents()
@@ -1111,6 +1135,16 @@
consumableMasterById.value = next
}
/** 通过 consumableCode 在已缓存的主表数据中反查 masterId */
function resolveConsumableMasterId(row: Record<string, any>): string | null {
const code = (row.consumableCode || '').trim()
if (!code) return null
for (const master of Object.values(consumableMasterById.value)) {
if ((master.consumableCode || '').trim() === code) return master.id
}
return null
}
async function searchConsumableOptions(query: string) {
consumableOptionsLoading.value = true
try {
@@ -1143,6 +1177,14 @@
}
return
}
// consumableId 为空(后端不存储该字段)— 通过 consumableCode 反查主表真实 ID
const masterId = resolveConsumableMasterId(row)
if (masterId) {
row.consumableId = masterId
// 主表选项已在 searchConsumableOptions 中加载,无需重复添加
return
}
// 实在找不到主表记录才走 legacy 兜底
const code = (row.consumableCode || '').trim()
const name = (row.consumableName || '').trim()
if (!code && !name) return
@@ -1169,6 +1211,16 @@
saveConsumables()
return
}
// 重复校验:同一耗材 ID 不可出现多次
const consumables = selectedStep.value?.consumables || []
const duplicate = consumables.find(
(c: Record<string, any>) => c !== row && c.consumableId === consumableId
)
if (duplicate) {
ElMessage.warning('该耗材已添加,不可重复选择')
row.consumableId = ''
return
}
const master = consumableMasterById.value[consumableId]
if (!master) {
saveConsumables()
@@ -1449,16 +1501,32 @@
async function saveReagents() {
if (!selectedStep.value || configSuppressSave.value) return
const reagents = selectedStep.value.reagents || []
// 按 reagentId(如有)或 reagentCode 检查重复
const seen = new Map<string, number>()
for (let i = 0; i < reagents.length; i++) {
const r = reagents[i]
const key = r.reagentId
? String(r.reagentId)
: (r.reagentCode || '').trim()
if (!key) continue
if (seen.has(key)) {
ElMessage.warning(`试剂"${r.reagentName || r.reagentCode}"重复,请移除重复项`)
return
}
seen.set(key, i)
}
try {
await fetchUpdateStepReagents({
stepId: selectedStep.value.id,
items: (selectedStep.value.reagents || []).map((r: Record<string, any>) => ({
items: reagents.map((r: Record<string, any>, idx: number) => ({
reagentCode: r.reagentCode,
reagentName: r.reagentName,
spec: r.spec,
standardUsage: r.standardUsage,
unit: r.unit,
isKeyMaterial: toApiFlag(r.isKeyMaterial),
orderNum: idx,
remark: r.remark || ''
}))
})
@@ -1491,16 +1559,32 @@
async function saveConsumables() {
if (!selectedStep.value || configSuppressSave.value) return
const consumables = selectedStep.value.consumables || []
// 按 consumableId(如有)或 consumableCode 检查重复
const seen = new Map<string, number>()
for (let i = 0; i < consumables.length; i++) {
const c = consumables[i]
const key = c.consumableId
? String(c.consumableId)
: (c.consumableCode || '').trim()
if (!key) continue
if (seen.has(key)) {
ElMessage.warning(`耗材"${c.consumableName || c.consumableCode}"重复,请移除重复项`)
return
}
seen.set(key, i)
}
try {
await fetchUpdateStepConsumables({
stepId: selectedStep.value.id,
items: (selectedStep.value.consumables || []).map((c: Record<string, any>) => ({
items: consumables.map((c: Record<string, any>, idx: number) => ({
consumableCode: c.consumableCode,
consumableName: c.consumableName,
specModel: c.specModel,
standardUsage: c.standardUsage,
unit: c.unit,
isRequired: toApiFlag(c.isRequired),
orderNum: idx,
remark: c.remark || ''
}))
})
@@ -1532,10 +1616,11 @@
try {
await fetchUpdateStepOutputs({
stepId: selectedStep.value.id,
items: (selectedStep.value.outputs || []).map((o: Record<string, any>) => ({
items: (selectedStep.value.outputs || []).map((o: Record<string, any>, idx: number) => ({
outputTypeId: o.outputTypeId,
outputName: o.outputName,
outputBarcode: o.outputBarcode,
orderNum: idx,
remark: o.remark || ''
}))
})
@@ -1573,10 +1658,10 @@
try {
await fetchUpdateStepDataCollections({
stepId: selectedStep.value.id,
items: (selectedStep.value.dataCollections || []).map((d: Record<string, any>) => ({
items: (selectedStep.value.dataCollections || []).map((d: Record<string, any>, idx: number) => ({
collectionName: d.collectionName,
unit: d.unit,
orderNum: parseOrderNum(d.orderNum),
orderNum: idx,
remark: d.remark || ''
}))
})
@@ -1585,6 +1670,30 @@
}
}
// ---------------------------------------------------------------------------
// 右侧区域手动保存
// ---------------------------------------------------------------------------
const manualSaveLoading = ref(false)
async function handleManualSave() {
if (!selectedStep.value) return
manualSaveLoading.value = true
try {
await Promise.all([
saveStepBasic(),
saveReagents(),
saveConsumables(),
saveOutputs(),
saveDataCollections()
])
ElMessage.success('保存成功')
} catch {
ElMessage.error('保存失败,请重试')
} finally {
manualSaveLoading.value = false
}
}
// ---------------------------------------------------------------------------
// 初始化
// ---------------------------------------------------------------------------
@@ -1874,6 +1983,14 @@
padding: 12px 16px;
}
.route-config-right-footer {
padding: 12px 16px;
border-top: 1px solid #e5e7eb;
display: flex;
justify-content: flex-end;
flex-shrink: 0;
}
.route-config-right-empty {
display: flex;
flex-direction: column;
@@ -7,23 +7,23 @@
<el-form label-position="top" class="route-config-step-form">
<div class="form-grid-2">
<el-form-item label="工序名称">
<el-input v-model="editor.selectedStep.value.processName" @change="editor.saveStepBasic" />
<el-input v-model="editor.selectedStep.value.processName" />
</el-form-item>
<el-form-item label="工序分类">
<el-select v-model="editor.selectedStep.value.categoryId" placeholder="选择分类" clearable @change="editor.saveStepBasic">
<el-select v-model="editor.selectedStep.value.categoryId" placeholder="选择分类" clearable>
<el-option v-for="cat in editor.categoryOptions.value" :key="cat.id"
:label="cat.categoryName || cat.name" :value="cat.id" />
</el-select>
</el-form-item>
<el-form-item label="描述" class="form-col-span-2">
<el-input v-model="editor.selectedStep.value.description" type="textarea" :rows="2"
placeholder="工序描述" @change="editor.saveStepBasic" />
placeholder="工序描述" />
</el-form-item>
<el-form-item label="设备名称">
<el-input v-model="editor.selectedStep.value.equipmentName" @change="editor.saveStepBasic" />
<el-input v-model="editor.selectedStep.value.equipmentName" />
</el-form-item>
<el-form-item label="预计时长(min)">
<el-input v-model="editor.selectedStep.value.estimatedDuration" placeholder="如 2h" @change="editor.saveStepBasic" />
<el-input v-model="editor.selectedStep.value.estimatedDuration" placeholder="如 2h" />
</el-form-item>
<el-form-item label="关联SOP" class="form-col-span-2">
<el-select v-model="editor.sopIdsArr.value" multiple placeholder="选择SOP文档" filterable
@@ -46,7 +46,7 @@
<el-table-column type="index" label="序号" width="56" align="center" :index="(i: number) => i + 1" />
<el-table-column label="试剂编码" min-width="110" align="center">
<template #default="{ row }">
<el-input v-model="row.reagentCode" placeholder="编码" class="inner-cell-input" @change="editor.saveReagents" />
<el-input v-model="row.reagentCode" placeholder="编码" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="试剂名称" min-width="160" align="center">
@@ -62,12 +62,12 @@
</el-table-column>
<el-table-column label="规格" min-width="100" align="center">
<template #default="{ row }">
<el-input v-model="row.spec" placeholder="规格" class="inner-cell-input" @change="editor.saveReagents" />
<el-input v-model="row.spec" placeholder="规格" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="标准用量" min-width="110" align="center">
<template #default="{ row }">
<el-input v-model="row.standardUsage" placeholder="用量" class="inner-cell-input" @change="editor.saveReagents" />
<el-input v-model="row.standardUsage" placeholder="用量" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="单位" min-width="120" align="center">
@@ -75,20 +75,19 @@
<el-select v-model="row.unit" placeholder="请选择单位" clearable filterable remote
reserve-keyword class="inner-cell-select" :loading="editor.itemUnitOptionsLoading.value"
:remote-method="editor.searchItemUnitOptions"
@visible-change="(vis: boolean) => vis && editor.searchItemUnitOptions('')"
@change="editor.saveReagents">
@visible-change="(vis: boolean) => vis && editor.searchItemUnitOptions('')">
<el-option v-for="item in editor.itemUnitOptions.value" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-table-column>
<el-table-column label="关键物料" width="90" align="center">
<template #default="{ row }">
<el-switch v-model="row.isKeyMaterial" @change="editor.saveReagents" />
<el-switch v-model="row.isKeyMaterial" />
</template>
</el-table-column>
<el-table-column label="备注" min-width="120" align="center">
<template #default="{ row }">
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" @change="editor.saveReagents" />
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center">
@@ -110,7 +109,7 @@
<el-table-column type="index" label="序号" width="56" align="center" :index="(i: number) => i + 1" />
<el-table-column label="耗材编码" min-width="110" align="center">
<template #default="{ row }">
<el-input v-model="row.consumableCode" placeholder="编码" class="inner-cell-input" @change="editor.saveConsumables" />
<el-input v-model="row.consumableCode" placeholder="编码" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="耗材名称" min-width="160" align="center">
@@ -126,12 +125,12 @@
</el-table-column>
<el-table-column label="规格型号" min-width="110" align="center">
<template #default="{ row }">
<el-input v-model="row.specModel" placeholder="规格型号" class="inner-cell-input" @change="editor.saveConsumables" />
<el-input v-model="row.specModel" placeholder="规格型号" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="标准用量" min-width="110" align="center">
<template #default="{ row }">
<el-input v-model="row.standardUsage" placeholder="用量" class="inner-cell-input" @change="editor.saveConsumables" />
<el-input v-model="row.standardUsage" placeholder="用量" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="单位" min-width="120" align="center">
@@ -139,20 +138,19 @@
<el-select v-model="row.unit" placeholder="请选择单位" clearable filterable remote
reserve-keyword class="inner-cell-select" :loading="editor.itemUnitOptionsLoading.value"
:remote-method="editor.searchItemUnitOptions"
@visible-change="(vis: boolean) => vis && editor.searchItemUnitOptions('')"
@change="editor.saveConsumables">
@visible-change="(vis: boolean) => vis && editor.searchItemUnitOptions('')">
<el-option v-for="item in editor.itemUnitOptions.value" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-table-column>
<el-table-column label="必需" width="80" align="center">
<template #default="{ row }">
<el-switch v-model="row.isRequired" @change="editor.saveConsumables" />
<el-switch v-model="row.isRequired" />
</template>
</el-table-column>
<el-table-column label="备注" min-width="120" align="center">
<template #default="{ row }">
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" @change="editor.saveConsumables" />
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center">
@@ -174,8 +172,7 @@
<el-table-column type="index" label="序号" width="56" align="center" :index="(i: number) => i + 1" />
<el-table-column label="产出类型" min-width="150" align="center">
<template #default="{ row }">
<el-select v-model="row.outputTypeId" placeholder="选择类型" filterable class="inner-cell-select"
@change="editor.saveOutputs">
<el-select v-model="row.outputTypeId" placeholder="选择类型" filterable class="inner-cell-select">
<el-option v-for="ot in editor.outputTypeOptions.value" :key="ot.id"
:label="ot.typeName || ot.name" :value="ot.id" />
</el-select>
@@ -183,17 +180,17 @@
</el-table-column>
<el-table-column label="名称" min-width="150" align="center">
<template #default="{ row }">
<el-input v-model="row.outputName" placeholder="名称" class="inner-cell-input" @change="editor.saveOutputs" />
<el-input v-model="row.outputName" placeholder="名称" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="条码" min-width="150" align="center">
<template #default="{ row }">
<el-input v-model="row.outputBarcode" placeholder="条码" class="inner-cell-input" @change="editor.saveOutputs" />
<el-input v-model="row.outputBarcode" placeholder="条码" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="备注" min-width="120" align="center">
<template #default="{ row }">
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" @change="editor.saveOutputs" />
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center">
@@ -215,8 +212,7 @@
<el-table-column type="index" label="序号" width="56" align="center" :index="(i: number) => i + 1" />
<el-table-column label="采集名称" min-width="180" align="center">
<template #default="{ row }">
<el-input v-model="row.collectionName" placeholder="采集项名称" class="inner-cell-input"
@change="editor.saveDataCollections" />
<el-input v-model="row.collectionName" placeholder="采集项名称" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="单位" min-width="120" align="center">
@@ -224,20 +220,19 @@
<el-select v-model="row.unit" placeholder="请选择单位" clearable filterable remote
reserve-keyword class="inner-cell-select" :loading="editor.itemUnitOptionsLoading.value"
:remote-method="editor.searchItemUnitOptions"
@visible-change="(vis: boolean) => vis && editor.searchItemUnitOptions('')"
@change="editor.saveDataCollections">
@visible-change="(vis: boolean) => vis && editor.searchItemUnitOptions('')">
<el-option v-for="item in editor.itemUnitOptions.value" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-table-column>
<el-table-column label="排序号" min-width="100" align="center">
<template #default="{ row }">
<el-input v-model="row.orderNum" placeholder="排序号" class="inner-cell-input" @change="editor.saveDataCollections" />
<el-input v-model="row.orderNum" placeholder="排序号" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="备注" min-width="120" align="center">
<template #default="{ row }">
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" @change="editor.saveDataCollections" />
<el-input v-model="row.remark" placeholder="备注" class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center">
@@ -250,6 +245,12 @@
</el-tab-pane>
</el-tabs>
</div>
<div class="route-config-right-footer">
<el-button class="btn-main" type="primary" :loading="editor.manualSaveLoading.value" @click="editor.handleManualSave">
<el-icon><Check /></el-icon>
保存
</el-button>
</div>
</template>
<template v-else>
<div class="route-config-right-empty">
@@ -261,7 +262,7 @@
</template>
<script setup lang="ts">
import { Plus, Rank } from '@element-plus/icons-vue'
import { Check, Plus, Rank } from '@element-plus/icons-vue'
import { useTaskStepEditor } from './useTaskStepEditor'
defineProps<{
@@ -148,6 +148,7 @@
<el-dialog v-model="taskSelectVisible" title="生产任务列表" width="780px" destroy-on-close align-center>
<div v-loading="taskSelectLoading" style="max-height:60vh;overflow-y:auto">
<el-table :data="taskSelectList" stripe style="width:100%">
<el-table-column type="index" label="序号" width="68" align="center" :index="(i) => i + 1" />
<el-table-column prop="taskName" label="任务名称" min-width="140" />
<el-table-column prop="routeName" label="工艺路线" min-width="140">
<template #default="{ row }">{{ row.routeName || '—' }}</template>
@@ -146,10 +146,19 @@ export function useTaskStepEditor() {
}
}
function onReagentRowSelect(row: Record<string, any>, reagentId: string) {
if (!reagentId) { row.reagentId = ''; saveReagents(); return }
if (String(reagentId).startsWith('legacy:')) { saveReagents(); return }
if (!reagentId) { row.reagentId = ''; return }
if (String(reagentId).startsWith('legacy:')) { return }
// 去重:同一试剂不允许出现多次(排除当前行和 legacy 占位符)
const dup = (selectedStep.value?.reagents || []).some(
(r: Record<string, any>) => r !== row && r.reagentId === reagentId && !String(r.reagentId).startsWith('legacy:')
)
if (dup) {
ElMessage.warning('该试剂已添加,请勿重复选择')
row.reagentId = ''
return
}
const master = reagentMasterById.value[reagentId]
if (!master) { saveReagents(); return }
if (!master) { return }
Object.assign(row, {
reagentId: master.id, reagentCode: master.reagentCode || '',
reagentName: master.reagentName || '', spec: master.spec || '',
@@ -158,7 +167,6 @@ export function useTaskStepEditor() {
})
ensureItemUnitOption(row.unit)
ensureReagentOption(row)
saveReagents()
}
function mapConsumableOptionLabel(c: { consumableName?: string; consumableCode?: string }) {
@@ -208,8 +216,28 @@ export function useTaskStepEditor() {
}
}
function onConsumableRowSelect(row: Record<string, any>, consumableId: string) {
if (!consumableId) { row.consumableId = ''; saveConsumables(); return }
if (String(consumableId).startsWith('legacy:')) { saveConsumables(); return }
if (!consumableId) { row.consumableId = ''; return }
if (String(consumableId).startsWith('legacy:')) { return }
// 去重:同一耗材不允许出现多次(排除当前行和 legacy 占位符)
const dup = (selectedStep.value?.consumables || []).some(
(c: Record<string, any>) => c !== row && c.consumableId === consumableId && !String(c.consumableId).startsWith('legacy:')
)
if (dup) {
ElMessage.warning('该耗材已添加,请勿重复选择')
row.consumableId = ''
return
}
const master = consumableMasterById.value[consumableId]
if (!master) { return }
Object.assign(row, {
consumableId: master.id, consumableCode: master.consumableCode || '',
consumableName: master.consumableName || '', specModel: master.specModel || '',
standardUsage: master.standardUsage ?? '', unit: master.unit || '',
remark: master.remark ?? master.description ?? ''
})
ensureItemUnitOption(row.unit)
ensureConsumableOption(row)
}
const master = consumableMasterById.value[consumableId]
if (!master) { saveConsumables(); return }
Object.assign(row, {
@@ -359,19 +387,18 @@ export function useTaskStepEditor() {
if (!selectedStep.value) return
try {
await fetchUpdateTaskStep(taskId.value, selectedStep.value.id, {
processName: selectedStep.value.processName,
categoryId: selectedStep.value.categoryId,
process_name: selectedStep.value.processName,
category_id: selectedStep.value.categoryId,
description: selectedStep.value.description,
equipmentName: selectedStep.value.equipmentName,
estimatedDuration: selectedStep.value.estimatedDuration,
sopIds: selectedStep.value.sopIds
equipment_name: selectedStep.value.equipmentName,
estimated_duration: selectedStep.value.estimatedDuration,
sop_ids: selectedStep.value.sopIds
})
} catch { /* ignore */ }
}
function onSopIdsChange(val: string[]) {
if (!selectedStep.value) return
selectedStep.value.sopIds = val.join(',')
saveStepBasic()
}
function addReagentRow() {
@@ -381,19 +408,17 @@ export function useTaskStepEditor() {
reagentId: '', reagentCode: '', reagentName: '', spec: '',
standardUsage: '', unit: '', isKeyMaterial: false, remark: ''
})
saveReagents()
}
function removeReagentRow(i: number) { selectedStep.value?.reagents?.splice(i, 1); saveReagents() }
function removeReagentRow(i: number) { selectedStep.value?.reagents?.splice(i, 1) }
async function saveReagents() {
if (!selectedStep.value || configSuppressSave.value) return
try {
await fetchReplaceStepReagents(taskId.value, selectedStep.value.id, {
items: (selectedStep.value.reagents || []).map((r: Record<string, any>) => ({
reagentCode: r.reagentCode, reagentName: r.reagentName, spec: r.spec,
standardUsage: r.standardUsage, unit: r.unit,
isKeyMaterial: toApiFlag(r.isKeyMaterial), remark: r.remark || ''
}))
})
const items = (selectedStep.value.reagents || []).map((r: Record<string, any>) => ({
material_code: r.reagentCode, material_name: r.reagentName, spec: r.spec,
standard_usage: r.standardUsage, unit: r.unit,
is_key_material: toApiFlag(r.isKeyMaterial), remark: r.remark || ''
}))
await fetchReplaceStepReagents(taskId.value, selectedStep.value.id, items)
} catch { /* ignore */ }
}
@@ -404,19 +429,18 @@ export function useTaskStepEditor() {
consumableId: '', consumableCode: '', consumableName: '', specModel: '',
standardUsage: '', unit: '', isRequired: false, remark: ''
})
saveConsumables()
}
function removeConsumableRow(i: number) { selectedStep.value?.consumables?.splice(i, 1); saveConsumables() }
function removeConsumableRow(i: number) { selectedStep.value?.consumables?.splice(i, 1) }
async function saveConsumables() {
if (!selectedStep.value || configSuppressSave.value) return
try {
await fetchReplaceStepConsumables(taskId.value, selectedStep.value.id, {
items: (selectedStep.value.consumables || []).map((c: Record<string, any>) => ({
consumableCode: c.consumableCode, consumableName: c.consumableName, specModel: c.specModel,
standardUsage: c.standardUsage, unit: c.unit,
isRequired: toApiFlag(c.isRequired), remark: c.remark || ''
}))
})
const items = (selectedStep.value.consumables || []).map((c: Record<string, any>) => ({
material_code: c.consumableCode, material_name: c.consumableName,
spec_model: c.specModel,
standard_usage: c.standardUsage, unit: c.unit,
is_required: toApiFlag(c.isRequired), remark: c.remark || ''
}))
await fetchReplaceStepConsumables(taskId.value, selectedStep.value.id, items)
} catch { /* ignore */ }
}
@@ -424,18 +448,16 @@ export function useTaskStepEditor() {
if (!selectedStep.value) return
if (!selectedStep.value.outputs) selectedStep.value.outputs = []
selectedStep.value.outputs.push({ outputTypeId: '', outputName: '', outputBarcode: '', remark: '' })
saveOutputs()
}
function removeOutputRow(i: number) { selectedStep.value?.outputs?.splice(i, 1); saveOutputs() }
function removeOutputRow(i: number) { selectedStep.value?.outputs?.splice(i, 1) }
async function saveOutputs() {
if (!selectedStep.value || configSuppressSave.value) return
try {
await fetchReplaceStepOutputs(taskId.value, selectedStep.value.id, {
items: (selectedStep.value.outputs || []).map((o: Record<string, any>) => ({
outputTypeId: o.outputTypeId, outputName: o.outputName,
outputBarcode: o.outputBarcode, remark: o.remark || ''
}))
})
const items = (selectedStep.value.outputs || []).map((o: Record<string, any>) => ({
output_type_id: o.outputTypeId, output_name: o.outputName,
output_barcode: o.outputBarcode, remark: o.remark || ''
}))
await fetchReplaceStepOutputs(taskId.value, selectedStep.value.id, items)
} catch { /* ignore */ }
}
@@ -443,21 +465,39 @@ export function useTaskStepEditor() {
if (!selectedStep.value) return
if (!selectedStep.value.dataCollections) selectedStep.value.dataCollections = []
selectedStep.value.dataCollections.push({ collectionName: '', unit: '', orderNum: 0, remark: '' })
saveDataCollections()
}
function removeDataCollectionRow(i: number) { selectedStep.value?.dataCollections?.splice(i, 1); saveDataCollections() }
function removeDataCollectionRow(i: number) { selectedStep.value?.dataCollections?.splice(i, 1) }
async function saveDataCollections() {
if (!selectedStep.value || configSuppressSave.value) return
try {
await fetchReplaceStepDataCollection(taskId.value, selectedStep.value.id, {
items: (selectedStep.value.dataCollections || []).map((d: Record<string, any>) => ({
collectionName: d.collectionName, unit: d.unit,
orderNum: parseOrderNum(d.orderNum), remark: d.remark || ''
}))
})
const items = (selectedStep.value.dataCollections || []).map((d: Record<string, any>) => ({
collection_name: d.collectionName, unit: d.unit,
collection_value: '', remark: d.remark || ''
}))
await fetchReplaceStepDataCollection(taskId.value, selectedStep.value.id, items)
} catch { /* ignore */ }
}
const manualSaveLoading = ref(false)
async function handleManualSave() {
if (!selectedStep.value) return
manualSaveLoading.value = true
try {
await Promise.all([
saveStepBasic(),
saveReagents(),
saveConsumables(),
saveOutputs(),
saveDataCollections()
])
ElMessage.success('保存成功')
} catch {
ElMessage.error('保存失败,请重试')
} finally {
manualSaveLoading.value = false
}
}
async function initEditor(id: string) {
taskId.value = id
selectedStepId.value = ''
@@ -491,6 +531,7 @@ export function useTaskStepEditor() {
addConsumableRow, removeConsumableRow, saveConsumables,
addOutputRow, removeOutputRow, saveOutputs,
addDataCollectionRow, removeDataCollectionRow, saveDataCollections,
manualSaveLoading, handleManualSave,
initEditor
}
}