Merge remote-tracking branch 'origin/0.8.X' into 0.8.X

This commit is contained in:
2026-01-15 17:06:00 +08:00
2 changed files with 310 additions and 0 deletions

View File

@@ -214,4 +214,14 @@ export function getMaxCoilNo(enterCoilNoPrefix) {
enterCoilNoPrefix
}
})
}
/**
* 查询存在重号的钢卷
*/
export function getDuplicateGroups() {
return request({
url: '/wms/materialCoil/duplicateGroups',
method: 'get'
})
}

View File

@@ -0,0 +1,300 @@
<template>
<div class="coil-duplicate-page" v-loading="loading">
<el-card shadow="hover" border>
<!-- Tab标签页 区分两个重号组 -->
<el-tabs v-model="activeTab" type="card">
<!-- 标签页一当前卷号重号组 -->
<el-tab-pane label="当前卷号重号组" name="current">
<!-- 搜索区域 + 刷新按钮 -->
<div class="search-bar">
<el-input v-model="currentSearchKey" placeholder="请输入卷号/规格/材质/厂家查询" clearable size="small"
@change="handleCurrentSearch" class="search-input" />
<el-button icon="el-icon-search" size="small" type="primary" plain @click="handleCurrentSearch"
:loading="loading" class="refresh-btn">查询</el-button>
<el-button icon="el-icon-refresh" size="small" type="primary" plain @click="handleCurrentRefresh"
:loading="loading" class="refresh-btn">刷新</el-button>
</div>
<!-- 重号组折叠面板 -->
<el-collapse v-model="currentOpenAllKeys" :accordion="false" style="margin-top:10px;" class="collapse-panel">
<el-collapse-item v-for="(item, index) in currentTableData" :key="`current-${index}`"
:name="`current-${index}`">
<!-- 折叠面板标题 -->
<template slot="title">
<span class="red-text">当前卷号{{ item.currentCoilNo }}</span>
<span class="count-text"> {{ item.coils.length }} 条重号钢卷数据</span>
</template>
<!-- 钢卷表格 -->
<el-table :data="item.coils" border stripe size="small" highlight-current-row style="width: 100%;"
empty-text="该重号组暂无钢卷数据">
<el-table-column prop="enterCoilNo" label="入厂卷号" align="center" min-width="120" />
<el-table-column prop="currentCoilNo" label="当前卷号" align="center" min-width="120" />
<el-table-column prop="productSpecification" label="规格" align="center" />
<el-table-column prop="manufacturer" label="厂家" align="center" />
<el-table-column prop="productMaterial" label="材质" align="center" />
<el-table-column prop="grossWeight" label="毛重(t)" align="center" width="90" />
<el-table-column prop="netWeight" label="净重(t)" align="center" width="90" />
<el-table-column prop="materialType" label="物料类型" align="center" />
<!-- <el-table-column prop="qualityStatus" label="质量状态" align="center" />
<el-table-column prop="trimmingRequirement" label="切边要求" align="center" />
<el-table-column prop="packagingRequirement" label="包装要求" align="center" /> -->
<el-table-column prop="createTime" label="创建时间" align="center" min-width="160" />
<el-table-column prop="updateTime" label="更新时间" align="center" min-width="160" />
</el-table>
</el-collapse-item>
</el-collapse>
<!-- 空数据兜底 -->
<div v-if="currentTableData.length === 0" class="empty-data">暂无当前卷号重号的钢卷数据</div>
</el-tab-pane>
<!-- 标签页二入厂卷号重号组 -->
<el-tab-pane label="入厂卷号重号组" name="enter">
<!-- 搜索区域 + 刷新按钮 -->
<div class="search-bar">
<el-input v-model="enterSearchKey" placeholder="请输入卷号/规格/材质/厂家查询" clearable size="small"
@change="handleEnterSearch" class="search-input" />
<el-button icon="el-icon-search" size="small" type="primary" plain @click="handleEnterSearch"
:loading="loading" class="refresh-btn">查询</el-button>
<el-button icon="el-icon-refresh" size="small" type="primary" plain @click="handleEnterRefresh"
:loading="loading" class="refresh-btn">刷新</el-button>
</div>
<!-- 重号组折叠面板 -->
<el-collapse v-model="enterOpenAllKeys" :accordion="false" style="margin-top:10px;" class="collapse-panel">
<el-collapse-item v-for="(item, index) in enterTableData" :key="`enter-${index}`" :name="`enter-${index}`">
<!-- 折叠面板标题 -->
<template slot="title">
<span class="red-text">入厂卷号{{ item.enterCoilNo }}</span>
<span class="count-text"> {{ item.coils.length }} 条重号钢卷数据</span>
</template>
<!-- 钢卷表格 -->
<el-table :data="item.coils" border stripe size="small" highlight-current-row style="width: 100%;"
empty-text="该重号组暂无钢卷数据">
<el-table-column prop="enterCoilNo" label="入厂卷号" align="center" min-width="120" />
<el-table-column prop="currentCoilNo" label="当前卷号" align="center" min-width="120" />
<el-table-column prop="productSpecification" label="规格" align="center" />
<el-table-column prop="manufacturer" label="厂家" align="center" />
<el-table-column prop="productMaterial" label="材质" align="center" />
<el-table-column prop="grossWeight" label="毛重(t)" align="center" width="90" />
<el-table-column prop="netWeight" label="净重(t)" align="center" width="90" />
<el-table-column prop="materialType" label="物料类型" align="center" />
<!-- <el-table-column prop="qualityStatus" label="质量状态" align="center" />
<el-table-column prop="trimmingRequirement" label="切边要求" align="center" />
<el-table-column prop="packagingRequirement" label="包装要求" align="center" /> -->
<el-table-column prop="createTime" label="创建时间" align="center" min-width="160" />
<el-table-column prop="updateTime" label="更新时间" align="center" min-width="160" />
</el-table>
</el-collapse-item>
</el-collapse>
<!-- 空数据兜底 -->
<div v-if="enterTableData.length === 0" class="empty-data">暂无入厂卷号重号的钢卷数据</div>
</el-tab-pane>
</el-tabs>
</el-card>
</div>
</template>
<script>
import { getDuplicateGroups } from '@/api/wms/coil'
export default {
name: 'CoilDuplicateList',
data() {
return {
// 基础数据-保留原始分组结构
currentNoGroups: [],
enterNoGroups: [],
loading: false,
activeTab: 'current',
// 当前卷号重号组 - 仅保留搜索配置,删除所有分页相关变量
currentSearchKey: '',
currentTableData: [],
// 入厂卷号重号组 - 仅保留搜索配置,删除所有分页相关变量
enterSearchKey: '',
enterTableData: []
}
},
computed: {
// 当前卷号折叠面板默认全开
currentOpenAllKeys() {
return this.currentTableData.map((_, index) => `current-${index}`)
},
// 入厂卷号折叠面板默认全开
enterOpenAllKeys() {
return this.enterTableData.map((_, index) => `enter-${index}`)
}
},
mounted() {
this.getRepeatedGroups()
},
methods: {
/**
* 统一格式化钢卷数据 - 处理所有嵌套字段判空,生成扁平字段,数值兜底
* @param {Object} coil 原始钢卷对象
* @returns {Object} 格式化后的钢卷对象
*/
formatCoilData(coil) {
const product = coil.product || {}
const rawMaterial = coil.rawMaterial || {}
const warehouse = coil.warehouse || {}
return {
...coil,
productSpecification: product.specification || rawMaterial.specification || '-',
productMaterial: product.material || rawMaterial.material || '-',
manufacturer: product.manufacturer || rawMaterial.manufacturer || '-',
warehouseName: warehouse.warehouseName || '-',
grossWeight: coil.grossWeight || '-',
netWeight: coil.netWeight || '-',
materialType: coil.materialType || '-',
qualityStatus: coil.qualityStatus || '-',
trimmingRequirement: coil.trimmingRequirement || '-',
packagingRequirement: coil.packagingRequirement || '-'
}
},
/**
* 格式化重号组数据 - 对组内所有钢卷执行格式化
* @param {Array} groups 原始重号组数组
* @returns {Array} 格式化后的重号组数组
*/
formatGroupData(groups) {
return groups.map(group => ({
...group,
coils: group.coils?.map(coil => this.formatCoilData(coil)) || []
}))
},
/**
* 查询存在重号的钢卷 - 核心请求方法
*/
async getRepeatedGroups() {
this.loading = true
try {
const res = await getDuplicateGroups()
this.currentNoGroups = this.formatGroupData(res.data.currentGroups || [])
this.enterNoGroups = this.formatGroupData(res.data.enterGroups || [])
// 初始化搜索过滤
this.handleCurrentSearch()
this.handleEnterSearch()
} catch (err) {
this.$message.error('查询重号钢卷数据失败!')
console.error(err)
} finally {
this.loading = false
}
},
/**
* 当前卷号重号组 - 搜索过滤逻辑(精简版,无分页)
*/
handleCurrentSearch() {
const key = this.currentSearchKey.trim().toLowerCase()
if (!key) {
this.currentTableData = [...this.currentNoGroups]
} else {
this.currentTableData = this.currentNoGroups.filter(group => {
const groupNo = (group.currentCoilNo || '').toLowerCase()
const hasMatchCoil = group.coils.some(item => {
const enterNo = (item.enterCoilNo || '').toLowerCase()
const currentNo = (item.currentCoilNo || '').toLowerCase()
const spec = (item.productSpecification || '').toLowerCase()
const material = (item.productMaterial || '').toLowerCase()
const manufacturer = (item.manufacturer || '').toLowerCase()
// const warehouse = (item.warehouseName || '').toLowerCase()
const matType = (item.materialType || '').toLowerCase()
return enterNo.includes(key) || currentNo.includes(key) || spec.includes(key) || material.includes(key) || manufacturer.includes(key) || matType.includes(key)
})
return groupNo.includes(key) || hasMatchCoil
})
}
},
/**
* 入厂卷号重号组 - 搜索过滤逻辑(精简版,无分页)
*/
handleEnterSearch() {
const key = this.enterSearchKey.trim().toLowerCase()
if (!key) {
this.enterTableData = [...this.enterNoGroups]
} else {
this.enterTableData = this.enterNoGroups.filter(group => {
const groupNo = (group.enterCoilNo || '').toLowerCase()
const hasMatchCoil = group.coils.some(item => {
const enterNo = (item.enterCoilNo || '').toLowerCase()
const currentNo = (item.currentCoilNo || '').toLowerCase()
const spec = (item.productSpecification || '').toLowerCase()
const material = (item.productMaterial || '').toLowerCase()
const manufacturer = (item.manufacturer || '').toLowerCase()
// const warehouse = (item.warehouseName || '').toLowerCase()
const matType = (item.materialType || '').toLowerCase()
return enterNo.includes(key) || currentNo.includes(key) || spec.includes(key) || material.includes(key) || manufacturer.includes(key) || matType.includes(key)
})
return groupNo.includes(key) || hasMatchCoil
})
}
},
// 刷新按钮方法 - 重置搜索+重新请求最新数据
handleCurrentRefresh() {
this.currentSearchKey = ''
this.getRepeatedGroups()
},
handleEnterRefresh() {
this.enterSearchKey = ''
this.getRepeatedGroups()
}
}
}
</script>
<style scoped lang="scss">
.coil-duplicate-page {
padding: 15px;
box-sizing: border-box;
.search-bar {
text-align: right;
.search-input {
width: 300px;
}
.refresh-btn {
margin-left: 8px;
}
}
// 折叠面板样式优化
.collapse-panel {
::v-deep .el-collapse-item__header {
font-weight: 600;
padding: 8px 15px;
}
.red-text {
color: #E6A23C;
font-weight: bold;
}
.count-text {
color: #666;
margin-left: 10px;
}
}
// 空数据样式
.empty-data {
text-align: center;
padding: 30px 0;
color: #999;
font-size: 14px;
}
}
</style>