Files
klp-oa/klp-ui/src/views/index.vue
2025-07-22 16:28:43 +08:00

556 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 代码已包含 CSS使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="dashboard-root">
<!-- 第一行头像+欢迎语 -->
<div class="user-greeting-row">
<img :src="avatar" class="user-avatar" alt="头像" />
<div class="greeting-text">
<div class="greeting-title">{{ greeting }}{{ name }}</div>
<div class="greeting-desc">愿你天黑有灯下雨有伞</div>
</div>
</div>
<!-- 数据概览区 -->
<div class="data-overview">
<div v-for="(card, index) in dataCards" :key="index"
class="data-card">
<div class="data-card-header">
<div>
<h3 class="data-card-title">{{ card.title }}</h3>
<p class="data-card-value">{{ card.value }}</p>
</div>
<i :class="['data-card-icon', card.icon, getIconColor(card.color)]"></i>
</div>
<div class="data-card-chart">
<div ref="charts" class="chart-inner"></div>
</div>
</div>
</div>
<!-- 业务功能区 -->
<div class="business-modules">
<div v-for="(module, index) in businessModules" :key="index"
class="business-module" @click="handleLink(module.link)">
<div :class="['business-module-icon', getModuleBg(module.bgColor)]">
<i :class="module.icon"></i>
</div>
<h3 class="business-module-title">{{ module.title }}</h3>
</div>
</div>
<!-- 监控面板 -->
<!-- <div class="monitor-panel">
<div class="monitor-resource">
<h3 class="monitor-title">系统资源监控</h3>
<div class="monitor-resource-charts">
<div v-for="(chart, index) in resourceCharts" :key="index" class="monitor-resource-chart">
<div ref="resourceChart" class="chart-inner"></div>
</div>
</div>
</div>
<div class="monitor-records">
<h3 class="monitor-title">最近操作记录</h3>
<div class="monitor-records-list">
<div v-for="(record, index) in operationRecords" :key="index"
class="monitor-record-item">
<div :class="['monitor-record-icon', getModuleBg(record.bgColor)]">
<i :class="['monitor-record-icon-inner', record.icon]"></i>
</div>
<div>
<p class="monitor-record-action">{{ record.action }}</p>
<p class="monitor-record-time">{{ record.time }}</p>
</div>
</div>
</div>
</div>
</div> -->
<!-- 全部应用 -->
<AllApplications />
</div>
</template>
<script>
import * as echarts from 'echarts';
import AllApplications from '@/views/components/AllApplications.vue';
export default {
components: {
AllApplications
},
data() {
return {
avatar: '',
name: '',
greeting: '',
dataCards: [
{
title: '订单总量',
value: '2,384',
icon: 'fas fa-shopping-cart',
color: 'text-blue-500',
chartData: [30, 40, 20, 50, 40, 60, 70],
},
{
title: '库存总量',
value: '12,857',
icon: 'fas fa-box',
color: 'text-green-500',
chartData: [40, 30, 50, 40, 60, 50, 70],
},
// {
// title: '今日任务',
// value: '48',
// icon: 'fas fa-tasks',
// color: 'text-yellow-500',
// chartData: [20, 40, 30, 50, 40, 60, 50],
// },
{
title: '系统状态',
value: '正常',
icon: 'fas fa-server',
color: 'text-purple-500',
chartData: [50, 30, 40, 50, 60, 70, 60]
}
],
businessModules: [
{
title: '仓库管理',
description: '库存管理与货位管理',
icon: 'fas fa-warehouse',
bgColor: 'bg-blue-500',
link: '/wms/stock'
},
{
title: '订单处理',
description: '订单审核与发货管理',
icon: 'fas fa-clipboard-check',
bgColor: 'bg-green-500',
link: '/wms/order'
},
{
title: '人员管理',
description: '员工信息与权限管理',
icon: 'fas fa-users',
bgColor: 'bg-yellow-500',
link: '/system/user'
},
{
title: '订单分析',
description: '订单数据可视化分析',
icon: 'fas fa-chart-line',
bgColor: 'bg-purple-500',
link: '/wms/order/dashboard'
},
{
title: '出库入库',
description: '出库入库管理',
icon: 'fas fa-tools',
bgColor: 'bg-red-500',
link: '/wms/stcokIo'
},
{
title: '系统设置',
description: '系统参数配置管理',
icon: 'fas fa-cog',
bgColor: 'bg-indigo-500',
link: '/system/setting'
}
],
resourceCharts: [
{ name: 'CPU使用率', value: 65 },
{ name: '内存使用率', value: 45 },
{ name: '存储使用率', value: 78 },
{ name: '网络使用率', value: 32 }
],
operationRecords: [
{
action: '张经理审批了采购订单 #38271',
time: '10分钟前',
icon: 'fas fa-check',
bgColor: 'bg-green-500'
},
{
action: '李工程师更新了系统配置',
time: '25分钟前',
icon: 'fas fa-cog',
bgColor: 'bg-blue-500'
},
{
action: '王主管确认了入库单 #92731',
time: '40分钟前',
icon: 'fas fa-box',
bgColor: 'bg-yellow-500'
},
{
action: '系统完成了日常数据备份',
time: '1小时前',
icon: 'fas fa-database',
bgColor: 'bg-purple-500'
},
{
action: '陈经理导出了月度报表',
time: '2小时前',
icon: 'fas fa-file-export',
bgColor: 'bg-indigo-500'
}
]
};
},
mounted() {
this.initCharts();
this.initResourceCharts();
this.avatar = this.$store.getters.avatar;
this.name = this.$store.getters.name;
this.greeting = this.getGreeting();
},
methods: {
getIconColor(color) {
// 统一映射为自定义 class
switch (color) {
case 'text-blue-500': return 'icon-blue';
case 'text-green-500': return 'icon-green';
case 'text-yellow-500': return 'icon-yellow';
case 'text-purple-500': return 'icon-purple';
default: return '';
}
},
handleLink(item) {
this.$router.push(item);
},
getGreeting() {
const hour = new Date().getHours();
if (hour < 6) return '凌晨好';
if (hour < 9) return '早上好';
if (hour < 12) return '上午好';
if (hour < 14) return '中午好';
if (hour < 18) return '下午好';
if (hour < 21) return '晚上好';
return '夜深了';
},
getModuleBg(bgColor) {
switch (bgColor) {
case 'bg-blue-500': return 'bg-blue';
case 'bg-green-500': return 'bg-green';
case 'bg-yellow-500': return 'bg-yellow';
case 'bg-purple-500': return 'bg-purple';
case 'bg-red-500': return 'bg-red';
case 'bg-indigo-500': return 'bg-indigo';
default: return '';
}
},
initCharts() {
this.$nextTick(() => {
const charts = document.querySelectorAll('.chart-inner');
this.dataCards.forEach((card, index) => {
const chart = echarts.init(charts[index]);
const option = {
animation: false,
grid: {
left: 0,
right: 0,
top: 0,
bottom: 0
},
xAxis: {
type: 'category',
show: false
},
yAxis: {
type: 'value',
show: false
},
series: [{
data: card.chartData,
type: 'line',
smooth: true,
showSymbol: false,
lineStyle: {
color: this.getColor(index)
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: this.getColor(index, 0.2)
}, {
offset: 1,
color: this.getColor(index, 0.1)
}])
}
}]
};
chart.setOption(option);
});
});
},
initResourceCharts() {
this.$nextTick(() => {
const charts = document.querySelectorAll('.monitor-resource-chart .chart-inner');
this.resourceCharts.forEach((item, index) => {
const chart = echarts.init(charts[index]);
const option = {
animation: false,
series: [{
type: 'gauge',
startAngle: 90,
endAngle: -270,
pointer: {
show: false
},
progress: {
show: true,
overlap: false,
roundCap: true,
clip: false,
itemStyle: {
color: this.getColor(index)
}
},
axisLine: {
lineStyle: {
width: 18
}
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
title: {
offsetCenter: [0, '70%'],
fontSize: 14,
color: '#666'
},
detail: {
offsetCenter: [0, '0%'],
valueAnimation: true,
formatter: '{value}% ',
color: '#666'
},
data: [{
value: item.value,
name: item.name
}]
}]
};
chart.setOption(option);
});
});
},
getColor(index, alpha = 1) {
const colors = [
`rgba(59, 130, 246, ${alpha})`,
`rgba(34, 197, 94, ${alpha})`,
`rgba(234, 179, 8, ${alpha})`,
`rgba(168, 85, 247, ${alpha})`
];
return colors[index % colors.length];
}
}
};
</script>
<style scoped>
.dashboard-root {
min-height: 100vh;
background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
padding: 32px;
}
.data-overview {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
margin-bottom: 32px;
}
.data-card {
padding: 24px;
border-radius: 16px;
backdrop-filter: blur(4px);
background: rgba(255,255,255,0.8);
box-shadow: 0 4px 24px 0 rgba(0,0,0,0.06);
border: 1px solid rgba(255,255,255,0.2);
transition: transform 0.2s;
}
.data-card:hover {
transform: scale(1.02);
}
.data-card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 16px;
}
.data-card-title {
color: #6b7280;
font-size: 14px;
margin-bottom: 4px;
}
.data-card-value {
font-size: 24px;
font-weight: 600;
}
.data-card-icon {
font-size: 24px;
}
.icon-blue { color: #3b82f6; }
.icon-green { color: #22c55e; }
.icon-yellow { color: #eab308; }
.icon-purple { color: #a855f7; }
.data-card-chart {
height: 48px;
width: 100%;
}
.chart-inner {
width: 100%;
height: 100%;
}
.business-modules {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 24px;
margin-bottom: 32px;
}
.business-module {
display: flex;
align-items: center;
padding: 16px;
border-radius: 12px;
background: #fff;
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.05);
transition: all 0.2s;
cursor: pointer;
}
.business-module:hover {
box-shadow: 0 4px 16px 0 rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.business-module-icon {
width: 40px;
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-right: 12px;
}
.business-module-icon i {
font-size: 20px;
color: #fff;
}
.bg-blue { background: #3b82f6; }
.bg-green { background: #22c55e; }
.bg-yellow { background: #eab308; }
.bg-purple { background: #a855f7; }
.bg-red { background: #ef4444; }
.bg-indigo { background: #6366f1; }
.business-module-title {
font-size: 16px;
font-weight: 500;
color: #303133;
}
.monitor-panel {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24px;
}
.monitor-resource, .monitor-records {
padding: 24px;
border-radius: 16px;
background: #fff;
box-shadow: 0 4px 24px 0 rgba(0,0,0,0.06);
}
.monitor-title {
font-size: 18px;
font-weight: 500;
margin-bottom: 24px;
}
.monitor-resource-charts {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.monitor-resource-chart {
height: 160px;
}
.monitor-records-list {
display: flex;
flex-direction: column;
gap: 16px;
}
.monitor-record-item {
display: flex;
align-items: center;
padding: 12px;
border-radius: 12px;
transition: background 0.2s;
}
.monitor-record-item:hover {
background: #f9fafb;
}
.monitor-record-icon {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16px;
}
.monitor-record-icon-inner {
font-size: 14px;
color: #fff;
}
.monitor-record-action {
font-size: 14px;
font-weight: 500;
}
.monitor-record-time {
font-size: 12px;
color: #6b7280;
}
.user-greeting-row {
display: flex;
align-items: center;
gap: 24px;
margin-bottom: 24px;
}
.user-avatar {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
border: 2px solid #e0e0e0;
background: #fff;
}
.greeting-text {
display: flex;
flex-direction: column;
justify-content: center;
}
.greeting-title {
font-size: 28px;
font-weight: 600;
color: #333;
}
.greeting-desc {
font-size: 16px;
color: #888;
margin-top: 4px;
}
</style>
<style>
.business-module-header,
.business-module-icon-inner,
.business-module-desc {
display: none;
}
</style>