Files
klp-oa/klp-ui/src/views/wms/report/template/out.vue
砂糖 5b6ad4796e feat(wms报表): 添加列设置功能并重构表格组件
引入可配置的列设置功能,允许用户自定义表格显示列
创建CoilTable通用组件替换原有表格实现
添加列设置对话框和默认列配置初始化逻辑
2026-03-19 15:08:04 +08:00

243 lines
9.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container" v-loading="loading">
<el-row>
<el-form label-width="80px" inline>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeStart" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择开始时间"></el-date-picker>
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeEnd" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择结束时间"></el-date-picker>
</el-form-item>
<el-form-item label="入场钢卷号" prop="endTime">
<el-input style="width: 200px; display: inline-block;" v-model="queryParams.enterCoilNo"
placeholder="请输入入场钢卷号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="当前钢卷号" prop="endTime">
<el-input style="width: 200px;" v-model="queryParams.currentCoilNo" placeholder="请输入当前钢卷号" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="逻辑库位" prop="endTime">
<!-- <warehouse-select v-model="queryParams.warehouseId" placeholder="请选择仓库/库区/库位"
style="width: 100%; display: inline-block; width: 200px;" clearable /> -->
<el-select v-model="warehouseIds" collapse-tags multiple placeholder="请选择逻辑库位" style="width: 200px;">
<el-option v-for="item in warehouseOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="产品名称" prop="endTime">
<el-input style="width: 200px;" v-model="queryParams.itemName" placeholder="请输入产品名称" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="规格" prop="endTime">
<memo-input style="width: 200px;" v-model="queryParams.itemSpecification" storageKey="coilSpec"
placeholder="请选择规格" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="材质" prop="endTime">
<muti-select style="width: 200px;" v-model="queryParams.itemMaterial" :options="dict.type.coil_material"
placeholder="请选择材质" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="厂家" prop="endTime">
<muti-select style="width: 200px;" v-model="queryParams.itemManufacturer"
:options="dict.type.coil_manufacturer" placeholder="请选择厂家" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item prop="endTime">
<el-button type="primary" @click="getList">查询</el-button>
<el-button type="primary" @click="exportData">导出</el-button>
<el-button type="primary" @click="settingVisible = true">列设置</el-button>
</el-form-item>
</el-form>
</el-row>
<el-descriptions title="统计信息" :column="3" border>
<el-descriptions-item label="总钢卷数量">{{ summary.totalCount }}</el-descriptions-item>
<el-descriptions-item label="总重">{{ summary.totalWeight }}t</el-descriptions-item>
<el-descriptions-item label="均重">{{ summary.avgWeight }}t</el-descriptions-item>
</el-descriptions>
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<coil-table :columns="outputColumns" :data="list"></coil-table>
<el-dialog title="列设置" :visible.sync="settingVisible" width="50%">
<el-radio-group v-model="activeColumnConfig">
<el-radio-button label="coil-report-output">产出明细配置</el-radio-button>
</el-radio-group>
<columns-setting :reportType="activeColumnConfig"></columns-setting>
</el-dialog>
</div>
</template>
<script>
import { listCoilWithIds } 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";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import ColumnsSetting from "@/views/wms/report/components/setting/columns.vue";
import CoilTable from "@/views/wms/report/components/coilTable/index.vue";
export default {
name: 'OutTemplate',
components: {
ProductInfo,
RawMaterialInfo,
CoilNo,
MemoInput,
MutiSelect,
WarehouseSelect,
ColumnsSetting,
CoilTable,
},
props: {
baseQueryParams: {
type: Object,
default: () => ({})
},
warehouseOptions: {
type: Array,
default: () => []
}
},
dicts: ['product_coil_status', 'coil_material', 'coil_itemname', 'coil_manufacturer'],
data() {
// 工具函数:个位数补零,保证格式统一(比如 9 → 095 → 05
const addZero = (num) => num.toString().padStart(2, '0')
const now = new Date() // 当前本地北京时间
// 核心:获取【昨天】的日期对象(自动处理跨月/跨年,无边界问题)
const yesterday = new Date(now)
yesterday.setDate(yesterday.getDate() - 1)
// 昨天的年、月、日(补零格式化)
const yesYear = yesterday.getFullYear()
const yesMonth = addZero(yesterday.getMonth() + 1)
const yesDay = addZero(yesterday.getDate())
// 今天的年、月、日(补零格式化)
const nowYear = now.getFullYear()
const nowMonth = addZero(now.getMonth() + 1)
const nowDay = addZero(now.getDate())
// ✅ 目标时间区间昨天早上6点 至 今天早上6点
const startTime = `${yesYear}-${yesMonth}-${yesDay} 07:00:00`
const endTime = `${nowYear}-${nowMonth}-${nowDay} 07:00:00`
return {
activeColumnConfig: 'coil-report-output',
settingVisible: false,
list: [],
queryParams: {
pageNum: 1,
pageSize: 9999,
// status: 1,
byCreateTimeStart: startTime,
byCreateTimeEnd: endTime,
enterCoilNo: '',
currentCoilNo: '',
warehouseId: '',
productName: '',
itemSpecification: '',
itemMaterial: '',
itemManufacturer: '',
},
loading: false,
warehouseIds: [
'1988150099140866050',
'1988150263284953089',
'1988150545175736322',
'1988150150521090049',
'2019583656787259393',
'2019583325311414274',
'2019583429955104769',
'2019583137616310273',
],
outputColumns: [],
}
},
watch: {
warehouseOptions: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.warehouseIds = newVal.map(item => item.value)
this.getList()
}
},
immediate: true,
}
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const totalCount = this.list.length
const totalWeight = this.list.reduce((acc, cur) => acc + parseFloat(cur.netWeight), 0)
const avgWeight = totalCount > 0 ? (totalWeight / totalCount).toFixed(2) : 0
return {
totalCount,
totalWeight: totalWeight.toFixed(2),
avgWeight,
}
}
},
methods: {
// 加载列设置
loadColumns() {
this.outputColumns = JSON.parse(localStorage.getItem('preference-tableColumns-coil-report-output') || '[]') || []
},
// 统一查询入口
handleQuery() {
this.getList()
},
getList() {
this.loading = true
Promise.all([
listCoilWithIds({
selectType: 'raw_material',
itemType: 'raw_material',
warehouseIds: this.warehouseIds.join(','),
...this.queryParams,
...this.baseQueryParams,
}),
listCoilWithIds({
selectType: 'product',
itemType: 'product',
warehouseIds: this.warehouseIds.join(','),
...this.queryParams,
...this.baseQueryParams,
}),
]).then((resList) => {
console.log(resList)
const list = resList.flatMap(res => res.rows)
// 按照createTime 降序排序
this.list = list.sort(
(a, b) => new Date(b.createTime) - new Date(a.createTime)
).map(item => {
// 计算宽度和厚度,将规格按照*分割,*前的是厚度,*后的是宽度
const [thickness, width] = item.specification.split('*')
return {
...item,
computedThickness: parseFloat(thickness),
computedWidth: parseFloat(width),
}
})
this.loading = false
})
},
// 导出
exportData() {
this.download('wms/materialCoil/export', {
coilIds: this.list.map(item => item.coilId).join(',')
}, `materialCoil_${new Date().getTime()}.xlsx`)
},
},
mounted() {
this.getList()
this.loadColumns()
}
}
</script>
<style scoped></style>