feat(wms): 新增APS排产对比功能页面
- 添加 compare.vue 页面实现排产明细与现存钢卷对比展示 - 实现左侧排产明细表格按工序筛选功能 - 实现右侧现存钢卷信息展示包括重量统计 - 添加日期查询和汇总统计功能 - 创建 materialCoil API 接口用于获取钢卷数据 - 集成排产明细和钢卷数据的并列对比显示
This commit is contained in:
10
klp-ui/src/api/aps/materialCoil.js
Normal file
10
klp-ui/src/api/aps/materialCoil.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询钢卷物料列表
|
||||
export function listMaterialCoil(query) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
312
klp-ui/src/views/wms/post/aps/compare.vue
Normal file
312
klp-ui/src/views/wms/post/aps/compare.vue
Normal file
@@ -0,0 +1,312 @@
|
||||
<template>
|
||||
<div class="aps-compare-page">
|
||||
<!-- 顶部工具栏 -->
|
||||
<div class="aps-compare-toolbar">
|
||||
<span class="aps-compare-label">生产日期:</span>
|
||||
<el-date-picker
|
||||
v-model="queryDate"
|
||||
type="date"
|
||||
placeholder="选择生产日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
size="small"
|
||||
style="width:160px"
|
||||
@change="handleQuery"
|
||||
/>
|
||||
<el-button size="small" class="aps-btn-red" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||
<div v-if="summaryText" class="aps-compare-summary">
|
||||
<span>{{ summaryText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="12" style="flex:1;min-height:0;">
|
||||
<!-- 左侧:排产明细(按工序筛选) -->
|
||||
<el-col :span="12" style="height:100%;display:flex;flex-direction:column;">
|
||||
<div class="detail-card aps-compare-card">
|
||||
<div class="detail-card-header">
|
||||
<span>排产明细 — 按工序筛选</span>
|
||||
<span v-if="scheduleList.length > 0" style="font-weight:normal;font-size:12px;opacity:0.8;">
|
||||
共 {{ 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"
|
||||
:data="filteredScheduleList"
|
||||
border
|
||||
size="small"
|
||||
class="aps-table"
|
||||
>
|
||||
<el-table-column label="排产单号" prop="scheduleNo" min-width="130" show-overflow-tooltip />
|
||||
<el-table-column label="工序类型" prop="actionType" width="90" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="规格" prop="spec" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="材质" prop="material" width="80" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="排产吨数" prop="scheduleWeight" width="90" align="right" />
|
||||
<el-table-column label="品名" prop="productType" min-width="80" show-overflow-tooltip />
|
||||
<el-table-column label="订货单位" prop="customerName" min-width="120" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<div v-else-if="!schLoading" style="padding:40px;text-align:center;color:#909399;">
|
||||
{{ hasQueried ? '暂无排产明细' : '请选择日期查询' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 右侧:现存钢卷 -->
|
||||
<el-col :span="12" style="height:100%;display:flex;flex-direction:column;">
|
||||
<div class="detail-card aps-compare-card">
|
||||
<div class="detail-card-header">
|
||||
<span>现存钢卷(今日加工)</span>
|
||||
<span v-if="coilList.length > 0" style="font-weight:normal;font-size:12px;opacity:0.8;">
|
||||
共 {{ coilTotal }} 条,净重合计 {{ coilTotalWeight }} 吨
|
||||
</span>
|
||||
</div>
|
||||
<div v-loading="coilLoading" class="detail-card-body" style="padding:0;flex:1;overflow:auto;">
|
||||
<el-table
|
||||
v-if="coilList.length > 0"
|
||||
:data="coilList"
|
||||
border
|
||||
size="small"
|
||||
class="aps-table"
|
||||
>
|
||||
<el-table-column label="入场钢卷号" prop="enterCoilNo" min-width="130" show-overflow-tooltip />
|
||||
<el-table-column label="当前钢卷号" prop="currentCoilNo" min-width="130" show-overflow-tooltip />
|
||||
<el-table-column label="净重(kg)" prop="netWeight" width="100" align="right" />
|
||||
<el-table-column label="材料类型" prop="materialType" width="90" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="物品类型" prop="itemType" width="90" align="center" />
|
||||
<el-table-column label="状态" prop="status" width="80" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span :style="{ color: scope.row.status === 0 ? '#52c41a' : scope.row.status === 1 ? '#1890ff' : '#ff4d4f' }">{{ coilStatusMap[scope.row.status] || scope.row.status }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="班组" prop="team" width="70" align="center" />
|
||||
<el-table-column label="备注" prop="remark" min-width="100" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<div v-else-if="!coilLoading" style="padding:40px;text-align:center;color:#909399;">
|
||||
{{ hasQueried ? '暂无钢卷数据' : '请选择日期查询' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listScheduleItem } from '@/api/aps/schedule'
|
||||
import { listMaterialCoil } from '@/api/aps/materialCoil'
|
||||
|
||||
export default {
|
||||
name: 'ApsCompare',
|
||||
data() {
|
||||
const today = new Date()
|
||||
const y = today.getFullYear()
|
||||
const m = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const d = String(today.getDate()).padStart(2, '0')
|
||||
return {
|
||||
queryDate: `${y}-${m}-${d}`,
|
||||
hasQueried: false,
|
||||
summaryText: '',
|
||||
|
||||
// 左侧排产明细
|
||||
schLoading: false,
|
||||
scheduleList: [],
|
||||
actionTypes: [],
|
||||
selectedActionType: '',
|
||||
coilStatusMap: { 0: '在库', 1: '在途', 2: '已出库' },
|
||||
|
||||
// 右侧钢卷
|
||||
coilLoading: false,
|
||||
coilList: [],
|
||||
coilTotal: 0,
|
||||
coilTotalWeight: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredScheduleList() {
|
||||
if (!this.selectedActionType) return this.scheduleList
|
||||
return this.scheduleList.filter(item => (item.actionType || '') === this.selectedActionType)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.handleQuery()
|
||||
},
|
||||
methods: {
|
||||
handleQuery() {
|
||||
if (!this.queryDate) {
|
||||
this.$message.warning('请选择生产日期')
|
||||
return
|
||||
}
|
||||
this.hasQueried = true
|
||||
this.queryScheduleItems()
|
||||
this.queryCoils()
|
||||
},
|
||||
|
||||
// ====== 左侧:排产明细 ======
|
||||
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
|
||||
},
|
||||
|
||||
// ====== 右侧:钢卷 ======
|
||||
queryCoils() {
|
||||
this.coilLoading = true
|
||||
this.coilList = []
|
||||
|
||||
listMaterialCoil({
|
||||
pageNum: 1,
|
||||
pageSize: 9999
|
||||
// 可根据需要加上日期和 dataType 过滤
|
||||
}).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()
|
||||
}).catch(() => {
|
||||
this.coilList = []
|
||||
this.coilTotal = 0
|
||||
this.coilTotalWeight = 0
|
||||
}).finally(() => {
|
||||
this.coilLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
updateSummary() {
|
||||
this.summaryText = `排产 ${this.scheduleList.length} 条 | 钢卷 ${this.coilTotal} 条 ${this.coilTotalWeight} 吨`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './scss/aps-theme.scss';
|
||||
|
||||
.aps-compare-page {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
background: $aps-bg;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.aps-compare-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 16px;
|
||||
background: $aps-white;
|
||||
border: 1px solid $aps-border;
|
||||
border-radius: $aps-radius;
|
||||
box-shadow: $aps-shadow-sm;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.aps-compare-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: $aps-text;
|
||||
}
|
||||
|
||||
.aps-compare-summary {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
color: $aps-text-muted;
|
||||
background: $aps-silver-1;
|
||||
padding: 4px 12px;
|
||||
border-radius: $aps-radius;
|
||||
border: 1px solid $aps-border;
|
||||
}
|
||||
|
||||
.aps-compare-card {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
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;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: $aps-white;
|
||||
border: 1px solid $aps-border;
|
||||
border-radius: $aps-radius;
|
||||
box-shadow: $aps-shadow-sm;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.detail-card-header {
|
||||
background: linear-gradient(to right, $aps-red-2, $aps-red-3);
|
||||
color: white;
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-card-body {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.aps-table {
|
||||
width: 100%;
|
||||
|
||||
::v-deep th {
|
||||
background: $aps-silver-1 !important;
|
||||
color: $aps-text !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
::v-deep td {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user