feat: 多个页面优化与功能增强

1. 磨削页面:添加操作人权限控制,自动填充上次硬度值,移除字典值字段
2. 质保书页面:新增质保书类型筛选与表单字段,移除模板选择弹窗
3. 成本综合页面:添加产线校验、录入/查看切换、表格列控制与快捷操作
4. 质保书条目页面:新增类型筛选与表单字段,移除模板选择弹窗
This commit is contained in:
2026-06-04 10:26:09 +08:00
parent b4fbb8dfc8
commit 31d8d1ee16
4 changed files with 187 additions and 204 deletions

View File

@@ -1,6 +1,8 @@
<template>
<div class="app-container">
<div class="report-tab-bar">
<el-empty v-if="noLineType" description="请通过产线页面进入" />
<template v-else>
<div class="report-tab-bar">
<div class="report-tabs">
<span v-for="r in tabs" :key="r.reportId"
:class="['report-tab', { active: activeReport && activeReport.reportId === r.reportId }]"
@@ -18,14 +20,18 @@
<el-tag size="mini" style="margin-left:6px">{{ lineName(activeReport) }}</el-tag>
<span class="entry-meta">{{ parseTime(activeReport.reportDate,'{y}-{m}-{d}') }} 投入{{ activeReport.inputWeight }}t 产出{{ activeReport.outputWeight }}t</span>
<el-button type="primary" size="mini" style="float:right;margin-left:8px" @click="saveGrid" :loading="saving">保存</el-button>
<el-button size="mini" style="float:right" @click="openColCfg">列配置</el-button>
<el-button size="mini" style="float:right;margin-left:8px" @click="openColCfg">列配置</el-button>
<span style="float:right;margin-right:12px;font-size:12px;color:#606266;display:flex;align-items:center">
<span style="margin-right:4px">{{ inputMode ? '录入' : '查看' }}</span>
<el-switch v-model="inputMode" size="small" />
</span>
</div>
<el-alert :title="'已配置'+allCols.length+'个列'" type="info" :closable="false" show-icon style="margin-bottom:8px" />
<el-table v-loading="gridLoading" :data="gridRows" border stripe size="mini" style="width:100%" :header-cell-style="headerStyle">
<el-table v-loading="gridLoading" :data="gridRows" border stripe size="mini" style="width:100%" :header-cell-style="headerStyle" :key="'tbl-'+inputMode">
<el-table-column label="日期" width="135" fixed>
<template slot-scope="s"><el-date-picker v-model="s.row.detailDate" type="date" value-format="yyyy-MM-dd" size="mini" style="width:124px" @change="sortGrid" /></template>
</el-table-column>
<template v-for="col in allCols">
<template v-for="col in displayCols">
<el-table-column v-if="col.$type==='detail' && !col.isShift" :key="'d'+col.itemId" :label="col.itemName+(col.unit?'('+col.unit+')':'')" width="105" align="center">
<template slot-scope="s">
<el-input v-model="s.row['q'+col.itemId]" size="mini" @input="recalcAll">
@@ -214,8 +220,13 @@
<el-table-column label="报表标题" prop="reportTitle" />
<el-table-column label="日期" width="120"><template slot-scope="s">{{ parseTime(s.row.reportDate,'{y}-{m}-{d}') }}</template></el-table-column>
<el-table-column label="产线" width="70"><template slot-scope="s">{{ lineName(s.row) }}</template></el-table-column>
<el-table-column label="投入(t)" prop="inputWeight" width="80" />
<el-table-column label="产出(t)" prop="outputWeight" width="80" />
<el-table-column label="操作" width="180" align="center">
<template slot-scope="s">
<el-button size="mini" type="text" style="padding:0" @click="editRp(s.row)">修改</el-button>
<el-button size="mini" type="text" style="padding:0" @click="copyInlineRp(s.row)">复制</el-button>
<el-button size="mini" type="text" style="padding:0;color:#f56c6c" @click="delRp(s.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="q.pageNum" :limit.sync="q.pageSize" @pagination="getList" />
@@ -223,9 +234,6 @@
<el-form ref="rpf" :model="rpForm" :rules="{reportTitle:[{required:true,message:'请输入',trigger:'blur'}]}" label-width="100px">
<el-form-item label="报表标题" prop="reportTitle"><el-input v-model="rpForm.reportTitle" /></el-form-item>
<el-form-item label="报表日期" prop="reportDate"><el-date-picker v-model="rpForm.reportDate" type="date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item>
<el-form-item label="产线" prop="lineType"><el-select v-model="rpForm.lineType" style="width:100%" placeholder="请选择产线"><el-option v-for="ln in lineOptions" :key="ln.lineId" :label="ln.lineName" :value="ln.lineId" /></el-select></el-form-item>
<el-form-item label="投入量(吨)" prop="inputWeight"><el-input-number v-model="rpForm.inputWeight" :precision="2" :min="0" style="width:100%" /></el-form-item>
<el-form-item label="产出量(吨)" prop="outputWeight"><el-input-number v-model="rpForm.outputWeight" :precision="2" :min="0" style="width:100%" /></el-form-item>
<el-form-item label="备注" prop="remark"><el-input v-model="rpForm.remark" type="textarea" /></el-form-item>
</el-form>
<div slot="footer"><el-button :loading="rpBtnLoading" type="primary" @click="submitRp"> </el-button><el-button @click="rpOpen=false"> </el-button></div>
@@ -242,7 +250,9 @@
<el-button @click="copyRpOpen=false"> </el-button>
</div>
</el-dialog>
</el-dialog>
</el-dialog>
</template>
</div>
</div>
</template>
@@ -352,7 +362,10 @@ export default {
copyCfgOpen: false, copyReports: [], copySrc: null,
configOpen: false,
autoLoading: {},
lineOptions: []
lineOptions: [],
lineType: null,
noLineType: false,
inputMode: false
}
},
computed: {
@@ -360,6 +373,10 @@ export default {
const used = new Set(this.allCols.filter(c => c.$type === 'detail').map(c => String(c.itemId)))
return this.allItems.filter(i => !used.has(String(i.itemId)))
},
displayCols() {
if (!this.inputMode) return this.allCols
return [...this.allCols.filter(c => c.$type === 'detail'), ...this.allCols.filter(c => c.$type === 'metric')]
},
headerStyle() {
return ({ column }) => {
if (!column || !column.label) return {}
@@ -373,14 +390,33 @@ export default {
}
},
watch: { configOpen(v) { if (!v) this.rpOpen = false } },
created() { this.getTabList(); this.loadItems(); this.loadLines() },
created() {
const lineType = this.$route.query.lineType
if (lineType) {
this.lineType = lineType
this.getTabList()
this.loadItems()
this.loadLines()
} else {
this.noLineType = true
}
},
methods: {
/* report */
getList() { this.loading = true; listProdReport(this.q).then(r=>{this.list=r.rows;this.total=r.total}).finally(()=>this.loading=false) },
getTabList() { listProdReport({ pageNum: 1, pageSize: 9999 }).then(r => { this.tabs = r.rows || [] }) },
getList() {
this.loading = true
const params = { ...this.q }
if (this.lineType) params.lineType = this.lineType
listProdReport(params).then(r=>{this.list=r.rows;this.total=r.total}).finally(()=>this.loading=false)
},
getTabList() {
const params = { pageNum: 1, pageSize: 9999 }
if (this.lineType) params.lineType = this.lineType
listProdReport(params).then(r => { this.tabs = r.rows || [] })
},
search() { this.q.pageNum = 1; this.getList() },
resetQ() { this.resetForm("qf"); this.search() },
addRp() { this.rpForm = {}; this.rpTitle = "新增"; this.rpOpen = true },
addRp() { this.rpForm = { lineType: this.lineType || undefined }; this.rpTitle = "新增"; this.rpOpen = true },
editRp(row) {
const id = (row&&row.reportId)||this.selIds[0]; if(!id)return
getProdReport(id).then(r=>{
@@ -414,6 +450,10 @@ export default {
this.copyRpForm = { reportId: this.selIds[0], reportTitle: (row ? row.reportTitle : '') + '-副本', reportDate: row ? row.reportDate : undefined }
this.copyRpOpen = true
},
copyInlineRp(row) {
this.copyRpForm = { reportId: row.reportId, reportTitle: row.reportTitle + '-副本', reportDate: row.reportDate }
this.copyRpOpen = true
},
async doCopyRp() {
const sid = this.copyRpForm.reportId
if (!sid) return
@@ -619,7 +659,6 @@ export default {
},
evalF(f) { const s = f.replace(/[^0-9+\-*/.()\s]/g,''); if(!s) return null; try { const r = new Function('return ('+s+')')(); return isFinite(r)?Math.round(r*10000)/10000:null } catch(e){ return null } },
sortGrid() { this.gridRows.sort((a,b)=>{if(!a.detailDate)return 1;if(!b.detailDate)return -1;return a.detailDate.localeCompare(b.detailDate)}) },
async saveGrid() {
const rid = this.activeReport.reportId; if (!rid) return; this.saving = true
try {