Files
backmanagerweb/src/components/home.vue
ChoChoX 9fe8130994 push
2026-06-30 23:10:56 +08:00

316 lines
7.9 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="workspace-container">
<!-- 顶部视频横幅 -->
<div class="video-banner">
<video src="/首页顶图.mp4" autoplay muted loop class="bg-video"></video>
<div class="video-overlay">
<div class="welcome-text">
<h2 class="banner-title">欢迎回来{{ userInfo?.name || '用户' }}</h2>
<p class="welcome-sub">{{ userInfo?.departmentDesc }} · {{ roleName }}</p>
<p class="welcome-date">{{ currentDate }}</p>
</div>
</div>
</div>
<!-- 功能卡片网格 -->
<div class="card-grid">
<div
v-for="card in visibleCards"
:key="card.route"
class="function-card"
:style="{ borderTopColor: themeColor, '--hover-bg': themeBg }"
@click="navigateTo(card.route)"
>
<div class="card-icon" :style="{ background: themeBg, color: themeColor }">
<el-icon :size="28"><component :is="card.icon" /></el-icon>
</div>
<div class="card-content">
<h3 class="card-title">{{ card.title }}</h3>
<p class="card-desc">{{ card.description }}</p>
</div>
<div class="card-arrow">
<el-icon :style="{ color: themeColor }"><ArrowRight /></el-icon>
</div>
</div>
</div>
<!-- 快捷信息 -->
<div class="info-section">
<el-row :gutter="20">
<el-col :span="12">
<el-card shadow="hover" class="info-card">
<template #header>
<div class="info-card-header">
<span>我的信息</span>
</div>
</template>
<div class="info-item">
<span class="info-label">用户名</span>
<span>{{ userInfo?.username }}</span>
</div>
<div class="info-item">
<span class="info-label">部门</span>
<span>{{ userInfo?.departmentDesc }}</span>
</div>
<div class="info-item">
<span class="info-label">角色</span>
<span>{{ roleName }}</span>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="hover" class="info-card">
<template #header>
<div class="info-card-header">
<span>快速操作</span>
</div>
</template>
<div class="quick-actions">
<el-button
v-for="card in visibleCards.slice(0, 3)"
:key="card.route"
:style="{ borderColor: themeColor, color: themeColor }"
@click="navigateTo(card.route)"
plain
>
{{ card.title }}
</el-button>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import { getUserInfo, hasPermission, getRoleLevel, isManager } from '../store/user'
const router = useRouter()
const userInfo = computed(() => getUserInfo())
const roleLevel = computed(() => getRoleLevel())
// 主题色
const themeColor = computed(() => roleLevel.value <= 3 ? '#E60012' : '#FF8C69')
const themeBg = computed(() => roleLevel.value <= 3 ? '#FEF0F0' : '#FFF5F0')
const bannerBg = computed(() => roleLevel.value <= 3
? 'linear-gradient(135deg, #FEF0F0 0%, #FFF5F5 100%)'
: 'linear-gradient(135deg, #FFF5F0 0%, #FFFAF5 100%)')
// 角色名称
const roleName = computed(() => {
const level = roleLevel.value
if (level === 1) return '总经理'
if (level === 2) return '部门经理'
if (level === 3) return '部门副经理'
return '一般专员'
})
// 当前日期
const currentDate = computed(() => {
const d = new Date()
const days = ['日', '一', '二', '三', '四', '五', '六']
return `${d.getFullYear()}${d.getMonth() + 1}${d.getDate()}日 星期${days[d.getDay()]}`
})
// 功能卡片定义
const allCards = [
{ title: '客户管理', description: '管理加盟商信息、联系方式、地址等', icon: 'Avatar', route: '/panel/customer', permission: ['customer', 'read'] },
{ title: '合同管理', description: '管理加盟合同和采购合同', icon: 'Document', route: '/panel/contract', permission: ['contract', 'read'] },
{ title: '售后管理', description: '处理客户反馈和售后服务', icon: 'Service', route: '/panel/service', permission: ['after_sale', 'read'] },
{ title: '产品管理', description: '管理茶饮原料、包装物料、设备', icon: 'Goods', route: '/panel/products', permission: ['product', 'read'] },
{ title: '供应商管理', description: '管理供应商信息和合作关系', icon: 'Box', route: '/panel/supplier', permission: ['supplier', 'read'] },
{ title: '员工管理', description: '管理员工信息、部门、职务', icon: 'User', route: '/panel/employee', permission: ['employee', 'read'] },
{ title: '用户管理', description: '管理系统用户账号和权限', icon: 'UserFilled', route: '/panel/user', permission: ['user', 'manage'] },
]
// 根据权限过滤可见卡片
const visibleCards = computed(() => {
return allCards.filter(card => hasPermission(card.permission[0], card.permission[1]))
})
// 导航
const navigateTo = (route) => {
router.push(route)
}
</script>
<style scoped>
.workspace-container {
max-width: 1200px;
margin: 0 auto;
}
/* ========== 视频横幅 ========== */
.video-banner {
position: relative;
width: calc(100% + 40px);
margin: -20px -20px 20px -20px;
height: 260px;
overflow: hidden;
border-radius: 0 0 12px 12px;
}
.bg-video {
width: 100%;
height: 100%;
object-fit: cover;
}
.video-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
to bottom,
rgba(230, 0, 18, 0.3) 0%,
rgba(0, 0, 0, 0.5) 100%
);
display: flex;
align-items: center;
justify-content: center;
}
.welcome-text {
text-align: center;
}
.banner-title {
color: #fff;
font-size: 28px;
font-weight: 600;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
margin: 0 0 8px 0;
}
.welcome-sub {
margin: 0 0 4px 0;
color: rgba(255,255,255,0.9);
font-size: 16px;
}
.welcome-date {
margin: 0;
color: rgba(255,255,255,0.7);
font-size: 14px;
}
/* ========== 功能卡片网格 ========== */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.function-card {
background: #fff;
border-radius: 12px;
padding: 24px;
border-top: 3px solid #E60012;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
display: flex;
align-items: center;
gap: 16px;
cursor: pointer;
transition: all 0.3s ease;
}
.function-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
background: var(--hover-bg, #FEF0F0);
}
.card-icon {
width: 56px;
height: 56px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.card-content {
flex: 1;
min-width: 0;
}
.card-title {
margin: 0 0 4px 0;
font-size: 16px;
font-weight: 600;
color: #303133;
}
.card-desc {
margin: 0;
font-size: 13px;
color: #909399;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card-arrow {
flex-shrink: 0;
opacity: 0;
transition: opacity 0.3s;
}
.function-card:hover .card-arrow {
opacity: 1;
}
/* ========== 信息区域 ========== */
.info-section {
margin-bottom: 20px;
}
.info-card {
height: 100%;
}
.info-card-header {
font-weight: 600;
}
.info-item {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px dashed #eee;
font-size: 14px;
}
.info-item:last-child {
border-bottom: none;
}
.info-label {
color: #909399;
}
.quick-actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
/* ========== 响应式 ========== */
@media (max-width: 768px) {
.card-grid {
grid-template-columns: 1fr;
}
.welcome-banner {
padding: 20px;
}
}
</style>