224 lines
6.8 KiB
Vue
224 lines
6.8 KiB
Vue
<template>
|
|
<design-task-panel v-if="showDesignEntry" />
|
|
<div v-else class="app-container workbench-container">
|
|
<!-- 顶部概览卡片 -->
|
|
<overview-cards :list="overviewList" />
|
|
|
|
<el-row :gutter="20" class="workbench-row">
|
|
<!-- 左侧:工单数量柱状图 -->
|
|
<el-col :xs="24" :sm="24" :lg="16">
|
|
<div class="workbench-panel">
|
|
<div class="workbench-panel-header">
|
|
<span class="workbench-panel-title">工单数量</span>
|
|
</div>
|
|
<div class="workbench-panel-body">
|
|
<work-order-bar :chart-data="workOrderData" height="400px" />
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
|
|
<!-- 右侧:工序不良率排名 -->
|
|
<el-col :xs="24" :sm="24" :lg="8">
|
|
<div class="workbench-panel">
|
|
<div class="workbench-panel-header">
|
|
<span class="workbench-panel-title">工序不良率排名</span>
|
|
</div>
|
|
<div class="workbench-panel-body">
|
|
<process-defect-rank :list="defectRankList" />
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row :gutter="20" class="workbench-row">
|
|
<!-- 左侧:工单实时进度 -->
|
|
<el-col :xs="24" :sm="24" :lg="14">
|
|
<div class="workbench-panel">
|
|
<div class="workbench-panel-header">
|
|
<span class="workbench-panel-title">工单实时进度</span>
|
|
</div>
|
|
<div class="workbench-panel-body">
|
|
<work-order-progress :list="workOrderProgressList" />
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import OverviewCards from './components/OverviewCards'
|
|
import WorkOrderBar from './components/WorkOrderBar'
|
|
import ProcessDefectRank from './components/ProcessDefectRank'
|
|
import WorkOrderProgress from './components/WorkOrderProgress'
|
|
import DesignTaskPanel from './design/index'
|
|
|
|
import {
|
|
getOverview,
|
|
getWorkOrderBar,
|
|
getProcessDefectRank,
|
|
getWorkOrderProgress
|
|
} from '@/api/system/workbench'
|
|
|
|
export default {
|
|
name: 'Workbench',
|
|
components: {
|
|
OverviewCards,
|
|
WorkOrderBar,
|
|
ProcessDefectRank,
|
|
WorkOrderProgress,
|
|
DesignTaskPanel
|
|
},
|
|
data() {
|
|
return {
|
|
overviewList: [
|
|
{ key: 'shipProductCount', title: '出货产品数', value: 0, mom: 0, yoy: 0 },
|
|
{ key: 'workOrderCount', title: '生产工单数', value: 0, mom: 0, yoy: 0 },
|
|
{ key: 'wipCount', title: '在制品', value: 0, mom: 0, yoy: 0 },
|
|
{ key: 'ngCount', title: '不良品数', value: 0, mom: 0, yoy: 0 }
|
|
],
|
|
workOrderData: { xAxis: [], series: [] },
|
|
defectRankList: [],
|
|
workOrderProgressList: []
|
|
}
|
|
},
|
|
computed: {
|
|
showDesignEntry() {
|
|
const roles = (this.$store.getters && this.$store.getters.roles) || []
|
|
const perms = (this.$store.getters && this.$store.getters.permissions) || []
|
|
return roles.includes('admin')
|
|
|| roles.includes('designer')
|
|
|| perms.includes('system:designTask:list')
|
|
|| perms.includes('*:*:*')
|
|
}
|
|
},
|
|
created() {
|
|
if (!this.showDesignEntry) {
|
|
this.fetchData()
|
|
}
|
|
},
|
|
methods: {
|
|
fetchData() {
|
|
// 获取概览数据
|
|
getOverview().then(res => {
|
|
if (res && res.data && res.data.cards) {
|
|
this.overviewList = res.data.cards
|
|
} else {
|
|
this.mockOverview()
|
|
}
|
|
}).catch(() => {
|
|
this.mockOverview()
|
|
})
|
|
|
|
// 获取柱状图数据
|
|
getWorkOrderBar().then(res => {
|
|
if (res && res.data && (res.data.xAxis || res.data.xaxis)) {
|
|
this.workOrderData = res.data
|
|
} else {
|
|
this.mockWorkOrder()
|
|
}
|
|
}).catch(() => {
|
|
this.mockWorkOrder()
|
|
})
|
|
|
|
// 获取排名数据
|
|
getProcessDefectRank().then(res => {
|
|
if (res && res.data && res.data.items) {
|
|
this.defectRankList = res.data.items
|
|
} else {
|
|
this.mockDefectRank()
|
|
}
|
|
}).catch(() => {
|
|
this.mockDefectRank()
|
|
})
|
|
|
|
// 获取工单进度
|
|
getWorkOrderProgress().then(res => {
|
|
if (res && res.data && res.data.items) {
|
|
this.workOrderProgressList = res.data.items
|
|
} else {
|
|
this.mockWorkOrderProgress()
|
|
}
|
|
}).catch(() => {
|
|
this.mockWorkOrderProgress()
|
|
})
|
|
},
|
|
mockOverview() {
|
|
this.overviewList = [
|
|
{ key: 'shipProductCount', title: '出货产品数', value: 7314, mom: 0.68, yoy: -0.05 },
|
|
{ key: 'workOrderCount', title: '生产工单数', value: 7326, mom: 0.58, yoy: -0.01 },
|
|
{ key: 'wipCount', title: '在制品', value: 5399, mom: 0.56, yoy: 0.03 },
|
|
{ key: 'ngCount', title: '不良品数', value: 85, mom: -0.45, yoy: -0.05 }
|
|
]
|
|
},
|
|
mockWorkOrder() {
|
|
this.workOrderData = {
|
|
xAxis: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
|
|
series: [{
|
|
name: "工单数量",
|
|
data: [9000, 8000, 12000, 9500, 10000, 9000, 14000, 6000, 9000, 13000, 10000, 9000]
|
|
}]
|
|
}
|
|
},
|
|
mockDefectRank() {
|
|
this.defectRankList = [
|
|
{ rank: 1, processName: "切割", defectRate: 0.40 },
|
|
{ rank: 2, processName: "焊接", defectRate: 0.38 },
|
|
{ rank: 3, processName: "委外烤漆", defectRate: 0.37 },
|
|
{ rank: 4, processName: "烧结炉", defectRate: 0.36 },
|
|
{ rank: 5, processName: "注水", defectRate: 0.32 },
|
|
{ rank: 6, processName: "冷却", defectRate: 0.28 },
|
|
{ rank: 7, processName: "散热", defectRate: 0.25 },
|
|
{ rank: 8, processName: "扣排线", defectRate: 0.22 },
|
|
{ rank: 9, processName: "上料", defectRate: 0.20 },
|
|
{ rank: 10, processName: "效能测试", defectRate: 0.18 }
|
|
]
|
|
},
|
|
mockWorkOrderProgress() {
|
|
this.workOrderProgressList = [
|
|
{ workOrderNo: 'MO202112160001', status: '已完工', progress: 100, totalQty: 679 },
|
|
{ workOrderNo: 'MO202112160002', status: '已开工', progress: 80, totalQty: 503 },
|
|
{ workOrderNo: 'MO202112160003', status: '已完工', progress: 100, totalQty: 7 },
|
|
{ workOrderNo: 'MO202112160004', status: '已开工', progress: 67, totalQty: 233 },
|
|
{ workOrderNo: 'MO202112160005', status: '已开工', progress: 55, totalQty: 983 }
|
|
]
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.workbench-container {
|
|
background-color: #f0f2f5;
|
|
min-height: calc(100vh - 84px);
|
|
padding: 20px;
|
|
}
|
|
|
|
.workbench-row {
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.workbench-panel {
|
|
background: #fff;
|
|
border-radius: 6px;
|
|
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
|
margin-bottom: 20px;
|
|
|
|
.workbench-panel-header {
|
|
padding: 16px 20px;
|
|
border-bottom: 1px solid #ebeef5;
|
|
|
|
.workbench-panel-title {
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
color: #303133;
|
|
}
|
|
}
|
|
|
|
.workbench-panel-body {
|
|
padding: 20px;
|
|
}
|
|
}
|
|
|
|
</style>
|