This commit is contained in:
zlwu committed 2026-05-24 09:34:01 +08:00
1 parent 07ed8c7a60
commit 2f350e7d73
15 files changed
+1693 -1654

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
# Graph Report - src (2026-05-23)
# Graph Report - src (2026-05-24)
## Corpus Check
- Large corpus: 595 files · ~325,194 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
@@ -28,61 +28,48 @@
</div>
</div>
</template>
<template #append>
<div
v-if="viewDetail?.taskType !== 'dsfjc'"
class="view-section qc-task-view-material-usages"
>
<h3>物料使用</h3>
<el-table
v-if="viewMaterialUsages.length"
:data="viewMaterialUsages"
stripe
class="list-table inner-table qc-task-view-material-table"
>
<el-table-column
type="index"
label="序号"
min-width="56"
align="center"
header-align="center"
:index="(index) => index + 1"
/>
<el-table-column
prop="materialName"
label="物料名称"
min-width="160"
align="center"
header-align="center"
/>
<el-table-column label="规格型号" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{ row.specModel || '—' }}</template>
</el-table-column>
<el-table-column label="用量" min-width="100" align="center" header-align="center">
<template #default="{ row }">
{{ row.qty != null && row.qty !== '' ? row.qty : '—' }}
</template>
</el-table-column>
<el-table-column label="单位" min-width="72" align="center" header-align="center">
<template #default="{ row }">{{ row.unit || '—' }}</template>
</el-table-column>
<el-table-column label="备注" min-width="140" align="center" header-align="center">
<template #default="{ row }">{{ row.remark || '—' }}</template>
</el-table-column>
</el-table>
<p v-else class="view-material-empty">暂无物料使用记录</p>
</div>
<div
v-if="viewDetail?.attachmentFiles?.length"
class="view-section qc-task-view-attachments"
>
<h3>{{ viewDetail?.taskType === 'dsfjc' ? '检测材料' : '检测附件' }}</h3>
<ProtocolAttachmentReadonly
:files="viewDetail.attachmentFiles"
@preview="handleAttachmentPreview"
@download="handleAttachmentDownload"
<template #material-usages>
<div v-if="viewMaterialUsages.length" class="view-subtable-wrap">
<el-table :data="viewMaterialUsages" stripe class="list-table view-subtable">
<el-table-column
type="index"
label="序号"
min-width="56"
align="center"
header-align="center"
:index="(index) => index + 1"
/>
<el-table-column
prop="materialName"
label="物料名称"
min-width="160"
align="center"
header-align="center"
/>
<el-table-column label="规格型号" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{ row.specModel || '—' }}</template>
</el-table-column>
<el-table-column label="用量" min-width="100" align="center" header-align="center">
<template #default="{ row }">
{{ row.qty != null && row.qty !== '' ? row.qty : '—' }}
</template>
</el-table-column>
<el-table-column label="单位" min-width="72" align="center" header-align="center">
<template #default="{ row }">{{ row.unit || '—' }}</template>
</el-table-column>
<el-table-column label="备注" min-width="140" align="center" header-align="center">
<template #default="{ row }">{{ row.remark || '—' }}</template>
</el-table-column>
</el-table>
</div>
<p v-else class="view-empty-hint">暂无物料使用记录</p>
</template>
<template #task-attachments>
<ProtocolAttachmentReadonly
:files="viewDetail?.attachmentFiles || []"
@preview="handleAttachmentPreview"
@download="handleAttachmentDownload"
/>
</template>
</SystemViewDialog>
</template>
@@ -262,8 +249,25 @@
if (r.etaTime) {
transportFields.push({ label: '预计到达', value: r.etaTime })
}
const resultSection =
d.results && d.results.length > 0
const taskResultSummaryFields: ViewSection['fields'] = [
{
label: '任务状态',
value: taskStatusLabel(d.taskStatus),
tagType: d.taskStatus === 'ywc' ? 'success' : d.taskStatus === 'jxz' ? 'warning' : 'info'
},
{
label: '检测结论',
value: d.conclusionLabel || qcTaskConclusionLabel(d.conclusion || '') || '—',
tagType: d.conclusion === 'tg' ? 'success' : d.conclusion === 'btg' ? 'danger' : 'info'
},
{ label: '备注', value: d.remark || '—' }
]
const resultSection: ViewSection[] = [
{
title: '质检结论',
fields: taskResultSummaryFields
},
...(d.results && d.results.length > 0
? [
{
title: '检测参数',
@@ -273,7 +277,19 @@
}))
}
]
: []
: [{ title: '检测参数', fields: [] }])
]
const tailSections: ViewSection[] = []
if (d.taskType !== 'dsfjc') {
tailSections.push({ title: '物料使用', fields: [], slot: 'material-usages' })
}
if (d.attachmentFiles?.length) {
tailSections.push({
title: d.taskType === 'dsfjc' ? '检测材料' : '检测附件',
fields: [],
slot: 'task-attachments'
})
}
return [
{
title: '任务信息',
@@ -290,19 +306,8 @@
{ label: '检测项目', value: d.itemName },
{ label: '项目编码', value: d.itemCode || '—' },
{ label: '第三方公司', value: d.companyName || '—' },
{
label: '任务状态',
value: taskStatusLabel(d.taskStatus),
tagType: d.taskStatus === 'ywc' ? 'success' : d.taskStatus === 'jxz' ? 'warning' : 'info'
},
{
label: '检测结论',
value: d.conclusionLabel || qcTaskConclusionLabel(d.conclusion || '') || '—',
tagType: d.conclusion === 'tg' ? 'success' : d.conclusion === 'btg' ? 'danger' : 'info'
},
{ label: '完成时间', value: d.completedTime || '—' },
{ label: '创建时间', value: d.createTime || '—' },
{ label: '备注', value: d.remark || '—', span: true }
{ label: '创建时间', value: d.createTime || '—' }
]
},
{
@@ -343,7 +348,8 @@
{ label: '备注', value: r.remark || '—', span: true }
]
},
...resultSection
...resultSection,
...tailSections
]
})
@@ -395,40 +401,4 @@
}
}
.qc-task-view-material-usages,
.qc-task-view-attachments {
padding: 12px 18px;
border-bottom: none;
h3 {
margin: 0 0 10px;
padding-left: 10px;
font-size: 13px;
font-weight: 600;
color: #1e293b;
border-left: 3px solid #10b981;
line-height: 1;
}
}
.qc-task-view-material-table {
width: 100%;
:deep(.el-table__header .cell),
:deep(.el-table__body .cell) {
font-size: 12px;
line-height: 1.4;
}
:deep(.el-table__header th.el-table__cell),
:deep(.el-table__body td.el-table__cell) {
padding: 6px 0;
}
}
.view-material-empty {
margin: 0;
font-size: 12px;
color: #64748b;
}
</style>
@@ -407,5 +407,62 @@
border-top: 1px solid #d9e8e2;
background: #f8fafc;
}
/* 区块标题:深色字 + 主色竖条(与 OpenSpec ui-conventions 一致,避免被全局 h3 染色) */
.view-section > h3 {
color: #1e293b;
font-weight: 600;
letter-spacing: normal;
text-transform: none;
}
/* 查看弹窗内嵌子表(对齐 fresh-mint §9.7 + OpenSpec 嵌套列表 14px) */
.view-section-slot .view-subtable-wrap {
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
}
.view-section-slot .view-subtable-wrap .el-table.view-subtable {
--el-table-header-bg-color: #f8fafc;
--el-table-header-text-color: #64748b;
--el-table-border-color: #e2e8f0;
width: 100%;
.el-table__header th.el-table__cell,
.el-table__body td.el-table__cell {
font-size: 14px;
padding: 8px 0;
}
.el-table__header th.el-table__cell .cell {
font-weight: 500;
color: #64748b;
}
.el-table__body td.el-table__cell .cell {
color: #1e293b;
}
}
.view-section-slot .view-empty-hint {
margin: 0;
font-size: 13px;
color: #64748b;
line-height: 1.5;
}
}
.system-view-dialog--compact {
.view-section-slot .view-subtable-wrap .el-table.view-subtable {
.el-table__header th.el-table__cell,
.el-table__body td.el-table__cell {
font-size: 13px;
}
}
.view-section-slot .view-empty-hint {
font-size: 12px;
}
}
</style>
@@ -11,7 +11,12 @@
@update:model-value="emit('update:modelValue', $event)"
@closed="handleClosed"
>
<div class="protocol-view-body" :class="{ 'is-detail-loading': detailLoading && !bundle }">
<div
class="protocol-view-body"
:class="{ 'is-detail-loading': detailLoading && !bundle }"
v-loading="detailLoading && !bundle"
element-loading-text="加载中…"
>
<div class="detail-tabs">
<div
v-for="tab in formTabs"
@@ -25,7 +30,7 @@
</div>
<template v-if="bundle">
<div v-loading="detailLoading && !bundle">
<div>
<!-- KPI 摘要条 -->
<div class="kpi-strip">
<div class="kpi-card">
@@ -891,19 +896,32 @@
</div>
</template>
<template v-else-if="step.key === 'receipt-finance'">
<!-- 财务确认 -->
<!-- 财务确认:jfqrz 为待财务确认,updateTime 为提交财务时间非确认时间 -->
<div class="flow-detail-card__kv">
<span class="flow-detail-card__label">确认状态</span>
<span class="flow-detail-card__value"
><el-tag type="success" size="small">已确认</el-tag></span
>
<span class="flow-detail-card__value">
<el-tag
v-if="isReceiptFinanceConfirmed(detail)"
type="success"
size="small"
>已确认</el-tag
>
<el-tag v-else type="warning" size="small">待确认</el-tag>
</span>
</div>
<div v-if="detail.updateTime" class="flow-detail-card__kv">
<div
v-if="isReceiptFinanceConfirmed(detail) && detail.updateTime"
class="flow-detail-card__kv"
>
<span class="flow-detail-card__label">确认时间</span>
<span class="flow-detail-card__value">{{ detail.updateTime }}</span>
</div>
<div
v-if="detail.financeRemark && String(detail.financeRemark).trim()"
v-if="
isReceiptFinanceConfirmed(detail) &&
detail.financeRemark &&
String(detail.financeRemark).trim()
"
class="flow-detail-card__kv"
>
<span class="flow-detail-card__label">财务备注</span>
@@ -912,7 +930,10 @@
}}</span>
</div>
<div
v-if="financeConfirmAttachmentFiles(detail).length"
v-if="
isReceiptFinanceConfirmed(detail) &&
financeConfirmAttachmentFiles(detail).length
"
class="flow-detail-card__kv"
>
<span class="flow-detail-card__label">财务附件</span>
@@ -1437,6 +1458,12 @@
return 'green'
}
/** 缴费明细是否已完成财务收款确认(jfqrz 仅已提交待财务处理) */
function isReceiptFinanceConfirmed(detail: Record<string, any>) {
const s = String(detail.payStatus || '')
return s !== 'jfqrz' && s !== 'dfj'
}
interface MiniFlowStep {
key: string
label: string
@@ -313,61 +313,48 @@
</div>
</div>
</template>
<template #append>
<div
v-if="viewDetail?.taskType !== 'dsfjc'"
class="view-section qc-task-view-material-usages"
>
<h3>物料使用</h3>
<el-table
v-if="viewMaterialUsages.length"
:data="viewMaterialUsages"
stripe
class="list-table inner-table qc-task-view-material-table"
>
<el-table-column
type="index"
label="序号"
min-width="56"
align="center"
header-align="center"
:index="(index) => index + 1"
/>
<el-table-column
prop="materialName"
label="物料名称"
min-width="160"
align="center"
header-align="center"
/>
<el-table-column label="规格型号" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{ row.specModel || '—' }}</template>
</el-table-column>
<el-table-column label="用量" min-width="100" align="center" header-align="center">
<template #default="{ row }">
{{ row.qty != null && row.qty !== '' ? row.qty : '—' }}
</template>
</el-table-column>
<el-table-column label="单位" min-width="72" align="center" header-align="center">
<template #default="{ row }">{{ row.unit || '—' }}</template>
</el-table-column>
<el-table-column label="备注" min-width="140" align="center" header-align="center">
<template #default="{ row }">{{ row.remark || '—' }}</template>
</el-table-column>
</el-table>
<p v-else class="view-material-empty">暂无物料使用记录</p>
</div>
<div
v-if="viewDetail?.attachmentFiles?.length"
class="view-section qc-task-view-attachments"
>
<h3>{{ viewDetail?.taskType === 'dsfjc' ? '检测材料' : '检测附件' }}</h3>
<ProtocolAttachmentReadonly
:files="viewDetail.attachmentFiles"
@preview="handleViewAttachmentPreview"
@download="handleViewAttachmentDownload"
<template #material-usages>
<div v-if="viewMaterialUsages.length" class="view-subtable-wrap">
<el-table :data="viewMaterialUsages" stripe class="list-table view-subtable">
<el-table-column
type="index"
label="序号"
min-width="56"
align="center"
header-align="center"
:index="(index) => index + 1"
/>
<el-table-column
prop="materialName"
label="物料名称"
min-width="160"
align="center"
header-align="center"
/>
<el-table-column label="规格型号" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{ row.specModel || '—' }}</template>
</el-table-column>
<el-table-column label="用量" min-width="100" align="center" header-align="center">
<template #default="{ row }">
{{ row.qty != null && row.qty !== '' ? row.qty : '—' }}
</template>
</el-table-column>
<el-table-column label="单位" min-width="72" align="center" header-align="center">
<template #default="{ row }">{{ row.unit || '—' }}</template>
</el-table-column>
<el-table-column label="备注" min-width="140" align="center" header-align="center">
<template #default="{ row }">{{ row.remark || '—' }}</template>
</el-table-column>
</el-table>
</div>
<p v-else class="view-empty-hint">暂无物料使用记录</p>
</template>
<template #task-attachments>
<ProtocolAttachmentReadonly
:files="viewDetail?.attachmentFiles || []"
@preview="handleViewAttachmentPreview"
@download="handleViewAttachmentDownload"
/>
</template>
</SystemViewDialog>
</section>
@@ -718,6 +705,17 @@
}
]
: []
const tailSections: ViewSection[] = []
if (d.taskType !== 'dsfjc') {
tailSections.push({ title: '物料使用', fields: [], slot: 'material-usages' })
}
if (d.attachmentFiles?.length) {
tailSections.push({
title: d.taskType === 'dsfjc' ? '检测材料' : '检测附件',
fields: [],
slot: 'task-attachments'
})
}
return [
{
title: '任务信息',
@@ -789,7 +787,8 @@
{ label: '备注', value: r.remark || '—', span: true }
]
},
...resultSection
...resultSection,
...tailSections
]
})
@@ -1086,32 +1085,6 @@
}
}
.qc-task-view-material-usages,
.qc-task-view-attachments {
padding: 18px 22px;
border-bottom: none;
h3 {
margin: 0 0 14px;
padding-left: 10px;
font-size: 14px;
font-weight: 600;
color: #1e293b;
border-left: 3px solid #10b981;
line-height: 1;
}
}
.qc-task-view-material-table {
width: 100%;
}
.view-material-empty {
margin: 0;
font-size: 13px;
color: #64748b;
}
.view-reception-attachments {
margin-top: 4px;
@@ -11,7 +11,12 @@
@update:model-value="emit('update:modelValue', $event)"
@closed="handleClosed"
>
<div class="donation-view-body" :class="{ 'is-detail-loading': loading && !bundle }">
<div
class="donation-view-body"
:class="{ 'is-detail-loading': loading && !bundle }"
v-loading="loading && !bundle"
element-loading-text="加载中…"
>
<div class="detail-tabs">
<div
v-for="tab in formTabs"
@@ -25,7 +30,7 @@
</div>
<template v-if="bundle">
<div v-loading="loading && !bundle">
<div>
<!-- KPI 摘要条 -->
<div class="kpi-strip">
<div class="kpi-card">
@@ -964,6 +969,8 @@
bundle.value = null
auditRecords.value = []
activeTab.value = 'basic'
loading.value = false
auditLoading.value = false
}
watch(