refactor(wms/coil): 抽象排产单组件,复用排产单展示逻辑

1.  新增PlanSheetViewer通用排产单展示组件,支持图片、excel、普通文件预览和空状态
2.  改造TimeInput组件,修复绑定属性写法
3.  替换typing.vue、stepSplit.vue、split.vue、merge.vue中的旧排产单代码,统一使用新组件
4.  删除冗余的排产单相关API调用和本地数据逻辑
This commit is contained in:
2026-06-08 10:22:30 +08:00
parent 857a3948d6
commit f6a74e58ea
6 changed files with 207 additions and 357 deletions

View File

@@ -0,0 +1,162 @@
<template>
<div v-if="lineName">
<div v-if="planSheetList.length > 0">
<el-descriptions v-if="showHeader" :column="1" border :title="'最近排产单(' + lineName + ''" size="small" />
<el-tabs v-model="activePlanSheetId" type="card" size="mini">
<el-tab-pane
v-for="sheet in planSheetList"
:key="sheet.planSheetId"
:name="sheet.planSheetId"
:label="sheet.planCode || ('排产单' + sheet.planSheetId)"
/>
</el-tabs>
<div v-if="activePlanSheet" class="preview-container">
<div v-if="!activePlanSheet.apsUrl" class="no-file">
<el-empty description="暂无排产文件" :image-size="60" />
</div>
<div v-else class="preview-panel">
<div v-if="isImage" class="image-preview">
<div class="image-wrapper">
<el-image :src="activePlanSheet.apsUrl" fit="scale-down" :preview-src-list="[activePlanSheet.apsUrl]" />
</div>
</div>
<div v-else-if="isExcel" class="excel-preview">
<xlsx-preview :src="activePlanSheet.apsUrl" height="420px" />
</div>
<div v-else class="file-link">
<a :href="activePlanSheet.apsUrl" target="_blank">
<i class="el-icon-document"></i> {{ getFileName(activePlanSheet.apsUrl) }}
</a>
</div>
</div>
</div>
</div>
<div v-else-if="!loading && showHeader">
<el-descriptions :column="1" border :title="'最近排产单(' + lineName + ''" size="small" />
<el-empty description="今天暂无排产单" :image-size="60" />
</div>
</div>
</template>
<script>
import { listPlanSheet, getPlanSheet } from '@/api/aps/planSheet'
import XlsxPreview from '@/components/FilePreview/preview/xlsx/index.vue'
export default {
name: 'PlanSheetViewer',
components: {
XlsxPreview
},
props: {
lineName: {
type: String,
default: ''
},
showHeader: {
type: Boolean,
default: true
},
tableMaxHeight: {
type: [Number, String],
default: 300
}
},
data() {
return {
planSheetList: [],
planSheetMap: {},
loading: false,
activePlanSheetId: null
}
},
computed: {
activePlanSheet() {
return this.planSheetMap[this.activePlanSheetId] || null
},
isImage() {
const url = (this.activePlanSheet && this.activePlanSheet.apsUrl) || ''
return /\.(jpg|jpeg|png|gif|bmp|webp)(\?|$)/i.test(url)
},
isExcel() {
const url = (this.activePlanSheet && this.activePlanSheet.apsUrl) || ''
return /\.(xlsx|xls)(\?|$)/i.test(url)
}
},
watch: {
lineName: {
immediate: true,
handler(val) {
if (val) {
this.fetchPlanSheets()
}
}
}
},
methods: {
async fetchPlanSheets() {
this.loading = true
try {
const res = await listPlanSheet({
lineName: this.lineName,
pageSize: 3,
pageNum: 1
})
this.planSheetList = res.rows || []
this.planSheetMap = {}
if (this.planSheetList.length > 0) {
this.activePlanSheetId = this.planSheetList[0].planSheetId
for (const sheet of this.planSheetList) {
this.fetchPlanSheetInfo(sheet.planSheetId)
}
}
} catch (e) {
console.error('查询排产单失败', e)
} finally {
this.loading = false
}
},
async fetchPlanSheetInfo(planSheetId) {
try {
const res = await getPlanSheet(planSheetId)
this.$set(this.planSheetMap, planSheetId, res.data)
} catch (e) {
console.error('查询排产单详情失败', e)
}
},
getFileName(url) {
if (!url) return ''
const parts = url.split('/')
return parts[parts.length - 1] || '文件'
}
}
}
</script>
<style scoped>
.preview-container {
min-height: 200px;
}
.no-file {
padding: 20px 0;
}
.image-preview {
text-align: center;
}
.image-wrapper {
max-height: 600px;
max-width: 100%;
overflow: auto;
}
.image-wrapper /deep/ .el-image__inner {
max-height: 600px;
max-width: 100%;
}
.file-link a {
font-size: 14px;
color: #409eff;
text-decoration: none;
}
.file-link a:hover {
text-decoration: underline;
}
</style>