refactor: 带来更美观精致的首页 (#848)

This commit is contained in:
xiaoming
2024-01-07 23:27:27 +08:00
committed by GitHub
parent bd8e90e6b6
commit 4fa6a47342
24 changed files with 787 additions and 1424 deletions

View File

@@ -1,60 +1,50 @@
<script setup lang="ts">
import dayjs from "dayjs";
import MdEditor from "md-editor-v3";
import Bar from "./components/Bar.vue";
import Pie from "./components/Pie.vue";
import Line from "./components/Line.vue";
import { getReleases } from "@/api/list";
import TypeIt from "@/components/ReTypeit";
import { useWindowSize } from "@vueuse/core";
import { ref, computed, markRaw } from "vue";
import Github from "./components/Github.vue";
import { randomColor } from "@pureadmin/utils";
import { ref, markRaw } from "vue";
import ReCol from "@/components/ReCol";
import PureTable from "./components/table/index.vue";
import { ReNormalCountTo } from "@/components/ReCountTo";
import { useRenderFlicker } from "@/components/ReFlicker";
import { barChart, lineChart, roundChart } from "./components/chart";
import Segmented, { type OptionsType } from "@/components/ReSegmented";
import { useResizeObserver, useDark, debounce, randomGradient } from "./utils";
import { chartData, barChartData, progressData, latestNewsData } from "./data";
defineOptions({
name: "Welcome"
});
const list = ref();
const loading = ref<boolean>(true);
const { version } = __APP_INFO__.pkg;
const titleClass = computed(() => {
return ["text-base", "font-medium"];
});
const barCardRef = ref();
const barChartRef = ref();
const { isDark } = useDark();
const { height } = useWindowSize();
let curWeek = ref(1); // 0上周、1本周
const optionsBasis: Array<OptionsType> = [
{
label: "上周"
},
{
label: "本周"
}
];
setTimeout(() => {
loading.value = !loading.value;
}, 800);
getReleases().then(({ data }) => {
list.value = data.list.map(v => {
return {
content: v.body,
timestamp: dayjs(v.published_at).format("YYYY/MM/DD hh:mm:ss A"),
icon: markRaw(
useRenderFlicker({
background: randomColor({ type: "hex" }) as string
})
)
};
});
});
useResizeObserver(
barCardRef,
debounce(() => barChartRef.value.resize(), 60)
);
</script>
<template>
<div>
<el-row :gutter="24">
<el-col
<el-row :gutter="24" justify="space-around">
<re-col
v-for="(item, index) in chartData"
:key="index"
v-motion
:xs="24"
:sm="24"
:md="12"
:lg="12"
:xl="12"
class="mb-[18px]"
:value="6"
:md="12"
:sm="12"
:xs="24"
:initial="{
opacity: 0,
y: 100
@@ -63,104 +53,54 @@ getReleases().then(({ data }) => {
opacity: 1,
y: 0,
transition: {
delay: 200
delay: 80 * (index + 1)
}
}"
>
<el-card
shadow="never"
:style="{ height: `calc(${height}px - 35vh - 250px)` }"
>
<template #header>
<a
:class="titleClass"
href="https://github.com/pure-admin/vue-pure-admin/releases"
target="_black"
<el-card shadow="never">
<div class="flex justify-between">
<span class="text-md font-medium">
{{ item.name }}
</span>
<div
class="w-8 h-8 flex justify-center items-center rounded-md"
:style="{
backgroundColor: isDark ? 'transparent' : item.bgColor
}"
>
<TypeIt
:className="'type-it2'"
:values="[`PureAdmin 版本日志(当前版本 v${version}`]"
:cursor="false"
:speed="60"
<IconifyIconOffline
:icon="item.icon"
:color="item.color"
width="18"
/>
</a>
</template>
<el-skeleton animated :rows="7" :loading="loading">
<template #default>
<el-scrollbar :height="`calc(${height}px - 35vh - 340px)`">
<el-timeline v-show="list?.length > 0">
<el-timeline-item
v-for="(item, index) in list"
:key="index"
:icon="item.icon"
:timestamp="item.timestamp"
>
<md-editor v-model="item.content" preview-only />
</el-timeline-item>
</el-timeline>
<el-empty v-show="list?.length === 0" />
</el-scrollbar>
</template>
</el-skeleton>
</el-card>
</el-col>
<el-col
v-motion
:xs="24"
:sm="24"
:md="12"
:lg="12"
:xl="12"
class="mb-[18px]"
:initial="{
opacity: 0,
y: 100
}"
:enter="{
opacity: 1,
y: 0,
transition: {
delay: 200
}
}"
>
<el-card
shadow="never"
:style="{ height: `calc(${height}px - 35vh - 250px)` }"
>
<template #header>
<a
:class="titleClass"
href="https://github.com/xiaoxian521"
target="_black"
>
<TypeIt
:className="'type-it1'"
:values="['GitHub信息']"
:cursor="false"
:speed="120"
</div>
</div>
<div class="flex justify-between items-start mt-3">
<div class="w-1/2">
<ReNormalCountTo
:duration="item.duration"
:fontSize="'1.6em'"
:startVal="100"
:endVal="item.value"
/>
</a>
</template>
<el-skeleton animated :rows="7" :loading="loading">
<template #default>
<el-scrollbar :height="`calc(${height}px - 35vh - 340px)`">
<Github />
</el-scrollbar>
</template>
</el-skeleton>
<p class="font-medium text-green-500">{{ item.percent }}</p>
</div>
<lineChart
v-if="item.data.length > 1"
class="!w-1/2"
:color="item.color"
:data="item.data"
/>
<roundChart v-else class="!w-1/2" />
</div>
</el-card>
</el-col>
</re-col>
<el-col
<re-col
v-motion
:xs="24"
:sm="24"
:md="12"
:lg="8"
:xl="8"
class="mb-[18px]"
:value="18"
:xs="24"
:initial="{
opacity: 0,
y: 100
@@ -173,37 +113,26 @@ getReleases().then(({ data }) => {
}
}"
>
<el-card shadow="never">
<template #header>
<a
:class="titleClass"
href="https://github.com/pure-admin/vue-pure-admin"
target="_black"
>
<TypeIt
:className="'type-it4'"
:values="['GitHub折线图信息']"
:cursor="false"
:speed="120"
/>
</a>
</template>
<el-skeleton animated :rows="7" :loading="loading">
<template #default>
<Line />
</template>
</el-skeleton>
<el-card ref="barCardRef" shadow="never">
<div class="flex justify-between">
<span class="text-md font-medium">分析概览</span>
<Segmented v-model="curWeek" :options="optionsBasis" />
</div>
<div class="flex justify-between items-start mt-3">
<barChart
ref="barChartRef"
:requireData="barChartData[curWeek].requireData"
:questionData="barChartData[curWeek].questionData"
/>
</div>
</el-card>
</el-col>
</re-col>
<el-col
<re-col
v-motion
:xs="24"
:sm="24"
:md="12"
:lg="8"
:xl="8"
class="mb-[18px]"
:value="6"
:xs="24"
:initial="{
opacity: 0,
y: 100
@@ -212,41 +141,45 @@ getReleases().then(({ data }) => {
opacity: 1,
y: 0,
transition: {
delay: 400
delay: 480
}
}"
>
<el-card shadow="never">
<template #header>
<a
:class="titleClass"
href="https://github.com/pure-admin/vue-pure-admin"
target="_black"
>
<TypeIt
:className="'type-it3'"
:values="['GitHub饼图信息']"
:cursor="false"
:speed="120"
/>
</a>
</template>
<el-skeleton animated :rows="7" :loading="loading">
<template #default>
<Pie />
</template>
</el-skeleton>
<div class="flex justify-between">
<span class="text-md font-medium">解决概率</span>
</div>
<div
v-for="(item, index) in progressData"
:key="index"
:class="[
'flex',
'justify-between',
'items-start',
index === 0 ? 'mt-8' : 'mt-[2.15rem]'
]"
>
<el-progress
:text-inside="true"
:percentage="item.percentage"
:stroke-width="21"
:color="item.color"
striped
striped-flow
:duration="item.duration"
/>
<span class="text-nowrap ml-2 text-text_color_regular text-sm">
{{ item.week }}
</span>
</div>
</el-card>
</el-col>
</re-col>
<el-col
<re-col
v-motion
:xs="24"
:sm="24"
:md="24"
:lg="8"
:xl="8"
class="mb-[18px]"
:value="18"
:xs="24"
:initial="{
opacity: 0,
y: 100
@@ -255,39 +188,94 @@ getReleases().then(({ data }) => {
opacity: 1,
y: 0,
transition: {
delay: 400
delay: 560
}
}"
>
<el-card shadow="never" class="h-[580px]">
<div class="flex justify-between">
<span class="text-md font-medium">数据统计</span>
</div>
<PureTable class="mt-3" />
</el-card>
</re-col>
<re-col
v-motion
class="mb-[18px]"
:value="6"
:xs="24"
:initial="{
opacity: 0,
y: 100
}"
:enter="{
opacity: 1,
y: 0,
transition: {
delay: 640
}
}"
>
<el-card shadow="never">
<template #header>
<a
:class="titleClass"
href="https://github.com/pure-admin/vue-pure-admin"
target="_black"
>
<TypeIt
:className="'type-it5'"
:values="['GitHub柱状图信息']"
:cursor="false"
:speed="120"
/>
</a>
</template>
<el-skeleton animated :rows="7" :loading="loading">
<template #default>
<Bar />
</template>
</el-skeleton>
<div class="flex justify-between">
<span class="text-md font-medium">最新动态</span>
</div>
<el-scrollbar max-height="504" class="mt-3">
<el-timeline>
<el-timeline-item
v-for="(item, index) in latestNewsData"
:key="index"
center
placement="top"
:icon="
markRaw(
useRenderFlicker({
background: randomGradient({
randomizeHue: true
})
})
)
"
:timestamp="item.date"
>
<p class="text-text_color_regular text-sm">
{{
`新增 ${item.requiredNumber} 条问题,${item.resolveNumber} 条已解决`
}}
</p>
</el-timeline-item>
</el-timeline>
</el-scrollbar>
</el-card>
</el-col>
</re-col>
</el-row>
</div>
</template>
<style lang="scss" scoped>
:deep(.el-timeline-item) {
margin: 6px 0 0 6px;
:deep(.el-card) {
--el-card-border-color: none;
/* 解决概率进度条宽度 */
.el-progress--line {
width: 85%;
}
/* 解决概率进度条字体大小 */
.el-progress-bar__innerText {
font-size: 15px;
}
/* 隐藏 el-scrollbar 滚动条 */
.el-scrollbar__bar {
display: none;
}
/* el-timeline 每一项上下、左右边距 */
.el-timeline-item {
margin: 0 6px;
}
}
.main-content {