mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 04:46:26 +00:00
refactor: 重构工作台与首页仪表盘模块
- 调整dashboard工作台与首页的组件布局与模块迁移 - 统一卡片样式与hover交互效果 - 修复部分样式顺序与css语法问题 - 移除冗余的github corner组件与重复的页面模块
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<!-- 卡片横幅组件 -->
|
||||
<template>
|
||||
<div class="fa-card-sm flex-c flex-col pb-6" :style="{ height: height }">
|
||||
<div class="fa-card p-5 flex-c flex-col pb-6 h-full" :style="{ height: height }">
|
||||
<div class="flex-c flex-col gap-4 text-center">
|
||||
<div class="w-45">
|
||||
<img :src="image" :alt="title" class="w-full h-full object-contain" loading="eager" />
|
||||
@@ -76,7 +76,7 @@ interface CardBannerProps {
|
||||
|
||||
// 定义组件属性默认值
|
||||
withDefaults(defineProps<CardBannerProps>(), {
|
||||
height: "24rem",
|
||||
height: "100%",
|
||||
image: defaultIcon,
|
||||
title: "",
|
||||
description: "",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- 数据列表卡片 -->
|
||||
<template>
|
||||
<div class="fa-card p-5">
|
||||
<div class="fa-card p-5 h-[28.2rem] overflow-hidden">
|
||||
<div class="pb-3.5">
|
||||
<p class="text-lg font-medium">{{ title }}</p>
|
||||
<p class="text-sm text-g-600">{{ subtitle }}</p>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- 图片卡片 -->
|
||||
<template>
|
||||
<div class="w-full c-p" @click="handleClick">
|
||||
<div class="fa-card overflow-hidden">
|
||||
<div class="w-full c-p h-full" @click="handleClick">
|
||||
<div class="fa-card overflow-hidden h-full">
|
||||
<div class="relative w-full aspect-16/10 overflow-hidden">
|
||||
<ElImage
|
||||
:src="props.imageUrl"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- 时间轴列表卡片 -->
|
||||
<template>
|
||||
<div class="fa-card p-5">
|
||||
<div class="fa-card p-5 h-[28.2rem] overflow-hidden">
|
||||
<div class="pb-3.5">
|
||||
<p class="text-lg font-medium">{{ title }}</p>
|
||||
<p class="text-sm text-g-600">{{ subtitle }}</p>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<!-- 地图图表 -->
|
||||
<template>
|
||||
<div class="relative w-full" :style="{ height: 'calc(100vh - 120px)' }">
|
||||
<div
|
||||
class="relative w-full h-100 p-5 mb-5 max-sm:mb-4"
|
||||
:style="{ height: 'calc(100vh - 180px)' }"
|
||||
>
|
||||
<div v-if="isEmpty" class="h-full flex-cc">
|
||||
<ElEmpty description="暂无地图数据" />
|
||||
</div>
|
||||
|
||||
@@ -25,11 +25,7 @@
|
||||
/>
|
||||
</ElTooltip>
|
||||
<ElTooltip content="关闭" placement="top">
|
||||
<FaIconButton
|
||||
class="core-overlay-icon-btn"
|
||||
icon="ri:close-line"
|
||||
@click="close"
|
||||
/>
|
||||
<FaIconButton class="core-overlay-icon-btn" icon="ri:close-line" @click="close" />
|
||||
</ElTooltip>
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,8 +137,8 @@ const dialogAttrs = computed(() => {
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +128,8 @@ const drawerAttrs = computed(() => {
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
<!-- github 角标 -->
|
||||
<template>
|
||||
<a
|
||||
href="https://github.com/fastapiadmin/FastapiAdmin"
|
||||
target="_blank"
|
||||
class="github-corner"
|
||||
aria-label="View source on Github"
|
||||
>
|
||||
<svg
|
||||
width="80"
|
||||
height="80"
|
||||
viewBox="0 0 250 250"
|
||||
:style="'color: var(--el-color-white); fill: var(--el-color-primary)'"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" />
|
||||
<path
|
||||
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
|
||||
fill="currentColor"
|
||||
:style="'transform-origin: 130px 106px'"
|
||||
class="octo-arm"
|
||||
/>
|
||||
<path
|
||||
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
|
||||
fill="currentColor"
|
||||
class="octo-body"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
defineOptions({ name: "FaGithubCorner" });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
20%,
|
||||
60% {
|
||||
transform: rotate(-25deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
80% {
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <= 500px) {
|
||||
.github-corner .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -120,11 +120,11 @@ html.dark .el-card {
|
||||
.el-dialog__title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
position: relative; // 为了兼容 el-pagination 样式,需要设置 relative,不然会影响 el-pagination 的样式,比如 el-pagination__jump--small 会被影响,导致 el-pagination__jump--small 按钮无法点击,详见 URL_ADDRESS.com/element-plus/element-plus/issues/5684#issuecomment-1176299275;
|
||||
padding: 12px 0px !important;
|
||||
padding: 12px 0 !important;
|
||||
}
|
||||
|
||||
.el-dialog.el-dialog-border {
|
||||
@@ -154,11 +154,11 @@ html.dark .el-card {
|
||||
.el-drawer__header {
|
||||
padding: 12px 8px !important;
|
||||
margin-bottom: 2px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-drawer__body {
|
||||
position: relative; // 为了兼容 el-pagination 样式,需要设置 relative,不然会影响 el-pagination 的样式,比如 el-pagination__jump--small 会被影响,导致 el-pagination__jump--small 按钮无法点击,详见 URL_ADDRESS.com/element-plus/element-plus/issues/5684#issuecomment-1176299275;
|
||||
padding: 0px 8px !important;
|
||||
padding: 0 8px !important;
|
||||
}
|
||||
|
||||
// el-message 样式优化
|
||||
|
||||
@@ -106,9 +106,9 @@
|
||||
// 表格按钮悬浮效果
|
||||
.hover-btn {
|
||||
&:hover {
|
||||
transform: translateY(-2px) scale(1.05);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
|
||||
filter: brightness(1.1);
|
||||
transform: translateY(-2px) scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 业务分析模块 -->
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :xl="14" :lg="15" :xs="24"><TodaySales /></ElCol>
|
||||
<ElCol :xl="10" :lg="9" :xs="24"><VisitorInsights /></ElCol>
|
||||
</ElRow>
|
||||
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :xl="10" :lg="10" :xs="24"><TotalRevenue /></ElCol>
|
||||
<ElCol :xl="7" :lg="7" :xs="24"><CustomerSatisfaction /></ElCol>
|
||||
<ElCol :xl="7" :lg="7" :xs="24"><TargetVsReality /></ElCol>
|
||||
<!-- 左侧2个组件 -->
|
||||
<ElCol :xl="6" :lg="6" :xs="24" class="flex flex-col gap-5">
|
||||
<CustomerSatisfaction class="flex-1" />
|
||||
<TotalRevenue class="flex-1" />
|
||||
</ElCol>
|
||||
|
||||
<!-- 中间地图 -->
|
||||
<ElCol :xl="12" :lg="12" :xs="24">
|
||||
<div class="fa-card" style="min-height: 500px">
|
||||
<FaMapChart />
|
||||
</div>
|
||||
</ElCol>
|
||||
|
||||
<!-- 右侧2个组件 -->
|
||||
<ElCol :xl="6" :lg="6" :xs="24" class="flex flex-col gap-5">
|
||||
<TargetVsReality class="flex-1" />
|
||||
<TopProducts class="flex-1" />
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :xl="10" :lg="10" :xs="24"><TopProducts /></ElCol>
|
||||
<ElCol :xl="7" :lg="7" :xs="24"><SalesMappingByCountry /></ElCol>
|
||||
<ElCol :xl="7" :lg="7" :xs="24"><VolumeServiceLevel /></ElCol>
|
||||
</ElRow>
|
||||
|
||||
<!-- 图表演示区 -->
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :xl="8" :lg="8" :xs="24"><SalesMappingByCountry /></ElCol>
|
||||
<ElCol :xl="8" :lg="8" :xs="24"><VolumeServiceLevel /></ElCol>
|
||||
<ElCol :xs="24" :md="12" :lg="8" class="mb-5">
|
||||
<div class="fa-card">
|
||||
<div class="pb-3.5"><span class="text-base font-medium">柱状图(单数据)</span></div>
|
||||
@@ -247,11 +256,6 @@
|
||||
</div>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
|
||||
<!-- 地图 -->
|
||||
<div class="page-content" element-loading-text="加载中...">
|
||||
<FaMapChart />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -268,7 +272,7 @@ import TopProducts from "./modules/top-products.vue";
|
||||
import SalesMappingByCountry from "./modules/sales-mapping-by-country.vue";
|
||||
import VolumeServiceLevel from "./modules/volume-service-level.vue";
|
||||
|
||||
defineOptions({ name: "Analysis" });
|
||||
defineOptions({ name: "DashboardAnalysis" });
|
||||
|
||||
const FaMapChart = defineAsyncComponent(() => import("@/components/charts/fa-map-chart/index.vue"));
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card h-82 p-5 mb-5 overflow-hidden max-sm:mb-4">
|
||||
<div class="fa-card h-100 p-5 mb-5 max-sm:mb-4">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>热门产品</h4>
|
||||
|
||||
@@ -1,131 +1,13 @@
|
||||
<template>
|
||||
<div class="dashboard-container">
|
||||
<FaGithubCorner class="github-corner" />
|
||||
<!-- 卡片组件演示区 ← workplace -->
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :xs="24" class="mb-5">
|
||||
<!-- 问候 + 外链 -->
|
||||
<ElCard shadow="hover">
|
||||
<div class="flex flex-wrap items-center gap-y-3">
|
||||
<div class="flex min-w-0 flex-1 items-center">
|
||||
<div class="size-20 shrink-0 rounded-full bg-g-100 flex items-center justify-center">
|
||||
<ElAvatar
|
||||
v-if="userStore.basicInfo.avatar"
|
||||
size="large"
|
||||
:src="userStore.basicInfo.avatar"
|
||||
class="workplace-hero__avatar"
|
||||
/>
|
||||
<ElIcon v-else :size="40" class="text-g-600"><UserFilled /></ElIcon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="workplace-hero__greeting">
|
||||
{{ timefix }}{{ currentUser.name }},{{ welcome }}
|
||||
</div>
|
||||
<ElText class="workplace-hero__meta">
|
||||
<p class="text-sm text-g-600">
|
||||
{{ currentUser.username }} · {{ currentUser.dept_name }} ·
|
||||
{{ currentUser.description }}
|
||||
</p>
|
||||
</ElText>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden shrink-0 sm:block">
|
||||
<div class="flex items-center space-x-6">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="flex items-center text-sm font-bold text-[#4080ff]">
|
||||
<ElIcon class="mr-0.5"><Document /></ElIcon>
|
||||
文档
|
||||
</div>
|
||||
<div class="mt-3 whitespace-nowrap">
|
||||
<ElLink
|
||||
href="https://blog.csdn.net/weixin_46768253/article/details/149569141"
|
||||
target="_blank"
|
||||
>
|
||||
<FaSvgIcon :icon="resolveIconForFaSvgIcon('csdn')" class="text-lg" />
|
||||
</ElLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="flex items-center text-sm font-bold text-[#ff9a2e]">
|
||||
<ElIcon class="mr-0.5"><Folder /></ElIcon>
|
||||
仓库
|
||||
</div>
|
||||
<div class="mt-3 whitespace-nowrap">
|
||||
<ElLink href="https://gitee.com/fastapiadmin/FastapiAdmin" target="_blank">
|
||||
<FaSvgIcon
|
||||
:icon="resolveIconForFaSvgIcon('gitee')"
|
||||
class="text-lg text-[#F76560]"
|
||||
/>
|
||||
</ElLink>
|
||||
<ElDivider direction="vertical" />
|
||||
<ElLink href="https://github.com/fastapiadmin/FastapiAdmin" target="_blank">
|
||||
<FaSvgIcon
|
||||
:icon="resolveIconForFaSvgIcon('github')"
|
||||
class="text-lg text-[#4080FF]"
|
||||
/>
|
||||
</ElLink>
|
||||
<ElDivider direction="vertical" />
|
||||
<ElLink href="https://gitcode.com/qq_36002987/FastapiAdmin" target="_blank">
|
||||
<FaSvgIcon
|
||||
:icon="resolveIconForFaSvgIcon('gitcode')"
|
||||
class="text-lg text-[#FF9A2E]"
|
||||
/>
|
||||
</ElLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full sm:hidden">
|
||||
<div class="flex justify-end space-x-4 overflow-x-auto">
|
||||
<ElLink href="https://gitee.com/fastapiadmin/FastapiAdmin" target="_blank">
|
||||
<FaSvgIcon :icon="resolveIconForFaSvgIcon('gitee')" class="text-lg text-[#F76560]" />
|
||||
</ElLink>
|
||||
<ElDivider direction="vertical" />
|
||||
<ElLink href="https://github.com/fastapiadmin/FastapiAdmin" target="_blank">
|
||||
<FaSvgIcon :icon="resolveIconForFaSvgIcon('github')" class="text-lg text-[#4080FF]" />
|
||||
</ElLink>
|
||||
<ElDivider direction="vertical" />
|
||||
<ElLink href="https://gitcode.com/qq_36002987/FastapiAdmin" target="_blank">
|
||||
<FaSvgIcon
|
||||
:icon="resolveIconForFaSvgIcon('gitcode')"
|
||||
class="text-lg text-[#FF9A2E]"
|
||||
/>
|
||||
</ElLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ElCard>
|
||||
<Banner />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" class="mb-5">
|
||||
<FaBasicBanner
|
||||
title="数据中心运行状态"
|
||||
subtitle="系统访问量同比增长 23%,所有服务运行稳定,数据监控正常。"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" class="mb-5">
|
||||
<FaBasicBanner
|
||||
title="欢迎使用 Fastapi Admin"
|
||||
subtitle="基于 Vue 3 + TypeScript + Element Plus 构建的现代化管理系统。"
|
||||
titleColor="#333"
|
||||
subtitleColor="#666"
|
||||
boxStyle="bg-[#D4F1F7]!"
|
||||
:buttonConfig="{
|
||||
show: true,
|
||||
text: '开始探索',
|
||||
color: 'var(--fa-success)',
|
||||
textColor: '#fff',
|
||||
radius: '6px',
|
||||
}"
|
||||
@buttonClick="handleBannerDemoClick"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" class="mb-5">
|
||||
<!-- CardList 概览统计(含在线用户/UV/PV/访问量等) -->
|
||||
<CardList />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" class="mb-5">
|
||||
<AboutProject />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" class="mb-5">
|
||||
<ElCard shadow="hover" class="flex flex-col h-full">
|
||||
<template #header>
|
||||
@@ -162,22 +44,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<ElRow v-if="quickLinks.length > 0" :gutter="12">
|
||||
<ElRow v-if="quickLinks.length > 0" :gutter="4">
|
||||
<ElCol
|
||||
v-for="(item, index) in quickLinks"
|
||||
:key="item.id || `${item.href}-${index}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="8"
|
||||
:lg="8"
|
||||
:xl="8"
|
||||
class="mb-3"
|
||||
:md="6"
|
||||
:lg="6"
|
||||
:xl="6"
|
||||
class="mb-1"
|
||||
>
|
||||
<ElTooltip
|
||||
placement="top"
|
||||
:show-after="400"
|
||||
:content="item.title"
|
||||
>
|
||||
<ElTooltip placement="top" :show-after="400" :content="item.title">
|
||||
<div
|
||||
class="workplace-quick-row workplace-quick-row--compact workplace-quick-row--chip"
|
||||
role="button"
|
||||
@@ -227,6 +105,7 @@
|
||||
</ElEmpty>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
|
||||
<ElCol :xs="24" :sm="12" :md="12" class="mb-5">
|
||||
<ElCard shadow="hover" class="workplace-surface workplace-ops-card flex flex-col h-full">
|
||||
<template #header>
|
||||
@@ -245,227 +124,19 @@
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" class="mb-5">
|
||||
<ElCard shadow="hover" class="h-full flex flex-col">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-medium">最新动态</span>
|
||||
<ElLink
|
||||
type="primary"
|
||||
underline="never"
|
||||
href="https://gitee.com/fastapiadmin/FastapiAdmin/releases"
|
||||
target="_blank"
|
||||
>
|
||||
完整记录
|
||||
<ElIcon class="link-icon"><TopRight /></ElIcon>
|
||||
</ElLink>
|
||||
</div>
|
||||
</template>
|
||||
<ElScrollbar class="h-full">
|
||||
<ElTimeline class="p-2">
|
||||
<ElTimelineItem
|
||||
v-for="(item, index) in vesionList"
|
||||
:key="index"
|
||||
:timestamp="item.date"
|
||||
placement="top"
|
||||
:color="index === 0 ? '#67C23A' : '#909399'"
|
||||
:hollow="index !== 0"
|
||||
>
|
||||
<div class="version-item" :class="{ 'latest-item': index === 0 }">
|
||||
<div class="flex items-center justify-between">
|
||||
<ElText tag="strong">{{ item.title }}</ElText>
|
||||
<ElTag v-if="item.tag" :type="index === 0 ? 'success' : 'info'" size="small">
|
||||
{{ item.tag }}
|
||||
</ElTag>
|
||||
</div>
|
||||
<ElText class="version-content">{{ item.content }}</ElText>
|
||||
<div v-if="item.link">
|
||||
<ElLink
|
||||
:type="index === 0 ? 'primary' : 'info'"
|
||||
:href="item.link"
|
||||
target="_blank"
|
||||
underline="never"
|
||||
>
|
||||
详情
|
||||
<ElIcon class="link-icon"><TopRight /></ElIcon>
|
||||
</ElLink>
|
||||
</div>
|
||||
</div>
|
||||
</ElTimelineItem>
|
||||
</ElTimeline>
|
||||
</ElScrollbar>
|
||||
</ElCard>
|
||||
<NewUser />
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in statsCards"
|
||||
:key="`t-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaStatsCard
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.iconStyle"
|
||||
:title="card.title"
|
||||
:description="card.description"
|
||||
:showArrow="card.showArrow"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in statsCards"
|
||||
:key="`n-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaStatsCard
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.iconStyle"
|
||||
:title="card.title"
|
||||
:description="card.description"
|
||||
:count="card.count"
|
||||
:decimals="0"
|
||||
:showArrow="card.showArrow"
|
||||
separator=","
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in statsCards"
|
||||
:key="`c-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaStatsCard
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.customIconStyle"
|
||||
:boxStyle="card.boxStyle"
|
||||
:title="card.title"
|
||||
:description="card.description"
|
||||
:textColor="card.textColor"
|
||||
:showArrow="card.showArrow"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in progressCards"
|
||||
:key="`p-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaProgressCard :percentage="card.percentage" :title="card.title" :color="card.color" />
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in progressCards"
|
||||
:key="`pi-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaProgressCard
|
||||
:percentage="card.percentage"
|
||||
:title="card.title"
|
||||
:color="card.color"
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.iconStyle"
|
||||
/>
|
||||
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<HotProductsList />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:isMiniChart="true"
|
||||
:value="2545"
|
||||
label="新用户"
|
||||
date="过去7天"
|
||||
:percentage="1.2"
|
||||
:height="9.5"
|
||||
:chartData="[120, 132, 101, 134, 90, 230, 210]"
|
||||
/>
|
||||
<TodoList />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaBarChartCard
|
||||
:isMiniChart="true"
|
||||
:value="15480"
|
||||
label="浏览量"
|
||||
date="过去14天"
|
||||
:percentage="-4.15"
|
||||
:height="9.5"
|
||||
barWidth="45%"
|
||||
:chartData="[120, 100, 150, 140, 90, 120, 130]"
|
||||
/>
|
||||
<FaTimelineListCard :list="timelineData" title="最近交易" subtitle="2024年12月20日" />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:isMiniChart="true"
|
||||
:value="2545"
|
||||
label="粉丝数"
|
||||
date="过去30天"
|
||||
:percentage="1.2"
|
||||
:height="9.5"
|
||||
:showAreaColor="true"
|
||||
:chartData="[150, 180, 160, 200, 180, 220, 240]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaDonutChartCard
|
||||
:value="36358"
|
||||
title="粉丝量"
|
||||
:percentage="18"
|
||||
percentageLabel="较去年"
|
||||
:data="[50, 40]"
|
||||
:height="9.5"
|
||||
currentValue="2022"
|
||||
previousValue="2021"
|
||||
:radius="['50%', '70%']"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:value="2545"
|
||||
label="新用户"
|
||||
:percentage="1.2"
|
||||
:height="11"
|
||||
:chartData="[120, 132, 101, 134, 90, 230, 210]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaBarChartCard
|
||||
:value="15480"
|
||||
label="浏览量"
|
||||
:percentage="-4.15"
|
||||
:height="11"
|
||||
:chartData="[120, 100, 150, 140, 90, 120, 130, 110]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:value="2545"
|
||||
label="粉丝数"
|
||||
:percentage="1.2"
|
||||
:height="11"
|
||||
:showAreaColor="true"
|
||||
:chartData="[150, 180, 160, 200, 180, 220, 240]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaDonutChartCard
|
||||
:value="36358"
|
||||
title="粉丝量"
|
||||
:percentage="-18"
|
||||
percentageLabel="较2021年"
|
||||
:data="[70, 30]"
|
||||
:height="11"
|
||||
currentValue="12月"
|
||||
previousValue="11月"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="8" class="mb-5">
|
||||
<FaDataListCard :list="dataList" title="待办事项" subtitle="今日待处理任务" />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="8" class="mb-5">
|
||||
<FaDataListCard
|
||||
:maxCount="4"
|
||||
:list="dataList"
|
||||
@@ -475,58 +146,25 @@
|
||||
@more="handleMore"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="8" class="mb-5">
|
||||
<FaTimelineListCard :list="timelineData" title="最近交易" subtitle="2024年12月20日" />
|
||||
</ElCol>
|
||||
<ElCol v-for="card in imageCards" :key="card.id" :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
|
||||
<ElCol :xs="24" :sm="8" :md="6" class="mb-5">
|
||||
<FaImageCard
|
||||
:imageUrl="card.imageUrl"
|
||||
:title="card.title"
|
||||
:category="card.category"
|
||||
:readTime="card.readTime"
|
||||
:views="card.views"
|
||||
:comments="card.comments"
|
||||
:date="card.date"
|
||||
@click="handleImageCardClick(card)"
|
||||
:imageUrl="imageCards.imageUrl"
|
||||
:title="imageCards.title"
|
||||
:category="imageCards.category"
|
||||
:readTime="imageCards.readTime"
|
||||
:views="imageCards.views"
|
||||
:comments="imageCards.comments"
|
||||
:date="imageCards.date"
|
||||
@click="handleImageCardClick(imageCards)"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" :lg="6" class="mb-5">
|
||||
<FaCardBanner
|
||||
title="系统运行正常"
|
||||
description="所有核心服务运行稳定,响应时间在正常范围内。"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" :lg="6" class="mb-5">
|
||||
<FaCardBanner
|
||||
:image="bannerIcon2"
|
||||
title="重要消息通知"
|
||||
description="您有 3 条待处理的重要消息,请及时查看。"
|
||||
:button="{
|
||||
show: true,
|
||||
text: '查看详情',
|
||||
color: 'var(--fa-warning)',
|
||||
textColor: '#fff',
|
||||
}"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" :lg="6" class="mb-5">
|
||||
<FaCardBanner
|
||||
:image="bannerIcon3"
|
||||
title="数据分析报告"
|
||||
description="本周业务数据分析报告已完成,请查看关键指标。"
|
||||
:button="{
|
||||
show: true,
|
||||
text: '下载报告',
|
||||
color: 'var(--fa-error)',
|
||||
textColor: '#fff',
|
||||
}"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" :lg="6" class="mb-5">
|
||||
|
||||
<ElCol :xs="24" :sm="4" :md="6" class="mb-5">
|
||||
<FaCardBanner
|
||||
:image="bannerIcon4"
|
||||
title="版本更新提醒"
|
||||
description="Art Design Pro v2.1.0 已发布,包含性能优化和新功能。"
|
||||
description="FastapiAdmin v3.0.0 已发布,包含优化和新功能。"
|
||||
:button="{
|
||||
show: true,
|
||||
text: '立即更新',
|
||||
@@ -538,6 +176,9 @@
|
||||
@cancel="handleBannerDemoCancel"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="12" class="mb-5">
|
||||
<AboutProject />
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</div>
|
||||
</template>
|
||||
@@ -545,100 +186,27 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({ name: "Home", inheritAttrs: false });
|
||||
|
||||
import { useUserStore } from "@stores";
|
||||
import CardList from "../workplace/modules/card-list.vue";
|
||||
import AboutProject from "../workplace/modules/about-project.vue";
|
||||
import {
|
||||
greetings,
|
||||
resolveIconForFaSvgIcon,
|
||||
quickStartManager,
|
||||
QUICK_LINK_MAX,
|
||||
type QuickLink,
|
||||
} from "@utils";
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
Delete,
|
||||
UserFilled,
|
||||
Close,
|
||||
Star,
|
||||
QuestionFilled,
|
||||
Document,
|
||||
Folder,
|
||||
TopRight,
|
||||
} from "@element-plus/icons-vue";
|
||||
import { Delete, Close, Star, QuestionFilled } from "@element-plus/icons-vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { dayjs } from "element-plus";
|
||||
import bannerIcon2 from "@imgs/3d/icon2.webp";
|
||||
import bannerIcon3 from "@imgs/3d/icon3.webp";
|
||||
import bannerIcon4 from "@imgs/3d/icon4.webp";
|
||||
import cover1 from "@imgs/cover/img1.webp";
|
||||
import cover2 from "@imgs/cover/img2.webp";
|
||||
import cover3 from "@imgs/cover/img3.webp";
|
||||
import cover4 from "@imgs/cover/img4.webp";
|
||||
import { quickStartManager, QUICK_LINK_MAX, type QuickLink } from "@utils";
|
||||
import FaCardBanner from "@/components/banners/fa-card-banner/index.vue";
|
||||
import FaDonutChartCard from "@/components/cards/fa-donut-chart-card/index.vue";
|
||||
import FaImageCard from "@/components/cards/fa-image-card/index.vue";
|
||||
import FaDataListCard from "@/components/cards/fa-data-list-card/index.vue";
|
||||
import FaLineChartCard from "@/components/cards/fa-line-chart-card/index.vue";
|
||||
import FaStatsCard from "@/components/cards/fa-stats-card/index.vue";
|
||||
import FaProgressCard from "@/components/cards/fa-progress-card/index.vue";
|
||||
import FaBarChartCard from "@/components/cards/fa-bar-chart-card/index.vue";
|
||||
import FaTimelineListCard from "@/components/cards/fa-timeline-list-card/index.vue";
|
||||
import FaBasicBanner from "@/components/banners/fa-basic-banner/index.vue";
|
||||
import HotProductsList from "./modules/hot-products-list.vue";
|
||||
import Banner from "./modules/banner.vue";
|
||||
import NewUser from "./modules/new-user.vue";
|
||||
import TodoList from "./modules/todo-list.vue";
|
||||
import CardList from "./modules/card-list.vue";
|
||||
import AboutProject from "./modules/about-project.vue";
|
||||
|
||||
const timefix = greetings();
|
||||
const userStore = useUserStore();
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const welcome = "祝你开心每一天!";
|
||||
|
||||
interface VersionItem {
|
||||
id: string;
|
||||
title: string;
|
||||
date: string;
|
||||
content: string;
|
||||
link: string;
|
||||
tag?: string;
|
||||
}
|
||||
const vesionList = ref<VersionItem[]>([
|
||||
{
|
||||
id: "1",
|
||||
title: "v3.2.1",
|
||||
date: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
||||
content: "优化性能,修复若干小bug。",
|
||||
link: "https://gitee.com/fastapiadmin/FastapiAdmin/releases",
|
||||
tag: "更新",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
title: "v3.2.0",
|
||||
date: dayjs().subtract(1, "day").format("YYYY-MM-DD HH:mm:ss"),
|
||||
content: "新增用户行为分析功能。",
|
||||
link: "https://gitee.com/fastapiadmin/FastapiAdmin/releases",
|
||||
tag: "新功能",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
title: "v3.1.0",
|
||||
date: dayjs().subtract(3, "day").format("YYYY-MM-DD HH:mm:ss"),
|
||||
content: "优化权限管理系统。",
|
||||
link: "https://gitee.com/fastapiadmin/FastapiAdmin/releases",
|
||||
tag: "优化",
|
||||
},
|
||||
]);
|
||||
|
||||
const currentUser = {
|
||||
avatar:
|
||||
userStore.basicInfo.avatar ||
|
||||
"https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
|
||||
name: userStore.basicInfo.name || "吴彦祖",
|
||||
username: userStore.basicInfo.username || "账号信息",
|
||||
description: userStore.basicInfo.description || "用户说明",
|
||||
dept_name: userStore.basicInfo.dept_name || "软件专业部",
|
||||
last_login: userStore.basicInfo.last_login || "2023-01-01 00:00:00",
|
||||
};
|
||||
|
||||
const quickLinks = ref<QuickLink[]>(quickStartManager.getQuickLinks());
|
||||
const handleQuickLinkClick = (item: QuickLink) => {
|
||||
@@ -693,10 +261,6 @@ const updateQuickLinks = (links: QuickLink[]) => {
|
||||
quickLinks.value = links;
|
||||
};
|
||||
|
||||
// === 横幅组件演示 ===
|
||||
function handleBannerDemoClick() {
|
||||
console.log("banner clicked");
|
||||
}
|
||||
function handleBannerDemoConfirm() {
|
||||
console.log("confirm clicked");
|
||||
}
|
||||
@@ -704,132 +268,17 @@ function handleBannerDemoCancel() {
|
||||
console.log("cancel clicked");
|
||||
}
|
||||
// === 卡片演示数据 ← workplace ===
|
||||
const statsCards = [
|
||||
{
|
||||
id: 1,
|
||||
title: "销售产品",
|
||||
count: 1235,
|
||||
description: "鞋子、牛仔裤、派对服装、手表",
|
||||
icon: "ri:bar-chart-box-line",
|
||||
boxStyle: "bg-theme/10!",
|
||||
customIconStyle: "text-theme! text-3xl!",
|
||||
iconStyle: "bg-info",
|
||||
textColor: "var(--theme-color)",
|
||||
showArrow: false,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "活跃用户",
|
||||
count: 5000,
|
||||
description: "日活跃用户超过5,000+",
|
||||
icon: "ri:account-box-2-line",
|
||||
boxStyle: "bg-warning/10!",
|
||||
customIconStyle: "text-warning! text-3xl!",
|
||||
iconStyle: "bg-warning",
|
||||
textColor: "var(--fa-warning)",
|
||||
showArrow: false,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "总收入",
|
||||
count: 35000,
|
||||
description: "月收入超过¥350,000+",
|
||||
icon: "ri:money-cny-box-line",
|
||||
boxStyle: "bg-secondary/10!",
|
||||
customIconStyle: "text-secondary! text-3xl!",
|
||||
iconStyle: "bg-secondary",
|
||||
textColor: "var(--fa-secondary)",
|
||||
showArrow: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "客户评价",
|
||||
count: 4800,
|
||||
description: "平均评分4.8/5",
|
||||
icon: "ri:message-3-line",
|
||||
boxStyle: "bg-error/10!",
|
||||
customIconStyle: "text-error! text-3xl!",
|
||||
iconStyle: "bg-error",
|
||||
textColor: "var(--fa-error)",
|
||||
showArrow: false,
|
||||
},
|
||||
];
|
||||
const progressCards = [
|
||||
{
|
||||
id: 1,
|
||||
title: "完成进度",
|
||||
percentage: 75,
|
||||
color: "var(--fa-success)",
|
||||
icon: "ri:arrow-up-circle-line",
|
||||
iconStyle: "bg-success/12 text-success",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "项目进度",
|
||||
percentage: 65,
|
||||
color: "var(--theme-color)",
|
||||
icon: "ri:twitch-line",
|
||||
iconStyle: "bg-theme/12 text-theme",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "学习进度",
|
||||
percentage: 45,
|
||||
color: "var(--fa-error)",
|
||||
icon: "ri:game-line",
|
||||
iconStyle: "bg-error/12! text-error",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "任务进度",
|
||||
percentage: 90,
|
||||
color: "var(--fa-secondary)",
|
||||
icon: "ri:flag-2-line",
|
||||
iconStyle: "bg-secondary/12 text-secondary",
|
||||
},
|
||||
];
|
||||
const imageCards = [
|
||||
{
|
||||
id: 1,
|
||||
imageUrl: cover1,
|
||||
title: "AI技术在医疗领域的创新应用与发展前景",
|
||||
category: "社交",
|
||||
readTime: "2分钟",
|
||||
views: 9125,
|
||||
comments: 3,
|
||||
date: "12月19日 周一",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
imageUrl: cover2,
|
||||
title: "大数据分析助力企业决策的实践案例",
|
||||
category: "技术",
|
||||
readTime: "3分钟",
|
||||
views: 7234,
|
||||
comments: 5,
|
||||
date: "12月20日 周二",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
imageUrl: cover3,
|
||||
title: "区块链技术在供应链管理中的应用",
|
||||
category: "科技",
|
||||
readTime: "4分钟",
|
||||
views: 5678,
|
||||
comments: 8,
|
||||
date: "12月21日 周三",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
imageUrl: cover4,
|
||||
title: "云计算技术发展趋势与未来展望",
|
||||
category: "云技术",
|
||||
readTime: "5分钟",
|
||||
views: 4321,
|
||||
comments: 6,
|
||||
date: "12月22日 周四",
|
||||
},
|
||||
];
|
||||
const imageCards = {
|
||||
id: 1,
|
||||
imageUrl: cover2,
|
||||
title: "大数据分析助力企业决策的实践案例",
|
||||
category: "技术",
|
||||
readTime: "3分钟",
|
||||
views: 7234,
|
||||
comments: 5,
|
||||
date: "12月20日 周二",
|
||||
};
|
||||
|
||||
const dataList = [
|
||||
{
|
||||
title: "新加坡之行",
|
||||
@@ -883,12 +332,45 @@ const timelineData = [
|
||||
code: "OR-9876",
|
||||
},
|
||||
{ time: "下午 17:00", status: "rgb(103, 232, 207)", content: "完成每日销售报表" },
|
||||
{
|
||||
time: "上午 09:30",
|
||||
status: "rgb(73, 190, 255)",
|
||||
content: "收到订单 #38291 支付 ¥385.90",
|
||||
},
|
||||
{
|
||||
time: "上午 10:00",
|
||||
status: "rgb(54, 158, 255)",
|
||||
content: "新商品上架",
|
||||
code: "SKU-3467",
|
||||
},
|
||||
{
|
||||
time: "上午 12:00",
|
||||
status: "rgb(103, 232, 207)",
|
||||
content: "向供应商支付了 ¥6495.00",
|
||||
},
|
||||
{
|
||||
time: "下午 14:30",
|
||||
status: "rgb(255, 193, 7)",
|
||||
content: "促销活动开始",
|
||||
code: "PROMO-2023",
|
||||
},
|
||||
{
|
||||
time: "下午 15:45",
|
||||
status: "rgb(255, 105, 105)",
|
||||
content: "订单取消提醒",
|
||||
code: "ORD-9876",
|
||||
},
|
||||
{
|
||||
time: "下午 17:00",
|
||||
status: "rgb(103, 232, 207)",
|
||||
content: "完成日销售报表",
|
||||
},
|
||||
];
|
||||
|
||||
function handleMore() {
|
||||
ElMessage.info("查看更多");
|
||||
}
|
||||
function handleImageCardClick(card: (typeof imageCards)[0]) {
|
||||
function handleImageCardClick(card: typeof imageCards) {
|
||||
console.log("点击卡片:", card);
|
||||
}
|
||||
onMounted(() => {
|
||||
@@ -927,14 +409,6 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.version-item {
|
||||
padding: 10px 12px;
|
||||
background: var(--el-fill-color-lighter);
|
||||
@@ -994,10 +468,6 @@ onUnmounted(() => {
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.workplace-hero__avatar {
|
||||
border: 2px solid var(--el-bg-color);
|
||||
}
|
||||
|
||||
.workplace-hero__greeting {
|
||||
margin-bottom: 6px;
|
||||
font-size: 20px;
|
||||
@@ -1051,8 +521,9 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.workplace-quick-row--compact {
|
||||
min-height: 44px;
|
||||
padding: 6px 8px 6px 4px;
|
||||
gap: 12px;
|
||||
min-height: 24px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.workplace-quick-row {
|
||||
@@ -1060,7 +531,7 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
min-height: 56px;
|
||||
min-height: 40px;
|
||||
padding: 8px 10px 8px 6px;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
@@ -1088,7 +559,7 @@ onUnmounted(() => {
|
||||
flex-shrink: 0;
|
||||
align-self: stretch;
|
||||
width: 3px;
|
||||
min-height: 36px;
|
||||
min-height: 24px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
@@ -1097,12 +568,12 @@ onUnmounted(() => {
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 22px;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
background: var(--el-color-primary-light-9);
|
||||
border-radius: 10px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.workplace-quick-row__text {
|
||||
@@ -1116,7 +587,7 @@ onUnmounted(() => {
|
||||
text-overflow: ellipsis;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 1.35;
|
||||
line-height: 1.3;
|
||||
color: var(--el-text-color-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -1147,8 +618,8 @@ onUnmounted(() => {
|
||||
opacity 0.2s;
|
||||
|
||||
.workplace-quick-row--chip & {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 flex-b">
|
||||
<div class="fa-card p-5 flex-b h-full">
|
||||
<div>
|
||||
<h2 class="text-2xl font-medium">关于项目</h2>
|
||||
<p class="text-g-700 mt-1">{{ systemName }} 是一款兼具设计美学与高效开发的后台系统</p>
|
||||
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<FaBasicBanner
|
||||
class="justify-center h-53! max-sm:pt-8! max-sm:h-48!"
|
||||
:title="`欢迎回来 ${userInfo?.username}`"
|
||||
:title="bannerTitle"
|
||||
:subtitle="bannerSubtitle"
|
||||
boxStyle="bg-theme/10!"
|
||||
titleColor="var(--fa-gray-900)"
|
||||
:decoration="false"
|
||||
@@ -11,7 +12,10 @@
|
||||
}"
|
||||
:buttonConfig="{
|
||||
show: false,
|
||||
text: '',
|
||||
text: '开始探索',
|
||||
color: 'var(--fa-success)',
|
||||
textColor: '#fff',
|
||||
radius: '6px',
|
||||
}"
|
||||
:imageConfig="{
|
||||
src: bannerCover,
|
||||
@@ -20,46 +24,49 @@
|
||||
}"
|
||||
@click="handleBannerClick"
|
||||
>
|
||||
<div class="flex mt-6">
|
||||
<div class="mr-8 pr-8 border-r border-g-400 dark:border-g-300/60">
|
||||
<p class="text-3xl">
|
||||
<FaCountTo
|
||||
class="number box-title"
|
||||
:target="2340"
|
||||
:duration="1500"
|
||||
prefix="¥"
|
||||
separator=","
|
||||
/>
|
||||
<FaSvgIcon icon="ri:arrow-right-up-line" class="text-xl text-success relative -top-2" />
|
||||
</p>
|
||||
<p class="mt-1 text-sm text-g-700">今日销售额</p>
|
||||
</div>
|
||||
<div class="mr-8">
|
||||
<p class="text-3xl">
|
||||
<FaCountTo class="number box-title" :target="35" :duration="1500" suffix="%" />
|
||||
<FaSvgIcon icon="ri:arrow-right-up-line" class="text-xl text-success relative -top-2" />
|
||||
</p>
|
||||
<p class="mt-1 text-sm text-g-700">较昨日</p>
|
||||
<div class="flex items-center gap-4 mt-2">
|
||||
<ElAvatar v-if="currentUser.avatar" :size="56" :src="currentUser.avatar" />
|
||||
<ElIcon v-else :size="56" class="text-g-500"><UserFilled /></ElIcon>
|
||||
<div>
|
||||
<div class="text-lg font-semibold text-g-800">{{ currentUser.name }}</div>
|
||||
<div class="text-sm text-g-600">
|
||||
{{ currentUser.dept_name }} · {{ currentUser.description }} · {{ currentUser.last_login }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FaBasicBanner>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import bannerCover from "@imgs/login/lf_icon2.webp";
|
||||
import FaBasicBanner from "@/components/banners/fa-basic-banner/index.vue";
|
||||
import { useUserStore } from "@stores";
|
||||
import { greetings } from "@utils";
|
||||
import { UserFilled } from "@element-plus/icons-vue";
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
*/
|
||||
const userInfo = computed(() => userStore.basicInfo);
|
||||
|
||||
/**
|
||||
* 处理横幅点击事件
|
||||
*/
|
||||
const handleBannerClick = (): void => {
|
||||
// TODO: 添加横幅点击处理逻辑
|
||||
console.log("banner clicked");
|
||||
};
|
||||
|
||||
const timefix = greetings();
|
||||
const welcome = "祝你开心每一天!";
|
||||
const currentUser = {
|
||||
avatar: userStore.basicInfo.avatar || "",
|
||||
name: userInfo.value.name || "吴彦祖",
|
||||
username: userInfo.value.username || "账号信息",
|
||||
description: userInfo.value.description || "用户说明",
|
||||
dept_name: userInfo.value.dept_name || "软件专业部",
|
||||
last_login: userInfo.value.last_login || "2023-01-01 00:00:00",
|
||||
};
|
||||
|
||||
const bannerTitle = `欢迎回来 ~ ${currentUser.name}(${currentUser.username}) ${timefix} ${welcome}`;
|
||||
|
||||
const bannerSubtitle = `基于 FastAPI + Vue3 + TypeScript 构建的企业级中后台解决方案,支持多端开发。`;
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 h-128 overflow-hidden">
|
||||
<div class="fa-card p-5 overflow-hidden flex flex-col h-full">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>新用户</h4>
|
||||
@@ -1,57 +0,0 @@
|
||||
<template>
|
||||
<FaTimelineListCard
|
||||
:list="timelineData"
|
||||
title="最近交易"
|
||||
subtitle="今日订单动态"
|
||||
class="h-[28.2rem]"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface TimelineItem {
|
||||
time: string;
|
||||
status: string;
|
||||
content: string;
|
||||
code?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最近交易时间线数据
|
||||
* 记录今日订单处理、商品上架、支付等关键活动
|
||||
*/
|
||||
const timelineData: TimelineItem[] = [
|
||||
{
|
||||
time: "上午 09:30",
|
||||
status: "rgb(73, 190, 255)",
|
||||
content: "收到订单 #38291 支付 ¥385.90",
|
||||
},
|
||||
{
|
||||
time: "上午 10:00",
|
||||
status: "rgb(54, 158, 255)",
|
||||
content: "新商品上架",
|
||||
code: "SKU-3467",
|
||||
},
|
||||
{
|
||||
time: "上午 12:00",
|
||||
status: "rgb(103, 232, 207)",
|
||||
content: "向供应商支付了 ¥6495.00",
|
||||
},
|
||||
{
|
||||
time: "下午 14:30",
|
||||
status: "rgb(255, 193, 7)",
|
||||
content: "促销活动开始",
|
||||
code: "PROMO-2023",
|
||||
},
|
||||
{
|
||||
time: "下午 15:45",
|
||||
status: "rgb(255, 105, 105)",
|
||||
content: "订单取消提醒",
|
||||
code: "ORD-9876",
|
||||
},
|
||||
{
|
||||
time: "下午 17:00",
|
||||
status: "rgb(103, 232, 207)",
|
||||
content: "完成日销售报表",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
+26
-8
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card h-128 p-5">
|
||||
<div class="fa-card p-5 h-[28.2rem] overflow-hidden">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>代办事项</h4>
|
||||
@@ -18,7 +18,11 @@
|
||||
:key="index"
|
||||
>
|
||||
<div>
|
||||
<p class="text-sm">{{ item.username }}</p>
|
||||
<p class="text-sm">
|
||||
<span class="text-g-800 font-medium">{{ item.username }}</span>
|
||||
<span class="mx-2 text-g-600">{{ item.type }}</span>
|
||||
<span class="text-theme">{{ item.target }}</span>
|
||||
</p>
|
||||
<p class="text-g-500 mt-1">{{ item.date }}</p>
|
||||
</div>
|
||||
<ElCheckbox v-model="item.complate" />
|
||||
@@ -33,6 +37,8 @@ interface TodoItem {
|
||||
username: string;
|
||||
date: string;
|
||||
complate: boolean;
|
||||
type: string;
|
||||
target: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,34 +47,46 @@ interface TodoItem {
|
||||
*/
|
||||
const list = reactive<TodoItem[]>([
|
||||
{
|
||||
username: "查看今天工作内容",
|
||||
username: "张无忌",
|
||||
date: "上午 09:30",
|
||||
complate: true,
|
||||
type: "查看",
|
||||
target: "查看今天工作内容",
|
||||
},
|
||||
{
|
||||
username: "回复邮件",
|
||||
username: "赵敏",
|
||||
date: "上午 10:30",
|
||||
complate: true,
|
||||
type: "回复",
|
||||
target: "回复邮件",
|
||||
},
|
||||
{
|
||||
username: "工作汇报整理",
|
||||
username: "小昭",
|
||||
date: "上午 11:00",
|
||||
complate: true,
|
||||
type: "工作",
|
||||
target: "工作汇报整理",
|
||||
},
|
||||
{
|
||||
username: "产品需求会议",
|
||||
username: "金毛狮王",
|
||||
date: "下午 02:00",
|
||||
complate: false,
|
||||
type: "会议",
|
||||
target: "产品需求会议",
|
||||
},
|
||||
{
|
||||
username: "整理会议内容",
|
||||
username: "金花婆婆",
|
||||
date: "下午 03:30",
|
||||
complate: false,
|
||||
type: "会议",
|
||||
target: "整理会议内容",
|
||||
},
|
||||
{
|
||||
username: "明天工作计划",
|
||||
username: "张三丰",
|
||||
date: "下午 06:30",
|
||||
complate: false,
|
||||
type: "计划",
|
||||
target: "明天工作计划",
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
@@ -1,80 +0,0 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 h-full flex flex-col">
|
||||
<div class="pb-3.5">
|
||||
<p class="text-lg font-medium">最近活动</p>
|
||||
<p class="text-sm text-g-600">订单处理状态</p>
|
||||
</div>
|
||||
<ElScrollbar :style="{ height: '264px' }">
|
||||
<div v-for="(item, index) in dataList" :key="index" class="flex-c py-3">
|
||||
<div v-if="item.icon" class="flex-cc mr-3 size-10 rounded-lg" :class="item.class">
|
||||
<FaSvgIcon :icon="item.icon" class="text-xl" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="mb-1 text-sm">{{ item.title }}</div>
|
||||
<div class="text-xs text-g-500">{{ item.status }}</div>
|
||||
</div>
|
||||
<div class="ml-3 text-xs text-g-500">{{ item.time }}</div>
|
||||
</div>
|
||||
</ElScrollbar>
|
||||
<ElButton class="mt-[17px] w-full text-center" v-ripple @click="handleMore">查看更多</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface TransactionItem {
|
||||
title: string;
|
||||
status: string;
|
||||
time: string;
|
||||
class: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最近活动数据列表
|
||||
* 展示订单处理、退款申请、投诉处理等业务活动状态
|
||||
*/
|
||||
const dataList: TransactionItem[] = [
|
||||
{
|
||||
title: "新订单 #38291",
|
||||
status: "待处理",
|
||||
time: "5分钟",
|
||||
class: "bg-theme/12 text-theme",
|
||||
icon: "ri:shopping-bag-4-line",
|
||||
},
|
||||
{
|
||||
title: "退款申请 #12845",
|
||||
status: "处理中",
|
||||
time: "10分钟",
|
||||
class: "bg-secondary/12 text-secondary",
|
||||
icon: "ri:profile-line",
|
||||
},
|
||||
{
|
||||
title: "客户投诉处理",
|
||||
status: "待处理",
|
||||
time: "15分钟",
|
||||
class: "bg-warning/12 text-warning",
|
||||
icon: "ri:customer-service-2-line",
|
||||
},
|
||||
{
|
||||
title: "库存不足提醒",
|
||||
status: "紧急",
|
||||
time: "20分钟",
|
||||
class: "bg-danger/12 text-danger",
|
||||
icon: "ri:box-1-line",
|
||||
},
|
||||
{
|
||||
title: "订单 #29384 已发货",
|
||||
status: "已完成",
|
||||
time: "20分钟",
|
||||
class: "bg-success/12 text-success",
|
||||
icon: "ri:shopping-bag-3-line",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 处理查看更多按钮点击事件
|
||||
*/
|
||||
const handleMore = (): void => {
|
||||
// TODO: 添加查看更多逻辑
|
||||
};
|
||||
</script>
|
||||
@@ -2,43 +2,197 @@
|
||||
<div class="workplace-container">
|
||||
<!-- 电商模块 -->
|
||||
<div class="card-group">
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="24" :lg="16"><Banner /></ElCol>
|
||||
<ElCol :sm="12" :md="12" :lg="4"><TotalOrderVolume /></ElCol>
|
||||
<ElCol :sm="12" :md="12" :lg="4"><TotalProducts /></ElCol>
|
||||
<ElRow :gutter="24">
|
||||
<ElCol :sm="12" :md="12" :lg="6"><TotalOrderVolume /></ElCol>
|
||||
<ElCol :sm="12" :md="12" :lg="6"><TotalProducts /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6"><ProductSales /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6"><SalesGrowth /></ElCol>
|
||||
</ElRow>
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="12" :md="12" :lg="8"><SalesTrend /></ElCol>
|
||||
<ElCol :sm="12" :md="12" :lg="8"><SalesClassification /></ElCol>
|
||||
<ElCol :sm="24" :md="24" :lg="8">
|
||||
<ElRow :gutter="20" class="card-row">
|
||||
<ElCol :sm="24" :md="12" :lg="12"><ProductSales /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12"><SalesGrowth /></ElCol>
|
||||
<ElCol :span="24"><CartConversionRate /></ElCol>
|
||||
</ElRow>
|
||||
</ElCol>
|
||||
|
||||
<ElRow :gutter="24">
|
||||
<ElCol :span="24"><CartConversionRate /></ElCol>
|
||||
</ElRow>
|
||||
|
||||
<ElRow :gutter="24">
|
||||
<ElCol :sm="12" :md="12" :lg="6"><SalesTrend /></ElCol>
|
||||
<ElCol :sm="12" :md="12" :lg="6"><SalesClassification /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6"><HotCommodity /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6"><AnnualSales /></ElCol>
|
||||
</ElRow>
|
||||
</div>
|
||||
|
||||
<!-- 用户分析 -->
|
||||
<div class="card-group">
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="12" :lg="10"><ActiveUser /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="14"><SalesOverview /></ElCol>
|
||||
</ElRow>
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="24" :lg="12"><NewUser /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6"><Dynamic /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6"><TodoList /></ElCol>
|
||||
</ElRow>
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="12" :lg="8"><HotCommodity /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="8"><AnnualSales /></ElCol>
|
||||
<ElCol :sm="24" :md="24" :lg="8"><TransactionList /></ElCol>
|
||||
</ElRow>
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :md="24" :lg="8"><RecentTransaction /></ElCol>
|
||||
<ElCol :md="24" :lg="16" class="no-margin-bottom"><HotProductsList /></ElCol>
|
||||
<ElRow :gutter="24">
|
||||
<ElCol :sm="24" :md="12" :lg="12" class="mb-5"><ActiveUser /></ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12" class="mb-5"><SalesOverview /></ElCol>
|
||||
<ElCol
|
||||
v-for="card in statsCards"
|
||||
:key="`t-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaStatsCard
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.iconStyle"
|
||||
:title="card.title"
|
||||
:description="card.description"
|
||||
:showArrow="card.showArrow"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in statsCards"
|
||||
:key="`n-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaStatsCard
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.iconStyle"
|
||||
:title="card.title"
|
||||
:description="card.description"
|
||||
:count="card.count"
|
||||
:decimals="0"
|
||||
:showArrow="card.showArrow"
|
||||
separator=","
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in statsCards"
|
||||
:key="`c-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaStatsCard
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.customIconStyle"
|
||||
:boxStyle="card.boxStyle"
|
||||
:title="card.title"
|
||||
:description="card.description"
|
||||
:textColor="card.textColor"
|
||||
:showArrow="card.showArrow"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in progressCards"
|
||||
:key="`p-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaProgressCard :percentage="card.percentage" :title="card.title" :color="card.color" />
|
||||
</ElCol>
|
||||
<ElCol
|
||||
v-for="card in progressCards"
|
||||
:key="`pi-${card.id}`"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="6"
|
||||
class="mb-5"
|
||||
>
|
||||
<FaProgressCard
|
||||
:percentage="card.percentage"
|
||||
:title="card.title"
|
||||
:color="card.color"
|
||||
:icon="card.icon"
|
||||
:iconStyle="card.iconStyle"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:isMiniChart="true"
|
||||
:value="2545"
|
||||
label="新用户"
|
||||
date="过去7天"
|
||||
:percentage="1.2"
|
||||
:height="9.5"
|
||||
:chartData="[120, 132, 101, 134, 90, 230, 210]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaBarChartCard
|
||||
:isMiniChart="true"
|
||||
:value="15480"
|
||||
label="浏览量"
|
||||
date="过去14天"
|
||||
:percentage="-4.15"
|
||||
:height="9.5"
|
||||
barWidth="45%"
|
||||
:chartData="[120, 100, 150, 140, 90, 120, 130]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:isMiniChart="true"
|
||||
:value="2545"
|
||||
label="粉丝数"
|
||||
date="过去30天"
|
||||
:percentage="1.2"
|
||||
:height="9.5"
|
||||
:showAreaColor="true"
|
||||
:chartData="[150, 180, 160, 200, 180, 220, 240]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaDonutChartCard
|
||||
:value="36358"
|
||||
title="粉丝量"
|
||||
:percentage="18"
|
||||
percentageLabel="较去年"
|
||||
:data="[50, 40]"
|
||||
:height="9.5"
|
||||
currentValue="2022"
|
||||
previousValue="2021"
|
||||
:radius="['50%', '70%']"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:value="2545"
|
||||
label="新用户"
|
||||
:percentage="1.2"
|
||||
:height="11"
|
||||
:chartData="[120, 132, 101, 134, 90, 230, 210]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaBarChartCard
|
||||
:value="15480"
|
||||
label="浏览量"
|
||||
:percentage="-4.15"
|
||||
:height="11"
|
||||
:chartData="[120, 100, 150, 140, 90, 120, 130, 110]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaLineChartCard
|
||||
:value="2545"
|
||||
label="粉丝数"
|
||||
:percentage="1.2"
|
||||
:height="11"
|
||||
:showAreaColor="true"
|
||||
:chartData="[150, 180, 160, 200, 180, 220, 240]"
|
||||
/>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :md="6" class="mb-5">
|
||||
<FaDonutChartCard
|
||||
:value="36358"
|
||||
title="粉丝量"
|
||||
:percentage="-18"
|
||||
percentageLabel="较2021年"
|
||||
:data="[70, 30]"
|
||||
:height="11"
|
||||
currentValue="12月"
|
||||
previousValue="11月"
|
||||
/>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,25 +201,107 @@
|
||||
<script setup lang="ts">
|
||||
import ActiveUser from "./modules/active-user.vue";
|
||||
import SalesOverview from "./modules/sales-overview.vue";
|
||||
import NewUser from "./modules/new-user.vue";
|
||||
import Dynamic from "./modules/dynamic-stats.vue";
|
||||
import TodoList from "./modules/todo-list.vue";
|
||||
import TotalOrderVolume from "./modules/total-order-volume.vue";
|
||||
import TotalProducts from "./modules/total-products.vue";
|
||||
import SalesTrend from "./modules/sales-trend.vue";
|
||||
import SalesClassification from "./modules/sales-classification.vue";
|
||||
import HotCommodity from "./modules/hot-commodity.vue";
|
||||
import AnnualSales from "./modules/annual-sales.vue";
|
||||
import ProductSales from "./modules/product-sales.vue";
|
||||
import SalesGrowth from "./modules/sales-growth.vue";
|
||||
import CartConversionRate from "./modules/cart-conversion-rate.vue";
|
||||
import FaLineChartCard from "@/components/cards/fa-line-chart-card/index.vue";
|
||||
import FaStatsCard from "@/components/cards/fa-stats-card/index.vue";
|
||||
import FaProgressCard from "@/components/cards/fa-progress-card/index.vue";
|
||||
import FaBarChartCard from "@/components/cards/fa-bar-chart-card/index.vue";
|
||||
import FaDonutChartCard from "@/components/cards/fa-donut-chart-card/index.vue";
|
||||
|
||||
import Banner from "../home/modules/banner.vue";
|
||||
import TotalOrderVolume from "../home/modules/total-order-volume.vue";
|
||||
import TotalProducts from "../home/modules/total-products.vue";
|
||||
import SalesTrend from "../home/modules/sales-trend.vue";
|
||||
import SalesClassification from "../home/modules/sales-classification.vue";
|
||||
import TransactionList from "../home/modules/transaction-list.vue";
|
||||
import HotCommodity from "../home/modules/hot-commodity.vue";
|
||||
import RecentTransaction from "../home/modules/recent-transaction.vue";
|
||||
import AnnualSales from "../home/modules/annual-sales.vue";
|
||||
import ProductSales from "../home/modules/product-sales.vue";
|
||||
import SalesGrowth from "../home/modules/sales-growth.vue";
|
||||
import CartConversionRate from "../home/modules/cart-conversion-rate.vue";
|
||||
import HotProductsList from "../home/modules/hot-products-list.vue";
|
||||
defineOptions({ name: "DashboardWorkplace" });
|
||||
|
||||
defineOptions({ name: "Console" });
|
||||
const statsCards = [
|
||||
{
|
||||
id: 1,
|
||||
title: "销售产品",
|
||||
count: 1235,
|
||||
description: "鞋子、牛仔裤、派对服装、手表",
|
||||
icon: "ri:bar-chart-box-line",
|
||||
boxStyle: "bg-theme/10!",
|
||||
customIconStyle: "text-theme! text-3xl!",
|
||||
iconStyle: "bg-info",
|
||||
textColor: "var(--theme-color)",
|
||||
showArrow: false,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "活跃用户",
|
||||
count: 5000,
|
||||
description: "日活跃用户超过5,000+",
|
||||
icon: "ri:account-box-2-line",
|
||||
boxStyle: "bg-warning/10!",
|
||||
customIconStyle: "text-warning! text-3xl!",
|
||||
iconStyle: "bg-warning",
|
||||
textColor: "var(--fa-warning)",
|
||||
showArrow: false,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "总收入",
|
||||
count: 35000,
|
||||
description: "月收入超过¥350,000+",
|
||||
icon: "ri:money-cny-box-line",
|
||||
boxStyle: "bg-secondary/10!",
|
||||
customIconStyle: "text-secondary! text-3xl!",
|
||||
iconStyle: "bg-secondary",
|
||||
textColor: "var(--fa-secondary)",
|
||||
showArrow: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "客户评价",
|
||||
count: 4800,
|
||||
description: "平均评分4.8/5",
|
||||
icon: "ri:message-3-line",
|
||||
boxStyle: "bg-error/10!",
|
||||
customIconStyle: "text-error! text-3xl!",
|
||||
iconStyle: "bg-error",
|
||||
textColor: "var(--fa-error)",
|
||||
showArrow: false,
|
||||
},
|
||||
];
|
||||
const progressCards = [
|
||||
{
|
||||
id: 1,
|
||||
title: "完成进度",
|
||||
percentage: 75,
|
||||
color: "var(--fa-success)",
|
||||
icon: "ri:arrow-up-circle-line",
|
||||
iconStyle: "bg-success/12 text-success",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "项目进度",
|
||||
percentage: 65,
|
||||
color: "var(--theme-color)",
|
||||
icon: "ri:twitch-line",
|
||||
iconStyle: "bg-theme/12 text-theme",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "学习进度",
|
||||
percentage: 45,
|
||||
color: "var(--fa-error)",
|
||||
icon: "ri:game-line",
|
||||
iconStyle: "bg-error/12! text-error",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "任务进度",
|
||||
percentage: 90,
|
||||
color: "var(--fa-secondary)",
|
||||
icon: "ri:flag-2-line",
|
||||
iconStyle: "bg-secondary/12 text-secondary",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 h-[28.2rem]">
|
||||
<div class="fa-card p-5 h-112">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>年度销售额</h4>
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<FaLineChartCard
|
||||
class=""
|
||||
class="fa-card h-53 p-5 pt-3.5"
|
||||
:value="2545"
|
||||
label="购物车转化率"
|
||||
:percentage="1.2"
|
||||
@@ -1,82 +0,0 @@
|
||||
<template>
|
||||
<div class="fa-card h-128 p-5">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>动态</h4>
|
||||
<p>
|
||||
新增
|
||||
<span class="text-success">+6</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-9/10 mt-2 overflow-hidden">
|
||||
<ElScrollbar>
|
||||
<div
|
||||
class="h-17.5 leading-17.5 border-b border-g-300 text-sm overflow-hidden last:border-b-0"
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
>
|
||||
<span class="text-g-800 font-medium">{{ item.username }}</span>
|
||||
<span class="mx-2 text-g-600">{{ item.type }}</span>
|
||||
<span class="text-theme">{{ item.target }}</span>
|
||||
</div>
|
||||
</ElScrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface DynamicItem {
|
||||
username: string;
|
||||
type: string;
|
||||
target: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户动态列表
|
||||
* 记录用户的关注、发文、提问、兑换等各类活动
|
||||
*/
|
||||
const list = reactive<DynamicItem[]>([
|
||||
{
|
||||
username: "中小鱼",
|
||||
type: "关注了",
|
||||
target: "誶誶淰",
|
||||
},
|
||||
{
|
||||
username: "何小荷",
|
||||
type: "发表文章",
|
||||
target: "Vue3 + Typescript + Vite 项目实战笔记",
|
||||
},
|
||||
{
|
||||
username: "中小鱼",
|
||||
type: "关注了",
|
||||
target: "誶誶淰",
|
||||
},
|
||||
{
|
||||
username: "何小荷",
|
||||
type: "发表文章",
|
||||
target: "Vue3 + Typescript + Vite 项目实战笔记",
|
||||
},
|
||||
{
|
||||
username: "誶誶淰",
|
||||
type: "提出问题",
|
||||
target: "主题可以配置吗",
|
||||
},
|
||||
{
|
||||
username: "发呆草",
|
||||
type: "兑换了物品",
|
||||
target: "《奇特的一生》",
|
||||
},
|
||||
{
|
||||
username: "甜筒",
|
||||
type: "关闭了问题",
|
||||
target: "发呆草",
|
||||
},
|
||||
{
|
||||
username: "冷月呆呆",
|
||||
type: "兑换了物品",
|
||||
target: "《高效人士的七个习惯》",
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 h-[28.2rem]">
|
||||
<div class="fa-card p-5 h-112">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>热销商品</h4>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 pt-3.5 h-46">
|
||||
<div class="fa-card h-53 p-5 pt-3.5">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4 class="text-2xl">
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 h-105">
|
||||
<div class="fa-card p-5 h-112">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>销售分类</h4>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 pt-3.5 h-46">
|
||||
<div class="fa-card h-53 p-5 pt-3.5">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4 class="text-2xl">
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="fa-card p-5 h-105">
|
||||
<div class="fa-card p-5 h-112">
|
||||
<div class="fa-card-header">
|
||||
<div class="title">
|
||||
<h4>销售趋势</h4>
|
||||
+1
-1
@@ -509,8 +509,8 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 300px;
|
||||
|
||||
@@ -966,9 +966,9 @@ function deleteEdge(edgeId: string, getEdges: () => Edge[], setEdges: (edges: Ed
|
||||
|
||||
.canvas-container {
|
||||
flex: 1;
|
||||
min-height: 400px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 400px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user