10/13

<template>
<div class="production-task-progress">
<el-card>
<h2>生产任务进度展示</h2>
<el-table :data="filteredReports" style="width: 100%" border>
<el-table-column prop="workOrderId" label="工单Id" width="100"></el-table-column>
<el-table-column prop="batchNumber" label="批次号" width="150"></el-table-column>
<el-table-column prop="employeeName" label="报工人" width="100"></el-table-column>
<el-table-column label="进度" width="800">
<template slot-scope="scope">
<div class="progress-flow">
<div
v-for="(process, index) in processFlow"
:key="index"
class="process-item"
:class="{
'completed-process': index < currentProcessIndex(scope.row.processName),
'current-process': index === currentProcessIndex(scope.row.processName),
'upcoming-process': index > currentProcessIndex(scope.row.processName)
}"
>
<div
class="process-name"
@click="hasProcessForBatch(scope.row.batchNumber, process) ? handleProcessClick(scope.row.batchNumber, process) : null"
:class="{ clickable: hasProcessForBatch(scope.row.batchNumber, process) }"
>
{{ process }}
</div>
<div class="process-circle">
<div class="process-circle-outer">
<span class="process-circle-inner"></span>
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="taskStatus" label="任务状态" width="100"></el-table-column>
<el-table-column prop="inspectionCompleted" label="是否检验完成" width="150">
<template slot-scope="scope">
{{ scope.row.inspectionCompleted ? '是' : '否' }}
</template>
</el-table-column>
<el-table-column label="物料统计" width="150">
<template slot-scope="scope">
<a href="javascript:;" @click="showMaterialDetails(scope.row)">查看详情</a>
</template>
</el-table-column>
<el-table-column label="设备统计" width="150">
<template slot-scope="scope">
<a href="javascript:;" @click="showEquipmentDetails(scope.row)">查看详情</a>
</template>
</el-table-column>
</el-table>
</el-card>

<!-- 报工信息弹窗 -->
<el-dialog title="报工信息" :visible.sync="isReportDialogVisible">
<div>
<p><strong>工单号:</strong> {{ selectedReport.workOrderId }}</p>
<p><strong>批次号:</strong> {{ selectedReport.batchNumber }}</p>
<p><strong>报工人:</strong> {{ selectedReport.employeeName }}</p>
<p><strong>开始时间:</strong> {{ selectedReport.startTime }}</p>
<p><strong>结束时间:</strong> {{ selectedReport.endTime }}</p>
<p><strong>转出成品数:</strong> {{ selectedReport.qualifiedTransferCount }}</p>
<p><strong>次品数:</strong> {{ selectedReport.defectiveCount }}</p>
</div>
<div slot="footer">
<el-button @click="isReportDialogVisible = false">关闭</el-button>
</div>
</el-dialog>

<!-- 物料统计弹窗 -->
<el-dialog title="物料统计" :visible.sync="isMaterialDialogVisible">
<el-table :data="materialStats" style="width: 100%" border>
<el-table-column prop="processName" label="工序名称" width="150"></el-table-column>
<el-table-column prop="worker" label="加工员工" width="150"></el-table-column>
<el-table-column prop="materialUsage" label="物料使用" width="200"></el-table-column>
<el-table-column prop="materialLoss" label="物料损耗" width="150"></el-table-column>
</el-table>
<div slot="footer">
<el-button @click="isMaterialDialogVisible = false">取 消</el-button>
</div>
</el-dialog>

<!-- 设备统计弹窗 -->
<el-dialog title="设备统计" :visible.sync="isEquipmentDialogVisible">
<el-table :data="equipmentStats" style="width: 100%" border>
<el-table-column prop="processName" label="当前工序" width="150"></el-table-column>
<el-table-column prop="equipmentName" label="使用设备" width="150"></el-table-column>
<el-table-column prop="usageTime" label="使用时间" width="150"></el-table-column>
<el-table-column prop="equipmentLoss" label="设备损耗" width="150"></el-table-column>
<el-table-column prop="depreciationCost" label="设备折旧费用" width="150"></el-table-column>
<el-table-column label="保修" width="100">
<template slot-scope="scope">
<el-button @click="repairEquipment(scope.row.equipmentName)">保修</el-button>
</template>
</el-table-column>
</el-table>
<div slot="footer">
<el-button @click="isEquipmentDialogVisible = false">取 消</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import axios from 'axios';

