3 changed files with 480 additions and 6 deletions
-
11src/api/yieldReport/abnormalRoll.js
-
438src/views/modules/yieldReport/com_abnormal_continue_roll.vue
-
37src/views/modules/yieldReport/com_produce_report_normal.vue
@ -0,0 +1,11 @@ |
|||||
|
import { createAPI } from '@/utils/httpRequest.js' |
||||
|
|
||||
|
// 查询卷号列表(去重)
|
||||
|
export const getAbnormalRollNoList = data => createAPI('schedule/abnormalRoll/getRollNoList', 'POST', data); |
||||
|
|
||||
|
// 根据卷号组合查询详细数据
|
||||
|
export const getAbnormalRollByRollNos = data => createAPI('schedule/abnormalRoll/getByRollNos', 'POST', data); |
||||
|
|
||||
|
// 异常续卷(更新数据)
|
||||
|
export const abnormalContinueRoll = data => createAPI('schedule/abnormalRoll/continueRoll', 'POST', data); |
||||
|
|
||||
@ -0,0 +1,438 @@ |
|||||
|
<template> |
||||
|
<div class="customer-css"> |
||||
|
<el-dialog :title="titleCon" v-drag v-bind="$attrs" v-on="$listeners" width="700px" style="height: 680px;" class="customer-dialog"> |
||||
|
<el-form :inline="true" label-position="top" style="height: auto;"> |
||||
|
<!-- 上半部分:卷号选择区域 --> |
||||
|
<div class="roll-select-section"> |
||||
|
<div class="section-title"> |
||||
|
<i class="el-icon-tickets"></i> |
||||
|
<span>卷号选择(双击选择)</span> |
||||
|
</div> |
||||
|
<el-table |
||||
|
:data="rollNoList" |
||||
|
border |
||||
|
style="width: 100%; margin-top: 10px;" |
||||
|
max-height="150" |
||||
|
@row-dblclick="selectRollNo" |
||||
|
highlight-current-row> |
||||
|
<el-table-column prop="currentRollNo" label="当前卷号" align="center" min-width="200"> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="newRollNo" label="新卷号" align="center" min-width="200"> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 下半部分:选中卷信息 + 产量数据 --> |
||||
|
<div class="rq" v-if="selectedRollNo.currentRollNo"> |
||||
|
<!-- 卷信息行 --> |
||||
|
<el-row> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="当前卷号"> |
||||
|
<el-input v-model="selectedRollNo.currentRollNo" readonly style="width: 200px;"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="新卷号"> |
||||
|
<el-input v-model="selectedRollNo.newRollNo" readonly style="width: 200px;"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
|
||||
|
<!-- 产量数据表格 - 与创建分卷样式一致 --> |
||||
|
<el-table |
||||
|
:data="rowDataList" |
||||
|
border |
||||
|
style="width: 100%;" |
||||
|
max-height="350" |
||||
|
:span-method="objectSpanMethod"> |
||||
|
<el-table-column prop="rowBumber" label="NO." width="50" align="center"> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="良品数" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-input-number |
||||
|
:controls="false" :step="0" |
||||
|
v-model="scope.row.goodQty" |
||||
|
@change="handleQtyChange(scope.row)" |
||||
|
style="width: 100%" |
||||
|
class="good-qty-input" |
||||
|
:style="{'color': '#67c23a', 'font-weight': 'bold'}"> |
||||
|
</el-input-number> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="面损" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-input-number |
||||
|
:controls="false" :step="0" |
||||
|
v-model="scope.row.surfaceLossQty" |
||||
|
@change="handleQtyChange(scope.row)" |
||||
|
style="width: 100%"> |
||||
|
</el-input-number> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="性能不良" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-input-number |
||||
|
:controls="false" :step="0" |
||||
|
v-model="scope.row.poorPerformanceQty" |
||||
|
@change="handleQtyChange(scope.row)" |
||||
|
style="width: 100%"> |
||||
|
</el-input-number> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="不良数" width="80" align="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="defect-display" :style="{'color': '#f56c6c', 'font-weight': 'bold', 'text-align': 'right', 'padding-right': '10px'}"> |
||||
|
{{ scope.row.defectQty }} |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="良率" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="yield-display" :style="{'color': '#409eff', 'font-weight': 'bold'}"> |
||||
|
{{ scope.row.yieldRate }} |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="总数" width="80" align="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="total-display" :style="{'text-align': 'right', 'padding-right': '10px'}"> |
||||
|
{{ scope.row.totalQty }} |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="备注" align="center" class-name="remark-column"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="remark-wrapper"> |
||||
|
<el-input |
||||
|
type="textarea" |
||||
|
v-model="scope.row.remark" |
||||
|
resize="none" |
||||
|
:autosize="false" |
||||
|
class="remark-textarea"> |
||||
|
</el-input> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 无数据提示 --> |
||||
|
<div v-if="rollNoList.length === 0" class="no-data-tip"> |
||||
|
<i class="el-icon-info"></i> |
||||
|
<span>暂无异常截卷数据</span> |
||||
|
</div> |
||||
|
</el-form> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="continueRoll" :disabled="rowDataList.length === 0">续卷</el-button> |
||||
|
<el-button @click="closeDialog">{{ buttons.closeButton }}</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { |
||||
|
getAbnormalRollNoList, |
||||
|
getAbnormalRollByRollNos, |
||||
|
abnormalContinueRoll |
||||
|
} from '@/api/yieldReport/abnormalRoll.js'; |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
titleCon: '异常续卷', |
||||
|
scheduleData: { |
||||
|
site: this.$store.state.user.site, |
||||
|
username: this.$store.state.user.name, |
||||
|
seqNo: '', |
||||
|
orderNo: '', |
||||
|
itemNo: 0, |
||||
|
}, |
||||
|
operatorData: { |
||||
|
site: this.$store.state.user.site, |
||||
|
username: this.$store.state.user.name, |
||||
|
operatorId: '', |
||||
|
operatorName: '', |
||||
|
}, |
||||
|
rollNoList: [], // 卷号列表 |
||||
|
selectedRollNo: { |
||||
|
currentRollNo: '', |
||||
|
newRollNo: '' |
||||
|
}, |
||||
|
rowDataList: [], // 原始数据(用于校验) |
||||
|
originalDataList: [], // 原始缓存数据(用于数量校验) |
||||
|
buttons: { |
||||
|
closeButton: '关闭', |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 初始化组件的参数 |
||||
|
init(scheduleData, operatorData) { |
||||
|
this.scheduleData = scheduleData; |
||||
|
this.operatorData = JSON.parse(JSON.stringify(operatorData)); |
||||
|
|
||||
|
// 重置数据 |
||||
|
this.rollNoList = []; |
||||
|
this.selectedRollNo = { currentRollNo: '', newRollNo: '' }; |
||||
|
this.rowDataList = []; |
||||
|
this.originalDataList = []; |
||||
|
|
||||
|
// 加载卷号列表 |
||||
|
this.loadRollNoList(); |
||||
|
}, |
||||
|
|
||||
|
// 加载卷号列表 |
||||
|
loadRollNoList() { |
||||
|
const params = { |
||||
|
site: this.scheduleData.site, |
||||
|
orderNo: this.scheduleData.orderNo |
||||
|
}; |
||||
|
|
||||
|
getAbnormalRollNoList(params).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.rollNoList = data.data || []; |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '加载卷号列表失败'); |
||||
|
} |
||||
|
}).catch(err => { |
||||
|
this.$message.error('加载卷号列表失败:' + (err.message || '未知错误')); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 双击选择卷号 |
||||
|
selectRollNo(row) { |
||||
|
this.selectedRollNo = { |
||||
|
currentRollNo: row.currentRollNo, |
||||
|
newRollNo: row.newRollNo |
||||
|
}; |
||||
|
|
||||
|
// 加载详细数据 |
||||
|
this.loadDetailData(); |
||||
|
}, |
||||
|
|
||||
|
// 加载详细数据 |
||||
|
loadDetailData() { |
||||
|
const params = { |
||||
|
site: this.scheduleData.site, |
||||
|
orderNo: this.scheduleData.orderNo, |
||||
|
currentRollNo: this.selectedRollNo.currentRollNo, |
||||
|
newRollNo: this.selectedRollNo.newRollNo |
||||
|
}; |
||||
|
|
||||
|
getAbnormalRollByRollNos(params).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
const list = data.data || []; |
||||
|
// 保存原始数据用于校验 |
||||
|
this.originalDataList = JSON.parse(JSON.stringify(list)); |
||||
|
|
||||
|
// 处理数据,添加计算字段 |
||||
|
this.rowDataList = list.map(item => { |
||||
|
const goodQty = parseFloat(item.goodQty) || 0; |
||||
|
const surfaceLossQty = parseFloat(item.surfaceLossQty) || 0; |
||||
|
const poorPerformanceQty = parseFloat(item.poorPerformanceQty) || 0; |
||||
|
const defectQty = surfaceLossQty + poorPerformanceQty; |
||||
|
const totalQty = goodQty + defectQty; |
||||
|
const yieldRate = totalQty > 0 ? ((goodQty / totalQty) * 100).toFixed(2) + '%' : '0.00%'; |
||||
|
|
||||
|
return { |
||||
|
...item, |
||||
|
goodQty: goodQty, |
||||
|
surfaceLossQty: surfaceLossQty, |
||||
|
poorPerformanceQty: poorPerformanceQty, |
||||
|
defectQty: defectQty, |
||||
|
totalQty: totalQty, |
||||
|
yieldRate: yieldRate |
||||
|
}; |
||||
|
}); |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '加载详细数据失败'); |
||||
|
} |
||||
|
}).catch(err => { |
||||
|
this.$message.error('加载详细数据失败:' + (err.message || '未知错误')); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 数量变化时重新计算 |
||||
|
handleQtyChange(row) { |
||||
|
const goodQty = parseFloat(row.goodQty) || 0; |
||||
|
const surfaceLossQty = parseFloat(row.surfaceLossQty) || 0; |
||||
|
const poorPerformanceQty = parseFloat(row.poorPerformanceQty) || 0; |
||||
|
|
||||
|
row.defectQty = surfaceLossQty + poorPerformanceQty; |
||||
|
row.totalQty = goodQty + row.defectQty; |
||||
|
row.yieldRate = row.totalQty > 0 ? ((goodQty / row.totalQty) * 100).toFixed(2) + '%' : '0.00%'; |
||||
|
}, |
||||
|
|
||||
|
// 合并行方法(如果需要) |
||||
|
objectSpanMethod({ row, column, rowIndex, columnIndex }) { |
||||
|
return { |
||||
|
rowspan: 1, |
||||
|
colspan: 1 |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
// 续卷操作 |
||||
|
continueRoll() { |
||||
|
// 校验数量必须大于等于原始数量 |
||||
|
for (let i = 0; i < this.rowDataList.length; i++) { |
||||
|
const currentRow = this.rowDataList[i]; |
||||
|
const originalRow = this.originalDataList[i]; |
||||
|
|
||||
|
if (!originalRow) continue; |
||||
|
|
||||
|
const currentGoodQty = parseFloat(currentRow.goodQty) || 0; |
||||
|
const originalGoodQty = parseFloat(originalRow.goodQty) || 0; |
||||
|
|
||||
|
const currentSurfaceLossQty = parseFloat(currentRow.surfaceLossQty) || 0; |
||||
|
const originalSurfaceLossQty = parseFloat(originalRow.surfaceLossQty) || 0; |
||||
|
|
||||
|
const currentPoorPerformanceQty = parseFloat(currentRow.poorPerformanceQty) || 0; |
||||
|
const originalPoorPerformanceQty = parseFloat(originalRow.poorPerformanceQty) || 0; |
||||
|
|
||||
|
if (currentGoodQty < originalGoodQty) { |
||||
|
this.$message.error(`第${currentRow.rowBumber}行的良品数不能小于原始数量(${originalGoodQty})`); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (currentSurfaceLossQty < originalSurfaceLossQty) { |
||||
|
this.$message.error(`第${currentRow.rowBumber}行的面损不能小于原始数量(${originalSurfaceLossQty})`); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (currentPoorPerformanceQty < originalPoorPerformanceQty) { |
||||
|
this.$message.error(`第${currentRow.rowBumber}行的性能不良不能小于原始数量(${originalPoorPerformanceQty})`); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 构建提交数据 |
||||
|
const submitData = { |
||||
|
processedBy: this.operatorData.operatorId || this.operatorData.username, |
||||
|
rowDataList: this.rowDataList.map(row => ({ |
||||
|
id: row.id, |
||||
|
goodQty: row.goodQty, |
||||
|
defectQty: row.defectQty, |
||||
|
surfaceLossQty: row.surfaceLossQty, |
||||
|
poorPerformanceQty: row.poorPerformanceQty, |
||||
|
remark: row.remark || '' |
||||
|
})) |
||||
|
}; |
||||
|
|
||||
|
abnormalContinueRoll(submitData).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.$message.success('续卷成功!'); |
||||
|
// 刷新数据 |
||||
|
this.loadRollNoList(); |
||||
|
this.selectedRollNo = { currentRollNo: '', newRollNo: '' }; |
||||
|
this.rowDataList = []; |
||||
|
this.originalDataList = []; |
||||
|
// 刷新父页面 |
||||
|
this.$emit('refreshPageData'); |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '续卷失败'); |
||||
|
} |
||||
|
}).catch(err => { |
||||
|
this.$message.error('续卷失败:' + (err.message || '未知错误')); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 关闭对话框 |
||||
|
closeDialog() { |
||||
|
this.$emit('refreshPageData'); |
||||
|
this.$emit('update:visible', false); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.roll-select-section { |
||||
|
background: #f5f7fa; |
||||
|
padding: 15px; |
||||
|
border-radius: 8px; |
||||
|
margin-bottom: 15px; |
||||
|
border: 1px solid #e4e7ed; |
||||
|
} |
||||
|
|
||||
|
.section-title { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
font-size: 14px; |
||||
|
font-weight: 600; |
||||
|
color: #303133; |
||||
|
|
||||
|
i { |
||||
|
margin-right: 8px; |
||||
|
font-size: 16px; |
||||
|
color: #409eff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.no-data-tip { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 50px 0; |
||||
|
color: #909399; |
||||
|
|
||||
|
i { |
||||
|
font-size: 48px; |
||||
|
margin-bottom: 15px; |
||||
|
} |
||||
|
|
||||
|
span { |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
/* 全局样式 - 良品数和不良数输入框颜色 */ |
||||
|
.customer-css .good-qty-input .el-input__inner { |
||||
|
font-weight: bold !important; |
||||
|
color: #67c23a !important; |
||||
|
font-size: 16px !important; |
||||
|
} |
||||
|
|
||||
|
.customer-css .defect-qty-input .el-input__inner { |
||||
|
font-weight: bold !important; |
||||
|
color: #f56c6c !important; |
||||
|
font-size: 16px !important; |
||||
|
} |
||||
|
|
||||
|
/* 备注列样式 - 填满整个单元格 */ |
||||
|
.customer-css .el-table td:last-child { |
||||
|
padding: 0 !important; |
||||
|
position: relative !important; |
||||
|
} |
||||
|
|
||||
|
/* 备注包装器 - 填满整个单元格 */ |
||||
|
.customer-css .remark-wrapper { |
||||
|
position: absolute !important; |
||||
|
top: 0 !important; |
||||
|
left: 0 !important; |
||||
|
right: 0 !important; |
||||
|
bottom: 0 !important; |
||||
|
width: 100% !important; |
||||
|
height: 100% !important; |
||||
|
} |
||||
|
|
||||
|
/* 备注textarea容器 */ |
||||
|
.customer-css .remark-textarea { |
||||
|
width: 100% !important; |
||||
|
height: 100% !important; |
||||
|
} |
||||
|
|
||||
|
.customer-css .remark-textarea .el-textarea__inner { |
||||
|
border: none !important; |
||||
|
padding: 8px 10px !important; |
||||
|
border-radius: 0 !important; |
||||
|
resize: none !important; |
||||
|
width: 100% !important; |
||||
|
height: 100% !important; |
||||
|
box-sizing: border-box !important; |
||||
|
overflow-y: auto !important; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue