Merge remote-tracking branch 'origin/0.8.X' into 0.8.X
This commit is contained in:
@@ -473,3 +473,13 @@ export function excludeLock(coilId) {
|
||||
timeout: 600000,
|
||||
})
|
||||
}
|
||||
|
||||
// 轻量钢卷列表
|
||||
export function listLightCoil(data) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/listForReport',
|
||||
method: 'get',
|
||||
timeout: 600000,
|
||||
params: data
|
||||
})
|
||||
}
|
||||
@@ -167,3 +167,15 @@ export function restorePendingAction(actionId) {
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 轻量待操作列表
|
||||
*/
|
||||
export function listLightPendingAction(query) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction/actionCoilIdList',
|
||||
method: 'get',
|
||||
params: query,
|
||||
timeout: 600000
|
||||
})
|
||||
}
|
||||
|
||||
@@ -430,6 +430,12 @@ export default {
|
||||
async handleRowClick(row) {
|
||||
// 快速点击防重:每次点击递增版本号,旧的 sync 任务检测到版本号变更后自动放弃
|
||||
const clickRev = ++this._clickRev
|
||||
|
||||
// 记录点击前的钢卷号,用于判断是否同一行重复点击
|
||||
const prevExcoilId = this.selectedRow
|
||||
? (this.selectedRow.EXCOILID || this.selectedRow.excoilid || null)
|
||||
: null
|
||||
|
||||
this.selectedRow = row
|
||||
this.segData = null
|
||||
this.gaugeRows = null
|
||||
@@ -450,8 +456,12 @@ export default {
|
||||
// 如果期间又点击了其他行则放弃后续操作
|
||||
if (this._clickRev !== clickRev) return
|
||||
|
||||
// 后台静默同步到规程(不阻塞 UI)
|
||||
this.autoSyncToActiveSpec(excoilId || encoilId, clickRev)
|
||||
// 同一钢卷重复点击:跳过规程同步,避免重复写入
|
||||
const isSameCoil = excoilId && excoilId === prevExcoilId
|
||||
if (!isSameCoil) {
|
||||
// 后台静默同步到规程(不阻塞 UI)
|
||||
this.autoSyncToActiveSpec(excoilId || encoilId, clickRev)
|
||||
}
|
||||
|
||||
await this.$nextTick()
|
||||
// 加载完成后自动选中第一个趋势参数
|
||||
@@ -879,22 +889,34 @@ export default {
|
||||
for (const item of items) {
|
||||
if (guard()) return
|
||||
|
||||
// 确保 plan 点位存在
|
||||
// 确保 plan 点位存在(幂等:插入失败时降级重查,应对并发竞态)
|
||||
let planId
|
||||
const ep = planMap[item.pointCode]
|
||||
if (ep) {
|
||||
planId = ep.planId
|
||||
} else {
|
||||
const r = await addProcessPlan({
|
||||
versionId,
|
||||
segmentType: 'PROCESS',
|
||||
segmentName: item.groupLabel,
|
||||
pointName: item.pointName,
|
||||
pointCode: item.pointCode,
|
||||
sortOrder: 0
|
||||
})
|
||||
if (guard()) return
|
||||
planId = r.data
|
||||
try {
|
||||
const r = await addProcessPlan({
|
||||
versionId,
|
||||
segmentType: 'PROCESS',
|
||||
segmentName: item.groupLabel,
|
||||
pointName: item.pointName,
|
||||
pointCode: item.pointCode,
|
||||
sortOrder: 0
|
||||
})
|
||||
if (guard()) return
|
||||
planId = r.data
|
||||
// 写入本地 map,同一次 sync 内不再重复插入
|
||||
planMap[item.pointCode] = { planId }
|
||||
} catch (_dupErr) {
|
||||
// 唯一键冲突:该点位已由并发请求写入,重新查询获取真实 planId
|
||||
const refetch = await listProcessPlan({ versionId, pageNum: 1, pageSize: 500 })
|
||||
if (guard()) return
|
||||
const found = (refetch.rows || []).find(p => p.pointCode === item.pointCode)
|
||||
if (!found) continue // 极端情况:查不到则跳过本条目
|
||||
planId = found.planId
|
||||
planMap[item.pointCode] = found
|
||||
}
|
||||
}
|
||||
|
||||
// 查已存储参数
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="coil-table">
|
||||
<div class="table-controls">
|
||||
<div class="filter-section">
|
||||
<!-- <div class="filter-section">
|
||||
<el-input v-model="filterKeyword" placeholder="输入关键词筛选" clearable @input="handleFilterChange"
|
||||
style="width: 200px; margin-right: 10px" />
|
||||
<el-select v-model="filterColumn" placeholder="选择筛选字段" @change="handleFilterChange"
|
||||
style="width: 200px; margin-right: 10px" multiple collapse-tags>
|
||||
<el-option v-for="column in columns" :key="column.prop" :label="column.title" :value="column.prop" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="sort-section">
|
||||
</div> -->
|
||||
<!-- <div class="sort-section">
|
||||
<el-select v-model="sortField" placeholder="选择排序字段" @change="handleSortChange"
|
||||
style="width: 150px; margin-right: 10px">
|
||||
<el-option v-for="column in columns" :key="column.prop" :label="column.title" :value="column.prop" />
|
||||
@@ -18,10 +18,10 @@
|
||||
<el-option label="升序" value="asc" />
|
||||
<el-option label="降序" value="desc" />
|
||||
</el-select>
|
||||
</div>
|
||||
<el-pagination layout="total, sizes, prev, pager, next, jumper" :total="total" :page-size.sync="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200, 500, 1000]" @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange" />
|
||||
</div> -->
|
||||
<el-pagination layout="total, sizes, prev, pager, next, jumper" :total="paginationTotal" :page-size="effectivePageSize"
|
||||
:current-page="pageNum" :page-sizes="[10, 20, 50, 100, 200, 500, 1000]" @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange" />
|
||||
|
||||
<slot name="settings"></slot>
|
||||
</div>
|
||||
@@ -107,13 +107,23 @@ export default {
|
||||
// 自定义高亮样式
|
||||
style: {}
|
||||
})
|
||||
},
|
||||
// 服务端分页总数(>0 时开启服务端分页模式)
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 服务端分页每页条数
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
dicts: ['coil_quality_status', 'coil_abnormal_code', 'coil_abnormal_degree'],
|
||||
data() {
|
||||
return {
|
||||
pageNum: 1,
|
||||
pageSize: 1000,
|
||||
innerPageSize: 1000,
|
||||
// 排序相关
|
||||
sortField: '',
|
||||
sortDirection: 'asc',
|
||||
@@ -133,8 +143,17 @@ export default {
|
||||
this.filterColumn = this.columns.map(column => column.prop)
|
||||
},
|
||||
computed: {
|
||||
// 处理排序和筛选后的数据
|
||||
isServerPagination() {
|
||||
return this.total > 0
|
||||
},
|
||||
effectivePageSize() {
|
||||
return this.pageSize > 0 ? this.pageSize : this.innerPageSize
|
||||
},
|
||||
// 处理排序和筛选后的数据(服务端分页模式下跳过筛选排序)
|
||||
processedData() {
|
||||
if (this.isServerPagination) {
|
||||
return this.data
|
||||
}
|
||||
let result = [...this.data]
|
||||
|
||||
// 筛选逻辑
|
||||
@@ -183,32 +202,48 @@ export default {
|
||||
|
||||
return result
|
||||
},
|
||||
// 内部实现前端分页逻辑
|
||||
// 内部实现前端分页逻辑(服务端分页模式下直接返回数据)
|
||||
tableData() {
|
||||
return this.processedData.slice((this.pageNum - 1) * this.pageSize, this.pageNum * this.pageSize)
|
||||
if (this.isServerPagination) {
|
||||
return this.data
|
||||
}
|
||||
return this.processedData.slice((this.pageNum - 1) * this.effectivePageSize, this.pageNum * this.effectivePageSize)
|
||||
},
|
||||
// 计算总页数
|
||||
totalPage() {
|
||||
return Math.ceil(this.processedData.length / this.pageSize)
|
||||
const total = this.isServerPagination ? this.total : this.processedData.length
|
||||
return Math.ceil(total / this.effectivePageSize)
|
||||
},
|
||||
// 计算总条数
|
||||
total() {
|
||||
pageTotal() {
|
||||
return this.processedData.length
|
||||
},
|
||||
// 分页总条数(服务端优先)
|
||||
paginationTotal() {
|
||||
return this.isServerPagination ? this.total : this.pageTotal
|
||||
},
|
||||
// 是否展示分页组件
|
||||
showPagination() {
|
||||
if (this.isServerPagination) return true
|
||||
return this.totalPage > 1
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 分页大小改变时触发
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
if (this.isServerPagination) {
|
||||
this.$emit('size-change', val)
|
||||
} else {
|
||||
this.innerPageSize = val
|
||||
}
|
||||
this.pageNum = 1
|
||||
},
|
||||
// 分页当前页改变时触发
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val
|
||||
if (this.isServerPagination) {
|
||||
this.$emit('current-change', val)
|
||||
}
|
||||
},
|
||||
// 生产耗时,单位分钟,渲染为xx天xx小时xx分钟
|
||||
formatProductionDuration(duration) {
|
||||
|
||||
@@ -55,7 +55,8 @@
|
||||
|
||||
<el-descriptions title="明细信息" :column="3" border>
|
||||
</el-descriptions>
|
||||
<coil-table :columns="deliveryColumns" :data="list"></coil-table>
|
||||
<coil-table :columns="deliveryColumns" :data="list" :total="total" :page-size="pageSize"
|
||||
@current-change="handlePageChange" @size-change="handleSizeChange"></coil-table>
|
||||
|
||||
<el-dialog title="列设置" :visible.sync="settingVisible" width="50%">
|
||||
<el-radio-group v-model="activeColumnConfig">
|
||||
@@ -67,7 +68,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listCoilWithIds, listWithBindInfoCoil } from "@/api/wms/coil";
|
||||
import { listWithBindInfoCoil, listLightCoil } from "@/api/wms/coil";
|
||||
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
|
||||
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
|
||||
import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
|
||||
@@ -118,11 +119,10 @@ export default {
|
||||
activeColumnConfig: 'coil-report-delivery',
|
||||
settingVisible: false,
|
||||
list: [],
|
||||
lightList: [],
|
||||
defaultStartTime: startTime,
|
||||
defaultEndTime: endTime,
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 99999,
|
||||
status: 1,
|
||||
dataType: 1,
|
||||
selectType: 'product',
|
||||
@@ -133,8 +133,10 @@ export default {
|
||||
itemSpecification: '',
|
||||
itemMaterial: '',
|
||||
itemManufacturer: '',
|
||||
includeBindInfo: true,
|
||||
},
|
||||
pageNum: 1,
|
||||
pageSize: 100,
|
||||
total: 0,
|
||||
loading: false,
|
||||
|
||||
deliveryColumns: [],
|
||||
@@ -142,9 +144,9 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
summary() {
|
||||
// 总钢卷数量、总重、均重
|
||||
const totalCount = this.list.length
|
||||
const totalWeight = this.list.reduce((acc, cur) => acc + parseFloat(cur.netWeight), 0)
|
||||
// 总钢卷数量、总重、均重(基于轻量全量列表)
|
||||
const totalCount = this.lightList.length
|
||||
const totalWeight = this.lightList.reduce((acc, cur) => acc + parseFloat(cur.netWeight), 0)
|
||||
const avgWeight = totalCount > 0 ? (totalWeight / totalCount).toFixed(2) : 0
|
||||
return {
|
||||
totalCount,
|
||||
@@ -153,7 +155,7 @@ export default {
|
||||
}
|
||||
},
|
||||
coilIds() {
|
||||
return this.list.map(item => item.coilId).join(',')
|
||||
return this.lightList.map(item => item.coilId).join(',')
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@@ -167,11 +169,20 @@ export default {
|
||||
},
|
||||
getList() {
|
||||
this.loading = true
|
||||
listWithBindInfoCoil({
|
||||
this.pageNum = 1
|
||||
Promise.all([
|
||||
this.fetchLightList(),
|
||||
this.fetchDetailList()
|
||||
]).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 轻量全量接口,用于统计计算
|
||||
fetchLightList() {
|
||||
return listLightCoil({
|
||||
...this.queryParams
|
||||
}).then(res => {
|
||||
this.list = res.rows.map(item => {
|
||||
// 计算宽度和厚度,将规格按照*分割,*前的是厚度,*后的是宽度
|
||||
this.lightList = (res || []).map(item => {
|
||||
const [thickness, width] = item.specification?.split('*') || []
|
||||
return {
|
||||
...item,
|
||||
@@ -179,6 +190,41 @@ export default {
|
||||
computedWidth: parseFloat(width),
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 分页明细接口,用于表格展示
|
||||
fetchDetailList() {
|
||||
return listWithBindInfoCoil({
|
||||
...this.queryParams,
|
||||
includeBindInfo: true,
|
||||
pageNum: this.pageNum,
|
||||
pageSize: this.pageSize,
|
||||
}).then(res => {
|
||||
this.total = res.total || 0
|
||||
this.list = (res.rows || []).map(item => {
|
||||
const [thickness, width] = item.specification?.split('*') || []
|
||||
return {
|
||||
...item,
|
||||
computedThickness: parseFloat(thickness),
|
||||
computedWidth: parseFloat(width),
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 切换页码
|
||||
handlePageChange(pageNum) {
|
||||
this.pageNum = pageNum
|
||||
this.loading = true
|
||||
this.fetchDetailList().finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 切换每页条数
|
||||
handleSizeChange(pageSize) {
|
||||
this.pageSize = pageSize
|
||||
this.pageNum = 1
|
||||
this.loading = true
|
||||
this.fetchDetailList().finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user