✨ feat(home): 更新首页组件注释和路由名称
优化首页各个组件的注释,增加可读性,并将导航逻辑中的 URL 替换为路由名称,提升代码的稳定性和可维护性。pull/871/MERGE
parent
8e8c1941b3
commit
fb213bfd76
|
|
@ -1,4 +1,4 @@
|
|||
<!-- TODO @AI:补充一些注释 -->
|
||||
<!-- 首页待办与异常提醒面板 -->
|
||||
<template>
|
||||
<el-card shadow="hover" class="h-full alert-card">
|
||||
<template #header>
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
v-for="item in alertItems"
|
||||
: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)]"
|
||||
@click="emit('navigate', item.url)"
|
||||
@click="emit('navigate', item.routeName)"
|
||||
>
|
||||
<div
|
||||
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<{
|
||||
navigate: [url: string]
|
||||
navigate: [name: string]
|
||||
}>()
|
||||
|
||||
/** 待办提醒列表:每项包含标签、描述、图标、目标路由名称、数量 */
|
||||
const alertItems = computed(() => [
|
||||
{
|
||||
label: '安灯报警',
|
||||
desc: '未处置的安灯呼叫',
|
||||
icon: 'ep:warning-filled',
|
||||
url: '/mes/pro/andon',
|
||||
routeName: 'MesProAndon',
|
||||
count: props.summary.andonActiveCount,
|
||||
iconClass: 'bg-[rgba(245,108,108,0.1)] color-[#f56c6c]'
|
||||
},
|
||||
|
|
@ -55,7 +56,7 @@ const alertItems = computed(() => [
|
|||
label: '设备维修',
|
||||
desc: '待处理的维修工单',
|
||||
icon: 'ep:set-up',
|
||||
url: '/mes/dv/repair',
|
||||
routeName: 'MesDvRepair',
|
||||
count: props.summary.repairActiveCount,
|
||||
iconClass: 'bg-[rgba(230,162,60,0.1)] color-[#e6a23c]'
|
||||
},
|
||||
|
|
@ -63,7 +64,7 @@ const alertItems = computed(() => [
|
|||
label: '待排产工单',
|
||||
desc: '草稿状态的生产工单',
|
||||
icon: 'ep:document-checked',
|
||||
url: '/mes/pro/workorder',
|
||||
routeName: 'MesProWorkOrder',
|
||||
count: props.summary.workOrderPrepareCount,
|
||||
iconClass: 'bg-[rgba(64,158,255,0.1)] color-[#409eff]'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,18 @@
|
|||
<!-- TODO @AI:补充一些注释 -->
|
||||
<!--
|
||||
HomeKpiCards - 首页核心 KPI 汇总卡片
|
||||
以 4 列卡片形式展示关键生产指标:
|
||||
1. 生产工单 —— 进行中数量 / 待排产 / 已完成
|
||||
2. 今日产量 —— 今日产出件数,对比昨日
|
||||
3. 质量合格率 —— 合格品 / 不良品计算百分比
|
||||
4. 设备状态 —— 运行中 / 停机 / 维护中
|
||||
-->
|
||||
<template>
|
||||
<el-row :gutter="16" class="mb-16px">
|
||||
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-16px">
|
||||
<el-card
|
||||
shadow="hover"
|
||||
class="kpi-card kpi-card--production"
|
||||
@click="handleNavigate('/mes/pro/workorder')"
|
||||
@click="handleNavigate('MesProWorkOrder')"
|
||||
>
|
||||
<div class="flex items-center gap-16px">
|
||||
<div
|
||||
|
|
@ -37,7 +44,7 @@
|
|||
<el-card
|
||||
shadow="hover"
|
||||
class="kpi-card kpi-card--output"
|
||||
@click="handleNavigate('/mes/pro/feedback')"
|
||||
@click="handleNavigate('MesProFeedback')"
|
||||
>
|
||||
<div class="flex items-center gap-16px">
|
||||
<div
|
||||
|
|
@ -67,7 +74,7 @@
|
|||
<el-card
|
||||
shadow="hover"
|
||||
class="kpi-card kpi-card--quality"
|
||||
@click="handleNavigate('/mes/qc/iqc')"
|
||||
@click="handleNavigate('MesQcIqc')"
|
||||
>
|
||||
<div class="flex items-center gap-16px">
|
||||
<div
|
||||
|
|
@ -100,7 +107,7 @@
|
|||
<el-card
|
||||
shadow="hover"
|
||||
class="kpi-card kpi-card--equipment"
|
||||
@click="handleNavigate('/mes/dv/machinery')"
|
||||
@click="handleNavigate('MesDvMachinery')"
|
||||
>
|
||||
<div class="flex items-center gap-16px">
|
||||
<div
|
||||
|
|
@ -143,17 +150,19 @@ const props = defineProps<{
|
|||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
navigate: [url: string]
|
||||
navigate: [name: string]
|
||||
}>()
|
||||
|
||||
/** 质量合格率 = 合格品 / (合格品 + 不良品) * 100,默认 100% */
|
||||
const qualityRate = computed(() => {
|
||||
const total = props.summary.todayQualifiedQuantity + props.summary.todayUnqualifiedQuantity
|
||||
if (total === 0) return 100
|
||||
return (props.summary.todayQualifiedQuantity / total) * 100
|
||||
})
|
||||
|
||||
const handleNavigate = (url: string) => {
|
||||
emit('navigate', url)
|
||||
/** 导航到目标页面,参数为路由 name */
|
||||
const handleNavigate = (name: string) => {
|
||||
emit('navigate', name)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- TODO @AI:补充一些注释 -->
|
||||
<!-- 首页生产趋势图表 -->
|
||||
<template>
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
|
|
@ -20,7 +20,7 @@ import { MesHomeStatisticsApi, MesHomeProductionTrendVO } from '@/api/mes/home'
|
|||
|
||||
defineOptions({ name: 'HomeProductionTrend' })
|
||||
|
||||
const trendDays = ref(7)
|
||||
const trendDays = ref(7) // 当前选中的天数范围
|
||||
const trendChartOptions = reactive<EChartsOption>({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
|
|
@ -54,8 +54,9 @@ const trendChartOptions = reactive<EChartsOption>({
|
|||
itemStyle: { color: '#F56C6C' }
|
||||
}
|
||||
]
|
||||
}) as EChartsOption
|
||||
}) as EChartsOption // ECharts 图表配置(reactive 以支持动态更新数据)
|
||||
|
||||
/** 加载生产趋势数据并更新图表 */
|
||||
const loadData = async () => {
|
||||
const data: MesHomeProductionTrendVO[] = await MesHomeStatisticsApi.getProductionTrend(
|
||||
trendDays.value
|
||||
|
|
@ -63,13 +64,15 @@ const loadData = async () => {
|
|||
const dates = data.map((d) => d.date.substring(5))
|
||||
const quantities = data.map((d) => d.quantity)
|
||||
const qualified = data.map((d) => d.qualifiedQuantity)
|
||||
const unqualified = data.map((d) => d.unqualifiedQuantity)
|
||||
;(trendChartOptions as any).xAxis.data = dates
|
||||
;(trendChartOptions as any).series[0].data = quantities
|
||||
;(trendChartOptions as any).series[1].data = qualified
|
||||
;(trendChartOptions as any).series[2].data = unqualified
|
||||
const unqualified = data.map((d) => d.unqualifiedQuantity);
|
||||
(trendChartOptions as any).xAxis.data = dates;
|
||||
(trendChartOptions as any).series[0].data = quantities;
|
||||
(trendChartOptions as any).series[1].data = qualified;
|
||||
(trendChartOptions as any).series[2].data = unqualified
|
||||
}
|
||||
|
||||
/** 暴露加载方法供父组件调用 */
|
||||
defineExpose({ loadData })
|
||||
/** 组件挂载时自动加载数据 */
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- TODO @AI:补充一些注释 -->
|
||||
<!-- 首页工单状态分布饼图 -->
|
||||
<template>
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
|
|
@ -13,17 +13,16 @@
|
|||
<script lang="ts" setup>
|
||||
import { EChartsOption } from 'echarts'
|
||||
import { MesHomeStatisticsApi, MesHomeWorkOrderStatusVO } from '@/api/mes/home'
|
||||
import { MesProWorkOrderStatusEnum } from '@/views/mes/utils/constants'
|
||||
|
||||
defineOptions({ name: 'HomeWorkOrderChart' })
|
||||
|
||||
const statusColorMap: Record<number, string> = {
|
||||
// TODO @AI:key 最好使用枚举;
|
||||
0: '#909399', // 草稿
|
||||
1: '#409EFF', // 已确认
|
||||
2: '#67C23A', // 已完成
|
||||
3: '#F56C6C' // 已取消
|
||||
}
|
||||
|
||||
[MesProWorkOrderStatusEnum.PREPARE]: '#909399', // 草稿
|
||||
[MesProWorkOrderStatusEnum.CONFIRMED]: '#409EFF', // 已确认
|
||||
[MesProWorkOrderStatusEnum.FINISHED]: '#67C23A', // 已完成
|
||||
[MesProWorkOrderStatusEnum.CANCELED]: '#F56C6C' // 已取消
|
||||
} // 工单状态对应的颜色映射
|
||||
const workOrderChartOptions = reactive<EChartsOption>({
|
||||
tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
|
||||
legend: { bottom: 0, type: 'scroll' },
|
||||
|
|
@ -38,8 +37,9 @@ const workOrderChartOptions = reactive<EChartsOption>({
|
|||
data: []
|
||||
}
|
||||
]
|
||||
}) as EChartsOption
|
||||
}) as EChartsOption // ECharts 饼图配置
|
||||
|
||||
/** 加载工单状态分布数据并更新饼图 */
|
||||
const loadData = async () => {
|
||||
const data: MesHomeWorkOrderStatusVO[] =
|
||||
await MesHomeStatisticsApi.getWorkOrderStatusDistribution()
|
||||
|
|
@ -50,6 +50,8 @@ const loadData = async () => {
|
|||
}))
|
||||
}
|
||||
|
||||
/** 暴露加载方法供父组件调用 */
|
||||
defineExpose({ loadData })
|
||||
/** 组件挂载时自动加载数据 */
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- TODO @AI:row 之间的间距太大了; -->
|
||||
<!-- Row 1: 核心 KPI 汇总卡片 -->
|
||||
<HomeKpiCards :summary="summary" @navigate="handleNavigate" />
|
||||
|
||||
|
|
@ -8,7 +7,7 @@
|
|||
<el-row :gutter="16" 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 :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-16px">
|
||||
|
|
@ -20,7 +19,7 @@
|
|||
<el-row :gutter="16">
|
||||
<!-- 工单状态分布 -->
|
||||
<el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24" class="mb-16px">
|
||||
<HomeWorkOrderChart ref="workOrderChartRef" />
|
||||
<HomeWorkOrderChart />
|
||||
</el-col>
|
||||
<!-- 快捷入口 -->
|
||||
<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,
|
||||
repairActiveCount: 0
|
||||
}) // 数据
|
||||
const productionTrendRef = ref<InstanceType<typeof HomeProductionTrend>>()
|
||||
const workOrderChartRef = ref<InstanceType<typeof HomeWorkOrderChart>>()
|
||||
|
||||
// TODO @AI:可以改成 name 么?因为 url 可能会变,而 name 更稳定!
|
||||
const handleNavigate = (url: string) => {
|
||||
router.push(url)
|
||||
// DONE @AI:跳转都不对了,是不是菜单里的组件名没对上?已确认所有 routeName 与目标页面 defineOptions({ name }) 一致
|
||||
// DONE @AI:可以改成 name 么?因为 url 可能会变,而 name 更稳定!已改为使用路由 name 导航
|
||||
const handleNavigate = (name: string) => {
|
||||
router.push({ name })
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const [summaryData] = await Promise.all([
|
||||
MesHomeStatisticsApi.getHomeSummary(),
|
||||
// TODO @AI:productionTrendRef、workOrderChartRef 可以自己加载自己的数据,自己使用么?
|
||||
productionTrendRef.value?.loadData(),
|
||||
workOrderChartRef.value?.loadData()
|
||||
])
|
||||
summary.value = summaryData
|
||||
summary.value = await MesHomeStatisticsApi.getHomeSummary()
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue