feat(admin): 新增用户端答题流程页面与相关功能模块
- 新增用户端答题流程主页面,包含封面、介绍、答题、答题图解四个状态 - 新增用户端组件:封面、介绍页、答题页、答题图解页、题目渲染器及通用布局组件 - 新增用户端类型定义、模拟数据及业务常量 - 新增用户路由及类型声明,包含组别和队伍选择页面 - 新增管理端首页模块:数据卡片、头部横幅、折线图、饼图、创意横幅和项目新闻 - 新增富文本编辑器组件,支持图片和视频上传至OSS - 优化题库分类树,改为扁平化列表结构 - 完善比赛创建功能,增加轮次类型、题目分数类型及关联AP字段 - 修复模板删除函数调用参数错误 - 添加 pinyin-pro 依赖以支持拼音处理功能
This commit is contained in:
112
apps/admin/src/views/admin-home/modules/card-data.vue
Normal file
112
apps/admin/src/views/admin-home/modules/card-data.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user