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