feat(mes/wms): 新增磨辊人管理与免验规则优化
1. 优化wms产线免验逻辑,新增镀铬产线免验支持 2. 新增磨辊人统计报表导出功能 3. 新增磨辊操作人字典维护功能
This commit is contained in:
@@ -108,14 +108,16 @@
|
||||
<el-card shadow="never" class="detail-card" body-style="padding:10px;overflow:auto">
|
||||
<div slot="header" class="card-header">
|
||||
<span class="card-title"><i class="el-icon-document" /> 磨削台账</span>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-plus"
|
||||
style="margin-left:auto"
|
||||
:disabled="!!editRow"
|
||||
@click="startAdd"
|
||||
>新增磨削记录</el-button>
|
||||
<span style="margin-left:auto;display:flex;gap:8px">
|
||||
<el-button size="mini" type="text" icon="el-icon-setting" @click="openOperatorDict">操作人维护</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-plus"
|
||||
:disabled="!!editRow"
|
||||
@click="startAdd"
|
||||
>新增磨削记录</el-button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
@@ -334,6 +336,52 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作人字典维护对话框 -->
|
||||
<el-dialog title="操作人字典维护" :visible.sync="operatorDictOpen" width="650px" append-to-body :close-on-click-modal="false" @closed="operatorDictList = []">
|
||||
<div style="margin-bottom:10px">
|
||||
<el-button type="primary" size="mini" icon="el-icon-plus" @click="handleAddOperator">新增操作人</el-button>
|
||||
</div>
|
||||
<el-table :data="operatorDictList" v-loading="operatorDictLoading" size="small" border style="width:100%">
|
||||
<el-table-column label="姓名" prop="dictLabel" align="center" />
|
||||
<el-table-column label="值" prop="dictValue" align="center" />
|
||||
<el-table-column label="状态" align="center" width="100">
|
||||
<template slot-scope="{row}">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'" size="mini">
|
||||
{{ row.status === '0' ? '在职' : '离职' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="140">
|
||||
<template slot-scope="{row}">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleEditOperator(row)">编辑</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" style="color:#c5221f" @click="handleDeleteOperator(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 操作人新增/修改对话框 -->
|
||||
<el-dialog :title="operatorFormTitle" :visible.sync="operatorFormOpen" width="400px" append-to-body :close-on-click-modal="false" @close="resetOperatorForm">
|
||||
<el-form ref="operatorForm" :model="operatorForm" :rules="operatorFormRules" label-width="80px" size="small">
|
||||
<el-form-item label="姓名" prop="dictLabel">
|
||||
<el-input v-model="operatorForm.dictLabel" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="值" prop="dictValue">
|
||||
<el-input v-model="operatorForm.dictValue" placeholder="请输入值" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="operatorForm.status">
|
||||
<el-radio label="0">在职</el-radio>
|
||||
<el-radio label="1">离职</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" size="small" @click="submitOperatorForm">确 定</el-button>
|
||||
<el-button size="small" @click="operatorFormOpen = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 轧辊新增/修改对话框 -->
|
||||
<el-dialog
|
||||
:title="rollFormTitle"
|
||||
@@ -437,6 +485,7 @@
|
||||
import { listRollInfo, getRollInfo, addRollInfo, updateRollInfo, delRollInfo } from '@/api/mes/roll/rollInfo'
|
||||
import { listRollGrind, addRollGrind, updateRollGrind, delRollGrind, getMonthlyStats } from '@/api/mes/roll/rollGrind'
|
||||
import { listProductionLine } from '@/api/wms/productionLine'
|
||||
import { listData, addData, updateData, delData } from '@/api/system/dict/data'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
|
||||
export default {
|
||||
@@ -474,6 +523,17 @@ export default {
|
||||
rollFormRules: {
|
||||
rollNo: [{ required: true, message: '轧辊编号不能为空', trigger: 'blur' }],
|
||||
rollType: [{ required: true, message: '请选择辊型', trigger: 'change' }]
|
||||
},
|
||||
|
||||
operatorDictOpen: false,
|
||||
operatorDictLoading: false,
|
||||
operatorDictList: [],
|
||||
operatorFormOpen: false,
|
||||
operatorFormTitle: '',
|
||||
operatorForm: {},
|
||||
operatorFormRules: {
|
||||
dictLabel: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
||||
dictValue: [{ required: true, message: '值不能为空', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -753,6 +813,54 @@ export default {
|
||||
resetRollForm() {
|
||||
this.rollForm = {}
|
||||
this.$nextTick(() => { this.$refs.rollForm && this.$refs.rollForm.clearValidate() })
|
||||
},
|
||||
|
||||
// ── 操作人字典维护 ──────────────────────────────
|
||||
openOperatorDict() {
|
||||
this.operatorDictOpen = true
|
||||
this.loadOperatorDict()
|
||||
},
|
||||
loadOperatorDict() {
|
||||
this.operatorDictLoading = true
|
||||
listData({ dictType: 'mes_roll_operator', pageNum: 1, pageSize: 999 }).then(res => {
|
||||
this.operatorDictList = res.rows || []
|
||||
}).finally(() => { this.operatorDictLoading = false })
|
||||
},
|
||||
handleAddOperator() {
|
||||
this.operatorForm = { dictType: 'mes_roll_operator', dictLabel: '', dictValue: '', status: '0' }
|
||||
this.operatorFormTitle = '新增操作人'
|
||||
this.$nextTick(() => { this.operatorFormOpen = true })
|
||||
},
|
||||
handleEditOperator(row) {
|
||||
this.operatorForm = { ...row }
|
||||
this.operatorFormTitle = '修改操作人'
|
||||
this.$nextTick(() => { this.operatorFormOpen = true })
|
||||
},
|
||||
handleDeleteOperator(row) {
|
||||
this.$modal.confirm(`确认删除操作人【${row.dictLabel}】?`).then(() => {
|
||||
return delData(row.dictCode)
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess('删除成功')
|
||||
this.$store.dispatch('dict/removeDict', 'mes_roll_operator')
|
||||
this.loadOperatorDict()
|
||||
})
|
||||
},
|
||||
submitOperatorForm() {
|
||||
this.$refs.operatorForm.validate(valid => {
|
||||
if (!valid) return
|
||||
const form = { ...this.operatorForm }
|
||||
const api = form.dictCode ? updateData : addData
|
||||
api(form).then(() => {
|
||||
this.$modal.msgSuccess(form.dictCode ? '修改成功' : '新增成功')
|
||||
this.operatorFormOpen = false
|
||||
this.$store.dispatch('dict/removeDict', 'mes_roll_operator')
|
||||
this.loadOperatorDict()
|
||||
})
|
||||
})
|
||||
},
|
||||
resetOperatorForm() {
|
||||
this.operatorForm = {}
|
||||
this.$nextTick(() => { this.$refs.operatorForm && this.$refs.operatorForm.clearValidate() })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,11 +78,19 @@
|
||||
<div class="card-header">
|
||||
<span class="card-title"><i class="el-icon-user" /> 磨辊人统计</span>
|
||||
<span class="card-subtitle" v-if="operatorStats.length">共 {{ operatorStats.length }} 人</span>
|
||||
<el-button size="mini" type="primary" plain icon="el-icon-download" style="margin-left:8px" @click="exportOperatorStats" :disabled="!operatorStats.length">导出</el-button>
|
||||
</div>
|
||||
<el-table :data="operatorStats" size="small" border stripe style="width:100%"
|
||||
v-if="operatorStats.length" :default-sort="{ prop: 'totalGrindAmount', order: 'descending' }">
|
||||
<el-table-column label="序号" type="index" align="center" />
|
||||
<el-table-column label="磨辊人" prop="operator" sortable />
|
||||
<el-table-column label="在职状态" align="center" width="90">
|
||||
<template slot-scope="{row}">
|
||||
<el-tag :type="operatorStatusType(row.operator)" size="mini" disable-transitions>
|
||||
{{ operatorStatusLabel(row.operator) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="CR(中间辊)" align="center">
|
||||
<el-table-column label="磨削次数" prop="crGrindCount" align="center" sortable />
|
||||
<el-table-column label="磨削总量(mm)" align="right" sortable>
|
||||
@@ -128,6 +136,7 @@
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import * as XLSX from 'xlsx'
|
||||
import { getRollStats, listRollInfo } from '@/api/mes/roll/rollInfo'
|
||||
import { listRollGrindAll } from '@/api/mes/roll/rollGrind'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
@@ -135,6 +144,7 @@ import rollLineMixin from '../rollLineMixin'
|
||||
export default {
|
||||
name: 'RollReport',
|
||||
mixins: [rollLineMixin],
|
||||
dicts: ['mes_roll_operator'],
|
||||
data() {
|
||||
const now = new Date()
|
||||
const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
|
||||
@@ -357,6 +367,20 @@ export default {
|
||||
this.trendChart && this.trendChart.resize()
|
||||
this.pieChart && this.pieChart.resize()
|
||||
},
|
||||
operatorStatusLabel(name) {
|
||||
if (!name) return ''
|
||||
const items = this.dict?.type?.mes_roll_operator || []
|
||||
const found = items.find(item => item.value === name)
|
||||
if (!found || !found.raw) return '未知'
|
||||
return found.raw.status === '0' ? '在职' : '离职'
|
||||
},
|
||||
operatorStatusType(name) {
|
||||
if (!name) return ''
|
||||
const items = this.dict?.type?.mes_roll_operator || []
|
||||
const found = items.find(item => item.value === name)
|
||||
if (!found || !found.raw) return 'info'
|
||||
return found.raw.status === '0' ? 'success' : 'danger'
|
||||
},
|
||||
handleQuery() {
|
||||
this.loadData()
|
||||
},
|
||||
@@ -367,6 +391,35 @@ export default {
|
||||
const fmt = d => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
|
||||
this.dateRange = [fmt(sevenDaysAgo), fmt(now)]
|
||||
this.loadData()
|
||||
},
|
||||
exportOperatorStats() {
|
||||
const rows = [
|
||||
['序号', '磨辊人', '在职状态', 'CR磨削次数', 'CR磨削总量(mm)', 'CR平均磨削量(mm)', 'BR磨削次数', 'BR磨削总量(mm)', 'BR平均磨削量(mm)', 'WR磨削次数', 'WR磨削总量(mm)', 'WR平均磨削量(mm)', '合计磨削次数', '合计磨削总量(mm)', '合计平均磨削量(mm)']
|
||||
]
|
||||
this.operatorStats.forEach((item, idx) => {
|
||||
rows.push([
|
||||
idx + 1,
|
||||
item.operator,
|
||||
this.operatorStatusLabel(item.operator),
|
||||
item.crGrindCount, item.crTotalGrindAmount, item.crAvgGrindAmount,
|
||||
item.brGrindCount, item.brTotalGrindAmount, item.brAvgGrindAmount,
|
||||
item.wrGrindCount, item.wrTotalGrindAmount, item.wrAvgGrindAmount,
|
||||
item.grindCount, item.totalGrindAmount, item.avgGrindAmount
|
||||
])
|
||||
})
|
||||
const ws = XLSX.utils.aoa_to_sheet(rows)
|
||||
const wb = XLSX.utils.book_new()
|
||||
XLSX.utils.book_append_sheet(wb, ws, '磨辊人统计')
|
||||
const buf = XLSX.write(wb, { bookType: 'xlsx', type: 'array' })
|
||||
const blob = new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `磨辊人统计_${this._beginTime || ''}_${this._endTime ? this._endTime.substring(0, 10) : ''}.xlsx`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,9 +642,9 @@ export default {
|
||||
isGrindAction() {
|
||||
return this.actionType == 505 || this.actionType == 525 || this.actionType == 206
|
||||
},
|
||||
// 镀锌/酸轧产线免验净重和厚度范围
|
||||
// 镀锌/酸轧/镀铬产线免验净重和厚度范围
|
||||
isExemptFromValidation() {
|
||||
return [11, 200, 520, 206, 501, 521].includes(Number(this.actionType))
|
||||
return [11, 200, 520, 206, 501, 521, 505, 525, 206].includes(Number(this.actionType))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
Reference in New Issue
Block a user