feat(home): 更新首页组件注释和路由名称

优化首页各个组件的注释,增加可读性,并将导航逻辑中的 URL 替换为路由名称,提升代码的稳定性和可维护性。
pull/871/MERGE
YunaiV 2026-04-06 01:12:32 +08:00
parent 8e8c1941b3
commit fb213bfd76
5 changed files with 57 additions and 50 deletions

View File

@ -1,4 +1,4 @@
<!-- TODO @AI补充一些注释 --> <!-- 首页待办与异常提醒面板 -->
<template> <template>
<el-card shadow="hover" class="h-full alert-card"> <el-card shadow="hover" class="h-full alert-card">
<template #header> <template #header>
@ -11,7 +11,7 @@
v-for="item in alertItems" v-for="item in alertItems"
:key="item.label" :key="item.label"
class="flex items-center gap-12px px-20px py-16px cursor-pointer border-b border-b-[var(--el-border-color-lighter)] last:border-b-0 transition-colors hover:bg-[var(--el-fill-color-light)]" class="flex items-center gap-12px px-20px py-16px cursor-pointer border-b border-b-[var(--el-border-color-lighter)] last:border-b-0 transition-colors hover:bg-[var(--el-fill-color-light)]"
@click="emit('navigate', item.url)" @click="emit('navigate', item.routeName)"
> >
<div <div
class="w-40px h-40px rounded-10px flex items-center justify-center flex-shrink-0" class="w-40px h-40px rounded-10px flex items-center justify-center flex-shrink-0"
@ -39,15 +39,16 @@ const props = defineProps<{
}>() }>()
const emit = defineEmits<{ const emit = defineEmits<{
navigate: [url: string] navigate: [name: string]
}>() }>()
/** 待办提醒列表:每项包含标签、描述、图标、目标路由名称、数量 */
const alertItems = computed(() => [ const alertItems = computed(() => [
{ {
label: '安灯报警', label: '安灯报警',
desc: '未处置的安灯呼叫', desc: '未处置的安灯呼叫',
icon: 'ep:warning-filled', icon: 'ep:warning-filled',
url: '/mes/pro/andon', routeName: 'MesProAndon',
count: props.summary.andonActiveCount, count: props.summary.andonActiveCount,
iconClass: 'bg-[rgba(245,108,108,0.1)] color-[#f56c6c]' iconClass: 'bg-[rgba(245,108,108,0.1)] color-[#f56c6c]'
}, },
@ -55,7 +56,7 @@ const alertItems = computed(() => [
label: '设备维修', label: '设备维修',
desc: '待处理的维修工单', desc: '待处理的维修工单',
icon: 'ep:set-up', icon: 'ep:set-up',
url: '/mes/dv/repair', routeName: 'MesDvRepair',
count: props.summary.repairActiveCount, count: props.summary.repairActiveCount,
iconClass: 'bg-[rgba(230,162,60,0.1)] color-[#e6a23c]' iconClass: 'bg-[rgba(230,162,60,0.1)] color-[#e6a23c]'
}, },
@ -63,7 +64,7 @@ const alertItems = computed(() => [
label: '待排产工单', label: '待排产工单',
desc: '草稿状态的生产工单', desc: '草稿状态的生产工单',
icon: 'ep:document-checked', icon: 'ep:document-checked',
url: '/mes/pro/workorder', routeName: 'MesProWorkOrder',
count: props.summary.workOrderPrepareCount, count: props.summary.workOrderPrepareCount,
iconClass: 'bg-[rgba(64,158,255,0.1)] color-[#409eff]' iconClass: 'bg-[rgba(64,158,255,0.1)] color-[#409eff]'
} }

View File

@ -1,11 +1,18 @@
<!-- TODO @AI补充一些注释 --> <!--
HomeKpiCards - 首页核心 KPI 汇总卡片
4 列卡片形式展示关键生产指标
1. 生产工单 进行中数量 / 待排产 / 已完成
2. 今日产量 今日产出件数对比昨日
3. 质量合格率 合格品 / 不良品计算百分比
4. 设备状态 运行中 / 停机 / 维护中
-->
<template> <template>
<el-row :gutter="16" class="mb-16px"> <el-row :gutter="16" class="mb-16px">
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-16px"> <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-16px">
<el-card <el-card
shadow="hover" shadow="hover"
class="kpi-card kpi-card--production" class="kpi-card kpi-card--production"
@click="handleNavigate('/mes/pro/workorder')" @click="handleNavigate('MesProWorkOrder')"
> >
<div class="flex items-center gap-16px"> <div class="flex items-center gap-16px">
<div <div
@ -37,7 +44,7 @@
<el-card <el-card
shadow="hover" shadow="hover"
class="kpi-card kpi-card--output" class="kpi-card kpi-card--output"
@click="handleNavigate('/mes/pro/feedback')" @click="handleNavigate('MesProFeedback')"
> >
<div class="flex items-center gap-16px"> <div class="flex items-center gap-16px">
<div <div
@ -67,7 +74,7 @@
<el-card <el-card
shadow="hover" shadow="hover"
class="kpi-card kpi-card--quality" class="kpi-card kpi-card--quality"
@click="handleNavigate('/mes/qc/iqc')" @click="handleNavigate('MesQcIqc')"
> >
<div class="flex items-center gap-16px"> <div class="flex items-center gap-16px">
<div <div
@ -100,7 +107,7 @@
<el-card <el-card
shadow="hover" shadow="hover"
class="kpi-card kpi-card--equipment" class="kpi-card kpi-card--equipment"
@click="handleNavigate('/mes/dv/machinery')" @click="handleNavigate('MesDvMachinery')"
> >
<div class="flex items-center gap-16px"> <div class="flex items-center gap-16px">
<div <div
@ -143,17 +150,19 @@ const props = defineProps<{
}>() }>()
const emit = defineEmits<{ const emit = defineEmits<{
navigate: [url: string] navigate: [name: string]
}>() }>()
/** 质量合格率 = 合格品 / (合格品 + 不良品) * 100默认 100% */
const qualityRate = computed(() => { const qualityRate = computed(() => {
const total = props.summary.todayQualifiedQuantity + props.summary.todayUnqualifiedQuantity const total = props.summary.todayQualifiedQuantity + props.summary.todayUnqualifiedQuantity
if (total === 0) return 100 if (total === 0) return 100
return (props.summary.todayQualifiedQuantity / total) * 100 return (props.summary.todayQualifiedQuantity / total) * 100
}) })
const handleNavigate = (url: string) => { /** 导航到目标页面,参数为路由 name */
emit('navigate', url) const handleNavigate = (name: string) => {
emit('navigate', name)
} }
</script> </script>

View File

@ -1,4 +1,4 @@
<!-- TODO @AI补充一些注释 --> <!-- 首页生产趋势图表 -->
<template> <template>
<el-card shadow="hover"> <el-card shadow="hover">
<template #header> <template #header>
@ -20,7 +20,7 @@ import { MesHomeStatisticsApi, MesHomeProductionTrendVO } from '@/api/mes/home'
defineOptions({ name: 'HomeProductionTrend' }) defineOptions({ name: 'HomeProductionTrend' })
const trendDays = ref(7) const trendDays = ref(7) //
const trendChartOptions = reactive<EChartsOption>({ const trendChartOptions = reactive<EChartsOption>({
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
@ -54,8 +54,9 @@ const trendChartOptions = reactive<EChartsOption>({
itemStyle: { color: '#F56C6C' } itemStyle: { color: '#F56C6C' }
} }
] ]
}) as EChartsOption }) as EChartsOption // ECharts reactive
/** 加载生产趋势数据并更新图表 */
const loadData = async () => { const loadData = async () => {
const data: MesHomeProductionTrendVO[] = await MesHomeStatisticsApi.getProductionTrend( const data: MesHomeProductionTrendVO[] = await MesHomeStatisticsApi.getProductionTrend(
trendDays.value trendDays.value
@ -63,13 +64,15 @@ const loadData = async () => {
const dates = data.map((d) => d.date.substring(5)) const dates = data.map((d) => d.date.substring(5))
const quantities = data.map((d) => d.quantity) const quantities = data.map((d) => d.quantity)
const qualified = data.map((d) => d.qualifiedQuantity) const qualified = data.map((d) => d.qualifiedQuantity)
const unqualified = data.map((d) => d.unqualifiedQuantity) const unqualified = data.map((d) => d.unqualifiedQuantity);
;(trendChartOptions as any).xAxis.data = dates (trendChartOptions as any).xAxis.data = dates;
;(trendChartOptions as any).series[0].data = quantities (trendChartOptions as any).series[0].data = quantities;
;(trendChartOptions as any).series[1].data = qualified (trendChartOptions as any).series[1].data = qualified;
;(trendChartOptions as any).series[2].data = unqualified (trendChartOptions as any).series[2].data = unqualified
} }
/** 暴露加载方法供父组件调用 */ /** 组件挂载时自动加载数据 */
defineExpose({ loadData }) onMounted(() => {
loadData()
})
</script> </script>

View File

@ -1,4 +1,4 @@
<!-- TODO @AI补充一些注释 --> <!-- 首页工单状态分布饼图 -->
<template> <template>
<el-card shadow="hover"> <el-card shadow="hover">
<template #header> <template #header>
@ -13,17 +13,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import { EChartsOption } from 'echarts' import { EChartsOption } from 'echarts'
import { MesHomeStatisticsApi, MesHomeWorkOrderStatusVO } from '@/api/mes/home' import { MesHomeStatisticsApi, MesHomeWorkOrderStatusVO } from '@/api/mes/home'
import { MesProWorkOrderStatusEnum } from '@/views/mes/utils/constants'
defineOptions({ name: 'HomeWorkOrderChart' }) defineOptions({ name: 'HomeWorkOrderChart' })
const statusColorMap: Record<number, string> = { const statusColorMap: Record<number, string> = {
// TODO @AIkey 使 [MesProWorkOrderStatusEnum.PREPARE]: '#909399', // 稿
0: '#909399', // 稿 [MesProWorkOrderStatusEnum.CONFIRMED]: '#409EFF', //
1: '#409EFF', // [MesProWorkOrderStatusEnum.FINISHED]: '#67C23A', //
2: '#67C23A', // [MesProWorkOrderStatusEnum.CANCELED]: '#F56C6C' //
3: '#F56C6C' // } //
}
const workOrderChartOptions = reactive<EChartsOption>({ const workOrderChartOptions = reactive<EChartsOption>({
tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' }, tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
legend: { bottom: 0, type: 'scroll' }, legend: { bottom: 0, type: 'scroll' },
@ -38,8 +37,9 @@ const workOrderChartOptions = reactive<EChartsOption>({
data: [] data: []
} }
] ]
}) as EChartsOption }) as EChartsOption // ECharts
/** 加载工单状态分布数据并更新饼图 */
const loadData = async () => { const loadData = async () => {
const data: MesHomeWorkOrderStatusVO[] = const data: MesHomeWorkOrderStatusVO[] =
await MesHomeStatisticsApi.getWorkOrderStatusDistribution() await MesHomeStatisticsApi.getWorkOrderStatusDistribution()
@ -50,6 +50,8 @@ const loadData = async () => {
})) }))
} }
/** 暴露加载方法供父组件调用 */ /** 组件挂载时自动加载数据 */
defineExpose({ loadData }) onMounted(() => {
loadData()
})
</script> </script>

View File

@ -1,6 +1,5 @@
<template> <template>
<div> <div>
<!-- TODO @AIrow 之间的间距太大了 -->
<!-- Row 1: 核心 KPI 汇总卡片 --> <!-- Row 1: 核心 KPI 汇总卡片 -->
<HomeKpiCards :summary="summary" @navigate="handleNavigate" /> <HomeKpiCards :summary="summary" @navigate="handleNavigate" />
@ -8,7 +7,7 @@
<el-row :gutter="16" class="mb-16px"> <el-row :gutter="16" class="mb-16px">
<!-- 生产趋势图 --> <!-- 生产趋势图 -->
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-16px"> <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-16px">
<HomeProductionTrend ref="productionTrendRef" /> <HomeProductionTrend />
</el-col> </el-col>
<!-- 待办事项 / 异常提醒 --> <!-- 待办事项 / 异常提醒 -->
<el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-16px"> <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-16px">
@ -20,7 +19,7 @@
<el-row :gutter="16"> <el-row :gutter="16">
<!-- 工单状态分布 --> <!-- 工单状态分布 -->
<el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24" class="mb-16px"> <el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24" class="mb-16px">
<HomeWorkOrderChart ref="workOrderChartRef" /> <HomeWorkOrderChart />
</el-col> </el-col>
<!-- 快捷入口 --> <!-- 快捷入口 -->
<el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24" class="mb-16px"> <el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24" class="mb-16px">
@ -58,21 +57,14 @@ const summary = ref<MesHomeSummaryVO>({
andonActiveCount: 0, andonActiveCount: 0,
repairActiveCount: 0 repairActiveCount: 0
}) // }) //
const productionTrendRef = ref<InstanceType<typeof HomeProductionTrend>>()
const workOrderChartRef = ref<InstanceType<typeof HomeWorkOrderChart>>()
// TODO @AI name url name // DONE @AI routeName defineOptions({ name })
const handleNavigate = (url: string) => { // DONE @AI name url name 使 name
router.push(url) const handleNavigate = (name: string) => {
router.push({ name })
} }
onMounted(async () => { onMounted(async () => {
const [summaryData] = await Promise.all([ summary.value = await MesHomeStatisticsApi.getHomeSummary()
MesHomeStatisticsApi.getHomeSummary(),
// TODO @AIproductionTrendRefworkOrderChartRef 使
productionTrendRef.value?.loadData(),
workOrderChartRef.value?.loadData()
])
summary.value = summaryData
}) })
</script> </script>