This commit is contained in:
zlwu committed 2026-06-17 20:31:34 +08:00
1 parent 6bfabac50d
commit 58a47b96a5
38 files changed
+10159 -9660

No files matched your search

@@ -43,6 +43,12 @@ export interface ProductionWorkOrderItem {
projectTitle?: string
/** 基础实验出库:客户名称(列表 enrich) */
customerName?: string
/** 出库工单:输注计划细胞类型(列表 enrich,无产品明细时兜底) */
cellType?: string
/** 出库工单:输注计划规格(列表 enrich,无产品明细时兜底) */
specText?: string
/** 出库工单:输注计划关联细胞产品明细(列表 enrich) */
products?: OutboundQcDetailProduct[]
paymentSummary?: QcProtocolPaymentSummary | null
feeSummary?: QcBasicExperimentFeeSummary | null
}
+6
View File
@@ -127,6 +127,12 @@ export type QcWorkOrder = {
/** 出库工单:输注计划总次数 */
totalCourseCount?: number | null
infusionTime?: string
/** 出库工单:输注计划细胞类型(列表 enrich,无产品明细时兜底) */
cellType?: string
/** 出库工单:输注计划规格(列表 enrich,无产品明细时兜底) */
specText?: string
/** 计划质检:输注计划关联细胞产品明细(列表 enrich) */
products?: OutboundQcDetailProduct[]
triggerSource?: string
triggerSourceLabel?: string
productionWorkOrderId?: string
@@ -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_quality_inspection_qc_work_order_qcworkordersinglecard_vue", "label": "QcWorkOrderSingleCard.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_productionworkordercardlist_vue", "label": "ProductionWorkOrderCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -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_utils_production_work_order_card_meta_ts", "label": "production-work-order-card-meta.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L1"}, {"id": "utils_production_work_order_card_meta_formatoutboundschedulesortno", "label": "formatOutboundScheduleSortNo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L40"}, {"id": "utils_production_work_order_card_meta_formatoutboundscheduletotalcount", "label": "formatOutboundScheduleTotalCount()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L46"}, {"id": "utils_production_work_order_card_meta_parsereceptiontime", "label": "parseReceptionTime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L52"}, {"id": "utils_production_work_order_card_meta_receptionover24hourslabel", "label": "receptionOver24HoursLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L59"}, {"id": "utils_production_work_order_card_meta_receptionover24hourstagtype", "label": "receptionOver24HoursTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L66"}, {"id": "utils_production_work_order_card_meta_protocolstatuslabelfortab", "label": "protocolStatusLabelForTab()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L73"}, {"id": "utils_production_work_order_card_meta_protocolstatustagtypefortab", "label": "protocolStatusTagTypeForTab()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L82"}, {"id": "utils_production_work_order_card_meta_buildinboundmetafields", "label": "buildInboundMetaFields()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L91"}, {"id": "utils_production_work_order_card_meta_getcardmetaconfig", "label": "getCardMetaConfig()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L263"}, {"id": "utils_production_work_order_card_meta_getcardmetaconfigforlegacytab", "label": "getCardMetaConfigForLegacyTab()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L267"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_production_work_order_card_meta_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_production_work_order_card_meta_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_labels", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_production_work_order_card_meta_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_production_work_order_card_meta_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_production_work_order_card_meta_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_production_work_order_tabs", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_work_order_card_meta_ts", "label": "qc-work-order-card-meta.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L1"}, {"id": "utils_qc_work_order_card_meta_formatdetectmethods", "label": "formatDetectMethods()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L45"}, {"id": "utils_qc_work_order_card_meta_formatqctarget", "label": "formatQcTarget()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L52"}, {"id": "utils_qc_work_order_card_meta_formatoutboundschedulesortno", "label": "formatOutboundScheduleSortNo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L60"}, {"id": "utils_qc_work_order_card_meta_formatoutboundscheduletotalcount", "label": "formatOutboundScheduleTotalCount()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L66"}, {"id": "utils_qc_work_order_card_meta_formattempcellproductfield", "label": "formatTempCellProductField()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L72"}, {"id": "utils_qc_work_order_card_meta_protocolstatuslabelbysource", "label": "protocolStatusLabelBySource()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L77"}, {"id": "utils_qc_work_order_card_meta_protocolstatustagtypebysource", "label": "protocolStatusTagTypeBySource()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L81"}, {"id": "utils_qc_work_order_card_meta_buildcellstoragegroupcontext", "label": "buildCellStorageGroupContext()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L155"}, {"id": "utils_qc_work_order_card_meta_builddonationgroupcontext", "label": "buildDonationGroupContext()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L167"}, {"id": "utils_qc_work_order_card_meta_buildoutboundpilotgroupcontext", "label": "buildOutboundPilotGroupContext()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L189"}, {"id": "utils_qc_work_order_card_meta_buildoutboundbasicexperimentgroupcontext", "label": "buildOutboundBasicExperimentGroupContext()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L198"}, {"id": "utils_qc_work_order_card_meta_getcardmetaconfig", "label": "getCardMetaConfig()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L288"}, {"id": "utils_qc_work_order_card_meta_buildgroupcontextsubtitle", "label": "buildGroupContextSubtitle()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L292"}, {"id": "utils_qc_work_order_card_meta_cardmetausesinboundgroups", "label": "cardMetaUsesInboundGroups()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L297"}, {"id": "utils_qc_work_order_card_meta_cardmetausesoutboundgroups", "label": "cardMetaUsesOutboundGroups()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L301"}, {"id": "utils_qc_work_order_card_meta_cardmetausesgroupedlist", "label": "cardMetaUsesGroupedList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L305"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_work_order_card_meta_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_work_order_card_meta_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/0Line 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_productionworkordercardlist_vue", "label": "ProductionWorkOrderCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L1"}, {"id": "production_work_order_productionworkordercardlist_visiblemetafields", "label": "visibleMetaFields()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L229"}, {"id": "production_work_order_productionworkordercardlist_showprotocolfeesummary", "label": "showProtocolFeeSummary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L233"}, {"id": "production_work_order_productionworkordercardlist_showoutboundfeesummary", "label": "showOutboundFeeSummary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L237"}, {"id": "production_work_order_productionworkordercardlist_productionwostatustag", "label": "productionWoStatusTag()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L241"}, {"id": "production_work_order_productionworkordercardlist_handlecardselect", "label": "handleCardSelect()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L251"}, {"id": "production_work_order_productionworkordercardlist_cardindex", "label": "cardIndex()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L255"}, {"id": "production_work_order_productionworkordercardlist_isselected", "label": "isSelected()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L259"}, {"id": "production_work_order_productionworkordercardlist_candispatchtask", "label": "canDispatchTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L263"}, {"id": "production_work_order_productionworkordercardlist_candispatchqc", "label": "canDispatchQc()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L267"}, {"id": "production_work_order_productionworkordercardlist_dispatchqctooltip", "label": "dispatchQcTooltip()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L273"}, {"id": "production_work_order_productionworkordercardlist_cancomplete", "label": "canComplete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L280"}, {"id": "production_work_order_productionworkordercardlist_caneditworkorder", "label": "canEditWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L284"}, {"id": "production_work_order_productionworkordercardlist_candeleteworkorder", "label": "canDeleteWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L292"}, {"id": "production_work_order_productionworkordercardlist_hasmoreactions", "label": "hasMoreActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L297"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_productionworkordercardlist_vue", "target": "production_work_order_productionworkordercardlist_visiblemetafields", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L229", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_productionLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_productionworkordercardlist_vue", "label": "ProductionWorkOrderCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "label": "production-work-order.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L1"}, {"id": "api_production_work_order_fetchproductionworkorderlist", "label": "fetchProductionWorkOrderList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L83"}, {"id": "api_production_work_order_fetchproductionworkorderdetail", "label": "fetchProductionWorkOrderDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L105"}, {"id": "api_production_work_order_fetchcompleteproductionworkorder", "label": "fetchCompleteProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L109"}, {"id": "api_production_work_order_fetchcreateproductionworkorder", "label": "fetchCreateProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L113"}, {"id": "api_production_work_order_fetchconfigureproductionworkorder", "label": "fetchConfigureProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L126"}, {"id": "api_production_work_order_fetchupdateproductionworkorder", "label": "fetchUpdateProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L142"}, {"id": "api_production_work_order_fetchdeleteproductionworkorder", "label": "fetchDeleteProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L149"}, {"id": "api_production_work_order_fetchproductionworkordercellproductoptions", "label": "fetchProductionWorkOrderCellProductOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L165"}, {"id": "api_production_work_order_fetchcreateqcfromproduction", "label": "fetchCreateQcFromProduction()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L171"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_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-work-order.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchproductionworkorderlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L83", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchproductionworkorderdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L105", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchcompleteproductionworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L109", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchcreateproductionworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L113", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchconfigureproductionworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.tsLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationformdialog_vue", "label": "ApplicationFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1"}, {"id": "pilot_application_applicationformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1454"}, {"id": "pilot_application_applicationformdialog_remotesearchcustomers", "label": "remoteSearchCustomers()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L2625"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationformdialog_vue", "target": "pilot_application_applicationformdialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1454", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationformdialog_vue", "target": "pilot_application_applicationformdialog_remotesearchcustomers", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L2625", "weight": 1.0}], "raw_calls": [{"caller_nid": "pilot_application_applicationformdialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1455"}, {"caller_nid": "pilot_application_applicationformdialog_remotesearchcustomers", "callee": "mapUrlsToAttachmentFiles", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L2699"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_qcworkordersamplegroup_vue", "label": "QcWorkOrderSampleGroup.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "label": "qc-work-order.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L1"}, {"id": "api_qc_work_order_fetchqcworkorderlist", "label": "fetchQcWorkOrderList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L180"}, {"id": "api_qc_work_order_fetchqcworkorderdetail", "label": "fetchQcWorkOrderDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L200"}, {"id": "api_qc_work_order_fetchconfigureqcworkorder", "label": "fetchConfigureQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L206"}, {"id": "api_qc_work_order_fetchcreateqcworkorder", "label": "fetchCreateQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L223"}, {"id": "api_qc_work_order_fetchupdateqcworkorder", "label": "fetchUpdateQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L238"}, {"id": "api_qc_work_order_fetchdeleteqcworkorder", "label": "fetchDeleteQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L248"}, {"id": "api_qc_work_order_fetchoutboundqcdetail", "label": "fetchOutboundQcDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L321"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_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/qc-work-order.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchqcworkorderlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L180", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchqcworkorderdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L200", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchconfigureqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L206", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchcreateqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L223", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchupdateqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L238", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchdeleteqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L248", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchoutboundqcdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L321", "weight": 1.0}], "raw_calls": [{"caller_nid": "api_qc_work_order_fetchqcworkorderlist", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L194"}, {"caller_nid": "api_qc_work_order_fetchqcworkorderdetail", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L201"}, {"caller_nid": "api_qc_work_order_fetchconfigureqcworkorder", "callee": "post", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L217"}, {"caller_nid": "api_qc_work_order_fetchcreateqcworkoLine truncated
@@ -25,6 +25,8 @@ export type ProductionWorkOrderCardMetaConfig = {
tabKey: ProductionWorkOrderTabKey
showProtocolFeeSummary: boolean
showOutboundFeeSummary: boolean
/** 卡片展示关联申请单/输注计划的细胞产品明细 */
showCellProducts: boolean
metaFields: CardMetaField[]
allowDispatchQc: boolean
allowSampleReception: boolean
@@ -181,6 +183,7 @@ const CARD_META_BY_TAB: Record<ProductionWorkOrderTabKey, ProductionWorkOrderCar
tabKey: 'inbound_cell_storage',
showProtocolFeeSummary: true,
showOutboundFeeSummary: false,
showCellProducts: false,
metaFields: buildInboundMetaFields('inbound_cell_storage'),
allowDispatchQc: true,
allowSampleReception: true,
@@ -192,6 +195,7 @@ const CARD_META_BY_TAB: Record<ProductionWorkOrderTabKey, ProductionWorkOrderCar
tabKey: 'inbound_research_donation',
showProtocolFeeSummary: false,
showOutboundFeeSummary: false,
showCellProducts: false,
metaFields: buildInboundMetaFields('inbound_research_donation'),
allowDispatchQc: true,
allowSampleReception: true,
@@ -203,6 +207,7 @@ const CARD_META_BY_TAB: Record<ProductionWorkOrderTabKey, ProductionWorkOrderCar
tabKey: 'outbound_pilot_service',
showProtocolFeeSummary: false,
showOutboundFeeSummary: false,
showCellProducts: true,
metaFields: outboundPilotClinicalFields,
allowDispatchQc: true,
allowSampleReception: false,
@@ -214,6 +219,7 @@ const CARD_META_BY_TAB: Record<ProductionWorkOrderTabKey, ProductionWorkOrderCar
tabKey: 'outbound_basic_experiment',
showProtocolFeeSummary: false,
showOutboundFeeSummary: true,
showCellProducts: true,
metaFields: outboundBasicExperimentFields,
allowDispatchQc: true,
allowSampleReception: false,
@@ -225,6 +231,7 @@ const CARD_META_BY_TAB: Record<ProductionWorkOrderTabKey, ProductionWorkOrderCar
tabKey: 'outbound_clinical_application',
showProtocolFeeSummary: false,
showOutboundFeeSummary: true,
showCellProducts: false,
metaFields: outboundPilotClinicalFields,
allowDispatchQc: false,
allowSampleReception: false,
@@ -236,6 +243,7 @@ const CARD_META_BY_TAB: Record<ProductionWorkOrderTabKey, ProductionWorkOrderCar
tabKey: 'temporary',
showProtocolFeeSummary: false,
showOutboundFeeSummary: false,
showCellProducts: false,
metaFields: temporaryFields,
allowDispatchQc: true,
allowSampleReception: false,
@@ -33,6 +33,8 @@ export type QcWorkOrderCardMetaConfig = {
showTriggerTag: boolean
showProtocolFeeSummary: boolean
showOutboundFeeSummary: boolean
/** 卡片展示计划质检订单细胞产品 / 生产过程质检细胞产品 */
showCellProducts: boolean
metaFields: CardMetaField[]
buildGroupContextParts: (row: QcWorkOrder) => string[]
allowEditTemporary: boolean
@@ -209,6 +211,7 @@ const CARD_META_BY_TAB: Record<QcWorkOrderTabKey, QcWorkOrderCardMetaConfig> = {
showTriggerTag: true,
showProtocolFeeSummary: true,
showOutboundFeeSummary: false,
showCellProducts: false,
metaFields: inboundGroupedFields,
buildGroupContextParts: buildCellStorageGroupContext,
allowEditTemporary: false,
@@ -221,6 +224,7 @@ const CARD_META_BY_TAB: Record<QcWorkOrderTabKey, QcWorkOrderCardMetaConfig> = {
showTriggerTag: true,
showProtocolFeeSummary: false,
showOutboundFeeSummary: false,
showCellProducts: false,
metaFields: inboundGroupedFields,
buildGroupContextParts: buildDonationGroupContext,
allowEditTemporary: false,
@@ -233,6 +237,7 @@ const CARD_META_BY_TAB: Record<QcWorkOrderTabKey, QcWorkOrderCardMetaConfig> = {
showTriggerTag: true,
showProtocolFeeSummary: false,
showOutboundFeeSummary: false,
showCellProducts: true,
metaFields: outboundGroupedFields,
buildGroupContextParts: buildOutboundPilotGroupContext,
allowEditTemporary: false,
@@ -245,6 +250,7 @@ const CARD_META_BY_TAB: Record<QcWorkOrderTabKey, QcWorkOrderCardMetaConfig> = {
showTriggerTag: true,
showProtocolFeeSummary: false,
showOutboundFeeSummary: true,
showCellProducts: true,
metaFields: outboundGroupedFields,
buildGroupContextParts: buildOutboundBasicExperimentGroupContext,
allowEditTemporary: false,
@@ -257,6 +263,7 @@ const CARD_META_BY_TAB: Record<QcWorkOrderTabKey, QcWorkOrderCardMetaConfig> = {
showTriggerTag: false,
showProtocolFeeSummary: false,
showOutboundFeeSummary: true,
showCellProducts: false,
metaFields: outboundPilotClinicalFields,
buildGroupContextParts: () => [],
allowEditTemporary: false,
@@ -269,6 +276,7 @@ const CARD_META_BY_TAB: Record<QcWorkOrderTabKey, QcWorkOrderCardMetaConfig> = {
showTriggerTag: true,
showProtocolFeeSummary: false,
showOutboundFeeSummary: false,
showCellProducts: false,
metaFields: temporaryFields,
buildGroupContextParts: () => [],
allowEditTemporary: true,
@@ -1639,6 +1639,133 @@
return items.length ? items.join(',') : '—'
})
/** 未完成结算的输注计划(已完成/已取消不再扣减) */
const isPendingSettlementSchedule = (schedule: Record<string, any>): boolean => {
const st = normalizeInfusionStatusCode(schedule.infusionStatus)
return st !== 'ywc' && st !== 'yqx'
}
const resolveYfkUnitPrice = (cp: Record<string, any>): number => {
const agreement = Number(cp.agreementPrice)
if (agreement > 0) return agreement
return Number(cp.actualPrice) || 0
}
const calcPendingSettlementAmount = (): number =>
infusionSchedules.value
.filter(isPendingSettlementSchedule)
.reduce(
(sum, s) =>
sum +
(s.cellProducts || []).reduce((lineSum: number, cp: any) => {
const qty = Math.max(1, Number(cp.quantity) || 1)
return lineSum + resolveYfkUnitPrice(cp) * qty
}, 0),
0
)
type PendingProductQtyItem = {
label: string
qty: number
projectCode: string
specText: string
cellTypeName: string
}
const calcPendingSettlementQtyByProduct = (): Map<string, PendingProductQtyItem> => {
const map = new Map<string, PendingProductQtyItem>()
for (const schedule of infusionSchedules.value.filter(isPendingSettlementSchedule)) {
for (const cp of schedule.cellProducts || []) {
const projectCode = (cp.projectCode || '').trim()
const specText = (cp.specText || '').trim()
const cellTypeName = (cp.cellTypeName || '').trim()
const key = projectCode ? `${projectCode}|${specText}` : `${cellTypeName}|${specText}`
if (!key.replace('|', '').trim()) continue
const qty = Math.max(1, Number(cp.quantity) || 1)
const label = formatCellProductDisplayLabel(cp)
const existing = map.get(key)
if (existing) {
existing.qty += qty
} else {
map.set(key, { label, qty, projectCode, specText, cellTypeName })
}
}
}
return map
}
const findOrderProductCurrentQty = (
orderProducts: any[],
item: PendingProductQtyItem
): number | null => {
const spec = item.specText
if (item.projectCode) {
const row = orderProducts.find(
(p) => (p.projectCode || '') === item.projectCode && (p.specText || '') === spec
)
if (row) return Number(row.currentQty) || 0
}
if (item.cellTypeName) {
const row = orderProducts.find(
(p) =>
(p.cellType || p.cellTypeName || '') === item.cellTypeName && (p.specText || '') === spec
)
if (row) return Number(row.currentQty) || 0
}
return null
}
/** 保存前校验渠道服务订单余额/份数,仅提示不阻断保存 */
const warnIfChannelSettlementInsufficient = async () => {
if (isClinical.value || isBasicExperiment.value) return
if (!formData.channelServiceOrderId || !formData.channelId) return
const pendingSchedules = infusionSchedules.value.filter(isPendingSettlementSchedule)
const hasProducts = pendingSchedules.some((s) => (s.cellProducts || []).length > 0)
if (!hasProducts) return
let orderDetail: any
try {
const res: any = await fetchChannelServiceOrderDetail(formData.channelServiceOrderId)
orderDetail = res?.data ?? res
} catch {
return
}
const orderType = orderDetail?.orderType || selectedServiceOrder.value?.orderType || ''
if (orderType === 'yfk') {
const required = calcPendingSettlementAmount()
if (required <= 0) return
const balance = Number(orderDetail.currentBalance) || 0
if (balance < required) {
ElMessage.warning(
`渠道服务订单余额可能不足:当前余额 ¥${formatMoneyDisplay(balance, 2)},待完成输注计划预估需 ¥${formatMoneyDisplay(required, 2)}。申请单仍会保存,完成输注时可能扣减失败。`
)
}
return
}
if (orderType === 'gmcp') {
const orderProducts = Array.isArray(orderDetail.products) ? orderDetail.products : []
const requiredMap = calcPendingSettlementQtyByProduct()
const shortfalls: string[] = []
for (const item of requiredMap.values()) {
const available = findOrderProductCurrentQty(orderProducts, item)
if (available === null) {
shortfalls.push(`「${item.label}」在服务订单中未找到持仓`)
} else if (available < item.qty) {
shortfalls.push(`「${item.label}」当前剩余 ${available} 份,预估需 ${item.qty} 份`)
}
}
if (shortfalls.length) {
ElMessage.warning(
`渠道服务订单产品份数可能不足:${shortfalls.join(';')}。申请单仍会保存,完成输注时可能扣减失败。`
)
}
}
}
const getCellProductProjectKey = (cp: any): string =>
(cp?.projectCode || cp?.priceId || '').trim()
@@ -2742,6 +2869,8 @@
}
}
await warnIfChannelSettlementInsufficient()
submitting.value = true
try {
const attachmentPayload = otherFileList.value.map((a) => ({
@@ -6,119 +6,172 @@
<header class="production-work-order-card__head">
<div class="production-work-order-card__title-band">
<div class="production-work-order-card__title-row">
<el-checkbox
v-if="!isMineMode"
:model-value="isSelected(row.id)"
class="production-work-order-card__checkbox"
@change="(val) => handleCardSelect(row, Boolean(val))"
/>
<span class="production-work-order-card__index">{{ cardIndex(idx) }}</span>
<span class="production-work-order-card__no">{{ row.workOrderNo || '—' }}</span>
<el-tag :type="productionWoStatusTag(row.workOrderStatus).type" size="small">
{{ productionWoStatusTag(row.workOrderStatus).label }}
</el-tag>
<div class="production-work-order-card__title-left">
<el-checkbox
v-if="!isMineMode"
:model-value="isSelected(row.id)"
class="production-work-order-card__checkbox"
@change="(val) => handleCardSelect(row, Boolean(val))"
/>
<span class="production-work-order-card__index">{{ cardIndex(idx) }}</span>
<span class="production-work-order-card__no">{{ row.workOrderNo || '—' }}</span>
<el-tag :type="productionWoStatusTag(row.workOrderStatus).type" size="small">
{{ productionWoStatusTag(row.workOrderStatus).label }}
</el-tag>
</div>
<div v-if="showCardOpsRow" class="production-work-order-card__ops">
<el-button
v-if="isMineMode"
class="btn-op-item primary"
type="primary"
@click="emit('view', row)"
>
<el-icon><View /></el-icon>查看
</el-button>
<el-button
v-else-if="showCardDispatchComplete && canDispatchTask(row)"
class="btn-op-item primary"
type="primary"
@click="emit('dispatch', row)"
>
<el-icon><Position /></el-icon>派发任务
</el-button>
<el-button
v-else-if="!canDispatchTask(row)"
class="btn-op-item primary"
@click="emit('view', row)"
>
<el-icon><View /></el-icon>查看
</el-button>
<el-tooltip
v-if="!isMineMode && cardMeta.allowDispatchQc"
:content="dispatchQcTooltip(row)"
:disabled="canDispatchQc(row)"
placement="top"
>
<span>
<el-button
class="btn-op-item"
:disabled="!canDispatchQc(row)"
@click="emit('dispatch-qc', row)"
>
<el-icon><Document /></el-icon>派发质检工单
</el-button>
</span>
</el-tooltip>
<el-button
v-if="cardMeta.allowSampleReception"
class="btn-op-item"
@click="emit('open-sample-reception', row)"
>
<el-icon><EditPen /></el-icon>样本接收信息填写
</el-button>
<el-button
v-if="!isMineMode && showCardDispatchComplete && canComplete(row)"
class="btn-op-item"
@click="emit('complete', row)"
>
<el-icon><Check /></el-icon>完成工单
</el-button>
<el-dropdown
v-if="!isMineMode && hasMoreActions(row)"
trigger="hover"
@command="(cmd) => emit('command', cmd, row)"
>
<el-button class="btn-op-item">
<el-icon><More /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="canDispatchTask(row)" command="view">
<el-icon><View /></el-icon>查看
</el-dropdown-item>
<el-dropdown-item v-if="canEditWorkOrder(row)" command="edit">
<el-icon><EditPen /></el-icon>编辑
</el-dropdown-item>
<el-dropdown-item v-if="canDeleteWorkOrder(row)" command="delete" divided>
<el-icon><Delete /></el-icon>删除
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
<div class="production-work-order-card__head-body">
<div class="production-work-order-card__head-main">
<dl class="production-work-order-card__meta">
<template v-for="field in visibleMetaFields(row)" :key="field.label">
<div
class="production-work-order-card__meta-item"
:class="{ 'production-work-order-card__meta-item--wide': field.wide }"
>
<dt>{{ field.label }}</dt>
<dd>
<el-tag
v-if="field.kind === 'tag'"
:type="field.getTagType?.(row) || 'info'"
size="small"
>
{{ field.getValue(row) }}
</el-tag>
<template v-else>{{ field.getValue(row) }}</template>
</dd>
</div>
</template>
</dl>
</div>
<div v-if="showCardOpsRow" class="production-work-order-card__ops">
<el-button
v-if="isMineMode"
class="btn-op-item primary"
type="primary"
@click="emit('view', row)"
>
<el-icon><View /></el-icon>查看
</el-button>
<el-button
v-else-if="showCardDispatchComplete && canDispatchTask(row)"
class="btn-op-item primary"
type="primary"
@click="emit('dispatch', row)"
>
<el-icon><Position /></el-icon>派发任务
</el-button>
<el-button
v-else-if="!canDispatchTask(row)"
class="btn-op-item primary"
@click="emit('view', row)"
>
<el-icon><View /></el-icon>查看
</el-button>
<el-tooltip
v-if="!isMineMode && cardMeta.allowDispatchQc"
:content="dispatchQcTooltip(row)"
:disabled="canDispatchQc(row)"
placement="top"
>
<span>
<el-button
class="btn-op-item"
:disabled="!canDispatchQc(row)"
@click="emit('dispatch-qc', row)"
<dl class="production-work-order-card__meta">
<template v-for="field in visibleMetaFields(row)" :key="field.label">
<div
class="production-work-order-card__meta-item"
:class="{ 'production-work-order-card__meta-item--wide': field.wide }"
>
<el-icon><Document /></el-icon>派发质检工单
</el-button>
</span>
</el-tooltip>
<el-button
v-if="cardMeta.allowSampleReception"
class="btn-op-item"
@click="emit('open-sample-reception', row)"
>
<el-icon><EditPen /></el-icon>样本接收信息填写
</el-button>
<el-button
v-if="!isMineMode && showCardDispatchComplete && canComplete(row)"
class="btn-op-item"
@click="emit('complete', row)"
>
<el-icon><Check /></el-icon>完成工单
</el-button>
<el-dropdown
v-if="!isMineMode && hasMoreActions(row)"
trigger="hover"
@command="(cmd) => emit('command', cmd, row)"
>
<el-button class="btn-op-item">
<el-icon><More /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="canDispatchTask(row)" command="view">
<el-icon><View /></el-icon>查看
</el-dropdown-item>
<el-dropdown-item v-if="canEditWorkOrder(row)" command="edit">
<el-icon><EditPen /></el-icon>编辑
</el-dropdown-item>
<el-dropdown-item v-if="canDeleteWorkOrder(row)" command="delete" divided>
<el-icon><Delete /></el-icon>删除
</el-dropdown-item>
</el-dropdown-menu>
<dt>{{ field.label }}</dt>
<dd>
<el-tag
v-if="field.kind === 'tag'"
:type="field.getTagType?.(row) || 'info'"
size="small"
>
{{ field.getValue(row) }}
</el-tag>
<template v-else>{{ field.getValue(row) }}</template>
</dd>
</div>
</template>
</el-dropdown>
</div>
</dl>
<section v-if="cardMeta.showCellProducts" class="production-work-order-card__cells">
<div v-if="cellProducts(row).length" class="production-work-order-card__cell-list">
<div
v-for="(product, pi) in cellProducts(row)"
:key="`${product.projectCode || product.projectName || pi}`"
class="production-work-order-card__cell-item"
>
<dl class="production-work-order-card__cell-fields">
<div class="production-work-order-card__cell-field">
<dt>项目编码</dt>
<dd>{{ product.projectCode || '—' }}</dd>
</div>
<div class="production-work-order-card__cell-field">
<dt>项目名称</dt>
<dd>{{ product.projectName || '—' }}</dd>
</div>
<div class="production-work-order-card__cell-field">
<dt>细胞类型</dt>
<dd>{{ product.cellTypeName || row.cellType || '—' }}</dd>
</div>
<div class="production-work-order-card__cell-field">
<dt>规格</dt>
<dd>{{ product.specText || row.specText || '—' }}</dd>
</div>
<div class="production-work-order-card__cell-field">
<dt>数量</dt>
<dd>{{ product.quantity != null ? product.quantity : '—' }}</dd>
</div>
<div class="production-work-order-card__cell-field">
<dt>产品状态</dt>
<dd>
<el-tag
v-if="product.productStatus"
:type="productStatusTagType(product.productStatus) as TagType"
size="small"
>
{{ productStatusLabel(product.productStatus, row.bizType || '') }}
</el-tag>
<span v-else>—</span>
</dd>
</div>
</dl>
</div>
</div>
<p v-else class="production-work-order-card__cells-fallback">
<template v-if="row.cellType || row.specText">
<span v-if="row.cellType">细胞类型:{{ row.cellType }}</span>
<span v-if="row.cellType && row.specText"> · </span>
<span v-if="row.specText">规格:{{ row.specText }}</span>
</template>
<template v-else>暂无细胞产品明细</template>
</p>
</section>
</div>
</header>
<QcWorkOrderProtocolPaymentPanel
@@ -168,9 +221,11 @@
import { computed } from 'vue'
import { View, Position, Document, Check, More, EditPen, Delete } from '@element-plus/icons-vue'
import type { ProductionWorkOrderItem } from '@/api/production-work-order'
import type { OutboundQcDetailProduct } from '@/api/qc-work-order'
import type { ProductionWorkOrderCardMetaConfig } from '@/utils/production-work-order-card-meta'
import { getCardMetaConfigForLegacyTab } from '@/utils/production-work-order-card-meta'
import type { TagType } from '@/utils/status-tag-registry'
import { productStatusLabel, productStatusTagType } from '@/utils/status-tag-registry'
import WorkOrderTaskSubList from './WorkOrderTaskSubList.vue'
import QcWorkOrderFeeSummaryBar from '@/views/quality-inspection/qc-work-order/QcWorkOrderFeeSummaryBar.vue'
import QcWorkOrderProtocolPaymentPanel from '@/views/quality-inspection/qc-work-order/QcWorkOrderProtocolPaymentPanel.vue'
@@ -238,6 +293,10 @@
return cardMeta.value.showOutboundFeeSummary && !!row.feeSummary
}
function cellProducts(row: ProductionWorkOrderItem): OutboundQcDetailProduct[] {
return row.products?.length ? row.products : []
}
function productionWoStatusTag(status: string): { label: string; type: TagType } {
const map: Record<string, { label: string; type: TagType }> = {
dpz: { label: '待配置', type: 'info' },
@@ -351,23 +410,27 @@
.production-work-order-card__head-body {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: 12px 20px;
padding: 14px 16px;
flex-direction: column;
gap: 12px;
padding: 12px 16px;
border-bottom: 1px solid #e2e8f0;
}
.production-work-order-card__head-main {
flex: 1;
min-width: 280px;
}
.production-work-order-card__title-row {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 8px 12px;
}
.production-work-order-card__title-left {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
flex: 1;
min-width: 0;
}
.production-work-order-card__checkbox {
@@ -423,14 +486,76 @@
}
}
.production-work-order-card__cells {
padding: 0;
}
.production-work-order-card__cell-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.production-work-order-card__cell-item {
&:not(:last-child) {
margin-bottom: 8px;
}
}
.production-work-order-card__cell-fields {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px 12px;
margin: 0;
}
.production-work-order-card__cell-field {
display: inline-flex;
align-items: center;
gap: 6px;
min-width: 0;
max-width: 100%;
dt {
flex-shrink: 0;
margin: 0;
font-size: 11px;
font-weight: 500;
color: #b91c1c;
line-height: 1.4;
white-space: nowrap;
&::after {
content: ':';
}
}
dd {
margin: 0;
font-size: 13px;
font-weight: 600;
color: #dc2626;
line-height: 1.4;
word-break: break-word;
}
}
.production-work-order-card__cells-fallback {
margin: 0;
font-size: 13px;
color: #dc2626;
line-height: 1.5;
}
.production-work-order-card__ops {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
gap: 8px;
gap: 6px;
flex-shrink: 0;
align-self: flex-end;
margin-left: auto;
}
:deep(.production-work-order-card__fee-in-head) {
@@ -42,6 +42,76 @@
</div>
</template>
</dl>
<section
v-if="showCellProductSection(row)"
class="qc-work-order-card__cells"
>
<template v-if="isScheduleTrigger(row)">
<div v-if="scheduleCellProducts(row).length" class="qc-work-order-card__cell-list">
<div
v-for="(product, pi) in scheduleCellProducts(row)"
:key="`${product.projectCode || product.projectName || pi}`"
class="qc-work-order-card__cell-item"
>
<dl class="qc-work-order-card__cell-fields">
<div class="qc-work-order-card__cell-field">
<dt>项目编码</dt>
<dd>{{ product.projectCode || '—' }}</dd>
</div>
<div class="qc-work-order-card__cell-field">
<dt>项目名称</dt>
<dd>{{ product.projectName || '—' }}</dd>
</div>
<div class="qc-work-order-card__cell-field">
<dt>细胞类型</dt>
<dd>{{ product.cellTypeName || row.cellType || '—' }}</dd>
</div>
<div class="qc-work-order-card__cell-field">
<dt>规格</dt>
<dd>{{ product.specText || row.specText || '—' }}</dd>
</div>
<div class="qc-work-order-card__cell-field">
<dt>数量</dt>
<dd>{{ product.quantity != null ? product.quantity : '—' }}</dd>
</div>
<div class="qc-work-order-card__cell-field">
<dt>产品状态</dt>
<dd>
<el-tag
v-if="product.productStatus"
:type="productStatusTagType(product.productStatus) as TagType"
size="small"
>
{{ productStatusLabel(product.productStatus, row.bizType || '') }}
</el-tag>
<span v-else>—</span>
</dd>
</div>
</dl>
</div>
</div>
<p v-else class="qc-work-order-card__cells-fallback">
<template v-if="row.cellType || row.specText">
<span v-if="row.cellType">细胞类型:{{ row.cellType }}</span>
<span v-if="row.cellType && row.specText"> · </span>
<span v-if="row.specText">规格:{{ row.specText }}</span>
</template>
<template v-else>暂无细胞产品明细</template>
</p>
</template>
<template v-else-if="isProductionTrigger(row)">
<dl class="qc-work-order-card__cell-fields">
<div
v-for="field in productionCellProductFields(row)"
:key="field.label"
class="qc-work-order-card__cell-field"
>
<dt>{{ field.label }}</dt>
<dd>{{ field.value }}</dd>
</div>
</dl>
</template>
</section>
</div>
<div
v-if="showWorkOrderOps || showWorkOrderViewOnly"
@@ -122,10 +192,11 @@
<script setup lang="ts">
import { computed } from 'vue'
import { Setting, View, More, EditPen, Delete } from '@element-plus/icons-vue'
import type { QcWorkOrder } from '@/api/qc-work-order'
import type { QcWorkOrder, OutboundQcDetailProduct } from '@/api/qc-work-order'
import type { QcTask } from '@/api/qc-task'
import { workOrderStatusLabel } from '@/utils/qc-labels'
import type { TagType } from '@/utils/status-tag-registry'
import { productStatusLabel, productStatusTagType } from '@/utils/status-tag-registry'
import type { QcWorkOrderCardMetaConfig } from '@/utils/qc-work-order-card-meta'
import { triggerSourceTabLabel, temporaryQcSourceLabel, temporaryQcSourceTagType } from '@/utils/qc-work-order-groups'
import QcWorkOrderTaskSubList from './QcWorkOrderTaskSubList.vue'
@@ -181,6 +252,35 @@
return 'success'
}
function showCellProductSection(row: QcWorkOrder) {
if (!props.cardMetaConfig.showCellProducts) return false
const ts = row.triggerSource || ''
return ts === 'schedule' || ts === 'production'
}
function isScheduleTrigger(row: QcWorkOrder) {
return (row.triggerSource || '') === 'schedule'
}
function isProductionTrigger(row: QcWorkOrder) {
return row.triggerSource === 'production'
}
function scheduleCellProducts(row: QcWorkOrder): OutboundQcDetailProduct[] {
return row.products?.length ? row.products : []
}
function productionCellProductFields(row: QcWorkOrder) {
const val = (v?: string | null) => String(v || '').trim() || '—'
return [
{ label: '产品编码', value: val(row.cellProductCode) },
{ label: '产品名称', value: val(row.cellProductName) },
{ label: '产品类型', value: val(row.cellProductTypeName) },
{ label: '代次', value: val(row.cellProductPassage) },
{ label: '规格', value: val(row.cellProductSpecName) }
]
}
function resolveTriggerTagLabel(row: QcWorkOrder) {
if (props.cardMetaConfig.tabKey === 'temporary') {
return temporaryQcSourceLabel(row)
@@ -325,6 +425,69 @@
}
}
.qc-work-order-card__cells {
margin-top: 10px;
padding: 0;
}
.qc-work-order-card__cell-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.qc-work-order-card__cell-item {
&:not(:last-child) {
margin-bottom: 8px;
}
}
.qc-work-order-card__cell-fields {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px 12px;
margin: 0;
}
.qc-work-order-card__cell-field {
display: inline-flex;
align-items: center;
gap: 6px;
min-width: 0;
max-width: 100%;
dt {
flex-shrink: 0;
margin: 0;
font-size: 11px;
font-weight: 500;
color: #b91c1c;
line-height: 1.4;
white-space: nowrap;
&::after {
content: ':';
}
}
dd {
margin: 0;
font-size: 13px;
font-weight: 600;
color: #dc2626;
line-height: 1.4;
word-break: break-word;
}
}
.qc-work-order-card__cells-fallback {
margin: 0;
font-size: 13px;
color: #dc2626;
line-height: 1.5;
}
:deep(.qc-work-order-card__fee-in-head) {
align-self: stretch;
width: calc(100% + 32px);