<template>
|
<div class="app-container teaching-demo-index">
|
<PageHeader content="工艺路线与BOM动画教学演示">
|
<template #right-button>
|
<el-button type="success" @click="goToFactoryDemo">
|
<el-icon><Monitor /></el-icon>
|
工厂演示
|
</el-button>
|
<el-button type="primary" @click="goToCombinedDemo">
|
联动演示
|
</el-button>
|
</template>
|
</PageHeader>
|
|
<div class="demo-intro">
|
<el-alert
|
title="教学演示说明"
|
type="info"
|
:closable="false"
|
show-icon
|
>
|
<template #default>
|
本模块通过动画演示帮助您理解 <strong>BOM(物料清单)</strong> 和 <strong>工艺路线</strong> 的概念。
|
选择下方的数据后点击进入演示,即可观看动画讲解。
|
</template>
|
</el-alert>
|
</div>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-card class="demo-card" shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span class="card-title">
|
<el-icon><List /></el-icon>
|
BOM 结构演示
|
</span>
|
<el-button type="primary" :disabled="!selectedBom" @click="goToBomDemo">
|
进入演示
|
</el-button>
|
</div>
|
</template>
|
|
<div class="card-content">
|
<p class="card-desc">展示物料清单的树形层级结构,理解产品由哪些零部件组成。</p>
|
|
<el-select
|
v-model="selectedBom"
|
placeholder="请选择一个BOM"
|
filterable
|
style="width: 100%"
|
@change="handleBomChange"
|
>
|
<el-option
|
v-for="item in bomList"
|
:key="item.id"
|
:label="`${item.bomNo} - ${item.productName}`"
|
:value="item.id"
|
/>
|
</el-select>
|
|
<div v-if="selectedBomInfo" class="selected-info">
|
<el-descriptions :column="1" border size="small">
|
<el-descriptions-item label="BOM编号">{{ selectedBomInfo.bomNo }}</el-descriptions-item>
|
<el-descriptions-item label="产品名称">{{ selectedBomInfo.productName }}</el-descriptions-item>
|
<el-descriptions-item label="规格型号">{{ selectedBomInfo.productModelName }}</el-descriptions-item>
|
<el-descriptions-item label="版本号">{{ selectedBomInfo.version }}</el-descriptions-item>
|
</el-descriptions>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
|
<el-col :span="12">
|
<el-card class="demo-card" shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span class="card-title">
|
<el-icon><Connection /></el-icon>
|
工艺路线演示
|
</span>
|
<el-button type="primary" :disabled="!selectedRoute" @click="goToRouteDemo">
|
进入演示
|
</el-button>
|
</div>
|
</template>
|
|
<div class="card-content">
|
<p class="card-desc">展示产品加工的工序流程,理解产品是如何一步步生产出来的。</p>
|
|
<el-select
|
v-model="selectedRoute"
|
placeholder="请选择一个工艺路线"
|
filterable
|
style="width: 100%"
|
@change="handleRouteChange"
|
>
|
<el-option
|
v-for="item in routeList"
|
:key="item.id"
|
:label="`${item.processRouteCode} - ${item.productName}`"
|
:value="item.id"
|
/>
|
</el-select>
|
|
<div v-if="selectedRouteInfo" class="selected-info">
|
<el-descriptions :column="1" border size="small">
|
<el-descriptions-item label="路线编号">{{ selectedRouteInfo.processRouteCode }}</el-descriptions-item>
|
<el-descriptions-item label="产品名称">{{ selectedRouteInfo.productName }}</el-descriptions-item>
|
<el-descriptions-item label="规格名称">{{ selectedRouteInfo.model }}</el-descriptions-item>
|
<el-descriptions-item label="BOM编号">{{ selectedRouteInfo.bomNo }}</el-descriptions-item>
|
</el-descriptions>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<el-card class="concept-card" shadow="hover">
|
<template #header>
|
<span class="card-title">
|
<el-icon><Reading /></el-icon>
|
概念说明
|
</span>
|
</template>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<div class="concept-item">
|
<h4>BOM(物料清单)</h4>
|
<p>
|
BOM(Bill of Materials)是产品结构的技术文件,它详细记录了产品由哪些零部件、原材料组成,
|
以及各组成部分之间的层级关系和数量关系。
|
</p>
|
<ul>
|
<li><strong>父项:</strong>上层产品或部件</li>
|
<li><strong>子项:</strong>组成父项的零部件或原材料</li>
|
<li><strong>用量:</strong>生产一个父项需要多少子项</li>
|
</ul>
|
</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="concept-item">
|
<h4>工艺路线</h4>
|
<p>
|
工艺路线是描述产品加工过程的文件,它规定了产品从原材料到成品需要经过哪些工序,
|
以及各工序的先后顺序和操作要求。
|
</p>
|
<ul>
|
<li><strong>工序:</strong>一个独立的加工步骤</li>
|
<li><strong>顺序:</strong>工序执行的先后次序</li>
|
<li><strong>参数:</strong>工序的具体操作要求</li>
|
</ul>
|
</div>
|
</el-col>
|
</el-row>
|
</el-card>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, computed, onMounted } from 'vue'
|
import { useRouter } from 'vue-router'
|
import { List, Connection, Reading, Monitor } from '@element-plus/icons-vue'
|
import { listPage as getBomList } from '@/api/productionManagement/productBom.js'
|
import { listPage as getRouteList } from '@/api/productionManagement/processRoute.js'
|
|
const router = useRouter()
|
|
const bomList = ref([])
|
const routeList = ref([])
|
const selectedBom = ref(null)
|
const selectedRoute = ref(null)
|
|
const selectedBomInfo = computed(() => {
|
return bomList.value.find(item => item.id === selectedBom.value)
|
})
|
|
const selectedRouteInfo = computed(() => {
|
return routeList.value.find(item => item.id === selectedRoute.value)
|
})
|
|
const fetchBomList = async () => {
|
try {
|
const res = await getBomList({ current: 1, size: 100 })
|
bomList.value = res?.data?.records || []
|
} catch (error) {
|
console.error('获取BOM列表失败:', error)
|
}
|
}
|
|
const fetchRouteList = async () => {
|
try {
|
const res = await getRouteList({ current: 1, size: 100 })
|
routeList.value = res?.data?.records || []
|
} catch (error) {
|
console.error('获取工艺路线列表失败:', error)
|
}
|
}
|
|
const handleBomChange = (val) => {
|
selectedBom.value = val
|
}
|
|
const handleRouteChange = (val) => {
|
selectedRoute.value = val
|
}
|
|
const goToBomDemo = () => {
|
if (!selectedBom.value) return
|
const info = selectedBomInfo.value
|
router.push({
|
path: '/productionManagement/teachingDemo/bom',
|
query: {
|
id: selectedBom.value,
|
bomNo: info?.bomNo || '',
|
productName: info?.productName || '',
|
productModelName: info?.productModelName || ''
|
}
|
})
|
}
|
|
const goToRouteDemo = () => {
|
if (!selectedRoute.value) return
|
const info = selectedRouteInfo.value
|
router.push({
|
path: '/productionManagement/teachingDemo/processRoute',
|
query: {
|
id: selectedRoute.value,
|
processRouteCode: info?.processRouteCode || '',
|
productName: info?.productName || '',
|
model: info?.model || '',
|
bomId: info?.bomId || ''
|
}
|
})
|
}
|
|
const goToCombinedDemo = () => {
|
router.push({
|
path: '/productionManagement/teachingDemo/combined',
|
query: {
|
bomId: selectedBom.value || '',
|
routeId: selectedRoute.value || ''
|
}
|
})
|
}
|
|
const goToFactoryDemo = () => {
|
router.push({
|
path: '/productionManagement/teachingDemo/factory',
|
query: {
|
routeId: selectedRoute.value || ''
|
}
|
})
|
}
|
|
onMounted(() => {
|
fetchBomList()
|
fetchRouteList()
|
})
|
</script>
|
|
<style scoped lang="scss">
|
.teaching-demo-index {
|
.demo-intro {
|
margin-bottom: 20px;
|
}
|
|
.demo-card {
|
margin-bottom: 20px;
|
|
.card-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.card-title {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
font-weight: 600;
|
font-size: 16px;
|
}
|
}
|
|
.card-content {
|
.card-desc {
|
color: #666;
|
margin-bottom: 16px;
|
line-height: 1.6;
|
}
|
|
.selected-info {
|
margin-top: 16px;
|
}
|
}
|
}
|
|
.concept-card {
|
.card-title {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
font-weight: 600;
|
font-size: 16px;
|
}
|
|
.concept-item {
|
h4 {
|
color: #409eff;
|
margin-bottom: 12px;
|
font-size: 15px;
|
}
|
|
p {
|
color: #666;
|
line-height: 1.8;
|
margin-bottom: 12px;
|
}
|
|
ul {
|
padding-left: 20px;
|
color: #888;
|
line-height: 1.8;
|
|
li {
|
margin-bottom: 4px;
|
}
|
}
|
}
|
}
|
}
|
</style>
|