3 changed files with 571 additions and 25 deletions
-
9src/api/yieldReport/com_abnormal_material_offline.js
-
516src/views/modules/yieldReport/com_abnormal_material_offline.vue
-
71src/views/modules/yieldReport/com_produce_report_normal.vue
@ -0,0 +1,9 @@ |
|||
import { createAPI } from "@/utils/httpRequest.js"; |
|||
|
|||
/** |
|||
* 材料生产过程中异常退料 |
|||
* @param {Object} data - 退料数据 |
|||
* @returns {Promise} |
|||
*/ |
|||
export const materialReturnDuringProduction = data => createAPI(`/schedule/materialReturnDuringProduction`, 'POST', data); |
|||
|
|||
@ -0,0 +1,516 @@ |
|||
<template> |
|||
<div class="customer-css"> |
|||
<el-dialog :title="titleCon" v-drag v-bind="$attrs" v-on="$listeners" |
|||
width="600px" class="material-dialog"> |
|||
<div class="material-content"> |
|||
<el-form :model="pageData" label-position="top" label-width="100px"> |
|||
<!-- 材料信息卡片 --> |
|||
<div class="material-info-card"> |
|||
<div class="info-header"> |
|||
<i class="el-icon-document"></i> |
|||
<span>材料信息</span> |
|||
</div> |
|||
<div class="info-content"> |
|||
<el-row :gutter="15"> |
|||
<el-col :span="12"> |
|||
<div class="info-row"> |
|||
<label class="info-label">材料卷号:</label> |
|||
<span class="info-value">{{ pageData.rmRollNo || '-' }}</span> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="12"> |
|||
<div class="info-row"> |
|||
<label class="info-label">零部件编码:</label> |
|||
<span class="info-value">{{ pageData.partNo || '-' }}</span> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row :gutter="15"> |
|||
<el-col :span="24"> |
|||
<div class="info-row"> |
|||
<label class="info-label">零部件名称:</label> |
|||
<span class="info-value">{{ pageData.partDesc || '-' }}</span> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row :gutter="15"> |
|||
<el-col :span="12"> |
|||
<div class="info-row"> |
|||
<label class="info-label">规格型号:</label> |
|||
<span class="info-value">{{ pageData.spec || '-' }}</span> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 下料设置区域 --> |
|||
<div class="return-settings"> |
|||
<el-row :gutter="15"> |
|||
<el-col :span="8"> |
|||
<el-form-item label="上机数量" class="form-item-enhanced"> |
|||
<el-input |
|||
v-model="displayOnMachineQty" |
|||
disabled |
|||
size="large" |
|||
style="width: 100%"> |
|||
</el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="8"> |
|||
<el-form-item label="下机数量" class="form-item-enhanced"> |
|||
<el-input class="inlineNumber numInput" |
|||
v-model="pageData.returnQty" |
|||
type="number" |
|||
placeholder="请输入下机数量" |
|||
size="large" |
|||
@input="calculateRemainQty" |
|||
style="width: 100%"> |
|||
</el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="8"> |
|||
<el-form-item label="剩余数量" class="form-item-enhanced"> |
|||
<el-input |
|||
v-model="displayRemainQty" |
|||
disabled |
|||
size="large" |
|||
:class="{'remain-negative': pageData.remainQty < 0}" |
|||
style="width: 100%"> |
|||
</el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
</el-row> |
|||
|
|||
<!-- 备注 --> |
|||
<el-row style="margin-bottom: 30px"> |
|||
<el-col :span="24"> |
|||
<el-form-item label="备注" > |
|||
<el-input |
|||
v-model="pageData.remark" |
|||
type="textarea" |
|||
:rows="3" |
|||
placeholder="请输入备注" |
|||
show-word-limit> |
|||
</el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
</el-form> |
|||
</div> |
|||
|
|||
<span slot="footer" class="dialog-footer"> |
|||
<button class="action-btn secondary" @click="submitAbnormalOffline"> |
|||
{{ buttons.confirmButton }} |
|||
</button> |
|||
<button class="action-btn secondary" @click="closeDialog"> |
|||
{{ buttons.closeButton }} |
|||
</button> |
|||
</span> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
materialReturnDuringProduction |
|||
} from '@/api/yieldReport/com_abnormal_material_offline.js'; |
|||
|
|||
var functionId = 'C10000019'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
titleCon: '异常下机', |
|||
scheduleData: { |
|||
site: this.$store.state.user.site, |
|||
username: this.$store.state.user.name, |
|||
seqNo: '', |
|||
orderNo: '', |
|||
itemNo: 0, |
|||
}, |
|||
pageData: { |
|||
site: this.$store.state.user.site, |
|||
orderNo: '', |
|||
itemNo: '', |
|||
seqNo: '', |
|||
rollNo: '', |
|||
rmRollNo: '', |
|||
partNo: '', |
|||
partDesc: '', |
|||
spec: '', |
|||
onMachineQty: 0, // 上机数量(来自行数据的数量) |
|||
returnQty: 0, // 下机数量 |
|||
remainQty: 0, // 剩余数量 |
|||
remark: '', // 备注 |
|||
histSeqNo: '', |
|||
operatorId: '', |
|||
}, |
|||
operatorData: { |
|||
site: this.$store.state.user.site, |
|||
username: this.$store.state.user.name, |
|||
operatorId: '', |
|||
operatorName: '', |
|||
}, |
|||
buttons: { |
|||
confirmButton: '确定', |
|||
closeButton: '关闭', |
|||
}, |
|||
} |
|||
}, |
|||
computed: { |
|||
// 显示上机数量(如果为0或空则显示空字符串) |
|||
displayOnMachineQty() { |
|||
return this.pageData.onMachineQty || this.pageData.onMachineQty === 0 ? String(this.pageData.onMachineQty) : ''; |
|||
}, |
|||
// 显示剩余数量(如果为0或空则显示空字符串) |
|||
displayRemainQty() { |
|||
return this.pageData.remainQty || this.pageData.remainQty === 0 ? String(this.pageData.remainQty) : ''; |
|||
} |
|||
}, |
|||
methods: { |
|||
//初始化组件的参数 |
|||
init(scheduleData, operatorData, materialRow) { |
|||
//初始化参数 |
|||
this.scheduleData = scheduleData; |
|||
this.operatorData = JSON.parse(JSON.stringify(operatorData)); |
|||
|
|||
//设置材料信息 |
|||
this.pageData.orderNo = scheduleData.orderNo; |
|||
this.pageData.itemNo = scheduleData.itemNo; |
|||
this.pageData.seqNo = scheduleData.seqNo; |
|||
this.pageData.rollNo = scheduleData.rollNo; |
|||
this.pageData.operatorId = operatorData.operatorId; |
|||
|
|||
// 从行数据获取材料信息 |
|||
this.pageData.rmRollNo = materialRow.rmRollNo || ''; |
|||
this.pageData.partNo = materialRow.partNo || ''; |
|||
this.pageData.partDesc = materialRow.partDesc || ''; |
|||
this.pageData.spec = materialRow.spec || ''; |
|||
this.pageData.histSeqNo = materialRow.histSeqNo || ''; |
|||
|
|||
// 获取上机数量(从行数据的 transQty 字段) |
|||
const transQty = parseFloat(materialRow.transQty); |
|||
this.pageData.onMachineQty = isNaN(transQty) ? 0 : transQty; |
|||
// 重置下机数量、剩余数量和备注 |
|||
this.pageData.returnQty = 0; |
|||
this.pageData.remainQty = this.pageData.onMachineQty; |
|||
this.pageData.remark = ''; |
|||
|
|||
this.titleCon = '异常下机'; |
|||
}, |
|||
|
|||
/*关闭modal*/ |
|||
closeDialog(){ |
|||
//刷新报工的页面 |
|||
this.$emit('refreshPageData'); |
|||
//关闭当前的页面 |
|||
this.$emit('update:visible', false); |
|||
}, |
|||
|
|||
/*计算剩余数量*/ |
|||
calculateRemainQty() { |
|||
const onMachineQty = parseFloat(this.pageData.onMachineQty) || 0; |
|||
const returnQty = parseFloat(this.pageData.returnQty) || 0; |
|||
this.pageData.remainQty = onMachineQty - returnQty; |
|||
}, |
|||
|
|||
/*提交异常下机*/ |
|||
submitAbnormalOffline() { |
|||
// 如果没有填写下机数量,默认为0 |
|||
if (!this.pageData.returnQty || this.pageData.returnQty === '' || this.pageData.returnQty < 0) { |
|||
this.pageData.returnQty = 0; |
|||
} |
|||
|
|||
// 计算剩余数量 |
|||
this.calculateRemainQty(); |
|||
|
|||
// 验证剩余数量必须大于等于0 |
|||
if (this.pageData.remainQty < 0) { |
|||
this.$message.warning('下机数量不能大于上机数量!'); |
|||
return false; |
|||
} |
|||
|
|||
// 构建提交数据(只传下机数量和备注,不传上机数量和剩余数量) |
|||
const submitData = { |
|||
site: this.pageData.site, |
|||
orderNo: this.pageData.orderNo, |
|||
itemNo: this.pageData.itemNo, |
|||
seqNo: this.pageData.seqNo, |
|||
rollNo: this.pageData.rollNo, |
|||
returnQty: this.pageData.returnQty, |
|||
histSeqNo: this.pageData.histSeqNo, |
|||
operatorId: this.pageData.operatorId, |
|||
remark: this.pageData.remark || '' // 备注(可选,默认为空字符串) |
|||
}; |
|||
|
|||
// 调用后端API |
|||
materialReturnDuringProduction(submitData).then(({data}) => { |
|||
//判断是否存在异常 |
|||
if(data.code == 500 || data.code == 400){ |
|||
this.$message.error(data.msg || data.message); |
|||
}else{ |
|||
//先提示 后关闭 |
|||
this.$message.success(data.msg || data.message || '操作成功'); |
|||
//关闭当前的页面 |
|||
this.closeDialog(); |
|||
} |
|||
}).catch((error) => { |
|||
this.$message.error('操作失败:' + (error.message || '未知错误')); |
|||
}); |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.numInput /deep/ .el-input__inner{ |
|||
text-align: right; |
|||
} |
|||
/deep/ .inlineNumber input::-webkit-outer-spin-button, |
|||
/deep/ .inlineNumber input::-webkit-inner-spin-button { |
|||
-webkit-appearance: none; |
|||
|
|||
} |
|||
/deep/ .inlineNumber input[type="number"]{ |
|||
-moz-appearance: textfield; |
|||
padding-right: 5px !important; |
|||
} |
|||
|
|||
// 材料异常下机对话框样式 - 参考材料上机 |
|||
.material-dialog { |
|||
::v-deep .el-dialog { |
|||
border-radius: 8px; |
|||
overflow: hidden; |
|||
|
|||
.el-dialog__header { |
|||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|||
padding: 18px 20px; |
|||
|
|||
.el-dialog__title { |
|||
color: #fff; |
|||
font-size: 16px; |
|||
font-weight: 600; |
|||
} |
|||
|
|||
.el-dialog__headerbtn { |
|||
.el-dialog__close { |
|||
color: #fff; |
|||
font-size: 18px; |
|||
|
|||
&:hover { |
|||
color: #f0f0f0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.el-dialog__body { |
|||
padding: 25px; |
|||
background-color: #f8f9fa; |
|||
} |
|||
|
|||
.el-dialog__footer { |
|||
padding: 15px 20px; |
|||
background-color: #fff; |
|||
border-top: 1px solid #e9ecef; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.material-content { |
|||
.form-item-enhanced { |
|||
margin-bottom: 10px; |
|||
|
|||
::v-deep .el-form-item__label { |
|||
color: #495057; |
|||
font-weight: 500; |
|||
font-size: 14px; |
|||
margin-bottom: 8px; |
|||
} |
|||
|
|||
::v-deep .el-input { |
|||
.el-input__inner { |
|||
border-radius: 6px; |
|||
border: 1px solid #dee2e6; |
|||
transition: all 0.3s; |
|||
height: 42px; |
|||
line-height: 42px; |
|||
font-size: 15px; |
|||
|
|||
&:focus { |
|||
border-color: #667eea; |
|||
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 文本域样式 |
|||
::v-deep .el-textarea { |
|||
.el-textarea__inner { |
|||
border-radius: 6px; |
|||
border: 1px solid #dee2e6; |
|||
transition: all 0.3s; |
|||
font-size: 14px; |
|||
padding: 8px 12px; |
|||
line-height: 1.5; |
|||
|
|||
&:focus { |
|||
border-color: #667eea; |
|||
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 剩余数量为负数时的红色警告样式 |
|||
::v-deep .remain-negative { |
|||
.el-input__inner { |
|||
color: #f56c6c; |
|||
font-weight: 600; |
|||
border-color: #f56c6c; |
|||
background-color: #fef0f0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 物料信息卡片样式 - 白色框连起来 |
|||
.material-info-card { |
|||
background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%); |
|||
border-radius: 8px; |
|||
padding: 16px; |
|||
margin-bottom: 20px; |
|||
border: 1px solid #e3e8f0; |
|||
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.08); |
|||
animation: fadeInDown 0.5s ease-out; |
|||
|
|||
.info-header { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 12px; |
|||
padding-bottom: 10px; |
|||
border-bottom: 1px solid #dee2e6; |
|||
|
|||
i { |
|||
font-size: 18px; |
|||
color: #667eea; |
|||
margin-right: 8px; |
|||
} |
|||
|
|||
span { |
|||
font-size: 14px; |
|||
font-weight: 600; |
|||
color: #495057; |
|||
} |
|||
} |
|||
|
|||
.info-content { |
|||
background-color: rgba(255, 255, 255, 0.8); |
|||
border-radius: 4px; |
|||
padding: 12px; |
|||
|
|||
.info-row { |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 4px 0; |
|||
|
|||
&:not(:last-child) { |
|||
border-bottom: 1px dashed #e9ecef; |
|||
} |
|||
|
|||
.info-label { |
|||
font-size: 13px; |
|||
color: #6c757d; |
|||
min-width: 90px; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.info-value { |
|||
font-size: 13px; |
|||
color: #212529; |
|||
font-weight: 600; |
|||
flex: 1; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 下料设置区域 |
|||
.return-settings { |
|||
background: #fff; |
|||
border-radius: 8px; |
|||
padding: 16px; |
|||
border: 1px solid #e3e8f0; |
|||
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.05); |
|||
} |
|||
|
|||
// 底部按钮样式 - 完全参考材料上机 |
|||
.dialog-footer { |
|||
display: flex; |
|||
justify-content: center; |
|||
gap: 12px; |
|||
padding: 0; |
|||
|
|||
.action-btn { |
|||
min-width: 80px; |
|||
padding: 6px 16px; |
|||
border-radius: 16px; |
|||
font-size: 13px; |
|||
font-weight: 500; |
|||
cursor: pointer; |
|||
transition: all 0.2s ease; |
|||
display: inline-flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
gap: 4px; |
|||
|
|||
i { |
|||
font-size: 13px; |
|||
} |
|||
|
|||
&.primary { |
|||
background: #17B3A3; |
|||
border: none; |
|||
color: white; |
|||
|
|||
&:hover { |
|||
background: #13998b; |
|||
box-shadow: 0 4px 12px rgba(23, 179, 163, 0.4); |
|||
transform: translateY(-1px); |
|||
} |
|||
|
|||
&:active { |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
|
|||
&.secondary { |
|||
background: white; |
|||
border: 1px solid #17B3A3; |
|||
color: #17B3A3; |
|||
|
|||
&:hover { |
|||
background: #17B3A3; |
|||
color: white; |
|||
} |
|||
|
|||
&:active { |
|||
transform: scale(0.98); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 动画效果 |
|||
@keyframes fadeInDown { |
|||
from { |
|||
opacity: 0; |
|||
transform: translateY(-10px); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue