OfficeSystem/components/ContentDashboard.vue
2025-11-05 11:04:47 +08:00

357 lines
7.4 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>
<scroll-view class="dashboard-scroll" scroll-y>
<!-- 任务概览 -->
<view class="task-overview">
<view class="task-card" v-for="item in taskStats" :key="item.label">
<text class="task-count">{{ item.count }}</text>
<text class="task-label">{{ item.label }}</text>
</view>
</view>
<!-- 逾期任务详情 -->
<view class="overdue-section" v-if="overdueTasks.length > 0">
<view class="overdue-card" v-for="task in overdueTasks" :key="task.id">
<view class="overdue-badge">逾期</view>
<view class="overdue-content">
<text class="overdue-date">{{ task.date }}</text>
<text class="overdue-project">所属项目: {{ task.project }}</text>
<text class="overdue-desc">{{ task.description }}</text>
<text class="overdue-owner">负责人: {{ task.owner }}</text>
<text class="overdue-time">发布时间: {{ task.releaseTime }}</text>
</view>
<view class="overdue-action">
<button class="handle-btn" @click="handleOverdueTask(task)">立即处理</button>
</view>
</view>
<view class="carousel-dots">
<view class="dot" :class="{ active: true }"></view>
<view class="dot"></view>
<view class="dot"></view>
</view>
</view>
<!-- 公告事项 -->
<view class="announcement-section">
<view class="section-header">
<text class="section-icon">📢</text>
<text class="section-title">公告事项</text>
</view>
<view class="announcement-item" v-for="announcement in announcements" :key="announcement.id" @click="viewAnnouncement(announcement)">
<view class="announcement-content">
<text class="announcement-title">{{ announcement.title }}</text>
<text class="announcement-desc">{{ announcement.description }}</text>
<text class="announcement-time">{{ announcement.time }}</text>
</view>
<text class="arrow"></text>
</view>
</view>
<!-- 项目状态 -->
<view class="project-status-section">
<view class="section-header">
<text class="section-icon">💎</text>
<text class="section-title">项目状态</text>
</view>
<view class="status-grid">
<view class="status-card" v-for="status in projectStatus" :key="status.label">
<text class="status-count">{{ status.count }}</text>
<text class="status-label">{{ status.label }}</text>
</view>
</view>
</view>
<!-- 客户状态 -->
<view class="customer-status-section">
<view class="section-header">
<text class="section-icon">👤</text>
<text class="section-title">客户状态</text>
</view>
<view class="status-grid">
<view class="status-card" v-for="status in customerStatus" :key="status.label">
<text class="status-count">{{ status.count }}</text>
<text class="status-label">{{ status.label }}</text>
</view>
</view>
</view>
</scroll-view>
</template>
<script setup>
import { ref } from 'vue';
// 任务统计
const taskStats = ref([
{ label: '完成任务', count: 78 },
{ label: '待完成任务', count: 28 },
{ label: '即将预期', count: 8 },
{ label: '逾期任务', count: 1 }
]);
// 逾期任务
const overdueTasks = ref([
{
id: 1,
date: '2025-10-15',
project: '创特项目管理系统',
description: '项目内容项目内容项目内容项目内容项目内容项目...',
owner: '张珊珊、李志',
releaseTime: '2025-03-21'
}
]);
// 公告事项
const announcements = ref([
{
id: 1,
title: '·国庆放假通知',
description: '国庆放假安排1号至6号,前后不调休...',
time: '2025-09-26 16:54:46'
}
]);
// 项目状态
const projectStatus = ref([
{ label: '运行中', count: 1 },
{ label: '运维中', count: 1 },
{ label: '即将到期', count: 1 },
{ label: '开发超期', count: 1 }
]);
// 客户状态
const customerStatus = ref([
{ label: '今日新增', count: 1 },
{ label: '今日已跟进', count: 1 },
{ label: '今日待跟进', count: 1 },
{ label: '即将跟进', count: 1 }
]);
// 处理逾期任务
const handleOverdueTask = (task) => {
console.log('处理逾期任务:', task);
uni.showToast({
title: '跳转到任务处理',
icon: 'none'
});
};
// 查看公告
const viewAnnouncement = (announcement) => {
console.log('查看公告:', announcement);
uni.showToast({
title: '查看公告详情',
icon: 'none'
});
};
</script>
<style lang="scss" scoped>
.dashboard-scroll {
}
.task-overview {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
gap: 12px;
}
.task-card {
flex: 1;
background: #fff;
border-radius: 8px;
padding: 16px;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.task-count {
font-size: 24px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.task-label {
font-size: 12px;
color: #666;
}
.overdue-section {
margin-bottom: 20px;
}
.overdue-card {
background: #ffe6e6;
border-radius: 8px;
padding: 16px;
margin-bottom: 12px;
display: flex;
align-items: flex-start;
position: relative;
}
.overdue-badge {
position: absolute;
left: 0;
top: 0;
background: #ff4444;
color: #fff;
font-size: 12px;
padding: 4px 8px;
border-radius: 4px 0 0 0;
}
.overdue-content {
flex: 1;
margin-left: 60px;
display: flex;
flex-direction: column;
gap: 8px;
}
.overdue-date {
font-size: 14px;
color: #333;
font-weight: 500;
}
.overdue-project,
.overdue-desc,
.overdue-owner,
.overdue-time {
font-size: 12px;
color: #666;
line-height: 1.5;
}
.overdue-action {
margin-left: 12px;
}
.handle-btn {
background: #ff4444;
color: #fff;
border: none;
border-radius: 4px;
padding: 8px 16px;
font-size: 12px;
}
.carousel-dots {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 8px;
}
.dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: #ddd;
}
.dot.active {
background: #2885ff;
}
.announcement-section,
.project-status-section,
.customer-status-section {
}
.section-header {
display: flex;
align-items: center;
margin-bottom: 12px;
gap: 8px;
}
.section-icon {
font-size: 18px;
}
.section-title {
font-size: 16px;
font-weight: 600;
color: #333;
}
.announcement-item {
background: #fff;
border-radius: 8px;
padding: 16px;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.announcement-content {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
}
.announcement-title {
font-size: 14px;
font-weight: 500;
color: #333;
}
.announcement-desc {
font-size: 12px;
color: #666;
line-height: 1.5;
}
.announcement-time {
font-size: 12px;
color: #999;
}
.arrow {
font-size: 20px;
color: #999;
margin-left: 12px;
}
.status-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
}
.status-card {
background: #fff;
border-radius: 8px;
padding: 16px;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.status-count {
font-size: 20px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.status-label {
font-size: 12px;
color: #666;
text-align: center;
}
</style>