- 新增用户端答题流程主页面,包含封面、介绍、答题、答题图解四个状态 - 新增用户端组件:封面、介绍页、答题页、答题图解页、题目渲染器及通用布局组件 - 新增用户端类型定义、模拟数据及业务常量 - 新增用户路由及类型声明,包含组别和队伍选择页面 - 新增管理端首页模块:数据卡片、头部横幅、折线图、饼图、创意横幅和项目新闻 - 新增富文本编辑器组件,支持图片和视频上传至OSS - 优化题库分类树,改为扁平化列表结构 - 完善比赛创建功能,增加轮次类型、题目分数类型及关联AP字段 - 修复模板删除函数调用参数错误 - 添加 pinyin-pro 依赖以支持拼音处理功能
113 lines
2.6 KiB
Vue
113 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
import { createReusableTemplate } from '@vueuse/core'
|
|
import { computed } from 'vue'
|
|
import { $t } from '@/locales'
|
|
import { useThemeStore } from '@/store/modules/theme'
|
|
|
|
defineOptions({
|
|
name: 'CardData',
|
|
})
|
|
|
|
interface CardData {
|
|
key: string
|
|
title: string
|
|
value: number
|
|
unit: string
|
|
color: {
|
|
start: string
|
|
end: string
|
|
}
|
|
icon: string
|
|
}
|
|
|
|
const cardData = computed<CardData[]>(() => [
|
|
{
|
|
key: 'visitCount',
|
|
title: $t('page.home.visitCount'),
|
|
value: 9725,
|
|
unit: '',
|
|
color: {
|
|
start: '#ec4786',
|
|
end: '#b955a4',
|
|
},
|
|
icon: 'ant-design:bar-chart-outlined',
|
|
},
|
|
{
|
|
key: 'turnover',
|
|
title: $t('page.home.turnover'),
|
|
value: 1026,
|
|
unit: '$',
|
|
color: {
|
|
start: '#865ec0',
|
|
end: '#5144b4',
|
|
},
|
|
icon: 'ant-design:money-collect-outlined',
|
|
},
|
|
{
|
|
key: 'downloadCount',
|
|
title: $t('page.home.downloadCount'),
|
|
value: 970925,
|
|
unit: '',
|
|
color: {
|
|
start: '#56cdf3',
|
|
end: '#719de3',
|
|
},
|
|
icon: 'carbon:document-download',
|
|
},
|
|
{
|
|
key: 'dealCount',
|
|
title: $t('page.home.dealCount'),
|
|
value: 9527,
|
|
unit: '',
|
|
color: {
|
|
start: '#fcbc25',
|
|
end: '#f68057',
|
|
},
|
|
icon: 'ant-design:trademark-circle-outlined',
|
|
},
|
|
])
|
|
|
|
interface GradientBgProps {
|
|
gradientColor: string
|
|
}
|
|
|
|
const [DefineGradientBg, GradientBg] = createReusableTemplate<GradientBgProps>()
|
|
|
|
const themeStore = useThemeStore()
|
|
|
|
function getGradientColor(color: CardData['color']) {
|
|
return `linear-gradient(to bottom right, ${color.start}, ${color.end})`
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<NCard :bordered="false" size="small" class="card-wrapper">
|
|
<DefineGradientBg v-slot="{ $slots, gradientColor }">
|
|
<div
|
|
class="px-16px pb-4px pt-8px text-white"
|
|
:style="{ backgroundImage: gradientColor, borderRadius: `${themeStore.themeRadius}px` }"
|
|
>
|
|
<component :is="$slots.default" />
|
|
</div>
|
|
</DefineGradientBg>
|
|
<NGrid cols="s:1 m:2 l:4" responsive="screen" :x-gap="16" :y-gap="16">
|
|
<NGi v-for="item in cardData" :key="item.key">
|
|
<GradientBg :gradient-color="getGradientColor(item.color)" class="flex-1">
|
|
<h3 class="text-16px">
|
|
{{ item.title }}
|
|
</h3>
|
|
<div class="flex justify-between pt-12px">
|
|
<SvgIcon :icon="item.icon" class="text-32px" />
|
|
<CountTo
|
|
:prefix="item.unit" :start-value="1" :end-value="item.value"
|
|
class="text-30px text-white dark:text-dark"
|
|
/>
|
|
</div>
|
|
</GradientBg>
|
|
</NGi>
|
|
</NGrid>
|
|
</NCard>
|
|
</template>
|
|
|
|
<style scoped></style>
|