For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 在现有质检工单页面新增"出库质检工单"Tab,展示由中试服务申请单/输注计划触发的出库质检工单,支持查看(含完整申请单+输注计划信息)、编辑备注、配置检测。
Architecture: 前端在 qc-work-order/index.vue 中新增第 4 个 Tab outbound,复用列表骨架、配置检测、编辑备注逻辑,新建独立查看对话框组件 OutboundQcViewDialog.vue。后端新增聚合查询 API,扩展现有列表 API 返回字段,并在输注计划取消时自动作废关联质检工单。
Tech Stack: Vue 3 + Element Plus (前端) / FastAPI + SQLAlchemy + Pydantic v2 (后端) / MySQL 5.7
设计文档: docs/superpowers/specs/2026-05-26-outbound-qc-work-order-design.md
Files:
docs/sql/2026-05-26-qc-work-order-add-biz-type.sqlModify: backend/app/models/models.py:1239 (在 infusion_schedule_id 后新增字段)
[ ] Step 1: 创建 SQL 迁移文件
-- 出库质检工单:新增 biz_type 字段
ALTER TABLE biz_qc_work_order
ADD COLUMN biz_type VARCHAR(20) NULL COMMENT '业务类型: pilot_service=中试服务, clinical_application=临床应用' AFTER infusion_schedule_id;
在 backend/app/models/models.py 的 BizQcWorkOrder 类中,在 infusion_schedule_id 字段之后添加:
biz_type = Column(String(20), nullable=True, comment="业务类型: pilot_service=中试服务, clinical_application=临床应用")
在 MySQL 客户端中执行迁移 SQL。
git add docs/sql/2026-05-26-qc-work-order-add-biz-type.sql backend/app/models/models.py
git commit -m "feat(qc): add biz_type column to qc_work_order table for outbound business type"
Files:
backend/app/crud/qc_work_order.py (扩展列表查询和 _row_to_dict)backend/app/schemas/qc_work_order.py (无改动,schema 跟随 _row_to_dict)参考文件(只读):
backend/app/crud/qc_work_order.py — 搜索 _row_to_dict 函数和 list_work_orders 函数backend/app/models/models.py — 搜索 BizPilotInfusionSchedule、BizPilotInfusionPlan、BizPilotApplication 模型
[ ] Step 1: 修改 list_work_orders() 函数,支持 outbound 类型的 JOIN 查询和 bizType 筛选参数
在 backend/app/crud/qc_work_order.py 中:
list_work_orders() 函数(查询质检工单列表)biz_type: Optional[str] = Nonework_order_type == 'outbound' 时,LEFT JOIN 以下链路获取关联数据:
biz_qc_work_order.infusion_schedule_id → biz_pilot_infusion_schedulebiz_pilot_infusion_schedule.infusion_plan_id → biz_pilot_infusion_planbiz_pilot_infusion_plan.pilot_application_id → biz_pilot_applicationbiz_type 筛选(当参数非空时)_row_to_dict() 函数,为 outbound 类型返回额外字段在 _row_to_dict() 函数中,当工单的 work_order_type == 'outbound' 时,额外返回:
# outbound 工单额外字段
'bizType': row.biz_type, # 业务类型
'bizTypeLabel': '中试服务' if row.biz_type == 'pilot_service' else ('临床应用' if row.biz_type == 'clinical_application' else ''),
'applicationNo': application_no if outbound else None, # 申请单号
'applicationName': application_name if outbound else None, # 申请单名称
'channelName': channel_name if outbound else None, # 渠道名称
'infusionTime': infusion_time if outbound else None, # 输注时间
这些字段从 JOIN 查询结果中获取。
在 backend/app/api/qc.py 的工单列表端点中,从 request.args 或 Pydantic 查询模型中接收 bizType 参数,传递给 list_work_orders()。
create_outbound_qc_work_order() 写入 biz_type在 create_outbound_qc_work_order() 函数中,创建工单时设置 biz_type = 'pilot_service'(当前场景均为中试服务)。
git add backend/app/crud/qc_work_order.py backend/app/api/qc.py
git commit -m "feat(qc): extend outbound work order list API with application/infusion fields and bizType filter"
Files:
backend/app/api/qc.py (新增路由)backend/app/crud/qc_work_order.py (新增查询函数)backend/app/schemas/qc_work_order.py (新增返回 Schema)参考文件(只读):
backend/app/crud/qc_work_order.py — 搜索 get_work_order_detail 了解现有详情查询模式backend/app/crud/pilot_application.py — 搜索申请单/方案/计划的查询模式backend/app/models/models.py — 搜索 BizPilotPatient、BizPilotInfusionScheduleProduct 模型
[ ] Step 1: 在 schemas/qc_work_order.py 中新增出库详情返回 Schema
class OutboundQcDetailApplication(BaseModel):
"""出库质检查看 - 申请单信息"""
model_config = ConfigDict(populate_by_name=True)
application_no: Optional[str] = Field(None, alias="applicationNo")
application_name: Optional[str] = Field(None, alias="applicationName")
application_status: Optional[str] = Field(None, alias="applicationStatus")
channel_name: Optional[str] = Field(None, alias="channelName")
class OutboundQcDetailPatient(BaseModel):
"""出库质检查看 - 患者信息"""
model_config = ConfigDict(populate_by_name=True)
patient_name: Optional[str] = Field(None, alias="patientName")
sex: Optional[str] = Field(None)
age: Optional[str] = Field(None)
phone_no: Optional[str] = Field(None, alias="phoneNo")
id_card_no: Optional[str] = Field(None, alias="idCardNo")
emergency_contact: Optional[str] = Field(None, alias="emergencyContact")
emergency_phone: Optional[str] = Field(None, alias="emergencyPhone")
clinical_diagnosis: Optional[str] = Field(None, alias="clinicalDiagnosis")
diagnosis_attachments: Optional[str] = Field(None, alias="diagnosisAttachments")
class OutboundQcDetailInfusionPlan(BaseModel):
"""出库质检查看 - 输注方案信息"""
model_config = ConfigDict(populate_by_name=True)
cell_type: Optional[str] = Field(None, alias="cellType")
spec_text: Optional[str] = Field(None, alias="specText")
total_course_count: Optional[int] = Field(None, alias="totalCourseCount")
course_interval: Optional[str] = Field(None, alias="courseInterval")
infusion_route: Optional[str] = Field(None, alias="infusionRoute")
infusion_start_date: Optional[str] = Field(None, alias="infusionStartDate")
class OutboundQcDetailInfusionSchedule(BaseModel):
"""出库质检查看 - 输注计划信息"""
model_config = ConfigDict(populate_by_name=True)
infusion_time: Optional[str] = Field(None, alias="infusionTime")
infusion_location: Optional[str] = Field(None, alias="infusionLocation")
infusion_method: Optional[str] = Field(None, alias="infusionMethod")
schedule_status: Optional[str] = Field(None, alias="scheduleStatus")
infusion_status: Optional[str] = Field(None, alias="infusionStatus")
qc_status: Optional[str] = Field(None, alias="qcStatus")
cancel_reason: Optional[str] = Field(None, alias="cancelReason")
class OutboundQcDetailProduct(BaseModel):
"""出库质检查看 - 产品明细"""
model_config = ConfigDict(populate_by_name=True)
project_code: Optional[str] = Field(None, alias="projectCode")
project_name: Optional[str] = Field(None, alias="projectName")
cell_type_name: Optional[str] = Field(None, alias="cellTypeName")
spec_text: Optional[str] = Field(None, alias="specText")
agreement_price: Optional[float] = Field(None, alias="agreementPrice")
actual_price: Optional[float] = Field(None, alias="actualPrice")
quantity: Optional[int] = Field(None)
product_status: Optional[str] = Field(None, alias="productStatus")
class OutboundQcDetailResponse(BaseModel):
"""出库质检聚合详情"""
model_config = ConfigDict(populate_by_name=True)
work_order: Optional[dict] = Field(None, alias="workOrder")
application: Optional[OutboundQcDetailApplication] = Field(None, alias="application")
patient: Optional[OutboundQcDetailPatient] = Field(None, alias="patient")
infusion_plan: Optional[OutboundQcDetailInfusionPlan] = Field(None, alias="infusionPlan")
infusion_schedule: Optional[OutboundQcDetailInfusionSchedule] = Field(None, alias="infusionSchedule")
products: Optional[list[OutboundQcDetailProduct]] = Field(None, alias="products")
tasks: Optional[list[dict]] = Field(None, alias="tasks")
crud/qc_work_order.py 中新增 get_outbound_qc_detail() 函数def get_outbound_qc_detail(db: Session, work_order_id: str, tenant_no: str) -> dict:
"""获取出库质检工单聚合详情(含申请单、患者、方案、计划、产品、任务)"""
# 1. 获取工单基本信息(复用现有 get_work_order_detail 或直接查询)
# 2. 通过 infusion_schedule_id JOIN 链路获取:
# - biz_pilot_infusion_schedule
# - biz_pilot_infusion_plan → biz_pilot_application → biz_pilot_patient
# - biz_pilot_infusion_schedule_product
# 3. 获取关联的质检任务(复用现有任务查询逻辑)
# 4. 组装返回 dict
实现时参考现有 get_work_order_detail() 的模式,通过 SQLAlchemy session 查询并组装字典返回。
api/qc.py 中新增路由@router.get("/qc-work-orders/{work_order_id}/outbound-detail")
def api_get_outbound_qc_detail(work_order_id: str, db: Session = Depends(get_db), current_user=Depends(require_auth)):
"""获取出库质检工单聚合详情"""
tenant_no = current_user["tenant_no"]
result = get_outbound_qc_detail(db, work_order_id, tenant_no)
return success(result)
启动后端服务,访问 /docs 确认新端点出现在 Swagger 文档中。
git add backend/app/schemas/qc_work_order.py backend/app/crud/qc_work_order.py backend/app/api/qc.py
git commit -m "feat(qc): add outbound QC work order aggregated detail API endpoint"
Files:
backend/app/crud/pilot_infusion_schedule_mgmt.py参考文件(只读):
backend/app/crud/pilot_infusion_schedule_mgmt.py — 搜索状态更新逻辑、update_status、取消相关代码backend/app/models/models.py — 搜索 BizQcWorkOrder 模型
[ ] Step 1: 找到输注计划取消/删除的状态更新入口
在 pilot_infusion_schedule_mgmt.py 中搜索输注计划状态变更为 yqx 的逻辑入口(通常在 update_status 或 cancel_schedule 函数中)。
在状态变更为 yqx 的逻辑之后,新增:
from app.models.models import BizQcWorkOrder
# 当输注计划被取消时,自动作废关联的未完成出库质检工单
pending_qc_orders = db.query(BizQcWorkOrder).filter(
BizQcWorkOrder.infusion_schedule_id == schedule_id,
BizQcWorkOrder.work_order_status.notin_(['ywc', 'yzf']),
BizQcWorkOrder.del_flag == 0
).all()
for order in pending_qc_orders:
order.work_order_status = 'yzf'
git add backend/app/crud/pilot_infusion_schedule_mgmt.py
git commit -m "feat(infusion): auto-void outbound QC work orders when infusion schedule is cancelled"
Files:
Modify: web-admin/src/api/qc-work-order.ts (新增类型和 API 函数)
[ ] Step 1: 在 QcWorkOrder 类型中新增 outbound 相关字段
在 QcWorkOrder 类型定义中新增:
bizType?: string
bizTypeLabel?: string
applicationNo?: string
applicationName?: string
channelName?: string
infusionTime?: string
同时,fetchQcWorkOrderList 的参数类型新增 bizType?: string:
export function fetchQcWorkOrderList(params?: {
page?: number
pageSize?: number
keyword?: string
workOrderStatus?: string
workOrderType?: string
bizType?: string
createTimeStart?: string
createTimeEnd?: string
}) {
export type OutboundQcDetailApplication = {
applicationNo?: string
applicationName?: string
applicationStatus?: string
channelName?: string
}
export type OutboundQcDetailPatient = {
patientName?: string
sex?: string
age?: string
phoneNo?: string
idCardNo?: string
emergencyContact?: string
emergencyPhone?: string
clinicalDiagnosis?: string
diagnosisAttachments?: string
}
export type OutboundQcDetailInfusionPlan = {
cellType?: string
specText?: string
totalCourseCount?: number
courseInterval?: string
infusionRoute?: string
infusionStartDate?: string
}
export type OutboundQcDetailInfusionSchedule = {
infusionTime?: string
infusionLocation?: string
infusionMethod?: string
scheduleStatus?: string
infusionStatus?: string
qcStatus?: string
cancelReason?: string
}
export type OutboundQcDetailProduct = {
projectCode?: string
projectName?: string
cellTypeName?: string
specText?: string
agreementPrice?: number
actualPrice?: number
quantity?: number
productStatus?: string
}
export type OutboundQcDetail = {
workOrder: QcWorkOrderDetail
application?: OutboundQcDetailApplication
patient?: OutboundQcDetailPatient
infusionPlan?: OutboundQcDetailInfusionPlan
infusionSchedule?: OutboundQcDetailInfusionSchedule
products?: OutboundQcDetailProduct[]
tasks?: QcWorkOrderDetail['tasks']
}
export function fetchOutboundQcDetail(id: string) {
return request.get<OutboundQcDetail>({
url: `/web/admin/qc-work-orders/${id}/outbound-detail`
})
}
git add web-admin/src/api/qc-work-order.ts
git commit -m "feat(qc): add outbound QC detail API types and fetch function"
Files:
Modify: web-admin/src/views/quality-inspection/qc-work-order/index.vue
[ ] Step 1: 扩展 Tab 类型定义和 el-tabs
在 <script setup> 中修改 WorkOrderTypeTab 类型:
type WorkOrderTypeTab = 'inbound' | 'temporary' | 'outbound' | 'all'
在模板的 <el-tabs> 中,在"临时质检工单"和"全部质检工单"之间新增:
<el-tab-pane label="出库质检工单" name="outbound" />
在 <script setup> 中新增:
const showOutboundCols = computed(() => activeTypeTab.value === 'outbound')
在筛选区域的 <div class="filter-grid"> 中,关键词输入框的 placeholder 需要根据 Tab 调整:
<el-input
v-model="searchForm.keyword"
:placeholder="
activeTypeTab === 'temporary'
? '工单号'
: activeTypeTab === 'outbound'
? '工单号/申请单号/申请单名称'
: '工单号/协议号/样本编码'
"
clearable
/>
在工单状态 el-select 之后,新增业务类型筛选(仅 outbound Tab 显示):
<el-form-item v-if="activeTypeTab === 'outbound'" label="业务类型">
<el-select
v-model="searchForm.bizType"
placeholder="全部"
clearable
style="width: 100%"
>
<el-option label="中试服务" value="pilot_service" />
<el-option label="临床应用" value="clinical_application" />
</el-select>
</el-form-item>
同时在 searchForm reactive 中新增 bizType: ''。
在 <div v-if="activeTypeTab !== 'all'" class="list-toolbar"> 中,新增 outbound 的排除:
<div v-if="activeTypeTab !== 'all' && activeTypeTab !== 'outbound'" class="list-toolbar">
在表格中,在"工单号"列之后、"业务类型"列之前(或复用业务类型列位置),新增出库专属列。在 <el-table-column prop="workOrderNo"...> 后面添加:
<!-- 出库质检专属列 -->
<el-table-column
v-if="showOutboundCols"
prop="bizTypeLabel"
label="业务类型"
min-width="100"
align="center"
>
<template #default="{ row }">
<el-tag
:type="row.bizType === 'pilot_service' ? 'primary' : 'warning'"
size="small"
>
{{ row.bizTypeLabel || (row.bizType === 'pilot_service' ? '中试服务' : '临床应用') }}
</el-tag>
</template>
</el-table-column>
<el-table-column
v-if="showOutboundCols"
prop="applicationNo"
label="申请单号"
min-width="160"
align="center"
show-overflow-tooltip
/>
<el-table-column
v-if="showOutboundCols"
prop="applicationName"
label="申请单名称"
min-width="200"
align="center"
show-overflow-tooltip
/>
<el-table-column
v-if="showOutboundCols"
prop="channelName"
label="渠道名称"
min-width="140"
align="center"
show-overflow-tooltip
/>
<el-table-column
v-if="showOutboundCols"
prop="infusionTime"
label="输注时间"
min-width="160"
align="center"
/>
在状态列的 el-tag 中,tagType 计算需新增 yzf 分支:
<el-tag
:type="
row.workOrderStatus === 'ywc'
? 'success'
: row.workOrderStatus === 'ypz'
? 'warning'
: row.workOrderStatus === 'yzf'
? 'danger'
: 'info'
"
size="small"
>
在 workOrderStatusLabel 映射函数中确认已支持 yzf → 已作废(需检查 utils/qc-labels.ts 或 utils/status-tag-registry.ts,如缺失则新增)。
在操作列的 <template #default="{ row }"> 中:
查看按钮 — 所有 Tab 都显示(保持不变)
编辑按钮 — 出库 Tab 显示"编辑备注"按钮(与入库的编辑备注行为一致):
<!-- 出库质检编辑备注 -->
<el-button
v-if="activeTypeTab === 'outbound' && row.workOrderStatus !== 'ywc' && row.workOrderStatus !== 'yzf'"
class="btn-op-item"
@click="handleEditRemark(row)"
>
<el-icon><EditPen /></el-icon>编辑
</el-button>
配置检测按钮 — 保持现有逻辑(dpz/ypz 时显示),对 outbound 同样适用
删除按钮 — outbound Tab 不显示。将删除按钮的条件修改为:
<el-button
v-if="activeTypeTab !== 'outbound' && activeTypeTab !== 'all' && row.workOrderStatus !== 'ywc'"
class="btn-op-item"
@click="handleDelete(row)"
>删除</el-button>
loadData() 传递 bizType 参数在 loadData() 函数中,调用 fetchQcWorkOrderList 时新增 bizType 参数:
const res = await fetchQcWorkOrderList({
page: pagination.page,
pageSize: pagination.pageSize,
keyword: searchForm.keyword || undefined,
workOrderStatus: searchForm.workOrderStatus || undefined,
workOrderType: activeTypeTab.value === 'all' ? undefined : activeTypeTab.value,
bizType: searchForm.bizType || undefined,
createTimeStart: createTimeRange.value?.[0] || undefined,
createTimeEnd: createTimeRange.value?.[1] || undefined
})
git add web-admin/src/views/quality-inspection/qc-work-order/index.vue
git commit -m "feat(qc): add outbound QC work order tab with list, filters and action buttons"
Files:
web-admin/src/views/quality-inspection/qc-work-order/OutboundQcViewDialog.vueweb-admin/src/views/quality-inspection/qc-work-order/index.vue (引入并使用新组件)参考文件(只读,必须先读取理解模式):
web-admin/src/components/business/system-view-dialog/index.vue — SystemViewDialog 组件接口web-admin/src/views/quality-inspection/qc-work-order/index.vue:425-460 — 现有查看对话框的使用方式web-admin/src/views/quality-inspection/qc-work-order/index.vue:964-1020 — buildTaskTypeSections() 函数web-admin/src/components/business/protocol-attachment/ProtocolAttachmentReadonly.vue — 附件预览组件web-admin/src/utils/status-tag-registry.ts — 状态标签映射函数
[ ] Step 1: 创建 OutboundQcViewDialog.vue 基础骨架
<!-- 出库质检工单查看对话框 -->
<template>
<SystemViewDialog
v-model:visible="dialogVisible"
title="出库质检工单详情"
width="1200px"
:grid-columns="4"
compact
:loading="loading"
:icon="Document"
:meta="detail?.workOrder?.workOrderNo || ''"
:sections="sections"
>
<!-- 诊断附件 slot -->
<template #diagnosis-attachments>
<ProtocolAttachmentReadonly
:files="diagnosisAttachmentFiles"
@preview="handlePreview"
@download="handleDownload"
/>
</template>
<!-- 任务附件 slots -->
<template v-for="task in tasksWithAttachments" #[taskAttachmentSlotName(task.id)]>
<div :key="task.id" class="outbound-qc-task-attachments">
<ProtocolAttachmentReadonly
:files="task.attachmentFiles || []"
@preview="handleTaskPreview"
@download="handleTaskDownload"
/>
</div>
</template>
</SystemViewDialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Document } from '@element-plus/icons-vue'
import { fetchOutboundQcDetail, type OutboundQcDetail } from '@/api/qc-work-order'
import { fetchQcTaskResults, type QcTaskResultItem } from '@/api/qc-task-result'
import {
workOrderStatusLabel,
taskStatusLabel,
qcTaskConclusionLabel
} from '@/utils/qc-labels'
import {
scheduleStatusLabel,
scheduleStatusTagType,
infusionStatusLabel,
infusionStatusTagType,
qcStatusLabel,
qcStatusTagType,
applicationStatusLabel,
applicationStatusTagType,
bizTypeLabel,
bizTypeTagType
} from '@/utils/status-tag-registry'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import type { ViewField, ViewSection } from '@/components/business/system-view-dialog/index.vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import { formatMoneyDisplay } from '@/utils/money-format'
const props = defineProps<{
visible: boolean
workOrderId: string
}>()
const emit = defineEmits<{
(e: 'update:visible', v: boolean): void
}>()
const dialogVisible = computed({
get: () => props.visible,
set: (v) => emit('update:visible', v)
})
const loading = ref(false)
const detail = ref<OutboundQcDetail | null>(null)
type TaskWithResults = { id: string; taskNo: string; taskType: string; itemCode?: string; itemName?: string; taskStatus: string; conclusion?: string; conclusionLabel?: string; remark?: string; completedTime?: string; attachmentFiles?: Array<{ id?: string; fileUrl?: string; fileName?: string }>; results?: QcTaskResultItem[]; companyName?: string; feeAmount?: number }
const tasksWithResults = ref<TaskWithResults[]>([])
// ... 后续步骤中补充 sections 计算逻辑和附件处理
在 <script setup> 中实现完整的 sections computed,包含 7 个 Section 组:
products 数组(项目编码、名称、细胞类型、规格、协议单价、实际单价、份数、产品状态)buildTaskTypeSections 的逻辑生成实验室和第三方项目的详情注意:状态标签映射函数需确认
status-tag-registry.ts中是否存在。如scheduleStatusLabel、infusionStatusLabel、qcStatusLabel、applicationStatusLabel、bizTypeLabel等不存在,需在该文件中新增。
watch(() => props.visible, async (v) => {
if (!v || !props.workOrderId) return
loading.value = true
tasksWithResults.value = []
try {
const d = await fetchOutboundQcDetail(props.workOrderId)
detail.value = d
// 加载任务结果
const rawTasks = (d.workOrder?.tasks || []) as TaskWithResults[]
const enriched = await Promise.all(
rawTasks.map(async (task) => {
if (task.taskType !== 'sysz' || task.taskStatus !== 'ywc') {
return { ...task, results: [] as QcTaskResultItem[] }
}
try {
const results = await fetchQcTaskResults(task.id)
return { ...task, results: results || [] }
} catch {
return { ...task, results: [] as QcTaskResultItem[] }
}
})
)
tasksWithResults.value = enriched
} finally {
loading.value = false
}
})
实现 diagnosisAttachmentFiles computed(解析 patient.diagnosisAttachments 为文件数组)、handlePreview、handleDownload、handleTaskPreview、handleTaskDownload、taskAttachmentSlotName 等函数。参照现有 index.vue 中同名函数的模式。
git add web-admin/src/views/quality-inspection/qc-work-order/OutboundQcViewDialog.vue
git commit -m "feat(qc): create OutboundQcViewDialog component with full detail sections"
Files:
Modify: web-admin/src/views/quality-inspection/qc-work-order/index.vue
[ ] Step 1: 导入 OutboundQcViewDialog 组件
在 <script setup> 的 import 区域添加:
import OutboundQcViewDialog from './OutboundQcViewDialog.vue'
const outboundViewVisible = ref(false)
const outboundViewId = ref('')
function handleOutboundView(row: QcWorkOrder) {
outboundViewId.value = row.id
outboundViewVisible.value = true
}
修改现有的 handleView 函数,当 activeTypeTab === 'outbound' 时调用 handleOutboundView:
async function handleView(row: QcWorkOrder) {
if (activeTypeTab.value === 'outbound') {
handleOutboundView(row)
return
}
// ... 原有逻辑不变
}
在 </section> 结束标签之前(与 WorkOrderRemarkDialog 同级)添加:
<OutboundQcViewDialog
v-model:visible="outboundViewVisible"
:work-order-id="outboundViewId"
/>
git add web-admin/src/views/quality-inspection/qc-work-order/index.vue
git commit -m "feat(qc): integrate OutboundQcViewDialog into QC work order page"
Files:
Modify: web-admin/src/utils/status-tag-registry.ts (如需新增标签函数)
[ ] Step 1: 检查 status-tag-registry.ts 中是否已有以下映射函数
需要确认的函数:
scheduleStatusLabel / scheduleStatusTagType — 输注计划生产状态 (dsc/ysc/yjf/yqx)infusionStatusLabel / infusionStatusTagType — 输注状态 (dtz/yrqr/yqx/ywc)qcStatusLabel / qcStatusTagType — 质检状态 (dzc/yzj/yqx)applicationStatusLabel / applicationStatusTagType — 申请单状态 (dks/jxz/ywc/yzf)bizTypeLabel / bizTypeTagType — 业务类型 (pilot_service/clinical_application)productStatusLabel / productStatusTagType — 产品状态 (dtz/yrqr/yqx/ywc)如果已存在,跳过此 Task。如果不存在,新增对应的映射函数。
遵循文件中已有的映射函数模式(label 函数返回中文名,tagType 函数返回 TagType),为每个缺失的状态类型新增。
git add web-admin/src/utils/status-tag-registry.ts
git commit -m "feat(qc): add missing status label/tag mappings for outbound QC view dialog"
cd web-admin && pnpm lint
修复所有 lint 错误。
cd web-admin && pnpm lint:prettier
cd web-admin && pnpm build:typecheck
确保无类型错误。
cd web-admin && pnpm build
确保构建成功。
对修改过的后端文件运行 lsp_diagnostics 确认无错误。