|
|
@@ -0,0 +1,206 @@
|
|
|
+<!-- 生产管理 — 入库生产工单 -->
|
|
|
+<!-- eslint-disable vue/no-v-model-argument -->
|
|
|
+<template>
|
|
|
+ <div class="page-container">
|
|
|
+ <header class="page-head">
|
|
|
+ <h1>入库生产工单</h1>
|
|
|
+ <p class="page-desc">入库生产工单管理,查看工单详情并完成待配置工单。</p>
|
|
|
+ </header>
|
|
|
+
|
|
|
+ <section class="panel">
|
|
|
+ <div class="panel-top">
|
|
|
+ <h2 class="title-bar-heading">工单列表</h2>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="filter-block">
|
|
|
+ <el-form :model="searchForm" class="filter-form" @submit.prevent>
|
|
|
+ <div class="filter-grid">
|
|
|
+ <el-form-item label="工单号">
|
|
|
+ <el-input v-model="searchForm.keyword" placeholder="请输入工单号" clearable />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="工单状态">
|
|
|
+ <el-select v-model="searchForm.workOrderStatus" placeholder="全部" clearable style="width: 100%">
|
|
|
+ <el-option label="待配置" value="dpz" />
|
|
|
+ <el-option label="已完成" value="ywc" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ <div class="filter-actions-row">
|
|
|
+ <div class="filter-actions-end">
|
|
|
+ <el-button class="btn-ghost" @click="handleReset"><el-icon><RefreshLeft /></el-icon>重置</el-button>
|
|
|
+ <el-button class="btn-main" type="primary" @click="handleSearch"><el-icon><Search /></el-icon>搜索</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="list-body list-wrap">
|
|
|
+ <el-table class="list-table" :data="tableData" v-loading="loading" stripe @row-dblclick="handleView">
|
|
|
+ <el-table-column type="index" label="序号" width="68" align="center" :index="(i) => (pagination.page - 1) * pagination.pageSize + i + 1" />
|
|
|
+ <el-table-column prop="workOrderNo" label="工单号" min-width="150" align="center" />
|
|
|
+ <el-table-column prop="protocolNo" label="协议号" min-width="140" align="center" />
|
|
|
+ <el-table-column prop="sampleCode" label="样本编码" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="receptionSource" label="来源类型" width="110" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tag :type="sourceTag(row.receptionSource).type" size="small">
|
|
|
+ {{ row.receptionSourceLabel || sourceTag(row.receptionSource).label }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="workOrderStatus" label="工单状态" width="100" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tag :type="woStatusTag(row.workOrderStatus).type" size="small">
|
|
|
+ {{ woStatusTag(row.workOrderStatus).label }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="createTime" label="创建时间" min-width="170" align="center" />
|
|
|
+ <el-table-column label="操作" width="280" fixed="right" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button class="btn-op-item" @click="handleView(row)"><el-icon><View /></el-icon>查看详情</el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="row.workOrderStatus === 'dpz'"
|
|
|
+ class="btn-op-item primary"
|
|
|
+ @click="handleComplete(row)"
|
|
|
+ >
|
|
|
+ <el-icon><Check /></el-icon>完成工单
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div class="pagination list-pager-bar">
|
|
|
+ <el-pagination
|
|
|
+ :current-page="pagination.page"
|
|
|
+ :page-size="pagination.pageSize"
|
|
|
+ :total="pagination.total"
|
|
|
+ layout="total, sizes, prev, pager, next"
|
|
|
+ @size-change="(v) => ((pagination.page = 1), (pagination.pageSize = v), loadData())"
|
|
|
+ @current-change="(v) => ((pagination.page = v), loadData())"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <SystemViewDialog
|
|
|
+ v-model:visible="viewVisible"
|
|
|
+ title="工单详情"
|
|
|
+ :icon="Document"
|
|
|
+ :meta="detail?.workOrderNo || ''"
|
|
|
+ :sections="viewSections"
|
|
|
+ />
|
|
|
+ </section>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+ import { ref, reactive, computed, onMounted } from 'vue'
|
|
|
+ import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+ import { Search, RefreshLeft, View, Check, Document } from '@element-plus/icons-vue'
|
|
|
+ import {
|
|
|
+ fetchProductionWorkOrderList,
|
|
|
+ fetchProductionWorkOrderDetail,
|
|
|
+ fetchCompleteProductionWorkOrder
|
|
|
+ } from '@/api/production-work-order'
|
|
|
+ import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
|
|
|
+ import type { ViewSection } from '@/components/business/system-view-dialog/index.vue'
|
|
|
+
|
|
|
+ defineOptions({ name: 'ProductionProductionWorkOrder' })
|
|
|
+
|
|
|
+ /* ---- 标签映射 ---- */
|
|
|
+ const woStatusTag = (status: string) => {
|
|
|
+ const map: Record<string, { label: string; type: string }> = {
|
|
|
+ dpz: { label: '待配置', type: 'info' },
|
|
|
+ ywc: { label: '已完成', type: 'success' }
|
|
|
+ }
|
|
|
+ return map[status] || { label: status, type: 'info' }
|
|
|
+ }
|
|
|
+
|
|
|
+ const sourceTag = (source: string) => {
|
|
|
+ const map: Record<string, { label: string; type: string }> = {
|
|
|
+ cell_storage: { label: '细胞存储', type: 'success' },
|
|
|
+ research_donation: { label: '科研捐赠', type: 'primary' }
|
|
|
+ }
|
|
|
+ return map[source] || { label: source, type: 'info' }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ---- 搜索 & 列表 ---- */
|
|
|
+ const searchForm = reactive({ keyword: '', workOrderStatus: '' })
|
|
|
+ const tableData = ref<any[]>([])
|
|
|
+ const loading = ref(false)
|
|
|
+ const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
|
|
|
+
|
|
|
+ async function loadData() {
|
|
|
+ loading.value = true
|
|
|
+ try {
|
|
|
+ const res = await fetchProductionWorkOrderList({
|
|
|
+ page: pagination.page,
|
|
|
+ pageSize: pagination.pageSize,
|
|
|
+ keyword: searchForm.keyword || undefined,
|
|
|
+ workOrderStatus: searchForm.workOrderStatus || undefined
|
|
|
+ })
|
|
|
+ tableData.value = res.list || []
|
|
|
+ pagination.total = res.total ?? 0
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleSearch() {
|
|
|
+ pagination.page = 1
|
|
|
+ loadData()
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleReset() {
|
|
|
+ searchForm.keyword = ''
|
|
|
+ searchForm.workOrderStatus = ''
|
|
|
+ pagination.page = 1
|
|
|
+ loadData()
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ---- 查看详情 ---- */
|
|
|
+ const viewVisible = ref(false)
|
|
|
+ const detail = ref<any>(null)
|
|
|
+
|
|
|
+ const viewSections = computed<ViewSection[]>(() => {
|
|
|
+ if (!detail.value) return []
|
|
|
+ const d = detail.value
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ title: '基本信息',
|
|
|
+ fields: [
|
|
|
+ { label: '工单号', value: d.workOrderNo },
|
|
|
+ { label: '协议号', value: d.protocolNo },
|
|
|
+ { label: '样本编码', value: d.sampleCode },
|
|
|
+ {
|
|
|
+ label: '来源类型',
|
|
|
+ value: sourceTag(d.receptionSource).label,
|
|
|
+ tagType: sourceTag(d.receptionSource).type as any
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '工单状态',
|
|
|
+ value: woStatusTag(d.workOrderStatus).label,
|
|
|
+ tagType: woStatusTag(d.workOrderStatus).type as any
|
|
|
+ },
|
|
|
+ { label: '创建时间', value: d.createTime || '—' },
|
|
|
+ { label: '备注', value: d.remark || '—', span: true }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+
|
|
|
+ async function handleView(row: any) {
|
|
|
+ detail.value = await fetchProductionWorkOrderDetail(row.id)
|
|
|
+ viewVisible.value = true
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ---- 完成工单 ---- */
|
|
|
+ async function handleComplete(row: any) {
|
|
|
+ await ElMessageBox.confirm('确定要完成该工单吗?', '提示', { type: 'warning' })
|
|
|
+ await fetchCompleteProductionWorkOrder(row.id, {})
|
|
|
+ ElMessage.success('工单已完成')
|
|
|
+ loadData()
|
|
|
+ }
|
|
|
+
|
|
|
+ onMounted(() => loadData())
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss"></style>
|