feat(aps): 优化排产页面与对比页面的工序类型展示和筛选功能
1. 为待审核、已排产卡片添加自定义加载提示文本 2. 替换工序类型输入框为下拉选择器,使用全局工序枚举数据 3. 为排产表格添加工序类型名称转换显示 4. 重构对比页面的工序筛选逻辑,改为顶部单选按钮组筛选 5. 优化钢卷数据查询逻辑,关联选中的工序类型进行查询 6. 修复编辑和合并表单的字段类型转换问题
This commit is contained in:
@@ -18,6 +18,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 工序选择 Tab(单选,影响右侧钢卷查询) -->
|
||||
<div class="process-tab-bar">
|
||||
<el-radio-group v-model="selectedProcessActionType" size="small" @change="onProcessChange">
|
||||
<el-radio-button
|
||||
v-for="p in processOptions"
|
||||
:key="p.actionType"
|
||||
:label="p.actionType"
|
||||
>{{ p.name }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="12" style="flex:1;min-height:0;">
|
||||
<!-- 左侧:排产明细(按工序筛选) -->
|
||||
<el-col :span="12" style="height:100%;display:flex;flex-direction:column;">
|
||||
@@ -28,17 +39,6 @@
|
||||
共 {{ scheduleList.length }} 条
|
||||
</span>
|
||||
</div>
|
||||
<!-- 工序筛选按钮 -->
|
||||
<div v-if="actionTypes.length > 0" class="action-filter-bar">
|
||||
<el-button
|
||||
v-for="at in actionTypes"
|
||||
:key="at"
|
||||
size="mini"
|
||||
:type="selectedActionType === at ? 'danger' : 'default'"
|
||||
@click="filterByActionType(at)"
|
||||
>{{ at || '(空)' }}</el-button>
|
||||
<el-button size="mini" :type="selectedActionType === '' ? 'danger' : ''" @click="filterByActionType('')">全部</el-button>
|
||||
</div>
|
||||
<div v-loading="schLoading" class="detail-card-body" style="padding:0;flex:1;overflow:auto;">
|
||||
<el-table
|
||||
v-if="filteredScheduleList.length > 0"
|
||||
@@ -71,7 +71,7 @@
|
||||
共 {{ coilTotal }} 条,净重合计 {{ coilTotalWeight }} 吨
|
||||
</span>
|
||||
</div>
|
||||
<div v-loading="coilLoading" class="detail-card-body" style="padding:0;flex:1;overflow:auto;">
|
||||
<div v-loading="coilLoading" element-loading-text="正在加载钢卷数据..." class="detail-card-body" style="padding:0;flex:1;overflow:auto;">
|
||||
<el-table
|
||||
v-if="coilList.length > 0"
|
||||
:data="coilList"
|
||||
@@ -105,6 +105,8 @@
|
||||
<script>
|
||||
import { listScheduleItem } from '@/api/aps/schedule'
|
||||
import { listMaterialCoil } from '@/api/aps/materialCoil'
|
||||
import { listLightPendingAction } from '@/api/wms/pendingAction'
|
||||
import { PROCESSES } from '@/utils/meta'
|
||||
|
||||
export default {
|
||||
name: 'ApsCompare',
|
||||
@@ -121,10 +123,12 @@ export default {
|
||||
// 左侧排产明细
|
||||
schLoading: false,
|
||||
scheduleList: [],
|
||||
actionTypes: [],
|
||||
selectedActionType: '',
|
||||
coilStatusMap: { 0: '在库', 1: '在途', 2: '已出库' },
|
||||
|
||||
// 工序筛选(顶部 radio tab)
|
||||
processOptions: PROCESSES,
|
||||
selectedProcessActionType: null,
|
||||
|
||||
// 右侧钢卷
|
||||
coilLoading: false,
|
||||
coilList: [],
|
||||
@@ -134,11 +138,15 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
filteredScheduleList() {
|
||||
if (!this.selectedActionType) return this.scheduleList
|
||||
return this.scheduleList.filter(item => (item.actionType || '') === this.selectedActionType)
|
||||
if (!this.selectedProcessActionType) return this.scheduleList
|
||||
return this.scheduleList.filter(item => String(item.actionType) === String(this.selectedProcessActionType))
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 默认选中第一个工序
|
||||
if (this.processOptions.length > 0) {
|
||||
this.selectedProcessActionType = this.processOptions[0].actionType
|
||||
}
|
||||
this.handleQuery()
|
||||
},
|
||||
methods: {
|
||||
@@ -156,44 +164,55 @@ export default {
|
||||
queryScheduleItems() {
|
||||
this.schLoading = true
|
||||
this.scheduleList = []
|
||||
this.actionTypes = []
|
||||
this.selectedActionType = ''
|
||||
|
||||
listScheduleItem({ prodDate: this.queryDate, pageNum: 1, pageSize: 9999 }).then(res => {
|
||||
this.scheduleList = (res.rows || []).sort((a, b) => (a.scheduleNo || '').localeCompare(b.scheduleNo || ''))
|
||||
// 提取所有不同的 actionType
|
||||
const types = new Set()
|
||||
this.scheduleList.forEach(item => {
|
||||
if (item.actionType) types.add(item.actionType)
|
||||
})
|
||||
this.actionTypes = [...types].sort()
|
||||
this.updateSummary()
|
||||
}).catch(() => {
|
||||
this.scheduleList = []
|
||||
this.actionTypes = []
|
||||
}).finally(() => {
|
||||
this.schLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
filterByActionType(type) {
|
||||
this.selectedActionType = type
|
||||
},
|
||||
|
||||
// ====== 右侧:钢卷 ======
|
||||
// ====== 右侧:钢卷(先查 pendingAction 获取 coilIds,再查实际钢卷) ======
|
||||
queryCoils() {
|
||||
if (!this.selectedProcessActionType) {
|
||||
this.coilList = []
|
||||
this.coilTotal = 0
|
||||
this.coilTotalWeight = 0
|
||||
return
|
||||
}
|
||||
this.coilLoading = true
|
||||
this.coilList = []
|
||||
|
||||
listMaterialCoil({
|
||||
pageNum: 1,
|
||||
pageSize: 9999
|
||||
// 可根据需要加上日期和 dataType 过滤
|
||||
const startTime = `${this.queryDate} 00:00:00`
|
||||
const endTime = `${this.queryDate} 23:59:59`
|
||||
|
||||
listLightPendingAction({
|
||||
actionType: this.selectedProcessActionType,
|
||||
startTime,
|
||||
endTime
|
||||
}).then(res => {
|
||||
this.coilList = res.rows || []
|
||||
this.coilTotal = res.total || this.coilList.length
|
||||
this.coilTotalWeight = this.coilList.reduce((sum, c) => sum + (parseFloat(c.netWeight) || 0) / 1000, 0).toFixed(3)
|
||||
this.updateSummary()
|
||||
const rows = res.rows || (Array.isArray(res) ? res : [])
|
||||
const coilIds = rows.map(r => r.processedCoilId).filter(Boolean)
|
||||
if (coilIds.length === 0) {
|
||||
this.coilList = []
|
||||
this.coilTotal = 0
|
||||
this.coilTotalWeight = 0
|
||||
this.updateSummary()
|
||||
return
|
||||
}
|
||||
return listMaterialCoil({
|
||||
coilIds: coilIds.join(','),
|
||||
pageNum: 1,
|
||||
pageSize: 1000
|
||||
}).then(coilRes => {
|
||||
this.coilList = coilRes.rows || []
|
||||
this.coilTotal = coilRes.total || this.coilList.length
|
||||
this.coilTotalWeight = this.coilList.reduce((sum, c) => sum + (parseFloat(c.netWeight) || 0) / 1000, 0).toFixed(3)
|
||||
this.updateSummary()
|
||||
})
|
||||
}).catch(() => {
|
||||
this.coilList = []
|
||||
this.coilTotal = 0
|
||||
@@ -203,6 +222,10 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
onProcessChange() {
|
||||
this.queryCoils()
|
||||
},
|
||||
|
||||
updateSummary() {
|
||||
this.summaryText = `排产 ${this.scheduleList.length} 条 | 钢卷 ${this.coilTotal} 条 ${this.coilTotalWeight} 吨`
|
||||
}
|
||||
@@ -251,6 +274,21 @@ export default {
|
||||
border: 1px solid $aps-border;
|
||||
}
|
||||
|
||||
.process-tab-bar {
|
||||
flex-shrink: 0;
|
||||
padding: 6px 0;
|
||||
::v-deep .el-radio-button__inner {
|
||||
padding: 6px 14px;
|
||||
font-size: 12px;
|
||||
}
|
||||
::v-deep .el-radio-button:first-child .el-radio-button__inner {
|
||||
border-radius: $aps-radius 0 0 $aps-radius;
|
||||
}
|
||||
::v-deep .el-radio-button:last-child .el-radio-button__inner {
|
||||
border-radius: 0 $aps-radius $aps-radius 0;
|
||||
}
|
||||
}
|
||||
|
||||
.aps-compare-card {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
@@ -259,15 +297,6 @@ export default {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.action-filter-bar {
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid $aps-border;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.aps-btn-red {
|
||||
@include aps-btn-red;
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
</div>
|
||||
|
||||
<!-- 待审核 Tab -->
|
||||
<div v-show="activeTab === 'pending'" class="detail-card aps-sch-card">
|
||||
<div v-loading="loading" v-show="activeTab === 'pending'" class="detail-card aps-sch-card">
|
||||
<div class="detail-card-header">
|
||||
<span>待审核产需单明细</span>
|
||||
<span v-if="pendingScheduleList.length > 0" style="font-weight:normal;font-size:12px;opacity:0.8;">
|
||||
共 {{ pendingScheduleList.length }} 个产需单
|
||||
</span>
|
||||
</div>
|
||||
<div v-loading="loading" class="detail-card-body" style="padding:0;">
|
||||
<div element-loading-text="正在加载待审核产需单..." class="detail-card-body" style="padding:0;">
|
||||
<div v-if="pendingScheduleList.length > 0" class="aps-sch-list">
|
||||
<div v-for="sch in pendingScheduleList" :key="sch.scheduleId" class="aps-sch-item">
|
||||
<!-- 产需单头部:排产单号 + 状态标签 + 操作 -->
|
||||
@@ -162,7 +162,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 已排产 Tab -->
|
||||
<div v-show="activeTab === 'scheduled'" class="detail-card aps-sch-card">
|
||||
<div v-loading="schLoading" v-show="activeTab === 'scheduled'" class="detail-card aps-sch-card">
|
||||
<div class="detail-card-header">
|
||||
<span>已排产明细</span>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
@@ -191,7 +191,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-loading="schLoading" class="detail-card-body" style="padding:0;">
|
||||
<div element-loading-text="正在加载已排产数据..." class="detail-card-body" style="padding:0;">
|
||||
<el-table
|
||||
v-if="scheduledItemList.length > 0"
|
||||
ref="scheduledTable"
|
||||
@@ -205,7 +205,11 @@
|
||||
<el-table-column type="selection" width="45" align="center" />
|
||||
<el-table-column label="排产单号" prop="scheduleNo" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column label="生产日期" prop="prodDate" width="110" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="工序类型" prop="actionType" width="100" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="工序类型" prop="actionType" width="100" align="center" show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
{{ getActionTypeName(scope.row.actionType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排产状态" prop="scheduleStatus" width="90" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span class="aps-status-tag" :class="'status-' + (scope.row.scheduleStatus || 1)">{{ statusMap[scope.row.scheduleStatus] || '未知' }}</span>
|
||||
@@ -303,17 +307,28 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工序类型">
|
||||
<el-input v-model="editForm.actionType" />
|
||||
<el-form-item label="排产状态">
|
||||
<el-select v-model="editForm.scheduleStatus" placeholder="请选择排产状态" style="width:100%">
|
||||
<el-option v-for="(label, val) in statusMap" :key="val" :label="label" :value="Number(val)" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工序类型">
|
||||
<el-select v-model="editForm.actionType" placeholder="请选择工序类型" clearable filterable style="width:100%">
|
||||
<el-option v-for="p in processOptions" :key="p.actionType" :label="p.name" :value="p.actionType" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="订货单位">
|
||||
<el-input v-model="editForm.customerName" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="规格" prop="spec">
|
||||
<el-input v-model="editForm.spec" />
|
||||
@@ -512,7 +527,11 @@
|
||||
<el-form-item label="排产单号"><el-input v-model="mergeForm.scheduleNo" /></el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工序类型"><el-input v-model="mergeForm.actionType" /></el-form-item>
|
||||
<el-form-item label="工序类型">
|
||||
<el-select v-model="mergeForm.actionType" placeholder="请选择工序类型" clearable filterable style="width:100%">
|
||||
<el-option v-for="p in processOptions" :key="p.actionType" :label="p.name" :value="p.actionType" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
@@ -635,6 +654,7 @@ import {
|
||||
receiveScheduleItem,
|
||||
mergeScheduleItem
|
||||
} from '@/api/aps/schedule'
|
||||
import { PROCESSES } from '@/utils/meta'
|
||||
|
||||
export default {
|
||||
name: 'ApsSchedule',
|
||||
@@ -654,6 +674,7 @@ export default {
|
||||
pendingScheduleList: [],
|
||||
summaryText: '',
|
||||
statusMap: { 1: '待审核', 2: '已接收', 3: '已驳回' },
|
||||
processOptions: PROCESSES,
|
||||
|
||||
// 已排产
|
||||
scheduledItemList: [],
|
||||
@@ -870,6 +891,14 @@ export default {
|
||||
|
||||
handleEditScheduled(row) {
|
||||
this.editForm = { ...this.getEmptyEditForm(), ...row }
|
||||
// 确保 actionType 为数字类型以匹配下拉选项
|
||||
if (this.editForm.actionType != null && typeof this.editForm.actionType !== 'number') {
|
||||
this.editForm.actionType = Number(this.editForm.actionType)
|
||||
}
|
||||
// 确保 scheduleStatus 为数字类型以匹配下拉选项
|
||||
if (this.editForm.scheduleStatus != null && typeof this.editForm.scheduleStatus !== 'number') {
|
||||
this.editForm.scheduleStatus = Number(this.editForm.scheduleStatus)
|
||||
}
|
||||
this.editDialogTitle = '编辑排产明细'
|
||||
this.editDialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
@@ -948,7 +977,7 @@ export default {
|
||||
this.mergeForm = {
|
||||
itemCount: this.mergeSourceRows.length,
|
||||
scheduleNo: row.scheduleNo || '',
|
||||
actionType: row.actionType || '',
|
||||
actionType: row.actionType != null ? Number(row.actionType) : '',
|
||||
customerName: row.customerName || '',
|
||||
spec: row.spec || '',
|
||||
material: row.material || '',
|
||||
@@ -1004,6 +1033,11 @@ export default {
|
||||
return total.toFixed(3)
|
||||
},
|
||||
|
||||
getActionTypeName(actionType) {
|
||||
const p = this.processOptions.find(item => String(item.actionType) === String(actionType))
|
||||
return p ? p.name : (actionType || '')
|
||||
},
|
||||
|
||||
handleDetailClick(sch, detail) {
|
||||
// 点击明细行查看来源订单
|
||||
if (!sch || !sch.orderList || sch.orderList.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user