变更数据中心静态页面完成

This commit is contained in:
2026-08-24 17:29:41 +08:00
parent 951aaa5f97
commit 473062741a
10 changed files with 597 additions and 1 deletions
+280
View File
@@ -0,0 +1,280 @@
<script setup lang="ts">
import { ref, computed } from 'vue';
import { useAppStore } from '@/store/modules/app';
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme';
import { getColorWithOpacity } from "@/utils/common";
import ColumnChart from './modules/columnChart.vue';
import RingChart from "./modules/ringChart.vue";
import RingChart2 from "./modules/ringChart2.vue";
const appStore = useAppStore();
const themeStore = useThemeStore();
const gap = computed(() => (appStore.isMobile ? 0 : 16));
const emit = defineEmits<{ go: [v: string, preset?: string]; openChange: [c: any] }>();
const range = ref("近一年");
const rangeOptions = [
{label: "近一年", value: "近一年"},
{label: "近半年", value: "近半年"},
{label: "近三个月", value: "近三个月"},
{label: "近一个月", value: "近一个月"},
];
const changeData = ref([
{
name: '一车间',
value: 42,
},
{
name: '二车间',
value: 35,
},
{
name: '三车间',
value: 28,
},
{
name: '供应部',
value: 12,
},
{
name: '质量部',
value: 9,
},
]);
const DEPT_ACCEPT = [
{ name: "工艺", value: 58 },
{ name: "设备", value: 41 },
{ name: "管理", value: 27 },
];
const ACCEPT_COLORS = ["#2080f0", "#faad14", "#52c41a"];
const DEPT_ACCEPT2 = [
{ name: "完全达到", value: 13, money: 61.2, rate: 68 },
{ name: "基本达到", value: 4, money: 19.8, rate: 21 },
{ name: "未达到", value: 2, money: 5.4, rate: 11 },
];
const ACCEPT_COLORS2 = ["#52c41a", "#faad14", "#ff4d4f"];
const residualHigh = ref<{id: string, title: string}>({id:'MOC-2026-R01-0035',title:'R-201 反应釜搅拌器电机更换(55kW→75kW 防爆电机)'});
</script>
<template>
<NSpace vertical :size="16">
<!-- 我的工作台 -->
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
<div class="flex flex-wrap items-center gap-2">
<p class="text-sm font-bold text-slate-800">全厂变更数据中心</p>
<p class="text-[11px] text-slate-400 mt-[1px]">时间相关数据统一在此查询 · 统计时段</p>
<NSelect v-model:value="range" :options="rangeOptions" size="tiny" class="w-28" />
<NButton ghost size="small" class="ml-auto text-xs">导出</NButton>
</div>
</NCard>
<!-- 卡片数据 -->
<NGrid cols="s:1 m:2 l:4" responsive="screen" :x-gap="gap" :y-gap="16"
:style="{
'--theme-color': themeStore.themeColor,
'--theme-bg': getColorWithOpacity(themeStore.themeColor, 0.2),
'--warning-bg': getColorWithOpacity(themeStore.otherColor.warning, 0.2),
'--warning-color': themeStore.otherColor.warning,
'--success-color': themeStore.otherColor.success,
'--success-bg': getColorWithOpacity(themeStore.otherColor.success, 0.2),
'--error-color': themeStore.otherColor.error,
'--error-bg': getColorWithOpacity(themeStore.otherColor.error, 0.2),
}"
>
<NGi>
<div
class="h-100% flex-1 flex items-center gap-3 bg-white px-16px py-12px cursor-pointer transition hover:-translate-y-1"
:style="{ borderRadius: themeStore.themeRadius + 'px' }"
@click="emit('go', 'tasks')"
>
<span class="shrink-0 rounded-lg p-2.5 bg-[var(--theme-bg)]">
<Icon icon="akar-icons:file" class="size-24px text-[--theme-color]" />
</span>
<div class="flex flex-col">
<CountTo
:start-value="0"
:end-value="126"
class="text-26px font-600"
/>
<p class="text-[11px] font-semibold text-slate-400">变更总数 · {{ range }}</p>
</div>
</div>
</NGi>
<NGi>
<div
class="h-100% flex-1 flex items-center gap-3 bg-white px-16px py-12px cursor-pointer transition hover:-translate-y-1"
:style="{ borderRadius: themeStore.themeRadius + 'px' }"
@click="emit('go', 'tasks')"
>
<span class="shrink-0 rounded-lg p-2.5 bg-[var(--warning-bg)]">
<Icon icon="lucide:shield-check" class="size-24px text-[--warning-color]" />
</span>
<div class="flex flex-col">
<CountTo
:start-value="0"
:end-value="18"
class="text-26px font-600"
/>
<p class="text-[11px] font-semibold text-slate-400">重要变更数量 · {{ range }} · 占比 14%</p>
</div>
</div>
</NGi>
<NGi>
<div
class="h-100% flex-1 flex items-center gap-3 bg-white px-16px py-12px cursor-pointer transition hover:-translate-y-1"
:style="{ borderRadius: themeStore.themeRadius + 'px' }"
@click="emit('go', 'tasks')"
>
<span class="shrink-0 rounded-lg p-2.5 bg-[var(--warning-bg)]">
<Icon icon="lucide:shield-check" class="size-24px text-[--warning-color]" />
</span>
<div class="flex flex-col">
<div class="flex items-center">
<CountTo
:start-value="0"
:end-value="4"
class="text-26px font-600 text-[var(--error-color)]"
/>
<p class="text-26px font-600 text-[var(--error-color)]"> 高 /</p>
<CountTo
:start-value="0"
:end-value="11"
class="text-26px font-600 text-[var(--error-color)]"
/><p class="text-26px font-600 text-[var(--error-color)]"> 中</p>
</div>
<p class="text-[11px] font-semibold text-slate-400">变更新增风险 · 剩余高风险 1 · 剩余中风险 6</p>
</div>
</div>
</NGi>
<NGi>
<div
class="h-100% flex-1 flex items-center gap-3 bg-white px-16px py-12px cursor-pointer transition hover:-translate-y-1"
:style="{ borderRadius: themeStore.themeRadius + 'px' }"
@click="emit('go', 'tasks')"
>
<span class="shrink-0 rounded-lg p-2.5 bg-[var(--success-bg)]">
<Icon icon="material-symbols:check-circle-outline" class="size-24px text-[--success-color]" />
</span>
<div class="flex flex-col">
<CountTo
:start-value="0"
:end-value="86.4"
class="text-26px font-600"
/>
<p class="text-[11px] font-semibold text-slate-400">验收投入合计 · 已验收 19 起 · 完全达标率 68%</p>
</div>
</div>
</NGi>
</NGrid>
<NGrid
:x-gap="gap" :y-gap="16" responsive="screen" item-responsive
:style="{
'--theme-color':themeStore.themeColor
}"
>
<NGi span="24 s:24 m:24 l:14">
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
<div class="flex items-center mb-3 gap-2">
<Icon icon="akar-icons:file" class="size-16px text-[--theme-color]" />
<p class="text-13px font-700 text-#64749a">各车间变更数量</p>
<p class="text-11px text-#94a3b8 mt-2px">{{range}} · 按申请部门</p>
</div>
<ColumnChart :data="changeData" style="height: 100%;" />
</NCard>
</NGi>
<NGi span="24 s:24 m:24 l:10">
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
<div class="flex items-center mb-3 gap-2">
<Icon icon="akar-icons:file" class="size-16px text-[--theme-color]" />
<p class="text-13px font-700 text-#64749a">变更类型分布</p>
<p class="text-11px text-#94a3b8 mt-2px">{{range}} · 工艺 / 设备 / 管理</p>
</div>
<RingChart :data="DEPT_ACCEPT" :colors="ACCEPT_COLORS" :range="range" />
</NCard>
</NGi>
</NGrid>
<NGrid
:x-gap="gap" :y-gap="16" responsive="screen" item-responsive
:style="{
'--error-color':themeStore.otherColor.error,
'--warning-color':themeStore.otherColor.warning,
'--success-color':themeStore.otherColor.success,
'--theme-color':themeStore.themeColor
}"
>
<NGi span="24 s:24 m:24 l:10">
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
<div class="flex items-center mb-3 gap-2">
<Icon icon="lucide:shield-alert" class="size-16px text-[--theme-color]" />
<p class="text-13px font-700 text-#64749a">风险增量与管控</p>
<p class="text-11px text-#94a3b8 mt-2px">{{range}} · 变更新增风险与管控落实</p>
</div>
<div class="space-y-2.5">
<div class="grid grid-cols-2 gap-2">
<div class="rounded-lg bg-red-50 px-3 py-2">
<div class="text-[11px] text-[var(--error-color)]">新增固有高风险项</div>
<div class="text-xl font-bold text-[var(--error-color)]">4</div>
</div>
<div class="rounded-lg bg-amber-50 px-3 py-2">
<div class="text-[11px] text-[var(--warning-color)]">新增中风险项</div>
<div class="text-xl font-bold text-[var(--warning-color)]">11</div>
</div>
<div class="rounded-lg bg-slate-50 px-3 py-2">
<div class="text-[11px] text-slate-500">剩余高风险项</div>
<div class="text-xl font-bold text-slate-800">1</div>
</div>
<div class="rounded-lg bg-slate-50 px-3 py-2">
<div class="text-[11px] text-slate-500">剩余中风险项</div>
<div class="text-xl font-bold text-slate-800">6</div>
</div>
</div>
<div>
<div class="flex justify-between text-[11px] text-slate-500">
<span>管控措施落实率</span>
<span class="font-semibold text-[var(--success-color)]">96%</span>
</div>
<div class="mt-1 h-2 w-full rounded-full bg-slate-100">
<div class="h-2 rounded-full bg-[var(--success-color)]" style="width: 96%" />
</div>
</div>
<div v-if="residualHigh.id" @click="emit('openChange', residualHigh)"
class="cursor-pointer w-full rounded-lg border border-red-100 bg-[#FFF2F0] px-3 py-2 text-left transition hover:border-red-300">
<span class="block text-[11px] font-medium text-[var(--error-color)]">剩余高风险 · 措施落实中</span>
<span class="mt-0.5 block truncate text-xs font-medium text-slate-800">{{ residualHigh.title }}</span>
<span class="mt-0.5 block text-[11px] text-slate-400">{{ residualHigh.id }} · 电机吊装作业管控措施执行跟踪</span>
</div>
</div>
</NCard>
</NGi>
<NGi span="24 s:24 m:24 l:14">
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
<div class="flex items-center mb-3 gap-2">
<Icon icon="material-symbols:check-circle-outline" class="size-16px text-[--theme-color]" />
<p class="text-13px font-700 text-#64749a">变更投入和效果</p>
<p class="text-11px text-#94a3b8 mt-2px">{{range}} · 支持查询验收明细</p>
</div>
<RingChart2 :data="DEPT_ACCEPT2" :colors="ACCEPT_COLORS2" style="height: 210px;" />
<div class="flex items-center justify-between border-slate-200 pt-1.5">
<span class="text-[11px] text-slate-400">投入合计(变更材料和实施费) · 完全达到率 68%</span>
<span class="text-xs font-bold text-[var(--theme-color)]">86.4 万元</span>
</div>
<div @click="emit('go', 'invest')"
class="cursor-pointer mt-3 flex w-full items-center justify-center gap-1 rounded-lg border border-dashed py-2 text-[11px] text-slate-400 transition hover:border-[#6E93C6] hover:text-[#1D4E9C]">
验收明细(名称 / 日期链 / 费用 / 结论)见左边栏「变更效果跟踪」<ChevronRight class="h-3 w-3" />
</div>
</NCard>
</NGi>
</NGrid>
</NSpace>
</template>
<style scoped></style>