Files
shgx_tz_vue-sync/src/views/materialManagement/mmMrpManagement/MrpList.vue
赵正易 cffba84e8f feat(mrp管理): 添加MRP清单导出功能并优化界面
- 在MRP清单页面添加导出全部数据功能,支持分页获取数据并生成Excel文件
- 添加导出进度条显示导出进度
- 为表格添加总成编号、总成名称和参考时间段列
- 统一容器样式为app-container
- 优化按钮大小和样式
2025-09-03 09:49:03 +08:00

346 lines
12 KiB
Vue

<!--
* @Descripttion: (MRP清单)
* @Author: (admin)
* @Date: (2025-08-13)
-->
<template>
<div class="app-container">
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item label="线别" prop="lineCode">
<el-select v-model="queryParams.lineCode" placeholder="请选择线别">
<el-option label="全部" value=""></el-option>
<el-option v-for="line in lineOptions" :key="line.value" :label="line.label" :value="line.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="日期" prop="workOrderDate">
<el-date-picker v-model="queryParams.workOrderDate" :clearable="false" type="date"
placeholder="选择日期"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 工具区域 -->
<el-row :gutter="15" class="mb10">
<el-col :span="1.5">
<el-button type="primary" size="mini" plain @click="openGenerateMrpDialog">手动更新MRP清单
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" icon="el-icon-download" size="mini" :disabled="loading"
@click="handleExportAll">导出全部数据</el-button>
</el-col>
<right-toolbar :show-search.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<!-- 添加进度条组件 -->
<el-row v-if="exportProgress > 0 && exportProgress < 100">
<el-col :span="4"><span>Excel导出进度:</span></el-col>
<el-col :span="20"><el-progress :percentage="exportProgress" show-text></el-progress></el-col>
</el-row>
<el-table :data="dataList" v-loading="loading" ref="table" border header-cell-class-name="el-table-header-cell"
highlight-current-row @sort-change="sortChange">
<el-table-column type="index" width="50" align="center" />
<el-table-column prop="lineCode" label="线别" align="center" />
<el-table-column prop="productionCode" label="总成编号" align="center" />
<el-table-column prop="productionName" label="总成名称" align="center" />
<el-table-column prop="materialCode" label="物料编号" align="center" />
<el-table-column prop="materialName" label="物料名称" align="center" />
<el-table-column prop="issuanceTime" label="参考时间段" align="center" />
<el-table-column prop="quantity" label="数量" align="center" />
<el-table-column prop="createdBy" label="创建人" align="center" />
<el-table-column prop="createdTime" label="创建时间" />
</el-table>
<pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 生成MRP清单对话框 -->
<el-dialog :title="'手动更新MRP清单'" :lock-scroll="false" :visible.sync="generateMrpOpen">
<el-form ref="mrpFormRef" :model="mrpForm" :rules="mrpRules" label-width="100px">
<el-row :gutter="20">
<el-col :lg="24">
<el-form-item label="线别" prop="lineCode">
<el-select v-model="mrpForm.lineCode" placeholder="请选择线别" style="width: 100%">
<el-option v-for="line in lineOptions" :key="line.value" :label="line.label"
:value="line.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="日期" prop="workOrderDate">
<el-date-picker v-model="mrpForm.workOrderDate" :clearable="false" type="date" placeholder="选择日期"
style="width: 100%"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelGenerateMrp">取消</el-button>
<el-button type="primary" @click="submitGenerateMrp">提交</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { saveAs } from 'file-saver'
import ExcelJS from 'exceljs'
import {
listMmMrp, GenerateLineMmMrp
}
from '@/api/materialManagement/mmMrpManagement.js'
export default {
name: 'mmMrpManagement',
components: {
},
data() {
// 线别选项 (1-28)
const lineOptions = []
for (let i = 1; i <= 28; i++) {
lineOptions.push({
value: i.toString(),
label: `线别${i}`
})
}
return {
ids: [],
loading: false,
showSearch: true,
queryParams: {
pageNum: 1,
pageSize: 10,
lineCode: '',
workOrderDate: '',
sort: '',
sortType: 'asc',
},
lineOptions: lineOptions,
columns: [],
total: 0,
dataList: [],
queryRef: null,
// 生成MRP相关
generateMrpOpen: false,
mrpFormRef: null,
mrpForm: {
lineCode: '1',
workOrderDate: this.$dayjs().format('YYYY-MM-DD') // 默认今天
},
mrpRules: {
lineCode: [{ required: true, message: '请选择线别', trigger: 'change' }],
workOrderDate: [{ required: true, message: '请选择日期', trigger: 'change' }]
},
exportProgress: 0, // 导出进度
}
},
created() {
this.queryParams.workOrderDate = this.$dayjs().format('YYYY-MM-DD')
this.getList()
},
methods: {
getList() {
this.loading = true
let params = { ...this.queryParams }
params.workOrderDate = this.$dayjs(params.workOrderDate).format('YYYY-MM-DD')
listMmMrp(params).then(res => {
const { code, data } = res
if (code == 200) {
this.dataList = data.result
this.total = data.totalNum
this.loading = false
}
})
},
// 查询
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
// 重置查询操作
resetQuery() {
this.resetForm("queryRef")
// 重置为默认线别和今天日期
this.queryParams.lineCode = '1'
this.queryParams.workOrderDate = this.$dayjs().format('YYYY-MM-DD')
this.handleQuery()
},
// 自定义排序
sortChange(column) {
var sort = undefined
var sortType = undefined
if (column.prop != null && column.order != null) {
sort = column.prop
sortType = column.order
}
this.queryParams.sort = sort
this.queryParams.sortType = sortType
this.handleQuery()
},
// 打开生成MRP对话框
openGenerateMrpDialog() {
this.generateMrpOpen = true
// 重置表单
this.mrpForm.lineCode = '1'
this.mrpForm.workOrderDate = this.$dayjs().format('YYYY-MM-DD')
this.resetForm("mrpFormRef")
},
// 关闭生成MRP对话框
cancelGenerateMrp() {
this.generateMrpOpen = false
},
// 提交生成MRP
submitGenerateMrp() {
this.$refs["mrpFormRef"].validate((valid) => {
if (valid) {
this.loading = true
let params = { ...this.mrpForm }
params.workOrderDate = this.$dayjs(params.workOrderDate).format('YYYY-MM-DD')
GenerateLineMmMrp(params).then(res => {
this.loading = false
if (res.code == 200) {
this.$modal.msgSuccess('生成MRP清单成功')
this.generateMrpOpen = false
this.getList()
} else {
this.$modal.msgError(res.msg || '生成失败')
}
}).catch(() => {
this.loading = false
this.$modal.msgError('生成失败')
})
}
})
},
// 生成Excel文件
async generateExcel(allData) {
const workbook = new ExcelJS.Workbook()
const worksheet = workbook.addWorksheet('MRP清单')
// 构建表头
const header = [
'线别',
'总成编号',
'总成名称',
'物料编号',
'物料名称',
'参考时间段',
'数量',
'创建人',
'创建时间'
]
const headerRow = worksheet.addRow(header)
headerRow.eachCell((cell) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FF2D3D51' },
}
cell.font = { color: { argb: 'FFFFFFFF' }, size: 16 }
cell.border = {
top: { style: 'thin', color: { argb: 'FF161823' } },
left: { style: 'thin', color: { argb: 'FF161823' } },
bottom: { style: 'thin', color: { argb: 'FF161823' } },
right: { style: 'thin', color: { argb: 'FF161823' } },
}
})
// 添加数据
allData.forEach((rowData) => {
const rowValues = [
rowData.lineCode,
rowData.productionCode,
rowData.productionName,
rowData.materialCode,
rowData.materialName,
rowData.issuanceTime,
rowData.quantity,
rowData.createdBy,
rowData.createdTime
]
worksheet.addRow(rowValues)
})
// 设置单元格样式
worksheet.eachRow((row, rowIndex) => {
if (rowIndex > 1) { // 跳过表头
row.eachCell((cell) => {
cell.border = {
top: { style: 'thin', color: { argb: 'FF161823' } },
left: { style: 'thin', color: { argb: 'FF161823' } },
bottom: { style: 'thin', color: { argb: 'FF161823' } },
right: { style: 'thin', color: { argb: 'FF161823' } },
}
cell.font = { size: 14, bold: true }
})
}
})
// 调整列宽
header.forEach((_, index) => {
worksheet.columns[index].width = 20
})
return workbook
},
// 导出全部数据
async handleExportAll() {
this.loading = true
this.exportProgress = 0
try {
// 计算总页数
const totalPages = Math.ceil(this.total / this.queryParams.pageSize)
const allData = []
// 分页获取数据
for (let page = 1; page <= totalPages; page++) {
const params = { ...this.queryParams, pageNum: page }
params.workOrderDate = this.$dayjs(params.workOrderDate).format('YYYY-MM-DD')
const res = await listMmMrp(params)
if (res.code === 200) {
allData.push(...res.data.result)
}
// 更新进度
this.exportProgress = Math.round((page / totalPages) * 100)
}
// 生成Excel文件
const workbook = await this.generateExcel(allData.sort((a, b) => {
// 先按线别升序排序
if (a.lineCode !== b.lineCode) {
return a.lineCode.localeCompare(b.lineCode, 'zh-CN');
}
// 同线别内按参考时间段升序排序
return new Date(a.issuanceTime) - new Date(b.issuanceTime);
}))
const buffer = await workbook.xlsx.writeBuffer()
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
saveAs(blob, `MRP清单_线别${this.queryParams.lineCode || '全部'}_日期${this.queryParams.workOrderDate}_${this.$dayjs().format('YYYY-MM-DD_HH-mm-ss')}.xlsx`)
this.exportProgress = 100
this.$modal.msgSuccess('导出成功')
} catch (error) {
console.error('导出全部数据失败:', error)
this.$modal.msgError('导出失败')
} finally {
this.loading = false
// 导出完成或出错,隐藏进度条
setTimeout(() => {
this.exportProgress = 0
}, 1000)
}
},
}
}
</script>
<style scoped>
/* 添加进度条样式 */
.el-progress {
margin-top: 10px;
}
</style>