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