Browse Source

2026-07-23

MRB异常单
master
fengyuan_yang 6 days ago
parent
commit
236ad20b66
  1. 4
      src/api/yieldReport/produce_order.js
  2. 4
      src/views/modules/todo/todoCenter.vue
  3. 646
      src/views/modules/yieldReport/com_mrb_register.vue
  4. 2
      src/views/modules/yieldReport/com_produce_report_normal.vue

4
src/api/yieldReport/produce_order.js

@ -57,8 +57,8 @@ export const updateOperatorTime = data => createAPI('schedule/updateOperatorTime
// 批量更新操作员时间
export const batchUpdateOperatorTime = data => createAPI('schedule/batchUpdateOperatorTime', 'POST', data)
// 更新派工单MRB信息
// 保存MRB异常单明细(工作台列表/代办审核单条)
export const updateScheduleMrbInfo = data => createAPI('schedule/updateScheduleMrbInfo', 'POST', data)
// 查询派工单MRB信息
// 查询MRB异常单明细
export const getScheduleMrbInfo = data => createAPI('schedule/getScheduleMrbInfo', 'POST', data)

4
src/views/modules/todo/todoCenter.vue

@ -268,6 +268,7 @@
<ComMrbRegister
ref="comMrbRegister"
:visible.sync="showMrbRegisterFlag"
mode="single"
:load-history="false"
@confirmed="onTodoMrbConfirmed">
</ComMrbRegister>
@ -521,7 +522,8 @@ export default {
site: row.site || this.searchData.site || this.$store.state.user.site,
orderNo: row.orderNo,
itemNo: itemNo,
seqNo: row.seqNo
seqNo: row.seqNo,
infoCode: row.infoCode || ''
}
this.showMrbRegisterFlag = false
this.$nextTick(() => {

646
src/views/modules/yieldReport/com_mrb_register.vue

@ -1,29 +1,114 @@
<template>
<div class="mrb-register">
<el-dialog title="MRB异常单登记" :close-on-click-modal="false" v-drag :visible.sync="visible" width="500px" :append-to-body="true" @close="handleClose">
<el-form :model="formData" :rules="rules" ref="mrbForm" label-width="65px" class="mrb-form">
<el-form-item prop="mrb">
<span slot="label" class="required-label">MRB</span>
<el-input v-model="formData.mrb" placeholder="请填写MRB异常单号" clearable></el-input>
<el-dialog
title="MRB异常单登记"
custom-class="mrb-register-dialog"
:close-on-click-modal="false"
v-drag
:visible.sync="visible"
:width="dialogWidth"
:append-to-body="true"
@close="handleClose">
<template v-if="isListMode">
<div class="table-toolbar">
<div>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="addModal">新增</el-button>
<el-button size="mini" icon="el-icon-delete" @click="deleteModal">删除</el-button>
</div>
<span class="toolbar-tip">卷号MRB制程异常单为必填项</span>
</div>
<div class="rq">
<el-table
ref="mrbTable"
:data="detailList"
border
class="mrb-detail-table"
max-height="420"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="45" align="center"></el-table-column>
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="rollNo" label="卷号" min-width="170" show-overflow-tooltip></el-table-column>
<el-table-column prop="mrb" label="MRB" min-width="170" show-overflow-tooltip></el-table-column>
<el-table-column prop="mrbInspectionReport" label="制程异常单" min-width="190" show-overflow-tooltip></el-table-column>
<el-table-column prop="mrbRemark" label="备注" min-width="220" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="90" align="center">
<template slot-scope="scope">
<el-link style="cursor: pointer" @click="editModal(scope.row)">编辑</el-link>
</template>
</el-table-column>
</el-table>
</div>
<el-footer style="height:25px;margin-top: 15px;text-align:center">
<el-button @click="closeDialog">关闭</el-button>
</el-footer>
</template>
<template v-else>
<el-form
ref="singleFormRef"
class="single-form"
:model="singleForm"
:rules="formRules"
label-width="90px">
<el-form-item label="卷号1" prop="rollNo">
<el-input v-model.trim="singleForm.rollNo" maxlength="100" clearable placeholder="请输入卷号"></el-input>
</el-form-item>
<el-form-item prop="mrbInspectionReport">
<span slot="label" class="required-label">制程异常单</span>
<el-input v-model="formData.mrbInspectionReport" placeholder="请填写制程异常单" clearable></el-input>
<el-form-item label="MRB" prop="mrb">
<el-input v-model.trim="singleForm.mrb" maxlength="100" clearable placeholder="请输入MRB异常单号"></el-input>
</el-form-item>
<el-form-item label="备注" prop="mrbRemark">
<el-input type="textarea" v-model="formData.mrbRemark" :rows="3"></el-input>
<el-form-item label="制程异常单" prop="mrbInspectionReport">
<el-input v-model.trim="singleForm.mrbInspectionReport" maxlength="100" clearable placeholder="请输入制程异常单号"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input v-model.trim="singleForm.mrbRemark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="备注(选填)"></el-input>
</el-form-item>
</el-form>
<el-footer style="height:35px;margin-top: 15px;text-align:center">
<el-footer style="height:25px;margin-top: 70px;text-align:center">
<el-button type="primary" :loading="loading" @click="submitForm">确定</el-button>
<el-button type="primary" @click="closeDialog">关闭</el-button>
<el-button @click="closeDialog">关闭</el-button>
</el-footer>
</template>
</el-dialog>
<el-dialog
:title="editDialogTitle"
custom-class="mrb-register-dialog"
:close-on-click-modal="false"
v-drag
:visible.sync="editDialogVisible"
width="540px"
:append-to-body="true"
@close="handleEditClose">
<el-form
ref="editFormRef"
class="single-form"
:model="editForm"
:rules="formRules"
label-width="90px">
<el-form-item label="卷号" prop="rollNo">
<el-input v-model.trim="editForm.rollNo" maxlength="100" clearable placeholder="请输入卷号"></el-input>
</el-form-item>
<el-form-item label="MRB" prop="mrb">
<el-input v-model.trim="editForm.mrb" maxlength="100" clearable placeholder="请输入MRB异常单号"></el-input>
</el-form-item>
<el-form-item label="制程异常单" prop="mrbInspectionReport">
<el-input v-model.trim="editForm.mrbInspectionReport" maxlength="100" clearable placeholder="请输入制程异常单号"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input v-model.trim="editForm.mrbRemark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="备注(选填)"></el-input>
</el-form-item>
</el-form>
<el-footer style="height:25px;margin-top: 70px;text-align:center">
<el-button type="primary" :loading="loading" @click="confirmEdit">确定</el-button>
<el-button @click="editDialogVisible = false">关闭</el-button>
</el-footer>
</el-dialog>
</div>
</template>
<script>
import { updateScheduleMrbInfo, getScheduleMrbInfo } from '@/api/yieldReport/produce_order.js';
import { updateScheduleMrbInfo, getScheduleMrbInfo } from '@/api/yieldReport/produce_order.js'
export default {
name: 'ComMrbRegister',
@ -35,264 +120,409 @@ export default {
loadHistory: {
type: Boolean,
default: true
},
mode: {
type: String,
default: 'list'
}
},
data() {
data () {
return {
loading: false,
scheduleData: {
site: '',
orderNo: '',
itemNo: '',
seqNo: ''
seqNo: '',
infoCode: ''
},
formData: {
mrb: '',
mrbInspectionReport: '',
mrbRemark: ''
},
rules: {
detailList: [],
selectedRowKeys: [],
editDialogVisible: false,
editDialogMode: 'add',
editForm: this.createEmptyForm(),
singleForm: this.createEmptyForm(),
rowKeySeed: 1,
formRules: {
rollNo: [
{ required: true, message: '请输入卷号', trigger: ['blur', 'change'] }
],
mrb: [
{
required: true,
message: ' ',
trigger: ['blur','change']
}
{ required: true, message: '请输入MRB异常单号', trigger: ['blur', 'change'] }
],
mrbInspectionReport: [
{
required: true,
message: ' ',
trigger: ['blur','change']
{ required: true, message: '请输入制程异常单号', trigger: ['blur', 'change'] }
]
}
],
}
};
},
computed: {
isListMode () {
return this.mode !== 'single'
},
dialogWidth () {
return this.isListMode ? '1000px' : '540px'
},
editDialogTitle () {
return this.editDialogMode === 'edit' ? 'MRB异常单编辑' : 'MRB异常单登记'
}
},
methods: {
/**
* 初始化对话框
* @param {Object} scheduleData - 派工单数据
*/
init(scheduleData) {
this.scheduleData = {
site: scheduleData.site,
orderNo: scheduleData.orderNo,
itemNo: scheduleData.itemNo,
seqNo: scheduleData.seqNo
};
//
this.formData = {
createEmptyForm () {
return {
id: null,
rowKey: '',
infoCode: '',
rollNo: '',
mrb: '',
mrbInspectionReport: '',
mrbRemark: ''
};
//
this.$nextTick(() => {
if (this.$refs.mrbForm) {
this.$refs.mrbForm.clearValidate();
}
});
// MRB
},
normalizeInfoCode (value) {
return (value || '').trim()
},
normalizeRowKey (row) {
if (row && row.id) {
return 'id-' + row.id
}
const key = 'tmp-' + this.rowKeySeed
this.rowKeySeed += 1
return key
},
normalizeHistoryRows (rows) {
return (rows || []).map((item) => ({
id: item.id || null,
rowKey: this.normalizeRowKey(item),
infoCode: this.normalizeInfoCode(item.infoCode),
rollNo: item.rollNo || '',
mrb: item.mrb || '',
mrbInspectionReport: item.mrbInspectionReport || item.processExceptionNo || '',
mrbRemark: item.mrbRemark || ''
}))
},
init (scheduleData) {
this.scheduleData = {
site: scheduleData.site || '',
orderNo: scheduleData.orderNo || '',
itemNo: scheduleData.itemNo,
seqNo: scheduleData.seqNo || '',
infoCode: scheduleData.infoCode || ''
}
this.loading = false
this.resetState()
if (this.loadHistory) {
this.loadMrbData();
this.loadMrbData()
}
},
/**
* 加载MRB数据
*/
loadMrbData() {
resetState () {
this.detailList = []
this.selectedRowKeys = []
this.editDialogVisible = false
this.editDialogMode = 'add'
this.editForm = this.createEmptyForm()
this.singleForm = this.createEmptyForm()
this.rowKeySeed = 1
this.clearValidate()
},
clearValidate () {
this.$nextTick(() => {
if (this.$refs.editFormRef) {
this.$refs.editFormRef.clearValidate()
}
if (this.$refs.singleFormRef) {
this.$refs.singleFormRef.clearValidate()
}
})
},
parseHistoryRows (data) {
const mrbInfo = (data && data.mrbInfo) || {}
const rows = Array.isArray(mrbInfo.detailList)
? mrbInfo.detailList
: (Array.isArray(data && data.detailList) ? data.detailList : [])
if (rows.length > 0) {
return rows
}
if (mrbInfo.mrb || mrbInfo.mrbInspectionReport || mrbInfo.mrbRemark || mrbInfo.rollNo) {
return [{
id: mrbInfo.id || null,
infoCode: this.normalizeInfoCode(mrbInfo.infoCode),
rollNo: mrbInfo.rollNo || '',
mrb: mrbInfo.mrb || '',
mrbInspectionReport: mrbInfo.mrbInspectionReport || '',
mrbRemark: mrbInfo.mrbRemark || ''
}]
}
return []
},
loadMrbData () {
const params = {
site: this.scheduleData.site,
orderNo: this.scheduleData.orderNo,
itemNo: this.scheduleData.itemNo,
seqNo: this.scheduleData.seqNo
};
seqNo: this.scheduleData.seqNo,
infoCode: this.scheduleData.infoCode
}
getScheduleMrbInfo(params).then(({ data }) => {
if (data.code === 0 || data.code === 200) {
if (data.mrbInfo) {
//
this.formData.mrb = data.mrbInfo.mrb || '';
this.formData.mrbInspectionReport = data.mrbInfo.mrbInspectionReport || '';
this.formData.mrbRemark = data.mrbInfo.mrbRemark || '';
if (!(data && (data.code === 0 || data.code === 200))) {
return
}
const historyRows = this.normalizeHistoryRows(this.parseHistoryRows(data))
if (this.isListMode) {
this.detailList = historyRows
} else if (historyRows.length > 0) {
const first = historyRows[0]
this.singleForm = {
id: first.id || null,
rowKey: first.rowKey || '',
rollNo: first.rollNo || '',
mrb: first.mrb || '',
mrbInspectionReport: first.mrbInspectionReport || '',
mrbRemark: first.mrbRemark || ''
}
}).catch((error) => {
console.error('查询MRB信息失败:', error);
});
}
}).catch(() => {})
},
/**
* 提交表单
*/
submitForm() {
this.$refs.mrbForm.validate((valid) => {
if (valid) {
this.loading = true;
handleSelectionChange (rows) {
this.selectedRowKeys = (rows || []).map(item => item.rowKey)
},
addModal () {
this.editDialogMode = 'add'
this.editForm = this.createEmptyForm()
this.editDialogVisible = true
this.clearValidate()
},
editModal (row) {
if (!row) {
return
}
this.editDialogMode = 'edit'
this.editForm = {
id: row.id || null,
rowKey: row.rowKey,
infoCode: this.normalizeInfoCode(row.infoCode),
rollNo: row.rollNo || '',
mrb: row.mrb || '',
mrbInspectionReport: row.mrbInspectionReport || '',
mrbRemark: row.mrbRemark || ''
}
this.editDialogVisible = true
this.clearValidate()
},
handleEditClose () {
this.editDialogMode = 'add'
this.editForm = this.createEmptyForm()
this.clearValidate()
},
confirmEdit () {
this.$refs.editFormRef.validate((valid) => {
if (!valid) {
return false
}
const rowData = {
id: this.editForm.id || null,
rowKey: this.editForm.rowKey || this.normalizeRowKey(this.editForm),
infoCode: this.normalizeInfoCode(this.editForm.infoCode),
rollNo: (this.editForm.rollNo || '').trim(),
mrb: (this.editForm.mrb || '').trim(),
mrbInspectionReport: (this.editForm.mrbInspectionReport || '').trim(),
mrbRemark: (this.editForm.mrbRemark || '').trim()
}
const index = this.detailList.findIndex(item => item.rowKey === rowData.rowKey)
const nextList = this.detailList.slice()
if (index > -1) {
nextList.splice(index, 1, rowData)
} else {
nextList.push(rowData)
}
const submitRows = this.buildSubmitRowsForList(nextList)
const successMessage = index > -1 ? 'MRB异常单编辑成功' : 'MRB异常单新增成功'
this.doSubmit(submitRows, {
successMessage: successMessage,
reloadList: true,
emitConfirmed: true,
onSuccess: () => {
this.editDialogVisible = false
}
})
})
},
deleteModal () {
if (!this.selectedRowKeys || this.selectedRowKeys.length === 0) {
this.$message.warning('请先勾选要删除的记录')
return
}
const selectedMap = {}
this.selectedRowKeys.forEach(key => {
selectedMap[key] = true
})
const nextList = this.detailList.filter(item => !selectedMap[item.rowKey])
const submitRows = this.buildSubmitRowsForList(nextList)
this.doSubmit(submitRows, {
successMessage: 'MRB异常单删除成功',
reloadList: true,
emitConfirmed: true,
onSuccess: () => {
this.selectedRowKeys = []
if (this.$refs.mrbTable) {
this.$refs.mrbTable.clearSelection()
}
}
})
},
buildSubmitRowsForList (sourceList) {
const rows = Array.isArray(sourceList) ? sourceList : this.detailList
return (rows || []).map(item => ({
infoCode: this.normalizeInfoCode(item.infoCode),
rollNo: (item.rollNo || '').trim(),
mrb: (item.mrb || '').trim(),
mrbInspectionReport: (item.mrbInspectionReport || '').trim(),
mrbRemark: (item.mrbRemark || '').trim()
}))
},
buildSubmitRowsForSingle () {
return [{
rollNo: (this.singleForm.rollNo || '').trim(),
mrb: (this.singleForm.mrb || '').trim(),
mrbInspectionReport: (this.singleForm.mrbInspectionReport || '').trim(),
mrbRemark: (this.singleForm.mrbRemark || '').trim()
}]
},
validateRows (rows) {
if (!rows || rows.length === 0) {
this.$message.warning('请至少维护一条MRB异常单信息')
return false
}
for (let i = 0; i < rows.length; i++) {
const row = rows[i]
const rowNo = i + 1
if (!row.rollNo) {
this.$message.warning(`${rowNo}行【卷号】不能为空`)
return false
}
if (!row.mrb) {
this.$message.warning(`${rowNo}行【MRB】不能为空`)
return false
}
if (!row.mrbInspectionReport) {
this.$message.warning(`${rowNo}行【制程异常单】不能为空`)
return false
}
}
return true
},
doSubmit (detailList, options) {
const submitOptions = Object.assign({
successMessage: 'MRB异常单登记成功',
closeMainDialog: false,
emitConfirmed: false,
reloadList: false,
onSuccess: null
}, options || {})
const params = {
site: this.scheduleData.site,
orderNo: this.scheduleData.orderNo,
itemNo: this.scheduleData.itemNo,
seqNo: this.scheduleData.seqNo,
mrb: this.formData.mrb,
mrbInspectionReport: this.formData.mrbInspectionReport,
mrbRemark: this.formData.mrbRemark
};
infoCode: this.scheduleData.infoCode,
operatorId: this.$store.state.user.name,
detailList: detailList
}
this.loading = true
updateScheduleMrbInfo(params).then(({ data }) => {
this.loading = false;
if (data.code === 0 || data.code === 200) {
this.$message.success('MRB异常单登记成功');
this.$emit('update:visible', false);
//
this.$emit('confirmed');
} else {
this.$message.error(data.msg || 'MRB异常单登记失败');
if (data && (data.code === 0 || data.code === 200)) {
this.$message.success(submitOptions.successMessage)
if (typeof submitOptions.onSuccess === 'function') {
submitOptions.onSuccess()
}
if (submitOptions.reloadList && this.isListMode) {
this.loadMrbData()
}
if (submitOptions.closeMainDialog) {
this.$emit('update:visible', false)
}
if (submitOptions.emitConfirmed) {
this.$emit('confirmed')
}
}).catch((error) => {
this.loading = false;
this.$message.error('MRB异常单登记失败: ' + (error.message || '未知错误'));
});
} else {
this.$message.warning('请填写必填项');
return false;
this.$message.error((data && data.msg) || 'MRB异常单登记失败')
}
});
},
/**
* 关闭对话框
*/
closeDialog() {
this.$emit('update:visible', false);
}).catch((error) => {
this.$message.error('MRB异常单登记失败: ' + ((error && error.message) || '未知错误'))
}).finally(() => {
this.loading = false
})
},
submitForm () {
if (this.isListMode) {
return
}
/**
* 对话框关闭事件
*/
handleClose() {
//
if (this.$refs.mrbForm) {
this.$refs.mrbForm.resetFields();
this.$refs.singleFormRef.validate((valid) => {
if (!valid) {
return false
}
const detailRows = this.buildSubmitRowsForSingle()
if (!this.validateRows(detailRows)) {
return false
}
//
this.$emit('update:visible', false);
this.doSubmit(detailRows, {
closeMainDialog: true,
emitConfirmed: true
})
})
},
closeDialog () {
this.$emit('update:visible', false)
},
handleClose () {
this.resetState()
this.$emit('update:visible', false)
}
}
};
}
</script>
<style scoped>
.mrb-register {
/* MRB异常单登记样式 */
}
/* 表单样式 */
.mrb-form {
padding: 10px 10px 20px 0px;
}
/* 必填标签样式 - 红色星号 */
.required-label::before {
color: #ff4d4f;
margin-right: 4px;
font-size: 14px;
}
.required-label {
color: #1ab394;
font-size: 14px;
font-weight: 500;
.table-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
/* 表单项间距 */
.mrb-form /deep/ .el-form-item {
margin-bottom: 22px;
.toolbar-tip {
font-size: 12px;
color: #909399;
}
/* 输入框样式 */
.mrb-form /deep/ .el-input__inner {
height: 36px;
line-height: 36px;
border-radius: 4px;
}
/* 文本域样式 */
.mrb-form /deep/ .el-textarea__inner {
border-radius: 4px;
}
/* 底部按钮区域 */
.dialog-footer {
text-align: center;
padding: 20px 0 10px 0;
}
/* 确定按钮 - 绿色主题 */
.confirm-btn {
background-color: #1ab394;
border-color: #1ab394;
color: #ffffff;
min-width: 80px;
padding: 10px 20px;
border-radius: 4px;
font-size: 14px;
}
.confirm-btn:hover {
background-color: #18a689;
border-color: #18a689;
}
.confirm-btn:active {
background-color: #16967d;
border-color: #16967d;
margin-top: 15px;
}
/* 关闭按钮 - 绿色边框 */
.close-btn {
background-color: #ffffff;
border-color: #1ab394;
color: #1ab394;
min-width: 80px;
padding: 10px 20px;
border-radius: 4px;
font-size: 14px;
margin-left: 20px;
.dialog-footer-single {
height: 25px;
margin-top: 70px;
}
.close-btn:hover {
background-color: #1ab394;
border-color: #1ab394;
color: #ffffff;
}
.close-btn:active {
background-color: #18a689;
border-color: #18a689;
.single-form {
padding: 6px 8px 0;
}
</style>
/* 对话框标题样式 */
.mrb-register /deep/ .el-dialog__title {
font-size: 16px;
font-weight: 500;
color: #333;
<style>
.mrb-register-dialog .el-dialog__body {
padding: 12px 20px;
}
/* 对话框body padding调整 */
.mrb-register /deep/ .el-dialog__body {
padding: 10px 20px;
.mrb-register-dialog .mrb-detail-table .el-table__header-wrapper th .cell {
line-height: 20px;
font-size: 13px;
}
/* placeholder文字颜色 */
.mrb-form /deep/ .el-input__inner::placeholder,
.mrb-form /deep/ .el-textarea__inner::placeholder {
color: #c0c4cc;
.mrb-register-dialog .mrb-detail-table .el-table__body-wrapper td {
padding-top: 6px !important;
padding-bottom: 6px !important;
}
</style>

2
src/views/modules/yieldReport/com_produce_report_normal.vue

@ -825,7 +825,7 @@
<ComProcessInspection :visible.sync="showProcessInspectionFlag" :orderNo="scheduleData.orderNo" :resourceId="scheduleData.resourceId" :seqNo="scheduleData.seqNo" :site="scheduleData.site" :buNo="scheduleData.buNo" :rollNo="scheduleData.rollNo" @closed="refreshPageData"></ComProcessInspection>
<!-- MRB异常单登记组件 -->
<ComMrbRegister ref="comMrbRegister" :visible.sync="showMrbRegisterFlag" @confirmed="onMrbConfirmed"></ComMrbRegister>
<ComMrbRegister ref="comMrbRegister" :visible.sync="showMrbRegisterFlag" mode="list" @confirmed="onMrbConfirmed"></ComMrbRegister>
<!-- SOP预览弹出框 -->
<el-dialog :visible.sync="showSopPreviewFlag" width="50%" top="5vh" :before-close="closeSopPreview">

Loading…
Cancel
Save