<template>
|
<div class="dashboard-container">
|
<!-- 顶部导航栏 -->
|
<div class="top-navbar">
|
<div class="welcome-message">
|
<h2>{{ getCurrentTimePeriod() }},{{ 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">{{ totalActiveTasks }}</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.projectName">
|
{{ project.projectName }}
|
</span>
|
</el-menu-item>
|
</el-menu>
|
<div class="project-actions">
|
<el-button type="primary" icon="el-icon-plus" size="small" @click="addProject">新建项目</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" @click="getWaitTaskList()" :disabled="waitTaskRefreshing">刷新</el-button>
|
</div>
|
<div>
|
<el-table
|
v-loading="loading"
|
:data="tasks"
|
border
|
style="width: 100%"
|
>
|
<el-table-column
|
prop="taskName"
|
label="任务名称"
|
width="240">
|
</el-table-column>
|
<el-table-column
|
prop="checkPointInfo.projectName"
|
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="endTime"
|
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.taskType === '待完成' ? 'success' : 'warning'" size="small">
|
{{ scope.row.taskType }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="操作"
|
fixed="right"
|
>
|
<template slot-scope="scope">
|
<el-button size="mini" @click="handleTaskEdit(scope.row)">办理</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
|
</div>
|
|
<!-- 项目办理日志 -->
|
<div class="log-section">
|
<div class="section-header">
|
<h3>项目办理日志</h3>
|
<el-button type="text" icon="el-icon-refresh" @click="getAuditHistoryPage" :disabled="auditHistoryRefreshing">刷新</el-button>
|
</div>
|
<div class="log-list" v-loading="auditHistoryLoading">
|
<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.projectName }}</span>
|
<span class="log-action">{{ getAuditTypeText(log.auditType) }}</span>
|
<span class="log-detail">{{ log.content }}</span>
|
</div>
|
</div>
|
|
</div>
|
<div class="pagination-container">
|
<el-pagination
|
@current-change="auditHistoryHandleCurrentChange"
|
:current-page="auditHistoryQuery.currentPage"
|
:page-size="auditHistoryQuery.pageSize"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="auditHistoryTotal"
|
>
|
</el-pagination>
|
</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" @click="getScheduleList" :disabled="scheduleRefreshing">刷新</el-button>
|
</div>
|
</div>
|
<div class="schedule-list">
|
<el-table
|
v-loading="scheduleLoading"
|
: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 class="pagination-container">
|
<el-pagination
|
@current-change="handleCurrentChange"
|
:current-page="waitTaskQuery.currentPage"
|
:page-size="waitTaskQuery.pageSize"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="waitTaskTotal"
|
>
|
</el-pagination>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<el-dialog
|
:title="diaLogTitle"
|
:visible.sync="scheduleDialogVisible"
|
width="500px"
|
@close="resetScheduleForm"
|
>
|
<el-form
|
ref="scheduleFormRef"
|
:model="scheduleForm"
|
:rules="scheduleRules"
|
label-width="80px"
|
>
|
<el-form-item label="选择项目" prop="projectId">
|
<el-select
|
v-model="scheduleForm.projectId"
|
clearable
|
placeholder="选择项目"
|
style="width: 100%"
|
>
|
<el-option
|
v-for="project in allProjects"
|
:key="project.id"
|
:label="project.name"
|
:value="project.id"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
<!-- 工作内容 -->
|
<el-form-item label="工作内容" prop="content">
|
<el-input
|
v-model="scheduleForm.content"
|
type="textarea"
|
placeholder="请输入工作内容"
|
rows="3"
|
></el-input>
|
</el-form-item>
|
<!-- 完成日期 -->
|
<el-form-item label="完成日期" prop="completedTime">
|
<el-date-picker
|
v-model="scheduleForm.completedTime"
|
type="datetime"
|
placeholder="请选择完成日期"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
style="width: 100%;"
|
></el-date-picker>
|
</el-form-item>
|
|
</el-form>
|
<template v-slot:footer>
|
<el-button @click="scheduleDialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="submitSaveSchedule">确定</el-button>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import {
|
getCountAchievements,
|
getProjectList,
|
getWaitTaskList,
|
add,
|
auditHistoryPage,
|
listByDate,
|
update,
|
del,
|
countTodayTask,
|
} from "@/api/workbench/workbench"
|
import {getTaskIsAuditing} from "@/api/projectProcess/projectProcess";
|
import {getProjectSelectList} from "@/api/index";
|
export default {
|
|
data() {
|
return {
|
|
|
diaLogTitle:"",
|
allProjects:[],
|
scheduleDialogVisible: false,
|
// 新增:新增日程表单数据(对应WorkStationSchedule实体)
|
scheduleForm: {
|
id:'',
|
content: '', // 工作内容
|
completedTime: '',
|
projectId:''
|
|
},
|
// 新增:表单校验规则
|
scheduleRules: {
|
content: [
|
{required: true, message: '请输入工作内容', trigger: 'blur'},
|
{max: 500, message: '工作内容最多500个字符', trigger: 'blur'}
|
],
|
completedTime: [
|
{required: true, message: '请选择完成日期', trigger: 'change'}
|
],
|
projectId:[
|
{required:true,message: '请选择项目', trigger: 'change'}
|
]
|
},
|
queryParams: {
|
taskName: '',
|
taskType: 'todo',
|
pageSize: 5,
|
currentPage: 1,
|
projectId: null,
|
processDefId: null,
|
processInsId: null,
|
deployId: null,
|
processName: '' // 流程名称
|
},
|
waitTaskRefreshing:false,
|
scheduleRefreshing:false,
|
auditHistoryRefreshing:false,
|
loading:false,
|
scheduleLoading:false,
|
auditHistoryLoading:false,
|
waitTaskQuery:{
|
pageSize:5,
|
currentPage:1,
|
},
|
auditHistoryQuery:{
|
pageSize:5,
|
currentPage:1,
|
},
|
waitTaskTotal:0,
|
auditHistoryTotal:0,
|
projectId:null,
|
|
userInfo: {
|
name: '张工程师',
|
avatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
|
department: '项目部'
|
},
|
currentDate: this.formatDate(new Date()),
|
todayTasks: 0,
|
todaySchedules: 0,
|
totalActiveTasks: 0,
|
activeProject: 'all',
|
projects: [],
|
tasks: [],
|
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: '射洪市现代种业示范基地建设项目', action: '创建', detail: '创建了新的安装计划' },
|
{ id: 5, time: '16:45', project: '射洪市沱牌镇综合水利设施建设项目', action: '审批', detail: '审批通过了安全方案' }
|
],
|
achievements: {
|
completedTasks: 0,
|
avgDuration: 0,
|
totalSchedules: 0,
|
completedSchedules: 0
|
},
|
calendarDate: new Date(),
|
schedules: []
|
}
|
},
|
computed: {
|
filteredSchedules() {
|
const selectedDate = this.formatCalendarDate(this.calendarDate);
|
return this.schedules.filter(schedule => schedule.date === selectedDate);
|
}
|
},
|
mounted() {
|
this.initData();
|
this.initSelect();
|
this.getScheduleList();
|
this.countTodayTask();
|
this.getAuditHistoryPage();
|
},
|
methods: {
|
getAuditTypeText(auditType) {
|
// 映射关系:后端值 → 前端汉字
|
const typeMap = {
|
Submit: '提交',
|
Review: '审核',
|
Reject: '驳回',
|
Forward: '转交'
|
};
|
// 兜底:未知值返回“未知操作”
|
return typeMap[auditType] || '未知操作';
|
},
|
countTodayTask(){
|
countTodayTask().then(res =>{
|
if (res.code === 200){
|
this.todayTasks = res.data.todayTasks;
|
this.todaySchedules = res.data.todaySchedules;
|
this.totalActiveTasks = res.data.totalActiveTasks;
|
}
|
})
|
},
|
initSelect(){
|
getProjectSelectList().then(res =>{
|
if (res.code === 200){
|
this.allProjects = Object.entries(res.data).map(([id, name]) => ({
|
id: id, // 项目ID(如"151")
|
name: name // 项目名称(如"射洪市万林钢厂片区棚户区改造项目")
|
}));
|
}
|
})
|
},
|
getScheduleList(){
|
if (this.scheduleRefreshing){
|
return
|
}
|
const form ={
|
completedTime:this.formatDateToFrontend(this.calendarDate),
|
projectId:this.activeProject
|
}
|
this.scheduleLoading = true
|
this.scheduleRefreshing = true
|
listByDate(form).then(res =>{
|
this.scheduleRefreshing = false
|
this.scheduleLoading = false
|
if (res.code === 200){
|
this.schedules = res.data;
|
}
|
})
|
},
|
formatDateToFrontend(date) {
|
if (!date) return '';
|
const d = new Date(date);
|
const year = d.getFullYear();
|
const month = (d.getMonth() + 1).toString().padStart(2, '0');
|
const day = d.getDate().toString().padStart(2, '0');
|
const hour = d.getHours().toString().padStart(2, '0');
|
const minute = d.getMinutes().toString().padStart(2, '0');
|
const second = d.getSeconds().toString().padStart(2, '0');
|
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
},
|
async submitSaveSchedule(){
|
this.$refs.scheduleFormRef.validate((valid, fields) => {
|
if (valid) {
|
console.log(this.scheduleForm.id)
|
if (this.scheduleForm.id === null || this.scheduleForm.id ==='' || this.scheduleForm.id === undefined){
|
const submitData = {
|
content: this.scheduleForm.content,
|
completedTime: this.formatDateToFrontend(this.scheduleForm.completedTime),
|
projectId:this.scheduleForm.projectId
|
};
|
this.$message.success('表单提交成功!');
|
add(submitData).then(res =>{
|
if (res.code === 200){
|
this.scheduleDialogVisible = false;
|
this.$message.success('新增日程成功')
|
//刷新列表
|
this.getScheduleList();
|
}
|
})
|
}else {
|
const submitData = {
|
id:this.scheduleForm.id,
|
content: this.scheduleForm.content,
|
completedTime: this.formatDateToFrontend(this.scheduleForm.completedTime),
|
projectId:this.scheduleForm.projectId
|
};
|
this.$message.success('表单提交成功!');
|
update(submitData).then(res =>{
|
if (res.code === 200){
|
this.scheduleDialogVisible = false;
|
this.$message.success('编辑日程成功')
|
//刷新列表
|
this.getScheduleList();
|
}
|
})
|
|
}
|
}else {
|
const firstError = Object.values(fields)[0][0].message;
|
this.$message.error(firstError);
|
}
|
|
|
});
|
},
|
handleAddSchedule() {
|
this.resetScheduleForm();
|
this.scheduleDialogVisible = true;
|
this.diaLogTitle = "新增日志"
|
},
|
handleEditSchedule(row){
|
this.resetScheduleForm();
|
this.scheduleDialogVisible = true;
|
this.diaLogTitle = "编辑日志"
|
//赋值
|
this.scheduleForm.id = row.id;
|
this.scheduleForm.content = row.title;
|
this.scheduleForm.projectId = row.projectId +"";
|
this.scheduleForm.completedTime = new Date(row.completedTime);
|
console.log(row)
|
},
|
// 新增:重置新增表单
|
resetScheduleForm() {
|
this.scheduleForm = {
|
if:'',
|
content: '',
|
completedTime: ''
|
};
|
// 重置表单校验状态
|
if (this.$refs.scheduleFormRef) {
|
this.$refs.scheduleFormRef.resetFields();
|
}
|
},
|
addProject(){
|
this.$router.push({path: '/projectEngineering/project/ProjectDetails'});
|
},
|
handleSizeChange(val) {
|
this.waitTaskQuery.pageSize = val;
|
},
|
handleCurrentChange(val) {
|
this.waitTaskQuery.currentPage = val;
|
this.getWaitTaskList();
|
},
|
auditHistoryHandleCurrentChange(val) {
|
this.auditHistoryTotal.currentPage = val;
|
this.getAuditHistoryPage();
|
},
|
getAuditHistoryPage(){
|
if (this.auditHistoryRefreshing)return;
|
this.auditHistoryLoading = true;
|
const form ={
|
pageSize:this.auditHistoryQuery.pageSize,
|
currentPage:this.auditHistoryQuery.currentPage,
|
projectId:this.activeProject
|
}
|
this.auditHistoryRefreshing = true
|
auditHistoryPage(form).then(res =>{
|
this.auditHistoryLoading = false;
|
this.auditHistoryRefreshing = false;
|
if (res.code === 200){
|
this.logs = res.data;
|
this.auditHistoryTotal = res.total;
|
}
|
})
|
|
},
|
getWaitTaskList(){
|
if (this.waitTaskRefreshing) return;
|
this.waitTaskRefreshing = true;
|
const form ={
|
pageSize:this.waitTaskQuery.pageSize,
|
currentPage:this.waitTaskQuery.currentPage,
|
id:this.activeProject
|
}
|
this.loading = true;
|
getWaitTaskList(form).then(res=>{
|
this.loading = false;
|
this.waitTaskRefreshing = false;
|
if (res.code === 200){
|
this.tasks = res.data.data;
|
this.waitTaskTotal = res.data.total;
|
}
|
|
})
|
},
|
getProjectList(){
|
getProjectList().then(res =>{
|
if (res.code === 200){
|
this.projects = res.data;
|
}
|
})
|
},
|
initData() {
|
this.getProjectList();
|
this.getWaitTaskList();
|
this.getCountAchievements();
|
},
|
getCountAchievements(){
|
getCountAchievements().then(res =>{
|
// 个人成就
|
if (res.code === 200){
|
this.achievements = res.data;
|
}
|
})
|
|
},
|
getCurrentTimePeriod() {
|
// 获取当前时间的小时和分钟
|
const now = new Date();
|
const hours = now.getHours();
|
|
// 按区间判断
|
if (hours >= 0 && hours < 6) {
|
// 0:00 - 5:59 为凌晨
|
return "凌晨好";
|
} else if (hours >= 6 && hours < 12) {
|
// 6:00 - 11:59 为早上
|
return "早上好";
|
} else if (hours >= 12 && hours < 14) {
|
// 12:00 - 13:59 为中午
|
return "中午好";
|
} else if (hours >= 14 && hours < 18) {
|
// 14:00 - 17:59 为下午
|
return "下午好";
|
} else {
|
// 18:00 - 23:59 为晚上
|
return "晚上好";
|
}
|
},
|
// 截断过长的项目名称
|
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;
|
console.log(this.activeProject)
|
this.getWaitTaskList();
|
// 这里可以添加项目筛选逻辑
|
},
|
getPriorityType(priority) {
|
switch (priority) {
|
case '高': return 'danger';
|
case '中': return 'warning';
|
case '低': return 'success';
|
default: return 'info';
|
}
|
},
|
handleTaskEdit(row) {
|
console.log(row)
|
if (row.taskType === '容缺') {
|
this.$router.push({
|
path: '/flowable/task/myProcess/send/index',
|
query: {
|
deployId: row.checkPointInfo.deployId,
|
procDefId: row.checkPointInfo.processDefinitionId,
|
procInsId: row.checkPointInfo.processInstanceId,
|
processName: row.taskName,
|
flowName: row.checkPointInfo.processName,
|
projectName: row.checkPointInfo.projectName,
|
taskId: row.id,
|
showAuditing: false,
|
projectId: row.checkPointInfo.id,
|
isWait: true,
|
goBackParams: this.queryParams
|
}
|
})
|
} else {
|
// 查询该任务是否配置了需要审批
|
let params = {
|
processDefId: row.checkPointInfo.processDefinitionId,
|
taskId: row.id
|
}
|
getTaskIsAuditing(params).then(res => {
|
console.log("row",row)
|
this.$router.push({
|
path: '/flowable/task/myProcess/send/index',
|
query: {
|
deployId: row.checkPointInfo.deployId,
|
procDefId: row.checkPointInfo.processDefinitionId,
|
procInsId: row.checkPointInfo.processInstanceId,
|
processName: row.taskName,
|
flowName: row.checkPointInfo.processName,
|
projectName: row.checkPointInfo.projectName,
|
taskId: row.id,
|
showAuditing: res.data,
|
projectId: row.checkPointInfo.id,
|
isWait: false,
|
goBackParams: this.queryParams
|
}
|
})
|
})
|
}
|
},
|
getScheduleCount(date) {
|
const dateStr = this.formatCalendarDate(date);
|
return this.schedules.filter(s => s.date === dateStr).length;
|
},
|
handleDeleteSchedule(schedule) {
|
this.$confirm('确定删除该日程吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
del(schedule.id).then(res =>{
|
if (res.code === 200){
|
this.$message.success('删除成功!');
|
}
|
this.getScheduleList()
|
})
|
}).catch(() => {
|
this.$message.info('已取消删除');
|
});
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.pagination-container {
|
margin-top: 20px;
|
padding-right: 5px;
|
text-align: center;
|
width: 100%;
|
}
|
.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: 450px;
|
}
|
|
.log-list {
|
border: 1px solid #ebeef5;
|
border-radius: 4px;
|
padding: 10px;
|
min-height: 100px;
|
}
|
|
.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: 10px;
|
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: 45px !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>
|