mirror of https://github.com/veypi/OneAuth.git
feat: change auth check
parent
96acf05fb6
commit
ada216cfd5
@ -1,696 +1,9 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>项目与用户管理 Dashboard</title>
|
|
||||||
<script src="/assets/libs/echarts.min.js"></script>
|
|
||||||
</head>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard {
|
|
||||||
max-width: 1400px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header h1 {
|
|
||||||
font-size: 28px;
|
|
||||||
color: #2c3e50;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header .date {
|
|
||||||
color: #7f8c8d;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
gap: 20px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
transition: transform 0.3s, box-shadow 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .icon {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .value {
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .label {
|
|
||||||
color: #7f8c8d;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card .trend {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trend.up {
|
|
||||||
color: #2ecc71;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trend.down {
|
|
||||||
color: #e74c3c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.charts-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: 20px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-container {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-container h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #2c3e50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart {
|
|
||||||
width: 100%;
|
|
||||||
height: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.recent-activities {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.recent-activities h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #2c3e50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-item {
|
|
||||||
display: flex;
|
|
||||||
padding: 15px 0;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-item:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-icon {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #f1f5f9;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-right: 15px;
|
|
||||||
color: #3b82f6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-content {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-title {
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-time {
|
|
||||||
color: #7f8c8d;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 3px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge-primary {
|
|
||||||
background: #e3f2fd;
|
|
||||||
color: #1976d2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge-success {
|
|
||||||
background: #e8f5e9;
|
|
||||||
color: #388e3c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge-warning {
|
|
||||||
background: #fff8e1;
|
|
||||||
color: #ffa000;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="dashboard">
|
hello
|
||||||
<div class="header">
|
</body>
|
||||||
<h1>项目与用户管理 Dashboard</h1>
|
|
||||||
<div class="date">{{ currentDate }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stats-grid">
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="icon" style="background: #e3f2fd; color: #1976d2;">
|
|
||||||
<i class="bi bi-people"></i>
|
|
||||||
</div>
|
|
||||||
<div class="value">{{ totalUsers }}</div>
|
|
||||||
<div class="label">总用户数</div>
|
|
||||||
<div class="trend up">
|
|
||||||
<i class="bi bi-arrow-up"></i> {{ userGrowthRate }}% 较上月
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="icon" style="background: #e8f5e9; color: #388e3c;">
|
|
||||||
<i class="bi bi-folder"></i>
|
|
||||||
</div>
|
|
||||||
<div class="value">{{ activeProjects }}</div>
|
|
||||||
<div class="label">活跃项目</div>
|
|
||||||
<div class="trend up">
|
|
||||||
<i class="bi bi-arrow-up"></i> {{ projectGrowthRate }}% 较上月
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="icon" style="background: #fff8e1; color: #ffa000;">
|
|
||||||
<i class="bi bi-clock-history"></i>
|
|
||||||
</div>
|
|
||||||
<div class="value">{{ pendingTasks }}</div>
|
|
||||||
<div class="label">待处理任务</div>
|
|
||||||
<div class="trend down">
|
|
||||||
<i class="bi bi-arrow-down"></i> {{ taskChangeRate }}% 较上周
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="icon" style="background: #f3e5f5; color: #8e24aa;">
|
|
||||||
<i class="bi bi-graph-up"></i>
|
|
||||||
</div>
|
|
||||||
<div class="value">{{ completionRate }}%</div>
|
|
||||||
<div class="label">项目完成率</div>
|
|
||||||
<div class="trend up">
|
|
||||||
<i class="bi bi-arrow-up"></i> {{ completionRateChange }}% 较上月
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="charts-grid">
|
|
||||||
<div class="chart-container">
|
|
||||||
<h2>用户增长趋势</h2>
|
|
||||||
<div id="userGrowthChart" class="chart"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="chart-container">
|
|
||||||
<h2>项目状态分布</h2>
|
|
||||||
<div id="projectStatusChart" class="chart"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="charts-grid">
|
|
||||||
<div class="chart-container">
|
|
||||||
<h2>用户活跃度</h2>
|
|
||||||
<div id="userActivityChart" class="chart"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="chart-container">
|
|
||||||
<h2>任务完成情况</h2>
|
|
||||||
<div id="taskCompletionChart" class="chart"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="recent-activities">
|
|
||||||
<h2>最近活动</h2>
|
|
||||||
<div v-for="activity in recentActivities" class="activity-item">
|
|
||||||
<div class="activity-icon">
|
|
||||||
<i :class="'bi bi-' + activity.icon"></i>
|
|
||||||
</div>
|
|
||||||
<div class="activity-content">
|
|
||||||
<div class="activity-title">
|
|
||||||
{{ activity.title }}
|
|
||||||
<span v-if="activity.type" :class="'badge badge-' + activity.type">{{ activity.typeLabel }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="activity-time">{{ activity.time }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
// 统计数据
|
|
||||||
totalUsers = 1248;
|
|
||||||
activeProjects = 86;
|
|
||||||
pendingTasks = 342;
|
|
||||||
completionRate = 78;
|
|
||||||
|
|
||||||
// 增长率
|
|
||||||
userGrowthRate = 12.5;
|
|
||||||
projectGrowthRate = 8.3;
|
|
||||||
taskChangeRate = 5.2;
|
|
||||||
completionRateChange = 3.7;
|
|
||||||
|
|
||||||
// 当前日期
|
|
||||||
currentDate = new Date().toLocaleDateString('zh-CN', {
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric',
|
|
||||||
weekday: 'long'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 最近活动数据
|
|
||||||
recentActivities = [
|
|
||||||
{
|
|
||||||
icon: 'plus-circle',
|
|
||||||
title: '新用户 "张小明" 注册',
|
|
||||||
type: 'primary',
|
|
||||||
typeLabel: '用户',
|
|
||||||
time: '10分钟前'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'folder-plus',
|
|
||||||
title: '新项目 "电商平台重构" 创建',
|
|
||||||
type: 'success',
|
|
||||||
typeLabel: '项目',
|
|
||||||
time: '35分钟前'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'check-circle',
|
|
||||||
title: '项目 "CRM系统升级" 完成',
|
|
||||||
type: 'success',
|
|
||||||
typeLabel: '项目',
|
|
||||||
time: '2小时前'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'exclamation-triangle',
|
|
||||||
title: '任务 "用户权限模块" 逾期',
|
|
||||||
type: 'warning',
|
|
||||||
typeLabel: '任务',
|
|
||||||
time: '5小时前'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'person-plus',
|
|
||||||
title: '团队成员 "李华" 加入项目',
|
|
||||||
type: 'primary',
|
|
||||||
typeLabel: '团队',
|
|
||||||
time: '昨天'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// 图表数据
|
|
||||||
userGrowthData = {
|
|
||||||
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'],
|
|
||||||
values: [820, 890, 920, 950, 1020, 1120, 1248]
|
|
||||||
};
|
|
||||||
|
|
||||||
projectStatusData = [
|
|
||||||
{value: 32, name: '进行中'},
|
|
||||||
{value: 24, name: '已完成'},
|
|
||||||
{value: 18, name: '规划中'},
|
|
||||||
{value: 12, name: '已暂停'}
|
|
||||||
];
|
|
||||||
|
|
||||||
userActivityData = {
|
|
||||||
days: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
|
||||||
activeUsers: [420, 532, 601, 534, 630, 410, 320],
|
|
||||||
newUsers: [120, 132, 101, 134, 90, 60, 40]
|
|
||||||
};
|
|
||||||
|
|
||||||
taskCompletionData = {
|
|
||||||
weeks: ['第1周', '第2周', '第3周', '第4周'],
|
|
||||||
completed: [120, 132, 101, 134],
|
|
||||||
pending: [80, 60, 90, 70]
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// 初始化图表
|
|
||||||
function initCharts() {
|
|
||||||
// 用户增长趋势图
|
|
||||||
const userGrowthChart = echarts.init(document.getElementById('userGrowthChart'));
|
|
||||||
userGrowthChart.setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: $data.userGrowthData.months,
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#9ca3af'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: '#6b7280'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#9ca3af'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: '#6b7280'
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#e5e7eb'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
series: [{
|
|
||||||
data: $data.userGrowthData.values,
|
|
||||||
type: 'line',
|
|
||||||
smooth: true,
|
|
||||||
lineStyle: {
|
|
||||||
width: 4,
|
|
||||||
color: '#3b82f6'
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
color: '#3b82f6',
|
|
||||||
borderWidth: 2
|
|
||||||
},
|
|
||||||
areaStyle: {
|
|
||||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
||||||
{
|
|
||||||
offset: 0,
|
|
||||||
color: 'rgba(59, 130, 246, 0.5)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offset: 1,
|
|
||||||
color: 'rgba(59, 130, 246, 0.1)'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 项目状态分布图
|
|
||||||
const projectStatusChart = echarts.init(document.getElementById('projectStatusChart'));
|
|
||||||
projectStatusChart.setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
orient: 'vertical',
|
|
||||||
right: 10,
|
|
||||||
top: 'center',
|
|
||||||
textStyle: {
|
|
||||||
color: '#6b7280'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '项目状态',
|
|
||||||
type: 'pie',
|
|
||||||
radius: ['40%', '70%'],
|
|
||||||
avoidLabelOverlap: false,
|
|
||||||
itemStyle: {
|
|
||||||
borderRadius: 10,
|
|
||||||
borderColor: '#fff',
|
|
||||||
borderWidth: 2
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
show: false,
|
|
||||||
position: 'center'
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
fontSize: '18',
|
|
||||||
fontWeight: 'bold'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
data: $data.projectStatusData.map((item, index) => ({
|
|
||||||
value: item.value,
|
|
||||||
name: item.name,
|
|
||||||
itemStyle: {
|
|
||||||
color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6'][index]
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 用户活跃度图
|
|
||||||
const userActivityChart = echarts.init(document.getElementById('userActivityChart'));
|
|
||||||
userActivityChart.setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'cross',
|
|
||||||
label: {
|
|
||||||
backgroundColor: '#6a7985'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
data: ['活跃用户', '新增用户'],
|
|
||||||
textStyle: {
|
|
||||||
color: '#6b7280'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '3%',
|
|
||||||
right: '4%',
|
|
||||||
bottom: '3%',
|
|
||||||
containLabel: true
|
|
||||||
},
|
|
||||||
xAxis: [
|
|
||||||
{
|
|
||||||
type: 'category',
|
|
||||||
boundaryGap: false,
|
|
||||||
data: $data.userActivityData.days,
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#9ca3af'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: '#6b7280'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
type: 'value',
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#9ca3af'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: '#6b7280'
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#e5e7eb'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '活跃用户',
|
|
||||||
type: 'line',
|
|
||||||
stack: 'Total',
|
|
||||||
smooth: true,
|
|
||||||
lineStyle: {
|
|
||||||
width: 0
|
|
||||||
},
|
|
||||||
showSymbol: false,
|
|
||||||
areaStyle: {
|
|
||||||
opacity: 0.8,
|
|
||||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
||||||
{
|
|
||||||
offset: 0,
|
|
||||||
color: 'rgba(59, 130, 246, 0.8)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offset: 1,
|
|
||||||
color: 'rgba(59, 130, 246, 0.1)'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: $data.userActivityData.activeUsers
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '新增用户',
|
|
||||||
type: 'line',
|
|
||||||
stack: 'Total',
|
|
||||||
smooth: true,
|
|
||||||
lineStyle: {
|
|
||||||
width: 0
|
|
||||||
},
|
|
||||||
showSymbol: false,
|
|
||||||
areaStyle: {
|
|
||||||
opacity: 0.8,
|
|
||||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
||||||
{
|
|
||||||
offset: 0,
|
|
||||||
color: 'rgba(16, 185, 129, 0.8)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offset: 1,
|
|
||||||
color: 'rgba(16, 185, 129, 0.1)'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: $data.userActivityData.newUsers
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 任务完成情况图
|
|
||||||
const taskCompletionChart = echarts.init(document.getElementById('taskCompletionChart'));
|
|
||||||
taskCompletionChart.setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
data: ['已完成', '待处理'],
|
|
||||||
textStyle: {
|
|
||||||
color: '#6b7280'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '3%',
|
|
||||||
right: '4%',
|
|
||||||
bottom: '3%',
|
|
||||||
containLabel: true
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: $data.taskCompletionData.weeks,
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#9ca3af'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: '#6b7280'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#9ca3af'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: '#6b7280'
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#e5e7eb'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '已完成',
|
|
||||||
type: 'bar',
|
|
||||||
stack: 'total',
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: $data.taskCompletionData.completed,
|
|
||||||
itemStyle: {
|
|
||||||
color: '#10b981'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '待处理',
|
|
||||||
type: 'bar',
|
|
||||||
stack: 'total',
|
|
||||||
emphasis: {
|
|
||||||
focus: 'series'
|
|
||||||
},
|
|
||||||
data: $data.taskCompletionData.pending,
|
|
||||||
itemStyle: {
|
|
||||||
color: '#f59e0b'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 窗口大小变化时重新调整图表大小
|
|
||||||
window.addEventListener('resize', function () {
|
|
||||||
userGrowthChart.resize();
|
|
||||||
projectStatusChart.resize();
|
|
||||||
userActivityChart.resize();
|
|
||||||
taskCompletionChart.resize();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面加载完成后初始化图表
|
</html>
|
||||||
initCharts()
|
|
||||||
</script>
|
|
||||||
|
|||||||
@ -0,0 +1,696 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>项目与用户管理 Dashboard</title>
|
||||||
|
<script src="/assets/libs/echarts.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header .date {
|
||||||
|
color: #7f8c8d;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
||||||
|
transition: transform 0.3s, box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .value {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .label {
|
||||||
|
color: #7f8c8d;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .trend {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend.up {
|
||||||
|
color: #2ecc71;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend.down {
|
||||||
|
color: #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.charts-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-activities {
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-activities h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 15px 0;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #f1f5f9;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 15px;
|
||||||
|
color: #3b82f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-time {
|
||||||
|
color: #7f8c8d;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-primary {
|
||||||
|
background: #e3f2fd;
|
||||||
|
color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-success {
|
||||||
|
background: #e8f5e9;
|
||||||
|
color: #388e3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-warning {
|
||||||
|
background: #fff8e1;
|
||||||
|
color: #ffa000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="dashboard">
|
||||||
|
<div class="header">
|
||||||
|
<h1>项目与用户管理 Dashboard</h1>
|
||||||
|
<div class="date">{{ currentDate }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="stats-grid">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="icon" style="background: #e3f2fd; color: #1976d2;">
|
||||||
|
<i class="bi bi-people"></i>
|
||||||
|
</div>
|
||||||
|
<div class="value">{{ totalUsers }}</div>
|
||||||
|
<div class="label">总用户数</div>
|
||||||
|
<div class="trend up">
|
||||||
|
<i class="bi bi-arrow-up"></i> {{ userGrowthRate }}% 较上月
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="icon" style="background: #e8f5e9; color: #388e3c;">
|
||||||
|
<i class="bi bi-folder"></i>
|
||||||
|
</div>
|
||||||
|
<div class="value">{{ activeProjects }}</div>
|
||||||
|
<div class="label">活跃项目</div>
|
||||||
|
<div class="trend up">
|
||||||
|
<i class="bi bi-arrow-up"></i> {{ projectGrowthRate }}% 较上月
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="icon" style="background: #fff8e1; color: #ffa000;">
|
||||||
|
<i class="bi bi-clock-history"></i>
|
||||||
|
</div>
|
||||||
|
<div class="value">{{ pendingTasks }}</div>
|
||||||
|
<div class="label">待处理任务</div>
|
||||||
|
<div class="trend down">
|
||||||
|
<i class="bi bi-arrow-down"></i> {{ taskChangeRate }}% 较上周
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="icon" style="background: #f3e5f5; color: #8e24aa;">
|
||||||
|
<i class="bi bi-graph-up"></i>
|
||||||
|
</div>
|
||||||
|
<div class="value">{{ completionRate }}%</div>
|
||||||
|
<div class="label">项目完成率</div>
|
||||||
|
<div class="trend up">
|
||||||
|
<i class="bi bi-arrow-up"></i> {{ completionRateChange }}% 较上月
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="charts-grid">
|
||||||
|
<div class="chart-container">
|
||||||
|
<h2>用户增长趋势</h2>
|
||||||
|
<div id="userGrowthChart" class="chart"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chart-container">
|
||||||
|
<h2>项目状态分布</h2>
|
||||||
|
<div id="projectStatusChart" class="chart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="charts-grid">
|
||||||
|
<div class="chart-container">
|
||||||
|
<h2>用户活跃度</h2>
|
||||||
|
<div id="userActivityChart" class="chart"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chart-container">
|
||||||
|
<h2>任务完成情况</h2>
|
||||||
|
<div id="taskCompletionChart" class="chart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="recent-activities">
|
||||||
|
<h2>最近活动</h2>
|
||||||
|
<div v-for="activity in recentActivities" class="activity-item">
|
||||||
|
<div class="activity-icon">
|
||||||
|
<i :class="'bi bi-' + activity.icon"></i>
|
||||||
|
</div>
|
||||||
|
<div class="activity-content">
|
||||||
|
<div class="activity-title">
|
||||||
|
{{ activity.title }}
|
||||||
|
<span v-if="activity.type" :class="'badge badge-' + activity.type">{{ activity.typeLabel }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="activity-time">{{ activity.time }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// 统计数据
|
||||||
|
totalUsers = 1248;
|
||||||
|
activeProjects = 86;
|
||||||
|
pendingTasks = 342;
|
||||||
|
completionRate = 78;
|
||||||
|
|
||||||
|
// 增长率
|
||||||
|
userGrowthRate = 12.5;
|
||||||
|
projectGrowthRate = 8.3;
|
||||||
|
taskChangeRate = 5.2;
|
||||||
|
completionRateChange = 3.7;
|
||||||
|
|
||||||
|
// 当前日期
|
||||||
|
currentDate = new Date().toLocaleDateString('zh-CN', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
weekday: 'long'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 最近活动数据
|
||||||
|
recentActivities = [
|
||||||
|
{
|
||||||
|
icon: 'plus-circle',
|
||||||
|
title: '新用户 "张小明" 注册',
|
||||||
|
type: 'primary',
|
||||||
|
typeLabel: '用户',
|
||||||
|
time: '10分钟前'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'folder-plus',
|
||||||
|
title: '新项目 "电商平台重构" 创建',
|
||||||
|
type: 'success',
|
||||||
|
typeLabel: '项目',
|
||||||
|
time: '35分钟前'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'check-circle',
|
||||||
|
title: '项目 "CRM系统升级" 完成',
|
||||||
|
type: 'success',
|
||||||
|
typeLabel: '项目',
|
||||||
|
time: '2小时前'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'exclamation-triangle',
|
||||||
|
title: '任务 "用户权限模块" 逾期',
|
||||||
|
type: 'warning',
|
||||||
|
typeLabel: '任务',
|
||||||
|
time: '5小时前'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'person-plus',
|
||||||
|
title: '团队成员 "李华" 加入项目',
|
||||||
|
type: 'primary',
|
||||||
|
typeLabel: '团队',
|
||||||
|
time: '昨天'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 图表数据
|
||||||
|
userGrowthData = {
|
||||||
|
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'],
|
||||||
|
values: [820, 890, 920, 950, 1020, 1120, 1248]
|
||||||
|
};
|
||||||
|
|
||||||
|
projectStatusData = [
|
||||||
|
{value: 32, name: '进行中'},
|
||||||
|
{value: 24, name: '已完成'},
|
||||||
|
{value: 18, name: '规划中'},
|
||||||
|
{value: 12, name: '已暂停'}
|
||||||
|
];
|
||||||
|
|
||||||
|
userActivityData = {
|
||||||
|
days: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||||||
|
activeUsers: [420, 532, 601, 534, 630, 410, 320],
|
||||||
|
newUsers: [120, 132, 101, 134, 90, 60, 40]
|
||||||
|
};
|
||||||
|
|
||||||
|
taskCompletionData = {
|
||||||
|
weeks: ['第1周', '第2周', '第3周', '第4周'],
|
||||||
|
completed: [120, 132, 101, 134],
|
||||||
|
pending: [80, 60, 90, 70]
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 初始化图表
|
||||||
|
function initCharts() {
|
||||||
|
// 用户增长趋势图
|
||||||
|
const userGrowthChart = echarts.init(document.getElementById('userGrowthChart'));
|
||||||
|
userGrowthChart.setOption({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: $data.userGrowthData.months,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#9ca3af'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#6b7280'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#9ca3af'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#6b7280'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#e5e7eb'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
data: $data.userGrowthData.values,
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 4,
|
||||||
|
color: '#3b82f6'
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#3b82f6',
|
||||||
|
borderWidth: 2
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(59, 130, 246, 0.5)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(59, 130, 246, 0.1)'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 项目状态分布图
|
||||||
|
const projectStatusChart = echarts.init(document.getElementById('projectStatusChart'));
|
||||||
|
projectStatusChart.setOption({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'vertical',
|
||||||
|
right: 10,
|
||||||
|
top: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#6b7280'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '项目状态',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['40%', '70%'],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: 10,
|
||||||
|
borderColor: '#fff',
|
||||||
|
borderWidth: 2
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
position: 'center'
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
fontSize: '18',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: $data.projectStatusData.map((item, index) => ({
|
||||||
|
value: item.value,
|
||||||
|
name: item.name,
|
||||||
|
itemStyle: {
|
||||||
|
color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6'][index]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 用户活跃度图
|
||||||
|
const userActivityChart = echarts.init(document.getElementById('userActivityChart'));
|
||||||
|
userActivityChart.setOption({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'cross',
|
||||||
|
label: {
|
||||||
|
backgroundColor: '#6a7985'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['活跃用户', '新增用户'],
|
||||||
|
textStyle: {
|
||||||
|
color: '#6b7280'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: $data.userActivityData.days,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#9ca3af'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#6b7280'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#9ca3af'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#6b7280'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#e5e7eb'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '活跃用户',
|
||||||
|
type: 'line',
|
||||||
|
stack: 'Total',
|
||||||
|
smooth: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 0
|
||||||
|
},
|
||||||
|
showSymbol: false,
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.8,
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(59, 130, 246, 0.8)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(59, 130, 246, 0.1)'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: $data.userActivityData.activeUsers
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '新增用户',
|
||||||
|
type: 'line',
|
||||||
|
stack: 'Total',
|
||||||
|
smooth: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 0
|
||||||
|
},
|
||||||
|
showSymbol: false,
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.8,
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(16, 185, 129, 0.8)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(16, 185, 129, 0.1)'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: $data.userActivityData.newUsers
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 任务完成情况图
|
||||||
|
const taskCompletionChart = echarts.init(document.getElementById('taskCompletionChart'));
|
||||||
|
taskCompletionChart.setOption({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['已完成', '待处理'],
|
||||||
|
textStyle: {
|
||||||
|
color: '#6b7280'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: $data.taskCompletionData.weeks,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#9ca3af'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#6b7280'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#9ca3af'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#6b7280'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#e5e7eb'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '已完成',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: $data.taskCompletionData.completed,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#10b981'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '待处理',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: $data.taskCompletionData.pending,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#f59e0b'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 窗口大小变化时重新调整图表大小
|
||||||
|
window.addEventListener('resize', function () {
|
||||||
|
userGrowthChart.resize();
|
||||||
|
projectStatusChart.resize();
|
||||||
|
userActivityChart.resize();
|
||||||
|
taskCompletionChart.resize();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载完成后初始化图表
|
||||||
|
initCharts()
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue