From 1fa6ac40e2ce16e1174cec9ca538d45eeb660fdc Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期四, 05 六月 2025 18:17:56 +0800
Subject: [PATCH] 工作台
---
src/views/workbench.vue | 596 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 596 insertions(+), 0 deletions(-)
diff --git a/src/views/workbench.vue b/src/views/workbench.vue
new file mode 100644
index 0000000..ce8c638
--- /dev/null
+++ b/src/views/workbench.vue
@@ -0,0 +1,596 @@
+<template>
+ <div class="dashboard-container">
+ <!-- 椤堕儴瀵艰埅鏍� -->
+ <div class="top-navbar">
+ <div class="welcome-message">
+ <h2>鏃╁畨锛寋{ this.$store.state.user.name }}锛�</h2>
+ <p>浠婂ぉ鏄瘂{ currentDate }}锛岀鎮ㄥ伐浣滄剦蹇紒</p>
+ </div>
+ <div class="quick-stats">
+ <div class="stat-item">
+ <span class="stat-number">{{ todayTasks }}</span>
+ <span class="stat-label">浠婃棩寰呭姙</span>
+ </div>
+ <div class="stat-item">
+ <span class="stat-number">{{ todaySchedules }}</span>
+ <span class="stat-label">浠婃棩鏃ョ▼</span>
+ </div>
+ <div class="stat-item">
+ <span class="stat-number">{{ unreadMessages }}</span>
+ <span class="stat-label">鏈娑堟伅</span>
+ </div>
+ </div>
+ <div class="user-profile">
+<!-- <el-dropdown>-->
+<!-- <div class="user-avatar">-->
+<!-- <img :src="userInfo.avatar" alt="鐢ㄦ埛澶村儚">-->
+<!-- <span>{{ userInfo.name }}</span>-->
+<!-- </div>-->
+<!-- <el-dropdown-menu slot="dropdown">-->
+<!-- <el-dropdown-item>涓汉涓績</el-dropdown-item>-->
+<!-- <el-dropdown-item>璁剧疆</el-dropdown-item>-->
+<!-- <el-dropdown-item divided>閫�鍑虹櫥褰�</el-dropdown-item>-->
+<!-- </el-dropdown-menu>-->
+<!-- </el-dropdown>-->
+ </div>
+ </div>
+
+ <!-- 涓诲唴瀹瑰尯 -->
+ <div class="main-content">
+ <!-- 宸︿晶椤圭洰鍒楄〃 -->
+ <div class="left-sidebar">
+ <div class="project-list">
+ <h3>椤圭洰鍒楄〃</h3>
+ <el-menu
+ :default-active="activeProject"
+ class="project-menu"
+ @select="handleProjectSelect">
+ <el-menu-item index="all">
+ <i class="el-icon-menu"></i>
+ <span slot="title">鍏ㄩ儴椤圭洰</span>
+ </el-menu-item>
+ <el-menu-item
+ v-for="project in projects"
+ :key="project.id"
+ :index="project.id">
+ <i class="el-icon-folder"></i>
+ <span slot="title" class="project-name" :title="project.name">
+ {{ project.name }}
+ </span>
+ </el-menu-item>
+ </el-menu>
+ <div class="project-actions">
+ <el-button type="primary" icon="el-icon-plus" size="small">鏂板缓椤圭洰</el-button>
+ </div>
+ </div>
+ </div>
+
+ <!-- 涓棿鍐呭鍖� -->
+ <div class="center-content">
+ <!-- 寰呭姙浠诲姟 -->
+ <div class="task-section">
+ <div class="section-header">
+ <h3>寰呭姙浠诲姟</h3>
+ <el-button type="text" icon="el-icon-refresh">鍒锋柊</el-button>
+ </div>
+ <el-table
+ :data="tasks"
+ border
+ style="width: 100%"
+ >
+ <el-table-column
+ prop="name"
+ label="浠诲姟鍚嶇О"
+ width="240">
+ </el-table-column>
+ <el-table-column
+ prop="project"
+ label="鎵�灞為」鐩�"
+ show-overflow-tooltip
+ width="300">
+ </el-table-column>
+ <el-table-column
+ prop="startTime"
+ label="寮�濮嬫椂闂�"
+ align="center"
+ width="160">
+ </el-table-column>
+ <el-table-column
+ prop="deadline"
+ label="鎴鏃堕棿"
+ align="center"
+ width="160">
+ </el-table-column>
+ <el-table-column
+ prop="status"
+ label="鐘舵��"
+ align="center"
+ width="100">
+ <template slot-scope="scope">
+ <el-tag :type="scope.row.status === '寰呭畬鎴�' ? 'success' : 'warning'" size="small">
+ {{ scope.row.status }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鎿嶄綔"
+ fixed="right"
+ width="120">
+ <template slot-scope="scope">
+ <el-button size="mini" @click="handleTaskEdit(scope.row)">鍔炵悊</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <!-- 椤圭洰鍔炵悊鏃ュ織 -->
+ <div class="log-section">
+ <div class="section-header">
+ <h3>椤圭洰鍔炵悊鏃ュ織</h3>
+ <el-button type="text" icon="el-icon-refresh">鍒锋柊</el-button>
+ </div>
+ <div class="log-list">
+ <div v-for="log in logs" :key="log.id" class="log-item">
+ <div class="log-time">{{ log.time }}</div>
+ <div class="log-content">
+ <span class="log-project">{{ log.project }}</span>
+ <span class="log-action">{{ log.action }}</span>
+ <span class="log-detail">{{ log.detail }}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鍙充晶杈规爮 -->
+ <div class="right-sidebar">
+ <!-- 涓汉鎴愬氨 -->
+ <div class="achievement-section">
+ <h3>涓汉鎴愬氨</h3>
+ <div class="achievement-stats">
+ <div class="stat-item">
+ <div class="stat-number">{{ achievements.completedTasks }}</div>
+ <div class="stat-label">瀹屾垚浠诲姟</div>
+ </div>
+ <div class="stat-item">
+ <div class="stat-number">{{ achievements.avgDuration }}澶�</div>
+ <div class="stat-label">骞冲潎鐢ㄦ椂</div>
+ </div>
+ <div class="stat-item">
+ <div class="stat-number">{{ achievements.totalSchedules }}</div>
+ <div class="stat-label">瀹夋帓鏃ョ▼</div>
+ </div>
+ <div class="stat-item">
+ <div class="stat-number">{{ achievements.completedSchedules }}</div>
+ <div class="stat-label">瀹屾垚鏃ョ▼</div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鏃ュ巻 -->
+ <div class="calendar-section">
+ <el-calendar v-model="calendarDate">
+ <template
+ slot="dateCell"
+ slot-scope="{date, data}">
+ <div class="calendar-day">
+ {{ data.day.split('-').slice(2).join('-') }}
+ <div v-if="getScheduleCount(date) > 0" class="schedule-count">
+ {{ getScheduleCount(date) }}涓棩绋�
+ </div>
+ </div>
+ </template>
+ </el-calendar>
+ </div>
+
+ <!-- 鏃ョ▼鍒楄〃 -->
+ <div class="schedule-list-section">
+ <div class="section-header">
+ <h3>鏃ョ▼鍒楄〃</h3>
+ <div>
+ <el-button type="text" icon="el-icon-plus" @click="handleAddSchedule">鏂板</el-button>
+ <el-button type="text" icon="el-icon-refresh">鍒锋柊</el-button>
+ </div>
+ </div>
+ <div class="schedule-list">
+ <el-table
+ :data="filteredSchedules"
+ style="width: 100%"
+ height="250">
+ <el-table-column
+ prop="time"
+ label="鏃堕棿"
+ width="100">
+ </el-table-column>
+ <el-table-column
+ prop="title"
+ label="浜嬮」"
+ width="120">
+ </el-table-column>
+ <el-table-column
+ label="鎿嶄綔"
+ width="120">
+ <template slot-scope="scope">
+ <el-button size="mini" @click="handleEditSchedule(scope.row)">缂栬緫</el-button>
+ <el-button size="mini" type="danger" @click="handleDeleteSchedule(scope.row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ data() {
+ return {
+ userInfo: {
+ name: '寮犲伐绋嬪笀',
+ avatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
+ department: '椤圭洰閮�'
+ },
+ currentDate: this.formatDate(new Date()),
+ todayTasks: 5,
+ todaySchedules: 3,
+ unreadMessages: 2,
+ activeProject: 'all',
+ projects: [
+ { id: '1', name: '灏勬椽甯傛脖鐗岄晣缁煎悎姘村埄璁炬柦寤鸿椤圭洰' },
+ { id: '2', name: '灏勬椽甯傚浗瀹跺偍澶囨灄寤鸿椤圭洰锛堜竴鏈燂級' },
+ { id: '3', name: '灏勬椽甯傜櫧缇借倝楦′骇涓氬缓璁鹃」鐩�' },
+ { id: '4', name: '閬傚畞甯傚皠娲�2024鈥�2027骞村害涓滃寳鐗囧尯楂樻爣鍑嗗啘鐢板缓璁鹃」鐩�' },
+ { id: '5', name: '灏勬椽甯傜幇浠g涓氱ず鑼冨熀鍦板缓璁鹃」鐩�' },
+ ],
+ tasks: [
+ { id: 1, name: '瀹℃牳鏂藉伐鍥剧焊', project: '灏勬椽甯傚浗瀹跺偍澶囨灄寤鸿椤圭洰锛堜竴鏈燂級', startTime: '2025-05-05', deadline: '2025-06-15', status: '寰呭畬鎴�' },
+ { id: 2, name: '閲囪喘鏉愭枡娓呭崟', project: '灏勬椽甯傜櫧缇借倝楦′骇涓氬缓璁鹃」鐩�', startTime: '2025-05-14', deadline: '2025-06-18', status: '寰呭畬鎴�' },
+ { id: 3, name: '鐜板満瀹夊叏妫�鏌�', project: '閬傚畞甯傚皠娲�2024鈥�2027骞村害涓滃寳鐗囧尯楂樻爣鍑嗗啘鐢板缓璁鹃」鐩�', startTime: '2025-05-10', deadline: '2025-06-12', status: '瀹圭己涓�' },
+ { id: 4, name: '椤圭洰杩涘害鎶ュ憡', project: '灏勬椽甯傜幇浠g涓氱ず鑼冨熀鍦板缓璁鹃」鐩�', startTime: '2025-05-23', deadline: '2025-06-20', status: '寰呭畬鎴�' },
+ { id: 5, name: '渚涘簲鍟嗕細璁�', project: '灏勬椽甯傛脖鐗岄晣缁煎悎姘村埄璁炬柦寤鸿椤圭洰', startTime: '2025-05-14', deadline: '2025-06-14', status: '瀹圭己涓�' }
+ ],
+ logs: [
+ { id: 1, time: '09:30', project: '灏勬椽甯傚浗瀹跺偍澶囨灄寤鸿椤圭洰锛堜竴鏈燂級', action: '鎻愪氦', detail: '鎻愪氦浜嗘柦宸ュ浘绾稿鏍哥敵璇�' },
+ { id: 2, time: '10:15', project: '灏勬椽甯傜櫧缇借倝楦′骇涓氬缓璁鹃」鐩�', action: '鏇存柊', detail: '鏇存柊浜嗘潗鏂欓噰璐竻鍗�' },
+ { id: 3, time: '11:00', project: '閬傚畞甯傚皠娲�2024鈥�2027骞村害涓滃寳鐗囧尯楂樻爣鍑嗗啘鐢板缓璁鹃」鐩�', action: '瀹屾垚', detail: '瀹屾垚浜嗙數鍔涜澶囨祴璇�' },
+ { id: 4, time: '14:30', project: '灏勬椽甯傜幇浠g涓氱ず鑼冨熀鍦板缓璁鹃」鐩�', action: '鍒涘缓', detail: '鍒涘缓浜嗘柊鐨勫畨瑁呰鍒�' },
+ { id: 5, time: '16:45', project: '灏勬椽甯傛脖鐗岄晣缁煎悎姘村埄璁炬柦寤鸿椤圭洰', action: '瀹℃壒', detail: '瀹℃壒閫氳繃浜嗗畨鍏ㄦ柟妗�' }
+ ],
+ achievements: {
+ completedTasks: 128,
+ avgDuration: 3.5,
+ totalSchedules: 89,
+ completedSchedules: 76
+ },
+ calendarDate: new Date(),
+ schedules: [
+ { id: 1, date: '2025-05-10', time: '09:00', title: '椤圭洰鍚姩浼氳', project: '灏勬椽甯傚浗瀹跺偍澶囨灄寤鸿椤圭洰锛堜竴鏈燂級' },
+ { id: 2, date: '2025-05-10', time: '14:00', title: '渚涘簲鍟嗘唇璋�', project: '灏勬椽甯傜櫧缇借倝楦′骇涓氬缓璁鹃」鐩�' },
+ { id: 3, date: '2025-05-11', time: '10:30', title: '鐜板満鍕樺療', project: '閬傚畞甯傚皠娲�2024鈥�2027骞村害涓滃寳鐗囧尯楂樻爣鍑嗗啘鐢板缓璁鹃」鐩�' },
+ { id: 4, date: '2025-05-12', time: '09:00', title: '瀹夊叏鍩硅', project: '灏勬椽甯傜幇浠g涓氱ず鑼冨熀鍦板缓璁鹃」鐩�' },
+ { id: 5, date: '2025-05-12', time: '15:00', title: '杩涘害姹囨姤', project: '灏勬椽甯傛脖鐗岄晣缁煎悎姘村埄璁炬柦寤鸿椤圭洰' },
+ { id: 6, date: '2025-05-15', time: '13:00', title: '璁惧楠屾敹', project: '灏勬椽甯傜櫧缇借倝楦′骇涓氬缓璁鹃」鐩�' }
+ ]
+ }
+ },
+ computed: {
+ filteredSchedules() {
+ const selectedDate = this.formatCalendarDate(this.calendarDate);
+ return this.schedules.filter(schedule => schedule.date === selectedDate);
+ }
+ },
+ methods: {
+ // 鎴柇杩囬暱鐨勯」鐩悕绉�
+ truncateProjectName(name) {
+ const maxLength = 10; // 鏈�澶ф樉绀洪暱搴�
+ return name.length > maxLength ? `${name.substring(0, maxLength)}...` : name;
+ },
+ // 鍒ゆ柇椤圭洰鍚嶆槸鍚﹁繃闀�
+ isProjectNameTooLong(name) {
+ return name.length > 10;
+ },
+ formatDate(date) {
+ const year = date.getFullYear();
+ const month = date.getMonth() + 1;
+ const day = date.getDate();
+ return `${year}骞�${month}鏈�${day}鏃;
+ },
+ formatCalendarDate(date) {
+ const year = date.getFullYear();
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
+ const day = date.getDate().toString().padStart(2, '0');
+ return `${year}-${month}-${day}`;
+ },
+ handleProjectSelect(index) {
+ this.activeProject = index;
+ // 杩欓噷鍙互娣诲姞椤圭洰绛涢�夐�昏緫
+ },
+ getPriorityType(priority) {
+ switch (priority) {
+ case '楂�': return 'danger';
+ case '涓�': return 'warning';
+ case '浣�': return 'success';
+ default: return 'info';
+ }
+ },
+ handleTaskEdit(task) {
+ console.log('缂栬緫浠诲姟:', task);
+ this.$message.info(`寮�濮嬪鐞嗕换鍔�: ${task.name}`);
+ },
+ getScheduleCount(date) {
+ const dateStr = this.formatCalendarDate(date);
+ return this.schedules.filter(s => s.date === dateStr).length;
+ },
+ handleAddSchedule() {
+ this.$message.info('鏂板鏃ョ▼');
+ },
+ handleEditSchedule(schedule) {
+ this.$message.info(`缂栬緫鏃ョ▼: ${schedule.title}`);
+ },
+ handleDeleteSchedule(schedule) {
+ this.$confirm('纭畾鍒犻櫎璇ユ棩绋嬪悧?', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }).then(() => {
+ this.$message.success('鍒犻櫎鎴愬姛');
+ }).catch(() => {
+ this.$message.info('宸插彇娑堝垹闄�');
+ });
+ }
+ }
+}
+</script>
+
+<style scoped>
+.dashboard-container {
+ font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background-color: #f5f7fa;
+}
+
+/* 椤堕儴瀵艰埅鏍忔牱寮� */
+.top-navbar {
+ background-color: #1e88e5;
+ color: white;
+ padding: 15px 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.welcome-message h2 {
+ margin: 0;
+ font-size: 20px;
+}
+
+.welcome-message p {
+ margin: 5px 0 0;
+ font-size: 14px;
+ opacity: 0.9;
+}
+
+.quick-stats {
+ display: flex;
+ gap: 30px;
+}
+
+.stat-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.stat-number {
+ font-size: 24px;
+ font-weight: bold;
+}
+
+.stat-label {
+ font-size: 14px;
+ opacity: 0.9;
+}
+
+.user-profile {
+ display: flex;
+ align-items: center;
+}
+
+.user-avatar {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+}
+
+.user-avatar img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ margin-right: 10px;
+}
+
+/* 涓诲唴瀹瑰尯鏍峰紡 */
+.main-content {
+ display: flex;
+ flex: 1;
+ overflow: hidden;
+}
+
+.left-sidebar {
+ width: 220px;
+ background-color: white;
+ border-right: 1px solid #e6e6e6;
+ padding: 15px;
+ margin-top: 10px;
+ overflow-y: auto;
+}
+.project-name {
+ display: inline-block;
+ max-width: 150px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.project-list h3 {
+ margin-top: 0;
+ color: #333;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #eee;
+}
+
+.project-menu {
+ border-right: none;
+}
+
+.project-actions {
+ margin-top: 15px;
+ text-align: center;
+}
+
+.center-content {
+ flex: 1;
+ padding: 15px;
+ overflow-y: auto;
+ background-color: white;
+ margin: 10px 10px 0px;
+ border-radius: 4px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.section-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+}
+
+.section-header h3 {
+ margin: 0;
+ color: #333;
+}
+
+.task-section {
+ margin-bottom: 20px;
+ height: 350px;
+}
+
+.log-list {
+ border: 1px solid #ebeef5;
+ border-radius: 4px;
+ padding: 10px;
+}
+
+.log-item {
+ display: flex;
+ padding: 8px 0;
+ border-bottom: 1px dashed #eee;
+}
+
+.log-item:last-child {
+ border-bottom: none;
+}
+
+.log-time {
+ width: 60px;
+ color: #666;
+ font-size: 14px;
+}
+
+.log-content {
+ flex: 1;
+}
+
+.log-project {
+ color: #1e88e5;
+ margin-right: 10px;
+ font-weight: bold;
+}
+
+.log-action {
+ color: #ff9800;
+ margin-right: 10px;
+}
+
+.right-sidebar {
+ width: 320px;
+ background-color: white;
+ border-left: 1px solid #e6e6e6;
+ padding: 15px;
+ margin-top: 10px;
+ overflow-y: auto;
+}
+
+.achievement-section h3 {
+ margin-top: 0;
+ color: #333;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #eee;
+}
+
+.achievement-stats {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 15px;
+ margin-bottom: 20px;
+}
+
+.achievement-stats .stat-item {
+ background-color: #f5f7fa;
+ padding: 15px;
+ border-radius: 4px;
+ text-align: center;
+}
+
+.achievement-stats .stat-number {
+ font-size: 24px;
+ color: #1e88e5;
+ font-weight: bold;
+ margin-bottom: 5px;
+}
+
+.achievement-stats .stat-label {
+ font-size: 14px;
+ color: #666;
+}
+
+.calendar-section {
+ margin-bottom: 20px;
+}
+
+.calendar-day {
+ height: 45px;
+ padding: 5px;
+ box-sizing: border-box;
+}
+
+.schedule-count {
+ font-size: 12px;
+ color: #1e88e5;
+ margin-top: 2px;
+}
+
+.schedule-list-section h3 {
+ margin-top: 0;
+ color: #333;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #eee;
+}
+
+.calendar-section >>> .el-calendar-table .el-calendar-day {
+ height: 40px !important; /* 璁剧疆姣忔棩鍗曞厓鏍奸珮搴� */
+ padding: 0 !important;
+}
+.calendar-section >>> .el-calendar__header {
+ padding: 0 !important;
+ border: none !important;
+}
+.calendar-section >>> .el-calendar__body {
+ padding: 0 !important;
+ border: none !important;
+}
+</style>
--
Gitblit v1.8.0