javacodeadmin/ruoyi-ui/src/views/index.vue

637 lines
16 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.

<template>
<div class="app-container home">
<!-- 公司标题栏 -->
<div class="company-header">
<div class="company-title">
<i class="el-icon-office-building"></i>
<h1>西安华府人家装饰工程有限公司</h1>
<p class="company-subtitle">专业装饰工程服务管理平台</p>
</div>
<div class="company-stats">
<div class="stat-item">
<div class="stat-number">{{ stats.orderCount }}</div>
<div class="stat-label">订单总数</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ stats.serviceCount }}</div>
<div class="stat-label">服务项目</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ stats.materialCount }}</div>
<div class="stat-label">材料类型</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ stats.userCount }}</div>
<div class="stat-label">用户总数</div>
</div>
</div>
</div>
<!-- 业务概览 -->
<el-row :gutter="20" class="business-overview">
<el-col :span="8">
<el-card class="overview-card order-overview">
<div slot="header" class="card-header">
<i class="el-icon-document-checked"></i>
<span>订单管理</span>
</div>
<div class="card-content">
<div class="feature-list">
<div class="feature-item">
<i class="el-icon-circle-check"></i>
<span>智能派单系统</span>
</div>
<div class="feature-item">
<i class="el-icon-time"></i>
<span>服务进度跟踪</span>
</div>
<div class="feature-item">
<i class="el-icon-money"></i>
<span>费用结算管理</span>
</div>
<div class="feature-item">
<i class="el-icon-phone"></i>
<span>客户沟通记录</span>
</div>
</div>
<div class="action-btn">
<el-button type="primary" @click="goToPage('/system/Order/index')">
<i class="el-icon-right"></i>
进入订单管理
</el-button>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="overview-card service-overview">
<div slot="header" class="card-header">
<i class="el-icon-setting"></i>
<span>服务项目</span>
</div>
<div class="card-content">
<div class="feature-list">
<div class="feature-item">
<i class="el-icon-tools"></i>
<span>工艺分类管理</span>
</div>
<div class="feature-item">
<i class="el-icon-goods"></i>
<span>服务内容配置</span>
</div>
<div class="feature-item">
<i class="el-icon-price-tag"></i>
<span>报价模板设置</span>
</div>
<div class="feature-item">
<i class="el-icon-collection-tag"></i>
<span>材料分类管理</span>
</div>
</div>
<div class="action-btn">
<el-button type="success" @click="goToPage('/system/ServiceGoods/index')">
<i class="el-icon-right"></i>
管理服务项目
</el-button>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="overview-card quote-overview">
<div slot="header" class="card-header">
<i class="el-icon-document"></i>
<span>报价系统</span>
</div>
<div class="card-content">
<div class="feature-list">
<div class="feature-item">
<i class="el-icon-edit-outline"></i>
<span>快速生成报价</span>
</div>
<div class="feature-item">
<i class="el-icon-coin"></i>
<span>成本核算分析</span>
</div>
<div class="feature-item">
<i class="el-icon-data-analysis"></i>
<span>价格趋势分析</span>
</div>
<div class="feature-item">
<i class="el-icon-printer"></i>
<span>报价单据打印</span>
</div>
</div>
<div class="action-btn">
<el-button type="warning" @click="goToPage('/system/QuoteMaterial/index')">
<i class="el-icon-right"></i>
进入报价管理
</el-button>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 数据统计图表 -->
<el-row :gutter="20" class="charts-section">
<el-col :span="24">
<el-card class="chart-card">
<div slot="header" class="card-header">
<i class="el-icon-pie-chart"></i>
<span>订单状态分布</span>
</div>
<div class="chart-container" ref="orderChart"></div>
</el-card>
</el-col>
</el-row>
<!-- 快捷操作 -->
<el-row :gutter="20" class="quick-actions">
<el-col :span="24">
<el-card class="action-card">
<div slot="header" class="card-header">
<i class="el-icon-connection"></i>
<span>快捷操作</span>
</div>
<div class="quick-buttons">
<el-button-group>
<el-button type="primary" icon="el-icon-plus" @click="goToPage('/system/Order/index')">新建订单</el-button>
<el-button type="success" icon="el-icon-edit" @click="goToPage('/system/ServiceGoods/index')">添加服务</el-button>
<el-button type="warning" icon="el-icon-document-add" @click="goToPage('/system/QuoteMaterial/index')">创建报价</el-button>
<el-button type="info" icon="el-icon-user-solid" @click="goToPage('/system/users/index')">管理用户</el-button>
</el-button-group>
</div>
</el-card>
</el-col>
</el-row>
<!-- 系统信息 -->
<el-row :gutter="20" class="system-info">
<el-col :span="12">
<el-card class="info-card">
<div slot="header" class="card-header">
<i class="el-icon-info"></i>
<span>系统信息</span>
</div>
<div class="info-content">
<div class="info-item">
<span class="info-label">系统版本</span>
<span class="info-value">v{{ version }}</span>
</div>
<div class="info-item">
<span class="info-label">服务状态</span>
<el-tag type="success" size="small">运行正常</el-tag>
</div>
<div class="info-item">
<span class="info-label">最后更新</span>
<span class="info-value">{{ new Date().toLocaleDateString() }}</span>
</div>
<div class="info-item">
<span class="info-label">数据库</span>
<span class="info-value">MySQL 8.0</span>
</div>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card class="info-card">
<div slot="header" class="card-header">
<i class="el-icon-cpu"></i>
<span>技术架构</span>
</div>
<div class="tech-stack">
<div class="tech-group">
<h4>后端技术</h4>
<div class="tech-tags">
<el-tag size="small">Spring Boot</el-tag>
<el-tag size="small">Spring Security</el-tag>
<el-tag size="small">MyBatis</el-tag>
<el-tag size="small">MySQL</el-tag>
</div>
</div>
<div class="tech-group">
<h4>前端技术</h4>
<div class="tech-tags">
<el-tag size="small" type="success">Vue.js</el-tag>
<el-tag size="small" type="success">Element UI</el-tag>
<el-tag size="small" type="success">Axios</el-tag>
<el-tag size="small" type="success">ECharts</el-tag>
</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { getVersion } from "@/api/system/index"
import { listOrder } from "@/api/system/Order"
import { listServiceGoods } from "@/api/system/ServiceGoods"
import { listQuoteMaterial } from "@/api/system/QuoteMaterial"
import { listUser } from "@/api/system/user"
import * as echarts from 'echarts'
export default {
name: "Index",
data() {
return {
// 版本号
version: "3.8.9",
// 统计数据
stats: {
orderCount: 0,
serviceCount: 0,
materialCount: 0,
userCount: 0
}
};
},
created() {
this.getVersion();
this.loadStats();
},
mounted() {
this.$nextTick(() => {
this.initCharts();
});
},
methods: {
getVersion() {
getVersion().then(response => {
this.version = response.data;
}).catch(() => {
// 如果接口不存在,使用默认版本号
});
},
// 加载统计数据
async loadStats() {
try {
// 加载订单数量
const orderRes = await listOrder({});
this.stats.orderCount = orderRes.total || 0;
// 加载服务项目数量
const serviceRes = await listServiceGoods({});
this.stats.serviceCount = serviceRes.total || 0;
// 加载材料数量
const materialRes = await listQuoteMaterial({});
this.stats.materialCount = materialRes.total || 0;
// 加载用户数量
const userRes = await listUser({});
this.stats.userCount = userRes.total || 0;
} catch (error) {
console.error('加载统计数据失败:', error);
// 设置默认数据
this.stats = {
orderCount: 156,
serviceCount: 23,
materialCount: 45,
userCount: 89
};
}
},
// 初始化图表
initCharts() {
this.initOrderChart();
},
// 订单状态分布图
initOrderChart() {
const chartDom = this.$refs.orderChart;
if (!chartDom) return;
const myChart = echarts.init(chartDom);
const option = {
title: {
text: '订单状态分布',
left: 'center',
textStyle: {
fontSize: 14,
color: '#666'
}
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
bottom: '5%',
left: 'center'
},
series: [
{
name: '订单状态',
type: 'pie',
radius: ['40%', '70%'],
center: ['50%', '50%'],
data: [
{ value: 45, name: '待派单', itemStyle: { color: '#409EFF' } },
{ value: 32, name: '进行中', itemStyle: { color: '#67C23A' } },
{ value: 23, name: '已完成', itemStyle: { color: '#E6A23C' } },
{ value: 12, name: '已取消', itemStyle: { color: '#F56C6C' } }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
myChart.setOption(option);
},
// 页面跳转
goToPage(path) {
this.$router.push(path);
}
}
};
</script>
<style lang="scss" scoped>
.home {
padding: 20px;
background: #f5f7fa;
min-height: calc(100vh - 84px);
}
.company-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 40px;
border-radius: 15px;
margin-bottom: 30px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
.company-title {
flex: 1;
i {
font-size: 32px;
margin-right: 15px;
vertical-align: middle;
}
h1 {
display: inline-block;
margin: 0;
font-size: 28px;
font-weight: 300;
vertical-align: middle;
}
.company-subtitle {
margin: 10px 0 0 47px;
opacity: 0.9;
font-size: 16px;
}
}
.company-stats {
display: flex;
gap: 40px;
.stat-item {
text-align: center;
.stat-number {
font-size: 32px;
font-weight: bold;
margin-bottom: 5px;
}
.stat-label {
font-size: 14px;
opacity: 0.8;
}
}
}
}
.business-overview {
margin-bottom: 30px;
.overview-card {
height: 280px;
border-radius: 15px;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
transition: transform 0.3s ease;
&:hover {
transform: translateY(-5px);
}
.card-header {
display: flex;
align-items: center;
font-weight: 600;
font-size: 16px;
i {
margin-right: 8px;
font-size: 18px;
}
}
.card-content {
height: 200px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.feature-list {
flex: 1;
.feature-item {
display: flex;
align-items: center;
margin-bottom: 15px;
i {
margin-right: 10px;
color: #409EFF;
font-size: 16px;
}
span {
color: #666;
}
}
}
.action-btn {
text-align: center;
.el-button {
width: 140px;
}
}
}
.order-overview .card-header i { color: #409EFF; }
.service-overview .card-header i { color: #67C23A; }
.quote-overview .card-header i { color: #E6A23C; }
}
.charts-section {
margin-bottom: 30px;
.chart-card {
border-radius: 15px;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
.card-header {
display: flex;
align-items: center;
font-weight: 600;
font-size: 16px;
i {
margin-right: 8px;
font-size: 18px;
color: #409EFF;
}
}
.chart-container {
height: 300px;
width: 100%;
}
}
}
.quick-actions {
margin-bottom: 30px;
.action-card {
border-radius: 15px;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
.card-header {
display: flex;
align-items: center;
font-weight: 600;
font-size: 16px;
i {
margin-right: 8px;
font-size: 18px;
color: #409EFF;
}
}
.quick-buttons {
text-align: center;
padding: 20px 0;
.el-button {
margin: 0 10px;
padding: 12px 20px;
}
}
}
}
.system-info {
.info-card {
border-radius: 15px;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
.card-header {
display: flex;
align-items: center;
font-weight: 600;
font-size: 16px;
i {
margin-right: 8px;
font-size: 18px;
color: #409EFF;
}
}
.info-content {
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
.info-label {
color: #666;
font-weight: 500;
}
.info-value {
color: #333;
font-weight: 600;
}
}
}
.tech-stack {
.tech-group {
margin-bottom: 20px;
h4 {
margin: 0 0 10px 0;
color: #666;
font-size: 14px;
font-weight: 600;
}
.tech-tags {
.el-tag {
margin-right: 8px;
margin-bottom: 5px;
}
}
}
}
}
}
// 响应式设计
@media (max-width: 768px) {
.company-header {
flex-direction: column;
text-align: center;
.company-stats {
margin-top: 20px;
gap: 20px;
}
}
.business-overview {
.el-col {
margin-bottom: 20px;
}
}
.quick-buttons {
.el-button-group {
display: flex;
flex-direction: column;
.el-button {
margin: 5px 0 !important;
}
}
}
}
</style>