export default {
data() {
return {
workReports: [],
processFlow: ["包壳", "焙烧", "熔炼", "光谱", "浇注", "扣箱", "沾水", "射帽"],
isReportDialogVisible: false,
isMaterialDialogVisible: false,
isEquipmentDialogVisible: false,
selectedReport: {},
materialStats: [],
equipmentStats: []
};
},
computed: {
filteredReports() {
const maxProcessReports = {};

this.workReports.forEach(report => {
const key = report.batchNumber;
if (!maxProcessReports[key] || this.currentProcessIndex(report.processName) > this.currentProcessIndex(maxProcessReports[key].processName)) {
maxProcessReports[key] = report;
}
});

return Object.values(maxProcessReports);
}
},
methods: {
currentProcessIndex(processName) {
return this.processFlow.indexOf(processName);
},
hasProcessForBatch(batchNumber, processName) {
return this.workReports.some(report => report.batchNumber === batchNumber && report.processName === processName);
},
handleProcessClick(batchNumber, processName) {
const report = this.workReports.find(report => report.batchNumber === batchNumber && report.processName === processName);
if (report) {
this.selectedReport = report;
this.isReportDialogVisible = true;
}
},
showMaterialDetails(task) {
this.isMaterialDialogVisible = true;
// 根据报工数据生成物料统计
this.materialStats = this.workReports
.filter(report => report.batchNumber === task.batchNumber)
.map(report => ({
processName: report.processName,
worker: report.employeeName,
materialUsage: `${report.materialUsed}(${report.materialAmount}kg)`,
materialLoss: `${report.materialLoss}kg`
}));
},
showEquipmentDetails(task) {
this.isEquipmentDialogVisible = true;
// 根据报工数据生成设备统计
this.equipmentStats = this.workReports
.filter(report => report.batchNumber === task.batchNumber)
.map(report => ({
processName: report.processName,
equipmentName: report.equipmentUsed,
usageTime: report.usageTime,
equipmentLoss: report.equipmentLoss,
depreciationCost: report.depreciationCost
}));
},
repairEquipment(equipmentName) {
console.log(`为设备 ${equipmentName} 申请保修`);
},
fetchWorkReports() {
axios.post('http://localhost:80/mes/select')
.then(response => {
this.workReports = response.data.map(report => ({
...report,
materialUsed: '蜡', // 示例数据
materialAmount: 50, // 示例数据
materialLoss: 0.5, // 示例数据
equipmentUsed: '蜡模机', // 示例数据
usageTime: '2小时', // 示例数据
equipmentLoss: '10%', // 示例数据
depreciationCost: '500元' // 示例数据
}));
})
.catch(error => {
console.error('Error fetching work reports:', error);
});
}
},
mounted() {
this.fetchWorkReports();
}
};
</script>

<style scoped>
.production-task-progress {
padding: 20px;
}

.progress-flow {
display: flex;
align-items: center;
justify-content: space-between;
}

.process-item {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
text-align: center;
flex: 1;
margin-right: 20px;
}

.process-name {
font-size: 12px;
color: #606266;
margin-bottom: 8px;
cursor: default;
}

.process-name.clickable {
cursor: pointer;
color: #003DA5;
}

.process-name:hover {
text-decoration: underline;
}

.process-circle {
display: flex;
align-items: center;
justify-content: center;
}

.process-circle-outer {
width: 24px;
height: 24px;
border-radius: 50%;
border: 3px solid #D3D3D3;
display: flex;
align-items: center;
justify-content: center;
background-color: #FFFFFF;
}

.process-circle-inner {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #FFFFFF;
}

.completed-process .process-circle-outer {
border-color: #67C23A;
background-color: #A5D6A7;
}

.current-process .process-circle-inner {
background-color: #E6A23C;
animation: blink 0.5s infinite alternate;
}

@keyframes blink {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0.5;
transform: scale(1.2);
}
}

.current-process .process-circle-outer {
border-color: #E6A23C;
background-color: #F5D4A3;
}

.current-process .process-circle-inner {
background-color: #E6A23C;
animation: blink 1s infinite;
}

@keyframes blink {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
</style>
posted on 2024-10-13 21:56  清荣峻茂  阅读(15)  评论(0)    收藏  举报