203 lines
8.9 KiB
Vue
203 lines
8.9 KiB
Vue
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue';
|
||
import { Icon } from '@iconify/vue'
|
||
import { useThemeStore } from '@/store/modules/theme';
|
||
import { getColorWithOpacity } from '@/utils/common';
|
||
import RingChart from './modules/ringChart.vue';
|
||
import ColumnChart from './modules/columnChart.vue';
|
||
import ColumnChart2 from './modules/columnChart2.vue';
|
||
import { factoryStatisticsApi } from '@/service/api/statistics';
|
||
|
||
|
||
const themeStore = useThemeStore();
|
||
|
||
const DEFAULT_EXPORTS = ["变更数量统计", "变更周期分析", "超期预警报表", "风险分析执行", "PSSR 与验收", "关闭及时率"];
|
||
|
||
const loading = ref<boolean>(false);
|
||
const homeData = ref<any>(null);
|
||
|
||
// 导出数据
|
||
const exportData = (type: string) => {
|
||
window.$message?.info('还差接口')
|
||
}
|
||
|
||
// 获取数据
|
||
const getData = async () => {
|
||
loading.value = true;
|
||
const {data,error} = await factoryStatisticsApi({
|
||
from: null,
|
||
to: null,
|
||
});
|
||
if(!error){
|
||
homeData.value = data;
|
||
}
|
||
loading.value = false;
|
||
}
|
||
|
||
onMounted(() => {
|
||
getData();
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<NSpace vertical :size="16">
|
||
<!-- 卡片数据 -->
|
||
<NGrid cols="s:1 m:4 l:4" responsive="screen" :x-gap="16" :y-gap="16" :style="{'--theme-color': themeStore.themeColor,'--theme-bg': getColorWithOpacity(themeStore.themeColor, 0.1)}">
|
||
<NGi>
|
||
<div
|
||
class="bg-white px-16px py-12px text-[#94a3b8]"
|
||
:style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }"
|
||
>
|
||
<p class="text-12px font-600 text-center">按期关闭率</p>
|
||
<div class="flex justify-center py-2.5">
|
||
<NProgress type="circle" :percentage="homeData?.gauges?.ontime_close_rate || 0" :offset-degree="180">
|
||
<div class="flex flex-col items-center mt-2">
|
||
<p class="flex items-end text-2xl font-bold leading-none text-[#1D2129]">
|
||
{{homeData?.gauges?.ontime_close_rate || 0}}<span class="text-sm font-semibold">%</span>
|
||
</p>
|
||
</div>
|
||
</NProgress>
|
||
</div>
|
||
<p class="text-12px text-center">近一年 · 全厂</p>
|
||
</div>
|
||
</NGi>
|
||
<NGi>
|
||
<div
|
||
class="bg-white px-16px py-12px text-[#94a3b8]"
|
||
:style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }"
|
||
>
|
||
<p class="text-12px font-600 text-center">PSSR 完成率</p>
|
||
<div class="flex justify-center py-2.5">
|
||
<NProgress type="circle" :percentage="homeData?.gauges?.pssr_rate || 0" :offset-degree="180" status="success">
|
||
<div class="flex flex-col items-center mt-2">
|
||
<p class="flex items-end text-2xl font-bold leading-none text-[#1D2129]">
|
||
{{homeData?.gauges?.pssr_rate || 0}}<span class="text-sm font-semibold">%</span>
|
||
</p>
|
||
</div>
|
||
</NProgress>
|
||
</div>
|
||
<p class="text-12px text-center">近一年 · 全厂</p>
|
||
</div>
|
||
</NGi>
|
||
<NGi>
|
||
<div
|
||
class="bg-white px-16px py-12px text-[#94a3b8] flex flex-col justify-center items-center"
|
||
:style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }"
|
||
>
|
||
<p class="text-12px font-600 text-center">当月临时变更数量</p>
|
||
<p class="mt-2 text-[40px] font-bold leading-none text-[#1D2129] text-center">{{homeData?.gauges?.month_created || 0}}</p>
|
||
<p class="text-12px text-center mt-1">近一年 · 全厂</p>
|
||
</div>
|
||
</NGi>
|
||
<NGi>
|
||
<div
|
||
class="bg-white px-16px py-12px text-[#94a3b8] flex flex-col justify-center items-center"
|
||
:style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }"
|
||
>
|
||
<p class="text-12px font-600 text-center">平均关闭时长</p>
|
||
<p class="mt-2 text-[40px] font-bold leading-none text-[#1D2129] text-center">{{homeData?.gauges?.avg_close_days || 0}}</p>
|
||
<p class="text-12px text-center mt-1">天 · 优于行业均值</p>
|
||
</div>
|
||
</NGi>
|
||
</NGrid>
|
||
|
||
<NGrid :x-gap="16" :y-gap="16" responsive="screen" item-responsive>
|
||
<NGi span="24 s:24 m:24 l:12">
|
||
<NCard :bordered="true" size="small" :content-style="{padding: 0}" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
|
||
<p class=" text-base font-semibold border-b border-slate-100 p-3">月度变更数量</p>
|
||
<div class="py-3 px-4">
|
||
<ColumnChart v-if="homeData" :data="homeData?.monthly_counts || []" />
|
||
</div>
|
||
</NCard>
|
||
</NGi>
|
||
<NGi span="24 s:24 m:24 l:6">
|
||
<NCard :bordered="true" size="small" :content-style="{padding: 0}" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
|
||
<p class=" text-base font-semibold border-b border-slate-100 p-3">变更类型分布</p>
|
||
<div class="py-3 px-4">
|
||
<RingChart v-if="homeData" :data="homeData?.type_dist || []" />
|
||
</div>
|
||
</NCard>
|
||
</NGi>
|
||
<NGi span="24 s:24 m:24 l:6">
|
||
<NCard :bordered="true" size="small" :content-style="{padding: 0}"
|
||
:style="{
|
||
borderRadius: themeStore.themeRadius + 'px',
|
||
height: '100%',
|
||
'--theme-color': themeStore.themeColor,
|
||
'--warning-color': themeStore.otherColor.warning,
|
||
'--error-color': themeStore.otherColor.error,
|
||
}"
|
||
>
|
||
<p class=" text-base font-semibold border-b border-slate-100 p-3">变更效率指标</p>
|
||
<div class="py-3 px-4">
|
||
<div class="space-y-5">
|
||
<div>
|
||
<div class="flex items-baseline gap-2">
|
||
<span class="text-2xl font-bold text-[#1D2129]">{{homeData?.eff?.ontime_use_rate || 0}}<span class="text-sm font-semibold">%</span></span>
|
||
<span class="text-xs text-slate-400">按期投用率</span>
|
||
</div>
|
||
<div class="mt-1.5 h-1 w-full overflow-hidden rounded-full bg-slate-100">
|
||
<div class="h-full rounded-full bg-[var(--theme-color)]" :style="{ width: `${homeData?.eff?.ontime_use_rate || 0}%` }"></div>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div class="flex items-baseline gap-2">
|
||
<span class="text-2xl font-bold text-[#1D2129]">{{homeData?.eff?.train_upload_rate || 0}}<span class="text-sm font-semibold">%</span></span>
|
||
<span class="text-xs text-slate-400">培训按期完成率</span>
|
||
</div>
|
||
<div class="mt-1.5 h-1 w-full overflow-hidden rounded-full bg-slate-100">
|
||
<div class="h-full rounded-full bg-[var(--warning-color)]" :style="{ width: `${homeData?.eff?.train_upload_rate || 0}%` }"></div>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div class="flex items-baseline gap-2">
|
||
<span class="text-2xl font-bold text-[#1D2129]">{{homeData?.eff?.overdue_rate || 0}}<span class="text-sm font-semibold">%</span></span>
|
||
<span class="text-xs text-slate-400">超期变更占比</span>
|
||
</div>
|
||
<div class="mt-1.5 h-1 w-full overflow-hidden rounded-full bg-slate-100">
|
||
<div class="h-full rounded-full bg-[var(--error-color)]" :style="{ width: `${homeData?.eff?.overdue_rate || 0}%` }"></div>
|
||
</div>
|
||
</div>
|
||
<div class="text-[11px] text-slate-400">近一年 · 全厂口径 · 超期占比越低越好</div>
|
||
</div>
|
||
</div>
|
||
</NCard>
|
||
</NGi>
|
||
</NGrid>
|
||
|
||
<NGrid :x-gap="16" :y-gap="16" responsive="screen" item-responsive>
|
||
<NGi span="24 s:24 m:24 l:16">
|
||
<NCard :bordered="true" size="small" :content-style="{padding: 0}" :style="{ borderRadius: themeStore.themeRadius + 'px', height: '100%' }">
|
||
<p class=" text-base font-semibold border-b border-slate-100 p-3">平均审批周期趋势(天)</p>
|
||
<div class="py-3 px-4">
|
||
<ColumnChart2 v-if="homeData" :data="homeData?.cycle_trend || []" />
|
||
</div>
|
||
</NCard>
|
||
</NGi>
|
||
<NGi span="24 s:24 m:24 l:8">
|
||
<NCard :bordered="true" size="small" :content-style="{padding: 0}"
|
||
:style="{
|
||
borderRadius: themeStore.themeRadius + 'px',
|
||
height: '100%',
|
||
'--theme-color': themeStore.themeColor,
|
||
'--theme-bg': getColorWithOpacity(themeStore.themeColor, 0.1),
|
||
}"
|
||
>
|
||
<p class=" text-base font-semibold border-b border-slate-100 p-3">报表导出</p>
|
||
<div class="py-3 px-4">
|
||
<div class="grid grid-cols-2 gap-2">
|
||
<div v-for="r in DEFAULT_EXPORTS" :key="r" @click="exportData(r)"
|
||
class="cursor-pointer flex items-center gap-2 rounded-lg border px-3 py-2.5 text-sm hover:border-[var(--theme-color)] hover:bg-[var(--theme-bg)]">
|
||
<Icon icon="akar-icons:file" class="size-16px text-slate-400" />
|
||
{{ r }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</NCard>
|
||
</NGi>
|
||
</NGrid>
|
||
</NSpace>
|
||
</template>
|
||
|
||
<style scoped></style>
|