Commit 1aaffa76 authored by chicheng's avatar chicheng

进度报表添加

parent d5d61e76
/**
* 进度报表、生产报工报表 API
*/
import request from '@/utils/request'
const BASE = '/report/pro/feedback'
/**
* 进度报表-工序名称列表(动态表头)
*/
export function getProgressReportProcessNames() {
return request({ url: BASE + '/progressReport/processNames', method: 'get' })
}
/**
* 进度报表-列表(分页)
* @param {Object} params - scheduleStartDate, scheduleEndDate, orderCode, orderSerial, productCode, productName, progressLessThan, requestDateBefore, pageNum, pageSize
*/
export function listProgressReport(params) {
return request({ url: BASE + '/progressReport/list', method: 'get', params })
}
...@@ -16,8 +16,8 @@ axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' ...@@ -16,8 +16,8 @@ axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
const service = axios.create({ const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分 // axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API, baseURL: process.env.VUE_APP_BASE_API,
// 超时 // 超时(2分钟)
timeout: 30000 timeout: 120000
}) })
// request拦截器 // request拦截器
......
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px" class="progress-report-form">
<el-form-item label="排产时间" prop="scheduleDateRange">
<el-date-picker
v-model="scheduleDateRange"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
style="width: 240px"
/>
</el-form-item>
<el-form-item label="订单单号" prop="orderCode">
<el-input v-model="queryParams.orderCode" placeholder="订单单号" clearable style="width: 160px" />
</el-form-item>
<el-form-item label="订单序号" prop="orderSerial">
<el-input v-model="queryParams.orderSerial" placeholder="订单序号" clearable style="width: 120px" />
</el-form-item>
<el-form-item label="产品编号" prop="productCode">
<el-input v-model="queryParams.productCode" placeholder="产品编号" clearable style="width: 140px" />
</el-form-item>
<el-form-item label="产品名称" prop="productName">
<el-input v-model="queryParams.productName" placeholder="产品名称" clearable style="width: 140px" />
</el-form-item>
<el-form-item label="在制进度小于(%)" prop="progressLessThan" class="progress-less-than-item">
<el-input
v-model="progressLessThanInput"
type="number"
placeholder="不填则不过滤"
clearable
style="width: 120px"
min="0"
max="100"
@input="onProgressLessThanInput"
/>
</el-form-item>
<el-form-item label="需求时间(小于)" prop="requestDateBefore">
<el-date-picker
v-model="queryParams.requestDateBefore"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
style="width: 160px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="tableData"
border
:header-cell-style="{ background: '#f5f7fa' }"
style="width: 100%; margin-top: 12px"
max-height="600"
>
<!-- 固定列 -->
<el-table-column prop="scheduleTime" label="排产时间" width="160" align="center" />
<el-table-column prop="orderCode" label="订单单号" width="140" align="center" />
<el-table-column prop="lineName" label="产线名称" width="100" align="center" />
<el-table-column prop="workorderCode" label="生产工单" width="140" align="center" />
<el-table-column prop="orderSerial" label="订单序号" width="100" align="center" />
<el-table-column prop="workorderType" label="工单类型" width="100" align="center" />
<el-table-column prop="productCode" label="产品编号" width="120" align="center" />
<el-table-column prop="productName" label="产品名称" min-width="140" align="center" show-overflow-tooltip />
<!-- 动态工序列:列名固定为 工序1~N,每个单元格两行:第一行工序名,第二行完工数量 -->
<el-table-column
v-for="i in maxProcessCount"
:key="'process-' + i"
:label="'工序' + i"
align="center"
width="120"
min-width="100"
>
<template slot-scope="scope">
<div class="process-cell">
<div class="process-name">{{ getProcessName(scope.row, i - 1) }}</div>
<div class="process-qty">{{ getProcessQty(scope.row, i - 1) }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="planQuantity" label="计划数量" width="100" align="center" />
<el-table-column label="在制进度%" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.progressPercent != null ? scope.row.progressPercent + '%' : '-' }}
</template>
</el-table-column>
<el-table-column prop="requestDate" label="需求时间" width="120" align="center" />
</el-table>
<el-pagination
v-show="total > 0"
:total="total"
:current-page.sync="queryParams.pageNum"
:page-size.sync="queryParams.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next"
@size-change="getList"
@current-change="getList"
style="margin-top: 12px"
/>
</div>
</template>
<script>
import { listProgressReport } from '@/api/mes/report/feedback'
export default {
name: 'ProgressReport',
data() {
return {
loading: false,
tableData: [],
total: 0,
scheduleDateRange: [],
maxProcessCount: 0,
progressLessThanInput: '', // 仅用于显示,空则不显示 0
queryParams: {
pageNum: 1,
pageSize: 10,
scheduleStartDate: null,
scheduleEndDate: null,
orderCode: null,
orderSerial: null,
productCode: null,
productName: null,
progressLessThan: null,
requestDateBefore: null
}
}
},
watch: {
scheduleDateRange(val) {
if (val && val.length === 2) {
this.queryParams.scheduleStartDate = val[0]
this.queryParams.scheduleEndDate = val[1]
} else {
this.queryParams.scheduleStartDate = null
this.queryParams.scheduleEndDate = null
}
}
},
created() {
this.getList()
},
methods: {
getList() {
this.loading = true
if (this.scheduleDateRange && this.scheduleDateRange.length === 2) {
this.queryParams.scheduleStartDate = this.scheduleDateRange[0]
this.queryParams.scheduleEndDate = this.scheduleDateRange[1]
}
listProgressReport(this.queryParams)
.then((res) => {
this.tableData = res.rows || []
this.total = res.total || 0
// 根据返回的 processQuantities,按行构造工序列表,并计算本次查询需要展示的工序列个数(1~N)
this.maxProcessCount = 0
this.tableData.forEach(row => {
const pq = row.processQuantities || {}
const list = Object.keys(pq).map(name => ({
name,
qty: pq[name]
}))
row._processList = list
if (list.length > this.maxProcessCount) {
this.maxProcessCount = list.length
}
})
})
.finally(() => {
this.loading = false
})
},
getProcessName(row, index) {
const list = row._processList || []
return list[index] ? list[index].name : ''
},
getProcessQty(row, index) {
const list = row._processList || []
if (!list[index]) return ''
const val = list[index].qty
return val != null ? Number(val) : ''
},
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
onProgressLessThanInput(val) {
if (val === '' || val == null) {
this.queryParams.progressLessThan = null
return
}
const num = Number(val)
if (!Number.isNaN(num) && num >= 0 && num <= 100) {
this.queryParams.progressLessThan = num
}
},
resetQuery() {
this.scheduleDateRange = []
this.progressLessThanInput = ''
this.queryParams = {
pageNum: 1,
pageSize: this.queryParams.pageSize,
scheduleStartDate: null,
scheduleEndDate: null,
orderCode: null,
orderSerial: null,
productCode: null,
productName: null,
progressLessThan: null,
requestDateBefore: null
}
this.getList()
}
}
}
</script>
<style scoped>
.process-header {
line-height: 1.2;
}
.process-name {
font-weight: 500;
padding-bottom: 2px;
}
.process-sub {
font-size: 12px;
color: #909399;
}
.process-cell {
display: flex;
flex-direction: column;
justify-content: space-between; /* 名称在上,数量在底 */
align-items: stretch;
width: 100%;
height: 60px; /* 固定单元格高度,可按需要微调 */
box-sizing: border-box;
position: relative; /* 让分割线可以绝对定位在固定位置 */
}
.process-cell::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 22px; /* 与数量区域的高度保持一致,分割线位置固定 */
border-top: 1px solid #ebeef5;
}
.process-cell .process-name {
width: 100%;
font-size: 13px;
line-height: 1.2;
padding-bottom: 4px;
word-break: break-all; /* 名称太长时自动换行 */
text-align: center;
}
.process-cell .process-qty {
text-align: center;
font-weight: 500;
padding-top: 4px;
height: 22px;
line-height: 22px; /* 数量区域高度固定,与上面的 bottom 对应 */
}
.progress-report-form .el-form-item {
margin-bottom: 12px;
}
/* 隐藏「在制进度小于」数字输入框的上下箭头 */
.progress-less-than-item ::v-deep input[type="number"]::-webkit-inner-spin-button,
.progress-less-than-item ::v-deep input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.progress-less-than-item ::v-deep input[type="number"] {
-moz-appearance: textfield;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment