Files
maintenance_system/src/views/zhinengxunjian/index.vue
2025-09-26 20:32:14 +08:00

1056 lines
28 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>
<div class="box-container">
<!-- 导航栏 -->
<!-- <div class="navigation-tabs">
<div class="nav-tab active" @click="handleInspection1">待办事项</div>
<div class="nav-tab" @click="handleInspection2">巡检管理</div>
<div class="nav-tab" @click="handleInspection3">试验管理</div>
<div class="nav-tab" @click="handleInspection4">报修管理</div>
<div class="nav-tab" @click="handleInspection5">抢修管理</div>
<div class="nav-tab" @click="handleInspection6">工单管理</div>
<div class="nav-tab" @click="handleInspection7">运维组织</div>
</div> -->
<div class="main-content">
<!-- 左侧日历区域 -->
<div class="calendar-container">
<div class="calendar-header">
<div class="calendar-title">待办月视图</div>
<div class="calendar-controls">
<!-- 月份选择器 -->
<el-date-picker v-model="currentDate" type="month" placeholder="选择月份" style="width: 120px; margin-right: 15px" />
<el-button type="primary" @click="goToToday">今日</el-button>
<el-button type="text" icon="el-icon-plus"></el-button>
</div>
</div>
<!-- 使用 Element Plus 的日历组件 -->
<el-calendar v-model="currentDate">
<template #date-cell="{ date, data }">
<div class="custom-date-cell" :class="getCellClass(data.day)">
<div class="date-day">{{ data.day.split('-').slice(2).join('-') }}</div>
<div class="date-events">
<div v-for="event in getDayEvents(data.day)" :key="event.id" class="event-item" :class="'event-' + event.type">
<div class="event-title">{{ event.title }}</div>
<div class="event-describeValue">{{ event.describeValue }}</div>
</div>
</div>
</div>
</template>
</el-calendar>
</div>
<!-- 右侧表单区域 -->
<div class="form-container">
<div class="form-header">
<h2>今日待办</h2>
<el-button type="primary" icon="Plus" @click="openAddTaskDialog">添加</el-button>
</div>
<!-- 待办事项列表 - 动态渲染 -->
<div class="todo-list">
<div
v-for="item in todoListData"
:key="item.id"
class="todo-item"
:class="{ 'important': item.taskLevel === '重要', 'completed': item.status === 2 }"
>
<el-checkbox class="todo-checkbox" :checked="item.status === 2" @change="handleStatusChange(item, $event)"></el-checkbox>
<div
class="todo-color-indicator"
:class="{
normal: item.taskLevel === '常规项' && item.status !== 2,
important: item.taskLevel === '重要' && item.status !== 2,
urgent: item.taskLevel === '紧急' && item.status !== 2,
completed: item.status === 2
}"
></div>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">{{ item.title }}</div>
<div v-if="item.workTimeRange1 || item.workTimeRange2" class="todo-time">
{{ item.workTimeRange1 }}
<span v-if="item.workTimeRange1 && item.workTimeRange2"></span>
{{ item.workTimeRange2 }}
</div>
</div>
<div class="todo-describeValue">{{ item.describeValue }}</div>
</div>
<div class="todo-actions">
<button class="action-btn edit-btn" @click="handleEdit(item.id)">
<img src="@/assets/images/xiugai.png" alt="编辑" class="action-icon" />
</button>
<button class="action-btn delete-btn" @click="handleDelete(item.id)">
<img src="@/assets/images/shanchu.png" alt="删除" class="action-icon" />
</button>
</div>
</div>
<!-- 无数据时显示 -->
<div v-if="todoListData.length === 0" class="empty-todo">
<p>暂无待办事项</p>
</div>
</div>
<!-- 状态图例 - 标签形式 -->
<div class="status-legend">
<span class="status-tag normal"><span class="color-block"></span>常规维护</span>
<span class="status-tag important"><span class="color-block"></span>重要</span>
<span class="status-tag urgent"><span class="color-block"></span>紧急</span>
</div>
</div>
</div>
<el-dialog
v-model="dialogVisible"
:title="editingTaskId ? '编辑任务' : '新增任务'"
width="480px"
class="custom-dialog"
:before-close="closeDialog"
>
<el-form :model="taskForm" label-width="80px" class="task-form">
<el-form-item label="任务名称" prop="name">
<el-input v-model="taskForm.name" placeholder="输入任务名称" class="form-input"></el-input>
</el-form-item>
<el-form-item label="任务描述" prop="describeValue">
<el-input v-model="taskForm.describeValue" placeholder="输入任务描述" class="form-input"></el-input>
</el-form-item>
<el-form-item label="时间" prop="timeRange">
<el-date-picker
v-model="taskForm.timeRange"
type="datetimerange"
start-placeholder="开始时间"
end-placeholder="结束时间"
:disabled-date="() => false"
class="form-input"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="优先级" prop="taskLevel">
<el-select v-model="taskForm.taskLevel" placeholder="选择优先级" class="form-input">
<el-option label="常规项" value="常规项"></el-option>
<el-option label="重要" value="重要"></el-option>
<el-option label="紧急" value="紧急"></el-option>
</el-select>
</el-form-item>
<el-form-item label="任务类型" prop="taskType">
<el-select v-model="taskForm.taskType" placeholder="选择任务类型" class="form-input">
<el-option label="常规维护" value="1"></el-option>
<el-option label="安全巡检" value="2"></el-option>
<el-option label="系统升级" value="3"></el-option>
<el-option label="数据备份" value="4"></el-option>
</el-select>
</el-form-item>
<!-- 新增:工作时间段选择器 -->
<el-form-item label="开始时间" prop="workTimeRange1">
<el-time-picker
v-model="taskForm.workTimeRange1"
type="timerange"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="HH:mm"
value-format="HH:mm"
class="form-input"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="结束时间" prop="workTimeRange2">
<el-time-picker
v-model="taskForm.workTimeRange2"
type="timerange"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="HH:mm"
value-format="HH:mm"
class="form-input"
style="width: 100%"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="saveTask">保存任务</el-button>
</template>
</el-dialog>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
import router from '@/router';
import { daibanlist, adddaiban, updatedaiban, deldaiban } from '@/api/zhinengxunjian/daiban/index';
// 默认显示当前月份
const currentDate = ref(new Date());
// 为了保持兼容性,保留这些变量
const targetYear = 2025;
const years = ref([]);
const selectedYear = ref(currentDate.value.getFullYear());
const selectedMonth = ref(currentDate.value.getMonth() + 1);
// 回到今天
const goToToday = () => {
currentDate.value = new Date();
updateYearAndMonth();
};
// 根据workTimeRange1和workTimeRange2生成taskTimeInfo字符串
const getTaskTimeInfoString = () => {
const timeInfoArray = [];
// 处理工作时间段1 - 更宽松的类型处理
if (taskForm.value.workTimeRange1) {
if (Array.isArray(taskForm.value.workTimeRange1)) {
// 如果是数组,直接拼接
timeInfoArray.push(taskForm.value.workTimeRange1.join('-'));
} else if (typeof taskForm.value.workTimeRange1 === 'string') {
// 如果已经是字符串,直接使用
timeInfoArray.push(taskForm.value.workTimeRange1);
}
}
// 处理工作时间段2 - 更宽松的类型处理
if (taskForm.value.workTimeRange2) {
if (Array.isArray(taskForm.value.workTimeRange2)) {
// 如果是数组,直接拼接
timeInfoArray.push(taskForm.value.workTimeRange2.join('-'));
} else if (typeof taskForm.value.workTimeRange2 === 'string') {
// 如果已经是字符串,直接使用
timeInfoArray.push(taskForm.value.workTimeRange2);
}
}
// 合并多个时间段为一个字符串,用逗号分隔
return timeInfoArray.join(',');
};
// 待办事项数据 - 从接口获取
const todoListData = ref([]);
const calendarEvents = ref([]);
// 格式化日期为YYYY-MM-DD格式
const formatDate = (date) => {
if (!date) return '';
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
// 格式化时间范围
const formatTimeRange = (startTime, endTime) => {
if (!startTime || !endTime) return '';
const start = new Date(startTime);
const end = new Date(endTime);
const formatHourMinute = (date) => {
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${hours}:${minutes}`;
};
return `${formatHourMinute(start)}-${formatHourMinute(end)}`;
};
// 从接口获取数据并处理 - 根据实际返回格式修正版
const fetchData = async () => {
try {
const response = await daibanlist();
console.log('接口原始返回:', response); // 打印原始响应,便于调试
// 初始化数据数组
let data = [];
// 根据实际返回格式提取数据数据在response.rows中
if (response && Array.isArray(response.rows)) {
data = response.rows;
} else if (response.data && Array.isArray(response.data.rows)) {
// 兼容可能的嵌套结构
data = response.data.rows;
} else {
console.warn('接口返回格式不符合预期,使用空数组', response);
data = [];
}
// 处理待办列表数据
todoListData.value = data.map((item) => ({
id: item.id,
title: item.taskName,
describeValue: item.describeValue,
timeRange: formatTimeRange(item.taskBeginTime, item.taskEndTime),
// 保存原始时间用于编辑
originalTimeRange: [new Date(item.taskBeginTime), new Date(item.taskEndTime)],
taskLevel: item.taskLevel === '1' ? '常规项' : item.taskLevel === '2' ? '紧急' : '重要',
// 注意根据返回数据调整了taskLevel映射原代码可能颠倒了重要和紧急
taskType: item.taskType,
// 从taskTimeInfo获取时间段数据格式为"17:00,20:00"
workTimeRange1: item.taskTimeInfo ? item.taskTimeInfo.split(',')[0] || '' : '',
workTimeRange2: item.taskTimeInfo && item.taskTimeInfo.split(',').length > 1 ? item.taskTimeInfo.split(',')[1] : '',
date: formatDate(item.taskBeginTime),
status: item.status || 1 // 添加状态字段默认1表示未完成
}));
// 确保每个项目都有status字段
todoListData.value.forEach((item) => {
if (item.status === undefined) {
item.status = 1; // 默认未完成
}
});
// 处理日历事件数据
calendarEvents.value = data.map((item) => ({
id: item.id,
date: formatDate(item.taskBeginTime),
title: item.taskName,
describeValue: item.describeValue,
type: getEventType(item.taskType),
status: item.status // 添加状态信息
}));
console.log('数据处理完成,共', data.length, '条记录');
} catch (error) {
console.error('获取待办数据失败:', error);
// 出错时确保数据是数组,避免页面报错
todoListData.value = [];
calendarEvents.value = [];
}
};
// 根据任务类型获取事件类型
const getEventType = (taskType) => {
// 任务类型映射: 1-常规维护, 2-安全巡检, 3-系统升级, 4-数据备份
const typeMap = {
'1': 'service', // 常规维护对应service
'2': 'database', // 安全巡检对应database
'3': 'upgrade', // 系统升级对应upgrade
'4': 'network' // 数据备份对应network
};
return typeMap[taskType] || 'service';
};
// 获取指定日期的事件
const getDayEvents = (dateStr) => {
return calendarEvents.value.filter((event) => event.date === dateStr);
};
// 根据事件类型获取单元格样式
const getCellClass = (date) => {
const events = getDayEvents(date);
if (events.length > 0) {
const eventType = events[0].type;
return `date-cell-${eventType}`;
}
return '';
};
// 更新年份和月份选择器的值
const updateYearAndMonth = () => {
selectedYear.value = currentDate.value.getFullYear();
selectedMonth.value = currentDate.value.getMonth() + 1;
};
// 监听日期变化,更新年份和月份
watch(currentDate, (newDate) => {
selectedYear.value = newDate.getFullYear();
selectedMonth.value = newDate.getMonth() + 1;
});
// 初始化年份和月份
updateYearAndMonth();
// 组件挂载时获取数据
onMounted(() => {
fetchData();
});
// 弹窗相关状态管理
const dialogVisible = ref(false);
const taskForm = ref({
name: '',
describeValue: '',
timeRange: null,
taskLevel: '常规项',
taskType: '1', // 默认值为1常规维护
workTimeRange1: null, // 工作时间段1
workTimeRange2: null // 工作时间段2
});
// 当前编辑的任务ID为null表示新建模式
const editingTaskId = ref(null);
// 打开添加任务弹窗
const openAddTaskDialog = () => {
// 重置表单为新建状态
editingTaskId.value = null;
taskForm.value = {
name: '',
describeValue: '',
timeRange: null,
taskLevel: '常规项',
taskType: '1',
workTimeRange1: null,
workTimeRange2: null
};
dialogVisible.value = true;
};
// 关闭弹窗
const closeDialog = () => {
dialogVisible.value = false;
};
// 保存任务
const saveTask = async () => {
// 表单验证
if (!taskForm.value.name || !taskForm.value.describeValue || !taskForm.value.timeRange) {
// 使用Element Plus的消息提示
ElMessage.warning('请填写必要的任务信息');
return;
}
// 验证工作时间段
if (!taskForm.value.workTimeRange1 && !taskForm.value.workTimeRange2) {
ElMessage.warning('请至少填写一个工作时间段');
return;
}
try {
// 构建接口所需的数据结构
const apiData = {
createDept: 0, // 根据实际情况设置
createBy: 0, // 根据实际情况设置
createTime: new Date().toISOString(),
updateBy: 0, // 根据实际情况设置
updateTime: new Date().toISOString(),
params: {
property1: 'string',
property2: 'string'
},
projectId: 0, // 根据实际情况设置
taskName: taskForm.value.name,
describeValue: taskForm.value.describeValue,
taskBeginTime: taskForm.value.timeRange[0].toISOString(),
taskEndTime: taskForm.value.timeRange[1].toISOString(),
// 使用taskTimeInfo替代workTimeRange1和workTimeRange2通过字符串拼接开始和结束时间
taskTimeInfo: getTaskTimeInfoString(),
taskLevel: taskForm.value.taskLevel === '常规项' ? '1' : taskForm.value.taskLevel === '重要' ? '3' : '2',
taskType: taskForm.value.taskType
};
let response;
// 判断是新增还是编辑
if (editingTaskId.value) {
// 编辑操作 - 修改参数传递方式将id合并到apiData中
response = await updatedaiban({ ...apiData, id: editingTaskId.value });
ElMessage.success('任务更新成功');
} else {
// 新增操作
response = await adddaiban(apiData);
console.log('保存任务成功:', response);
ElMessage.success('任务添加成功');
}
// 重新从接口获取最新数据,确保列表数据与后端保持一致
await fetchData();
// 重置表单
taskForm.value = {
name: '',
describeValue: '',
timeRange: null,
taskLevel: '常规项',
taskType: '1',
workTimeRange1: null,
workTimeRange2: null
};
// 重置编辑状态
editingTaskId.value = null;
// 关闭弹窗
closeDialog();
} catch (error) {
console.error('保存任务失败:', error);
ElMessage.error('保存任务失败,请重试');
}
};
// 处理状态变更
const handleStatusChange = async (item, checked) => {
try {
// 更新本地状态
item.status = checked ? 2 : 1;
// 直接更新相关的日历事件以反映状态变化
const calendarEvent = calendarEvents.value.find((event) => event.id === item.id);
if (calendarEvent) {
calendarEvent.status = item.status;
}
// 这里可以添加API调用更新后端状态
// await updateTaskStatus(item.id, item.status);
console.log('任务状态已更新:', item.id, '状态:', item.status);
} catch (error) {
console.error('更新任务状态失败:', error);
ElMessage.error('更新任务状态失败,请重试');
// 恢复原始状态
item.status = checked ? 1 : 2;
}
};
// 编辑和删除处理函数
const handleEdit = (id) => {
console.log('执行编辑操作:', id);
// 找到对应的数据项
const item = todoListData.value.find((item) => item.id === id);
if (item) {
// 存储编辑的任务ID
editingTaskId.value = id;
// 填充表单数据,使用原始时间范围
// 处理工作时间段格式:如果是字符串格式(如"HH:mm-HH:mm")则转换为数组格式
let workTimeRange1 = item.workTimeRange1;
let workTimeRange2 = item.workTimeRange2;
if (typeof workTimeRange1 === 'string' && workTimeRange1.includes('-')) {
workTimeRange1 = workTimeRange1.split('-');
}
if (typeof workTimeRange2 === 'string' && workTimeRange2.includes('-')) {
workTimeRange2 = workTimeRange2.split('-');
}
taskForm.value = {
name: item.title,
describeValue: item.describeValue,
timeRange: item.originalTimeRange, // 使用保存的原始时间对象
taskLevel: item.taskLevel,
taskType: item.taskType,
workTimeRange1: workTimeRange1,
workTimeRange2: workTimeRange2
};
// 打开弹窗
dialogVisible.value = true;
}
};
const handleDelete = (id) => {
console.log('执行删除操作:', id);
ElMessageBox.confirm('确定要删除这个任务吗?', '删除确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
try {
// 对于单个ID直接作为路径参数传递
// 接口要求格式: /ops/matter/{ids}这里ids是单个ID
await deldaiban(id);
// 删除成功后重新获取最新数据
await fetchData();
ElMessage.success('任务已删除');
} catch (error) {
console.error('删除任务失败:', error);
ElMessage.error('删除任务失败,请重试');
}
})
.catch(() => {
ElMessage.info('已取消删除');
});
};
const handleInspection1 = () => {
router.push('/rili/rili');
};
const handleInspection2 = () => {
router.push('/rili/InspectionManagement');
};
const handleInspection3 = () => {
router.push('/rili/shiyanguanli');
};
const handleInspection4 = () => {
router.push('/rili/baoxiuguanli');
};
const handleInspection5 = () => {
router.push('/rili/qiangxiuguanli');
};
const handleInspection6 = () => {
router.push('/rili/gongdanliebiao');
};
const handleInspection7 = () => {
router.push('/rili/renyuanzhuangtai');
};
</script>
<style scoped>
.box-container {
width: 100%;
padding: 20px;
background-color: #f5f7fa;
min-height: 100vh;
}
/* 已完成任务的样式 */
.todo-color-indicator.completed {
background-color: #dcdfe6;
}
.todo-item.completed .todo-content {
color: #909399;
text-decoration: line-through;
}
/* 导航栏样式 */
.navigation-tabs {
display: flex;
margin-bottom: 20px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
padding: 2px;
}
.nav-tab {
padding: 12px 24px;
cursor: pointer;
transition: all 0.3s ease;
border-radius: 4px;
font-size: 14px;
color: #606266;
border-right: 1px solid #f0f0f0;
flex: 1;
text-align: center;
}
.nav-tab:last-child {
border-right: none;
}
.nav-tab:hover {
color: #409eff;
background-color: #ecf5ff;
}
.nav-tab.active {
background-color: #409eff;
color: #fff;
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3);
}
.nav-tab {
cursor: pointer;
user-select: none;
}
.header {
margin-bottom: 20px;
}
.header h1 {
font-size: 24px;
font-weight: 600;
color: #303133;
margin: 0;
}
.header p {
font-size: 14px;
color: #606266;
margin: 5px 0 0 0;
}
.main-content {
display: flex;
gap: 20px;
width: 100%;
}
/* 日历区域样式 */
.calendar-container {
flex: 1;
min-width: 0;
background-color: #fff;
border-radius: 4px;
padding: 20px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
height: 100%;
}
/* 自定义弹窗样式 */
.custom-dialog {
border-radius: 8px;
overflow: hidden;
}
.custom-dialog .el-dialog__header {
background-color: #f5f7fa;
border-bottom: 1px solid #e4e7ed;
padding: 15px 20px;
}
.custom-dialog .el-dialog__title {
font-size: 16px;
color: #303133;
}
.custom-dialog .el-dialog__body {
padding: 20px;
}
/* 确保所有输入框长度相等 */
.task-form .form-input {
height: 30px;
width: 100%;
}
/* 时间选择器样式调整 */
.task-form .el-date-editor {
width: 100%;
height: 30px;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.calendar-title {
font-size: 16px;
font-weight: 600;
color: #303133;
}
.calendar-controls {
display: flex;
align-items: center;
gap: 10px;
}
.el-select {
margin-right: 5px;
}
.form-container {
flex: 0 0 360px; /* 调整宽度以匹配设计图,更贴合右侧区域宽度 */
background-color: #fff;
border-radius: 4px;
padding: 20px 20px 80px 20px; /* 增加底部内边距,为固定标签留出空间 */
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: relative; /* 设置为相对定位,使内部绝对定位元素相对于此容器定位 */
}
.form-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #f0f0f0;
}
.form-header h2 {
font-size: 16px;
font-weight: 600;
color: #303133;
margin: 0;
}
.todo-list {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
max-height: 480px;
overflow-y: auto;
}
.todo-item {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 12px 12px 12px 20px;
background-color: #fafafa;
border-radius: 4px;
position: relative;
transition: all 0.3s ease;
overflow: hidden;
}
.todo-checkbox {
margin-top: 2px;
flex-shrink: 0;
}
.todo-content {
flex: 1;
position: relative;
transition: all 0.3s ease;
}
.todo-main {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
}
.todo-title {
font-size: 14px;
font-weight: 500;
color: #303133;
}
.todo-time {
font-size: 12px;
color: #909399;
}
.todo-describeValue {
font-size: 12px;
color: #606266;
line-height: 1.4;
}
.todo-actions {
position: absolute;
right: -120px;
top: 0;
bottom: 0;
display: flex;
align-items: center;
gap: 8px;
padding: 0 12px;
background-color: inherit;
opacity: 0;
transition: all 0.3s ease;
}
.action-btn {
width: 36px;
height: 36px;
border: none;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
}
.action-btn:hover {
background-color: #f5f7fa;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
/* 悬停显示操作按钮 */
.todo-item:hover .todo-actions {
background: linear-gradient(to right, rgba(173, 216, 230, 0), rgb(64, 158, 255));
right: 0;
opacity: 0.8;
}
/* 取消内容区域平移效果 */
.todo-item:hover .todo-content {
transform: none;
}
.action-icon {
width: 16px;
height: 16px;
object-fit: contain;
}
/* 调整按钮间距 */
.todo-actions {
gap: 12px;
}
/* 空状态样式 */
.empty-todo {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
color: #909399;
font-size: 14px;
background-color: #fafafa;
border-radius: 4px;
}
.status-legend {
display: flex;
gap: 20px;
padding: 15px 0;
border-top: 1px solid #ebeef5;
justify-content: center;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
}
.status-tag {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 14px;
color: #303133;
}
.status-tag .color-block {
width: 12px;
height: 12px;
border-radius: 2px;
flex-shrink: 0;
}
.status-tag.normal .color-block {
background-color: #52c41a;
}
.status-tag.important .color-block {
background-color: #faad14;
}
.status-tag.urgent .color-block {
background-color: #ff4d4f;
}
.todo-color-indicator {
width: 8px;
height: 100%;
border-radius: 0 4px 4px 0;
position: absolute;
left: 0;
top: 0;
flex-shrink: 0;
}
.todo-color-indicator.normal {
background-color: #52c41a;
}
.todo-color-indicator.important {
background-color: #faad14;
}
.todo-color-indicator.urgent {
background-color: #ff4d4f;
}
:deep(.custom-date-cell) {
width: 100%;
height: 100%;
padding: 5px;
text-align: center;
box-sizing: border-box; /* 确保内边距不撑大元素 */
}
/* 系统升级事件样式 */
.event-upgrade {
background-color: #fff1f0;
color: #f5222d;
}
/* 日期单元格背景色 - 按事件类型 */
.date-cell-service {
background-color: #e6f7ff;
}
.date-cell-database {
background-color: #f0f9ff;
}
.date-cell-network {
background-color: #fffbe6;
}
.date-cell-upgrade {
background-color: #fff1f0;
}
/* 日历样式优化 */
.el-calendar {
width: 100%;
}
.el-calendar-table {
width: 100%;
}
/* 穿透作用域,强制设置日历单元格为正方形 */
:deep(.el-calendar-table td) {
padding: 2px;
vertical-align: top;
width: 120px; /* 强制宽度 */
height: 120px; /* 强制高度(与宽度一致) */
}
:deep(.el-calendar-day) {
padding: 0; /* 移除默认内边距 */
width: 100%;
height: 100%;
border-radius: 4px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.date-day {
font-weight: bold;
margin-bottom: 5px;
}
.date-events {
flex: 1;
overflow: hidden;
}
.event-item {
padding: 3px;
margin-bottom: 2px;
border-radius: 3px;
font-size: 12px;
}
.event-title {
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.event-describeValue {
font-size: 11px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 服务维护事件样式 */
.event-service {
background-color: #e6f7ff;
color: #1890ff;
}
/* 数据库管理事件样式 */
.event-database {
background-color: #f0f9ff;
color: #36cfc9;
}
/* 网络维护事件样式 */
.event-network {
background-color: #fffbe6;
color: #faad14;
}
/* 系统升级事件样式 */
.event-upgrade {
background-color: #fff1f0;
color: #f5222d;
}
</style>