mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-01 00:05:17 +00:00
开源准备
This commit is contained in:
@@ -0,0 +1,669 @@
|
||||
<template>
|
||||
<div style="padding: 15px 0;">
|
||||
<a-row :gutter="24">
|
||||
<a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">总销售额</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span>¥ 126,560</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; height: 45px; padding-top: 10px;">
|
||||
<div style="margin-right: 16px; align-self: flex-end;">
|
||||
<span>
|
||||
周同比
|
||||
<span style="margin-left: 8px;">
|
||||
12%
|
||||
<CaretUpOutlined style="color:red;" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div style="align-self: flex-end;">
|
||||
<span>
|
||||
日同比
|
||||
<span style="margin-left: 8px;">
|
||||
11%
|
||||
<CaretDownOutlined style="color:green;" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="border-top: 1px solid rgba(5, 5, 5, 0.06); margin-top: 10px; padding-top: 10px;">
|
||||
<span>
|
||||
日销售额
|
||||
<span>¥12,423</span>
|
||||
</span>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">访问量</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span>8,846</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 45px; padding-top: 10px;">
|
||||
<v-chart class="line-chart" :option="visitOption" autoresize />
|
||||
</div>
|
||||
<div style="border-top: 1px solid rgba(5, 5, 5, 0.06); margin-top: 10px; padding-top: 10px;">
|
||||
<span>
|
||||
日访问量
|
||||
<span>1,234</span>
|
||||
</span>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">支付笔数</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span>6,560</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; height: 45px; padding-top: 10px;">
|
||||
<v-chart class="payment-chart" :option="paymentOption" autoresize />
|
||||
</div>
|
||||
<div style="border-top: 1px solid rgba(5, 5, 5, 0.06); margin-top: 10px; padding-top: 10px;">
|
||||
<span>
|
||||
转化率
|
||||
<span>60%</span>
|
||||
</span>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<a-card :bodyStyle="{ padding: '20px 24px 8px' }">
|
||||
<a-skeleton :loading="loading">
|
||||
<div>
|
||||
<span style="color: rgba(0, 0, 0, 0.65)">运营活动效果</span>
|
||||
<div style="float: right;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span>78%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 45px; line-height: 45px; padding-top: 10px;">
|
||||
<a-progress :percent="78" status="active" :strokeColor="{ from: '#108ee9', to: '#87d068' }" />
|
||||
</div>
|
||||
<div style="display: flex; border-top: 1px solid rgba(5, 5, 5, 0.06); margin-top: 10px; padding-top: 10px;">
|
||||
<div style="margin-right: 16px; align-self: flex-end;">
|
||||
<span>
|
||||
周同比
|
||||
<span style="margin-left: 8px;">
|
||||
12%
|
||||
<CaretUpOutlined style="color:red;" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div style="align-self: flex-end;">
|
||||
<span>
|
||||
日同比
|
||||
<span style="margin-left: 8px;">
|
||||
11%
|
||||
<CaretDownOutlined style="color:green;" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div style="margin-top: 25px;">
|
||||
<a-card :tab-list="tabList" :active-tab-key="barTypeKey" @tabChange="onTabChange">
|
||||
<a-skeleton :loading="loading">
|
||||
<template #tabBarExtraContent>
|
||||
<div class="extra-item" style="">
|
||||
<a>今日</a>
|
||||
<a>本周</a>
|
||||
<a>本月</a>
|
||||
<a>本年</a>
|
||||
</div>
|
||||
<a-range-picker :style="{ width: '256px' }" />
|
||||
</template>
|
||||
<div v-if="barTypeKey == 'sales'">
|
||||
<a-row :gutter="24">
|
||||
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<v-chart :option="barOption" autoresize style="width: 1060px; height: 300px;" />
|
||||
</a-col>
|
||||
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<div class="rank">
|
||||
<h4>门店销售额排名</h4>
|
||||
<ul style="list-style: none; margin: 25px 0 0;">
|
||||
<li :key="i" v-for="(item, i) in barRank">
|
||||
<span class="active" v-if="i < 3">{{ i + 1 }}</span>
|
||||
<span v-else>{{ i + 1 }}</span>
|
||||
<span>{{ item }}</span>
|
||||
<span>323,234</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-row :gutter="24">
|
||||
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<v-chart :option="barOption" autoresize style="width: 1060px; height: 300px;" />
|
||||
</a-col>
|
||||
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<div class="rank">
|
||||
<h4>门店访问量排名</h4>
|
||||
<ul style="list-style: none; margin: 25px 0 0;">
|
||||
<li :key="i" v-for="(item, i) in barRank">
|
||||
<span class="active" v-if="i < 3">{{ i + 1 }}</span>
|
||||
<span v-else>{{ i + 1 }}</span>
|
||||
<span>{{ item }}</span>
|
||||
<span>323,234</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 25px;">
|
||||
<a-col :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
|
||||
<a-card title="线上热门搜索">
|
||||
<a-skeleton :loading="loading">
|
||||
<template #extra>
|
||||
<a-dropdown placement="bottomRight">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1">操作一</a-menu-item>
|
||||
<a-menu-item key="2">操作二</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<EllipsisOutlined />
|
||||
</a-dropdown>
|
||||
</template>
|
||||
|
||||
<a-row :gutter="68">
|
||||
<a-col :sm="12" :xs="24">
|
||||
<div style="color: rgba(0, 0, 0, 0.65);">
|
||||
<span>搜索用户数</span>
|
||||
<span style="margin-left: 8px;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<v-chart class="line-chart" :option="searchOption" autoresize />
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :sm="12" :xs="24">
|
||||
<div style="color: rgba(0, 0, 0, 0.65);">
|
||||
<span>人均搜索次数</span>
|
||||
<span style="margin-left: 8px;">
|
||||
<a-tooltip title="指标说明" placement="top">
|
||||
<InfoCircleOutlined />
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<v-chart class="line-chart" :option="searchOption" autoresize />
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div style="margin-top: 10px;">
|
||||
<a-table row-key="index" size="small" :columns="searchColumns" :data-source="searchData"
|
||||
:pagination="{ pageSize: 5 }">
|
||||
<template v-slot:bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'keyword'">
|
||||
<a>{{ record.keyword }}</a>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'range'">
|
||||
<span v-if="record.status === 0">
|
||||
{{ `${record.range}%` }}
|
||||
<CaretUpOutlined style="color:red;" />
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ `${record.range}%` }}
|
||||
<CaretDownOutlined style="color:green;" />
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
|
||||
<a-card title="销售额类别占比">
|
||||
<a-skeleton :loading="loading">
|
||||
<template #extra>
|
||||
<span>
|
||||
<a-radio-group v-model:value="salesType" @change="salesTabChange">
|
||||
<a-radio-button value="all">全部渠道</a-radio-button>
|
||||
<a-radio-button value="online">线上</a-radio-button>
|
||||
<a-radio-button value="offline">门店</a-radio-button>
|
||||
</a-radio-group>
|
||||
</span>
|
||||
<span style="margin-left: 20px;">
|
||||
<a-dropdown placement="bottomRight">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1">操作一</a-menu-item>
|
||||
<a-menu-item key="2">操作二</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<EllipsisOutlined />
|
||||
</a-dropdown>
|
||||
</span>
|
||||
</template>
|
||||
<span>
|
||||
销售额
|
||||
<v-chart class="pie-chart" :option="pieOptions" autoresize />
|
||||
</span>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { InfoCircleOutlined, CaretUpOutlined, CaretDownOutlined, EllipsisOutlined } from '@ant-design/icons-vue';
|
||||
import { getRangeDate } from '@/utils/util'
|
||||
|
||||
const loading = ref(true);
|
||||
|
||||
let y: number[] = [];
|
||||
for (let i = 0; i < 15; i += 1) {
|
||||
y.push(Math.ceil(Math.random() * 10 % 9))
|
||||
}
|
||||
let x: string[] = getRangeDate('2024-03-01', '2024-03-15');
|
||||
|
||||
const visitOption = {
|
||||
color: '#2289ff',
|
||||
grid: {
|
||||
left: '-5%',
|
||||
right: '0%',
|
||||
bottom: '100%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
show: false,
|
||||
data: x
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false,
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: y,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 0
|
||||
},
|
||||
showSymbol: false,
|
||||
areaStyle: {},
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const paymentOption = {
|
||||
color: '#2289ff',
|
||||
grid: {
|
||||
left: '-5%',
|
||||
right: '0%',
|
||||
bottom: '100%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
show: false,
|
||||
data: x
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false,
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: y,
|
||||
type: 'bar'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const tabList = [
|
||||
{
|
||||
key: 'sales',
|
||||
tab: '销售额',
|
||||
},
|
||||
{
|
||||
key: 'visit',
|
||||
tab: '访问量',
|
||||
},
|
||||
];
|
||||
const barTypeKey = ref('sales');
|
||||
|
||||
let bar_x: string[] = [];
|
||||
let bar_y = [1106, 505, 845, 778, 1098, 762, 615, 345, 343, 1177, 431, 813];
|
||||
|
||||
for (let i = 1; i < 13; i += 1) {
|
||||
bar_x.push(`${i}月`)
|
||||
}
|
||||
|
||||
const barOption = reactive({
|
||||
color: '#2289ff',
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '0%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: bar_x,
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '销售量',
|
||||
type: 'bar',
|
||||
barWidth: '50%',
|
||||
data: bar_y
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
let barRank: string[] = [];
|
||||
for (let i = 0; i < 7; i += 1) {
|
||||
barRank.push(`工专路${i}号店`)
|
||||
}
|
||||
|
||||
const onTabChange = (value: string) => {
|
||||
barTypeKey.value = value;
|
||||
barOption.series[0].name = value == 'sales' ? '销售量' : '访问量';
|
||||
};
|
||||
|
||||
let search_y: number[] = [];
|
||||
for (let i = 0; i < 7; i += 1) {
|
||||
search_y.push(Math.ceil(Math.random() * 10 % 9))
|
||||
}
|
||||
let search_x: string[] = getRangeDate('2024-03-01', '2024-03-07');
|
||||
|
||||
const searchOption = {
|
||||
color: '#2289ff',
|
||||
grid: {
|
||||
left: '-6%',
|
||||
right: '0%',
|
||||
bottom: '100%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
show: false,
|
||||
data: search_x
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false,
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: search_y,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 0
|
||||
},
|
||||
showSymbol: false,
|
||||
areaStyle: {},
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const searchColumns = [
|
||||
{
|
||||
dataIndex: 'index',
|
||||
title: '排名',
|
||||
width: 90
|
||||
},
|
||||
{
|
||||
dataIndex: 'keyword',
|
||||
title: '搜索关键词'
|
||||
},
|
||||
{
|
||||
dataIndex: 'count',
|
||||
title: '用户数',
|
||||
sorter: (a, b) => a.count - b.count
|
||||
},
|
||||
{
|
||||
dataIndex: 'range',
|
||||
title: '周涨幅',
|
||||
sorter: (a, b) => a.range - b.range
|
||||
}
|
||||
];
|
||||
const searchData = [];
|
||||
for (let i = 0; i < 50; i += 1) {
|
||||
searchData.push({
|
||||
index: i + 1,
|
||||
keyword: `搜索关键词-${i}`,
|
||||
count: Math.floor(Math.random() * 1000),
|
||||
range: Math.floor(Math.random() * 100),
|
||||
status: Math.floor((Math.random() * 10) % 2)
|
||||
})
|
||||
}
|
||||
|
||||
const salesType = ref('all');
|
||||
|
||||
const salesTabChange = (item: any) => {
|
||||
if (item.target.value == 'all') {
|
||||
pieOptions.value.series[0].data = [
|
||||
{ value: 1231, name: '其他' },
|
||||
{ value: 1231, name: '母婴产品' },
|
||||
{ value: 2341, name: '服饰箱包' },
|
||||
{ value: 3113, name: '个护健康' },
|
||||
{ value: 3321, name: '食用酒水' },
|
||||
{ value: 4544, name: '家用电器' }
|
||||
]
|
||||
} else if (item.target.value == 'online') {
|
||||
pieOptions.value.series[0].data = [
|
||||
{ value: 111, name: '其他' },
|
||||
{ value: 121, name: '母婴产品' },
|
||||
{ value: 41, name: '服饰箱包' },
|
||||
{ value: 311, name: '个护健康' },
|
||||
{ value: 321, name: '食用酒水' },
|
||||
{ value: 244, name: '家用电器' }
|
||||
]
|
||||
} else {
|
||||
pieOptions.value.series[0].data = [
|
||||
{ value: 65, name: '其他' },
|
||||
{ value: 0, name: '母婴产品' },
|
||||
{ value: 255, name: '服饰箱包' },
|
||||
{ value: 344, name: '个护健康' },
|
||||
{ value: 188, name: '食用酒水' },
|
||||
{ value: 99, name: '家用电器' }
|
||||
]
|
||||
}
|
||||
}
|
||||
const pieOptions = ref({
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
data: [
|
||||
{ value: 1231, name: '其他' },
|
||||
{ value: 1231, name: '母婴产品' },
|
||||
{ value: 2341, name: '服饰箱包' },
|
||||
{ value: 3113, name: '个护健康' },
|
||||
{ value: 3321, name: '食用酒水' },
|
||||
{ value: 4544, name: '家用电器' }
|
||||
],
|
||||
itemStyle: {
|
||||
color: function (colors) {
|
||||
var colorList = [
|
||||
'#68c738',
|
||||
'#7f6bff',
|
||||
'#d787ff',
|
||||
'#f18e56',
|
||||
'#0dcccc',
|
||||
'#2389ff'
|
||||
];
|
||||
return colorList[colors.dataIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 500);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.value {
|
||||
height: 38px;
|
||||
padding-top: 4px;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
font-size: 30px;
|
||||
line-height: 38px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.line-chart {
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.payment-chart {
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.extra-item {
|
||||
display: inline-block;
|
||||
|
||||
a {
|
||||
margin-right: 25px;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.rank {
|
||||
padding: 0 32px 32px 72px;
|
||||
|
||||
h4 {
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
ul li {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
ul li span {
|
||||
&:first-child {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 20px;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-right: 24px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
float: right;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #314659;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pie-chart {
|
||||
width: 725px;
|
||||
height: 350px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<page-header />
|
||||
<div class="container">
|
||||
<div class="page-header-content" style="display: flex; justify-content: space-between; padding-bottom: 20px;">
|
||||
<a-row align="middle">
|
||||
<a-col class="avatar">
|
||||
<a-avatar :size="75" :src="userInfo.avatar" />
|
||||
</a-col>
|
||||
<a-col class="content" style="margin-left: 20px;">
|
||||
<div class="content-title"
|
||||
style="font-size: 20px; font-weight: 500; color: rgba(0, 0, 0, 0.88); margin-bottom: 12px;">
|
||||
{{ timefix }},{{ userInfo.name }}<span class="welcome-text">,{{ welcome }}</span>
|
||||
</div>
|
||||
<div style="color: rgba(0, 0, 0, 0.65);">{{userInfo.positions[0].name}} | {{userInfo.dept_name}}</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="extra-content" justify="space-around">
|
||||
<a-col class="stat-item">
|
||||
<a-statistic title="项目数" :value="56" />
|
||||
</a-col>
|
||||
<a-col class="stat-item">
|
||||
<a-statistic title="团队内排名" :value="8" suffix="/ 24" />
|
||||
</a-col>
|
||||
<a-col class="stat-item">
|
||||
<a-statistic title="项目访问" :value="2223" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div>
|
||||
<a-row :gutter="24">
|
||||
<a-col :xl="16" :lg="24" :md="24" :sm="24" :xs="24">
|
||||
<a-card title="进行中的项目">
|
||||
<template #extra>
|
||||
<a>全部项目</a>
|
||||
</template>
|
||||
<a-card-grid :key="i" v-for="(item, i) in projectItems" style="width: 33.33%;">
|
||||
<a-skeleton :loading="loading">
|
||||
<a-card-meta>
|
||||
<template #title>
|
||||
<a-avatar :size="30" :src="item.avatar" />
|
||||
<a class="a-hover" style="margin-left: 10px; color: rgba(0, 0, 0, 0.88);">{{ item.title }}</a>
|
||||
</template>
|
||||
<template #description>
|
||||
<div style="min-height: 45px;">{{ item.description }}</div>
|
||||
</template>
|
||||
</a-card-meta>
|
||||
<div class="project-item">
|
||||
<a class="a-hover" style="color: rgba(0, 0, 0, 0.65)">{{ item.author }}</a>
|
||||
<span class="item-datetime">{{ item.datetime }}</span>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card-grid>
|
||||
</a-card>
|
||||
<a-card title="动态" :bordered="false" :bodyStyle="{ padding: '10px' }" style="margin-top: 20px;">
|
||||
<a-list item-layout="horizontal" :data-source="activities">
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item>
|
||||
<a-skeleton :loading="loading" active avatar>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-avatar :src="item.avatar" />
|
||||
</template>
|
||||
<template #title>
|
||||
<a class="a-hover">{{ item.username }}</a>
|
||||
<span>
|
||||
在
|
||||
<a>{{ item.project }}</a>
|
||||
{{ item.action }}
|
||||
<a>{{ item.event }}</a>
|
||||
</span>
|
||||
</template>
|
||||
<template #description>
|
||||
<span class="item-datetime">几秒前</span>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</a-skeleton>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</a-col>
|
||||
|
||||
<a-col :xl="8" :lg="24" :md="24" :sm="24" :xs="24">
|
||||
<a-card title="快速开始 / 便捷导航" :bodyStyle="{ padding: '20px 0 8px 24px' }">
|
||||
<a-button type="primary" size="small" ghost>
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
添加
|
||||
</a-button>
|
||||
</a-card>
|
||||
<a-card title="XX 指数" style="margin-top: 20px;">
|
||||
<a-skeleton :loading="loading">
|
||||
<v-chart class="chart" :option="chartOptions" autoresize />
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
<a-card title="团队" :bodyStyle="{ padding: '10px' }" style="margin-top: 20px;">
|
||||
<a-skeleton :loading="loading">
|
||||
<div class="members">
|
||||
<a-row>
|
||||
<a-col :span="12" v-for="(item, index) in teams" :key="index" style="padding-left: 10px">
|
||||
<a>
|
||||
<a-avatar size="small" :src="item.avatar" />
|
||||
<span class="member">{{ item.name }}</span>
|
||||
</a>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-skeleton>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import { timeFix } from '@/utils/util';
|
||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||
import store from '@/store';
|
||||
|
||||
const loading = ref(true);
|
||||
|
||||
let timefix = timeFix();
|
||||
|
||||
const userInfo = store.state.user.basicInfo;
|
||||
|
||||
console.log("store.state.user.basicInfo",store.state.user.basicInfo)
|
||||
const welcome = '祝你开心每一天!';
|
||||
|
||||
const projectItems = [
|
||||
{ title: 'Ant Design Vue', avatar: 'https://aliyuncdn.antdv.com/favicon.ico', description: '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', author: '中二少女团', datetime: '几秒前' },
|
||||
{ title: 'Ant Design Pro', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', description: '那时候我只会想自己想要什么,从不想自己拥有什么', author: '程序员日常', datetime: '7年前' },
|
||||
{ title: 'Fastapi', avatar: 'https://fastapi.tiangolo.com/img/favicon.png', description: '那是一种内在的东西,他们到达不了,也无法触及的', author: '科学搬砖组', datetime: '几秒前' },
|
||||
{ title: 'Vite', avatar: 'https://vitejs.dev/logo.svg', description: '生命就像一盒巧克力,结果往往出人意料', author: '骗你来学计算机', datetime: '7年前' },
|
||||
{ title: 'Vue', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', description: '希望是一个好东西,也许是最好的,好东西是不会消亡的', author: '全组都是吴彦祖', datetime: '几秒前' },
|
||||
{ title: 'Python', avatar: 'https://python.p2hp.com/static/favicon.ico', description: '人生苦短,我用Python', author: '高逼格语言天团', datetime: '7年前' }
|
||||
]
|
||||
|
||||
const activities = [
|
||||
{
|
||||
username: '曲丽丽',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
|
||||
project: '高逼格设计天团',
|
||||
action: '新建项目',
|
||||
event: '六月迭代'
|
||||
},
|
||||
{
|
||||
username: '付小小',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/cnrhVkzwxjPwAaCfPbdc.png',
|
||||
project: '高逼格设计天团',
|
||||
action: '更新项目',
|
||||
event: '六月迭代'
|
||||
},
|
||||
{
|
||||
username: '林东东',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/gaOngJwsRYRaVAuXXcmB.png',
|
||||
project: '中二少女团',
|
||||
action: '新建项目',
|
||||
event: '六月迭代'
|
||||
},
|
||||
{
|
||||
username: '周星星',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/WhxKECPNujWoWEFNdnJE.png',
|
||||
project: '白鹭酱油开发组',
|
||||
action: '更新项目',
|
||||
event: '番组计划'
|
||||
},
|
||||
{
|
||||
username: '朱偏右',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ubnKSIfAJTxIgXOKlciN.png',
|
||||
project: '工程效能',
|
||||
action: '发布了',
|
||||
event: '留言'
|
||||
}
|
||||
// ,{
|
||||
// username: '乐哥',
|
||||
// avatar: 'https://gw.alipayobjects.com/zos/rmsportal/jZUIxmJycoymBprLOUbT.png',
|
||||
// project: '程序员日常',
|
||||
// action: '新建项目',
|
||||
// event: '品牌迭代'
|
||||
// }
|
||||
];
|
||||
|
||||
const chartOptions = {
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
icon: 'path://M773.12 870.4c-163.84 0-225.28-184.32-276.48-343.04C440.32 363.52 399.36 256 312.32 256 225.28 256 179.2 256 102.4 558.08c-5.12 25.6-35.84 46.08-61.44 35.84-25.6-5.12-46.08-35.84-35.84-61.44C76.8 230.4 143.36 153.6 312.32 153.6c163.84 0 225.28 184.32 276.48 343.04 56.32 163.84 97.28 271.36 184.32 271.36 40.96 0 117.76 0 143.36-174.08 5.12-25.6 30.72-46.08 56.32-40.96 25.6 5.12 46.08 30.72 40.96 56.32-20.48 174.08-102.4 261.12-240.64 261.12z',
|
||||
data: ['个人', '团队', '部门'],
|
||||
bottom: 10,
|
||||
itemHeight: 7,
|
||||
},
|
||||
radar: {
|
||||
shape: 'circle',
|
||||
indicator: [
|
||||
{ name: '引用', max: 10 },
|
||||
{ name: '热度', max: 10 },
|
||||
{ name: '贡献', max: 10 },
|
||||
{ name: '产量', max: 10 },
|
||||
{ name: '口碑', max: 10 }
|
||||
]
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Budget vs spending',
|
||||
type: 'radar',
|
||||
areaStyle: {},
|
||||
symbol: 'none',
|
||||
emphasis: {
|
||||
focus: 'self'
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: [10, 7, 5, 4, 8],
|
||||
name: '个人'
|
||||
},
|
||||
{
|
||||
value: [3, 1, 3, 6, 9],
|
||||
name: '团队'
|
||||
},
|
||||
{
|
||||
value: [4, 7, 5, 6, 1],
|
||||
name: '部门'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const teams = [
|
||||
{ avatar: 'https://aliyuncdn.antdv.com/favicon.ico', name: '中二少女团' },
|
||||
{ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', name: '程序员日常' },
|
||||
{ avatar: 'https://fastapi.tiangolo.com/img/favicon.png', name: '科学搬砖组' },
|
||||
{ avatar: 'https://vitejs.dev/logo.svg', name: '骗你来学计算机' },
|
||||
{ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', name: '全组都是吴彦祖' },
|
||||
{ avatar: 'https://python.p2hp.com/static/favicon.ico', name: '高逼格语言天团' }
|
||||
]
|
||||
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 500);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.stat-item:not(:last-child)::after {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 0;
|
||||
width: 1px;
|
||||
height: 45px;
|
||||
background-color: rgba(5, 5, 5, 0.06);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
padding: 0 25px;
|
||||
}
|
||||
|
||||
.project-item {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.item-datetime {
|
||||
float: right;
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.a-hover:hover {
|
||||
color: #1890ff !important;
|
||||
}
|
||||
|
||||
:deep(.ant-list-item-meta-content) {
|
||||
h4 {
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 450px;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.members {
|
||||
a {
|
||||
display: block;
|
||||
margin: 12px 0;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
|
||||
.member {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
line-height: 24px;
|
||||
max-width: 100px;
|
||||
vertical-align: top;
|
||||
margin-left: 12px;
|
||||
transition: all 0.3s;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
span {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user