This commit is contained in:
dhr
2025-09-17 20:03:00 +08:00
parent 31a2b405db
commit 834b0ab161
10 changed files with 642 additions and 777 deletions

View File

@ -1,8 +1,10 @@
<template>
<el-row style="padding: 0 20px;">
<el-row style="padding: 0 20px">
<el-col>
<div style="color: rgba(0, 30, 59, 1); font-family: 'Alibaba-PuHuiTi-Bold'; margin: 10px 0 0 0"
:style="{ fontSize: fontLevelMap[props.fontLevel] }">
<div
style="color: rgba(0, 30, 59, 1); font-family: 'Alibaba-PuHuiTi-Bold'; margin: 10px 0 0 0"
:style="{ fontSize: fontLevelMap[props.fontLevel] }"
>
{{ props.title }}
</div>
</el-col>

View File

@ -97,10 +97,10 @@
<div class="chart-card-container">
<div class="chart-card">
<div class="chart-header">
<h3>班组周任务情况</h3>
<h3>班组周任务情况</h3>
</div>
<div class="chart-content">
<!-- 环形图容器 - 增加明确的尺寸设置 -->
<!-- 环形图容器 -->
<div id="teamChart" class="chart-container"></div>
</div>
</div>
@ -110,6 +110,9 @@
<!-- 班组任务完成情况表格 -->
<div class="table-wrapper">
<div class="table-header-title">
<h2>班组任务完成情况</h2>
</div>
<el-table :data="pagedTableData" stripe style="width: 100%" highlight-current-row class="custom-table">
<el-table-column align="center" prop="name" label="班组名称" min-width="120"></el-table-column>
<el-table-column align="center" prop="leader" label="组长" min-width="100"></el-table-column>
@ -181,6 +184,7 @@ import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue';
import router from '@/router';
import TitleComponent from './TitleComponent.vue';
import * as echarts from 'echarts'; // 导入ECharts
import renwuImage from '@/assets/images/renwu.png';
// 搜索条件
const searchKeyword = ref('');
@ -228,6 +232,20 @@ const rawTeamData = ref([
}
]);
// 提取任务数据用于图表展示
const teamChartData = computed(() => {
return rawTeamData.value.map((team) => ({
name: team.name,
value: team.currentTasks, // 使用当前任务数
teamId: team.id
}));
});
// 计算总任务数
const totalTasks = computed(() => {
return teamChartData.value.reduce((sum, item) => sum + item.value, 0);
});
// 分页相关
const currentPage = ref(1);
const pageSize = ref(10);
@ -352,7 +370,7 @@ const handleInspectionManagement3 = () => {
// ECharts实例
let chartInstance = null;
// 初始化ECharts环形图
// 初始化ECharts图表 - 修改为环形图样式
const initChart = () => {
// 使用nextTick确保DOM已完全渲染
nextTick(() => {
@ -372,79 +390,100 @@ const initChart = () => {
chartInstance = echarts.init(chartDom);
// 准备图表数据
const allData = teamChartData.value;
// 定义颜色方案
const teamColors = [
'#1890ff', // 第一运维组 - 蓝色
'#faad14', // 第二运维组 - 黄色
'#722ed1' // 第三运维组 - 紫色
];
// 准备图表配置项
const option = {
backgroundColor: 'transparent',
// 提示框 - 显示详细数据
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)',
formatter: '{a} <br/>{b}: {c} ',
backgroundColor: 'rgba(255, 255, 255, 0.95)',
borderColor: '#e8e8e8',
borderWidth: 1,
textStyle: {
color: '#333'
color: '#333',
fontSize: 14
},
padding: 12,
borderRadius: 8,
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'
},
// 图例 - 在底部横向排列
legend: {
orient: 'vertical',
left: 10,
top: 'center',
orient: 'horizontal',
bottom: 10,
left: 'center',
itemWidth: 14,
itemHeight: 14,
textStyle: {
fontSize: 12,
color: '#666'
},
itemGap: 12
itemGap: 20,
// 当数据过多时启用分页
pageShow: allData.length > 6,
pageFormatter: '{current}/{total}'
},
// 系列数据 - 环形图
series: [
{
name: '已完成任务',
name: '每周任务',
type: 'pie',
radius: ['40%', '70%'],
center: ['60%', '50%'],
radius: ['50%', '70%'], // 调整内半径和外半径,使环形更宽
center: ['50%', '50%'], // 调整中心位置
avoidLabelOverlap: false,
// 扇区样式
itemStyle: {
borderRadius: 10,
borderRadius: 2,
borderColor: '#fff',
borderWidth: 2,
shadowBlur: 15,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.15)'
},
label: {
show: false,
position: 'center'
},
emphasis: {
scale: true,
scaleSize: 15,
label: {
show: true,
fontSize: 18,
fontWeight: 'bold',
color: '#333'
},
itemStyle: {
shadowBlur: 25,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.25)'
color: function (params) {
return teamColors[params.dataIndex % teamColors.length];
}
},
// 扇区标签 - 不显示外部标签
label: {
show: false
},
// 标签连接线 - 隐藏
labelLine: {
show: false
},
// 中心文本 - 使用富文本自定义样式
emphasis: {
scale: true,
scaleSize: 5,
label: {
show: false
}
},
// 动画效果
animationType: 'scale',
animationEasing: 'elasticOut',
animationDuration: 1500,
animationDelay: function (idx) {
return Math.random() * 300;
return idx * 150;
},
data: [
{ value: 19, name: '第一运维组', itemStyle: { color: '#1890ff' } },
{ value: 14, name: '第二运维组', itemStyle: { color: '#faad14' } },
{ value: 11, name: '第三运维组', itemStyle: { color: '#ff4d4f' } },
{ value: 4 + 8 + 13, name: '未完成', itemStyle: { color: '#f5f5f5' } }
]
// 任务数据
data: allData
}
]
};
@ -452,6 +491,41 @@ const initChart = () => {
// 设置图表配置项
chartInstance.setOption(option);
// 添加中心圆形白色背景和图片 - 使用ECharts的graphic组件
chartInstance.setOption({
graphic: {
elements: [
// 圆形白色背景
{
type: 'circle',
z: 90,
left: 'center',
top: 'center',
shape: {
r: 35 // 圆形半径
},
style: {
fill: '#ffffff',
stroke: '#f0f0f0',
lineWidth: 2
}
},
// 中心图片 - 使用本地图片renwu.png
{
type: 'image',
z: 100,
left: 'center',
top: 'center',
style: {
image: renwuImage,
width: 30,
height: 30
}
}
]
}
});
// 处理窗口大小变化
const handleResize = () => {
chartInstance.resize();
@ -481,6 +555,7 @@ onUnmounted(() => {
</script>
<style scoped>
/* 样式保持不变 */
.execution-records {
padding: 20px;
background-color: #f5f7fa;
@ -614,13 +689,28 @@ onUnmounted(() => {
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
/* 确保图表容器有明确的尺寸 */
/* 图表容器样式 */
.chart-container {
width: 100%;
height: 100%;
min-height: 280px; /* 增加最小高度确保图表可见 */
min-height: 320px;
}
/* 新增任务数标签样式 */
.task-count-label {
position: absolute;
bottom: 40px;
right: 40px;
background-color: #722ed1;
color: white;
padding: 6px 12px;
border-radius: 16px;
font-size: 14px;
font-weight: 500;
box-shadow: 0 2px 8px rgba(114, 46, 209, 0.3);
}
.team-header {
@ -793,6 +883,22 @@ onUnmounted(() => {
border-top: 1px dashed #f0f0f0;
}
/* 表格标题样式 */
.table-header-title {
border-radius: 12px;
padding: 16px 24px;
margin-bottom: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.table-header-title h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #303133;
display: inline-block;
}
/* 表格样式优化 */
.table-wrapper {
background-color: #fff;
@ -1025,7 +1131,7 @@ onUnmounted(() => {
/* 响应式调整图表大小 */
.chart-container {
min-height: 220px;
min-height: 280px;
}
}
</style>

View File

@ -14,7 +14,6 @@
<TitleComponent title="报修管理模块" subtitle="创建报修任务,跟进报修记录,管理维修进度"></TitleComponent>
<!-- 选项卡 -->
<!-- 选项卡和按钮组合 -->
<div class="tabs-wrapper">
<div style="display: flex; align-items: center; gap: 10px">
<el-button type="primary" @click="handleInspectionManagement1">报修任务</el-button>
@ -59,12 +58,13 @@
<!-- 任务卡片列表 -->
<div class="task-cards">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index" :class="task.leftLineClass">
<div class="task-header">
<div class="task-title">
{{ task.title }}
</div>
<div class="task-status" :class="task.statusClass">
<!-- 恢复优先级标签背景色样式 -->
<div class="task-status" :class="task.priorityClass">
{{ task.priority }}
</div>
</div>
@ -82,6 +82,11 @@
<span class="detail-label">维修人</span>
<span class="detail-value">{{ task.maintainer }}</span>
</div>
<!-- 恢复预计完成时间字段 -->
<div class="detail-item">
<span class="detail-label">预计完成</span>
<span class="detail-value">{{ task.expectedCompleteTime }}</span>
</div>
<div class="detail-item">
<span class="detail-label">状态</span>
<span class="detail-value">{{ task.statusText }}</span>
@ -164,7 +169,7 @@
<el-input v-model="createTaskForm.faultLocation" placeholder="例如A区102" />
</el-form-item>
<el-form-item label="上传图片(可选)*">
<el-form-item label="上传图片(可选)">
<div class="upload-container">
<div class="upload-box">
<i class="el-icon-plus avatar-uploader-icon"></i>
@ -212,17 +217,19 @@ const taskStatus = ref('');
const planType = ref('');
const executor = ref('');
// 任务数据
// 任务数据 - 恢复优先级标签样式和预计完成时间
const tasks = ref([
{
title: '服务器A1电源故障',
status: 'executing',
statusText: '处理中',
statusClass: 'status-high',
leftLineClass: 'left-line-high',
priorityClass: 'priority-high', // 恢复优先级标签样式类
priority: '高优先级',
reportTime: '2025-06-16 08:30',
reporter: '李明',
maintainer: '张明',
expectedCompleteTime: '2025-06-16 12:00', // 恢复预计完成时间
actionText: '跟进',
actionClass: 'follow-btn'
},
@ -230,11 +237,13 @@ const tasks = ref([
title: '机房环境检查',
status: 'pending',
statusText: '待处理',
statusClass: 'status-medium',
leftLineClass: 'left-line-medium',
priorityClass: 'priority-medium', // 恢复优先级标签样式类
priority: '中优先级',
reportTime: '2025-06-16 08:30',
reporter: '张伟',
maintainer: '未分配',
expectedCompleteTime: '2025-06-16 18:00', // 恢复预计完成时间
actionText: '分配',
actionClass: 'assign-btn'
},
@ -242,11 +251,13 @@ const tasks = ref([
title: '测试软件授权过期',
status: 'executing',
statusText: '处理中',
statusClass: 'status-low',
leftLineClass: 'left-line-low',
priorityClass: 'priority-low', // 恢复优先级标签样式类
priority: '低优先级',
reportTime: '2025-06-16 08:30',
reporter: '李明',
maintainer: '李阳',
expectedCompleteTime: '2025-06-17 09:00', // 恢复预计完成时间
actionText: '跟进',
actionClass: 'follow-btn'
},
@ -254,11 +265,13 @@ const tasks = ref([
title: '打印机卡纸故障',
status: 'completed',
statusText: '已完成',
statusClass: 'status-low',
leftLineClass: 'left-line-completed',
priorityClass: 'priority-low', // 恢复优先级标签样式类
priority: '低优先级',
reportTime: '2025-06-17 08:30',
reporter: '李明',
maintainer: '张明',
expectedCompleteTime: '2025-06-17 10:00', // 恢复预计完成时间
completeTime: '2025-06-17 09:15',
actionText: '评价',
actionClass: 'evaluate-btn'
@ -267,11 +280,13 @@ const tasks = ref([
title: '服务器A1电源故障',
status: 'executing',
statusText: '处理中',
statusClass: 'status-high',
leftLineClass: 'left-line-high',
priorityClass: 'priority-high',
priority: '高优先级',
reportTime: '2025-06-16 08:30',
reporter: '李明',
maintainer: '张明',
expectedCompleteTime: '2025-06-16 12:00',
actionText: '跟进',
actionClass: 'follow-btn'
},
@ -279,11 +294,13 @@ const tasks = ref([
title: '机房环境检查',
status: 'pending',
statusText: '待处理',
statusClass: 'status-medium',
leftLineClass: 'left-line-medium',
priorityClass: 'priority-medium',
priority: '中优先级',
reportTime: '2025-06-16 08:30',
reporter: '张伟',
maintainer: '未分配',
expectedCompleteTime: '2025-06-16 18:00',
actionText: '分配',
actionClass: 'assign-btn'
},
@ -291,11 +308,13 @@ const tasks = ref([
title: '测试软件授权过期',
status: 'executing',
statusText: '处理中',
statusClass: 'status-low',
leftLineClass: 'left-line-low',
priorityClass: 'priority-low',
priority: '低优先级',
reportTime: '2025-06-16 08:30',
reporter: '李明',
maintainer: '李阳',
expectedCompleteTime: '2025-06-17 09:00',
actionText: '跟进',
actionClass: 'follow-btn'
},
@ -303,11 +322,13 @@ const tasks = ref([
title: '打印机卡纸故障',
status: 'completed',
statusText: '已完成',
statusClass: 'status-low',
leftLineClass: 'left-line-completed',
priorityClass: 'priority-low',
priority: '低优先级',
reportTime: '2025-06-17 08:30',
reporter: '李明',
maintainer: '张明',
expectedCompleteTime: '2025-06-17 10:00',
completeTime: '2025-06-17 09:15',
actionText: '评价',
actionClass: 'evaluate-btn'
@ -360,7 +381,6 @@ const createTaskForm = ref({
const createTaskRules = {
repairName: [{ required: true, message: '请输入报修名称', trigger: 'blur' }],
briefDescription: [{ required: true, message: '请输入简要描述', trigger: 'blur' }],
repairType: [{ required: true, message: '请选择报修类型', trigger: 'change' }],
priority: [{ required: true, message: '请选择优先级', trigger: 'change' }],
detailedDescription: [{ required: true, message: '请输入详细描述', trigger: 'blur' }],
@ -828,7 +848,7 @@ const handleInspection7 = () => {
border-color: #0e42d2;
}
/* 任务卡片样式 */
/* 任务卡片样式 - 恢复优先级标签背景色 */
.task-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
@ -844,7 +864,7 @@ const handleInspection7 = () => {
transition: all 0.3s ease;
position: relative;
overflow: hidden;
min-height: 240px;
min-height: 260px; /* 增加高度以适应新增的预计完成时间 */
}
.task-actions {
@ -867,6 +887,7 @@ const handleInspection7 = () => {
padding: 6px 16px;
}
/* 左侧状态线样式 */
.task-card::before {
content: '';
position: absolute;
@ -876,19 +897,19 @@ const handleInspection7 = () => {
width: 4px;
}
.task-card.status-high::before {
.left-line-high::before {
background-color: #ff4d4f;
}
.task-card.status-medium::before {
.left-line-medium::before {
background-color: #fa8c16;
}
.task-card.status-low::before {
.left-line-low::before {
background-color: #1677ff;
}
.task-card.status-completed::before {
.left-line-completed::before {
background-color: #52c41a;
}
@ -913,6 +934,7 @@ const handleInspection7 = () => {
line-height: 1.4;
}
/* 恢复优先级标签背景色样式 */
.task-status {
padding: 4px 10px;
border-radius: 6px;
@ -921,34 +943,24 @@ const handleInspection7 = () => {
border: 1px solid transparent;
}
/* 高优先级状态 - 红色 */
.status-high {
.priority-high {
background-color: #fff2f0;
color: #ff4d4f;
border-color: #ffccc7;
}
/* 中优先级状态 - 橙色 */
.status-medium {
.priority-medium {
background-color: #fffbe6;
color: #fa8c16;
border-color: #ffe58f;
}
/* 低优先级状态 - 蓝色 */
.status-low {
.priority-low {
background-color: #e6f7ff;
color: #1677ff;
color: #1890ff;
border-color: #91d5ff;
}
/* 已完成状态 - 绿色 */
.status-completed {
background-color: #f6ffed;
color: #52c41a;
border-color: #b7eb8f;
}
.task-details {
margin-bottom: 16px;
}
@ -970,39 +982,6 @@ const handleInspection7 = () => {
word-break: break-all;
}
.delay-reason {
display: flex;
margin: 10px 0;
font-size: 13px;
padding-top: 8px;
border-top: 1px dashed #f0f2f5;
}
.progress-container {
display: flex;
flex-direction: column;
margin: 10px 0;
padding-top: 8px;
border-top: 1px dashed #f0f2f5;
z-index: 1;
}
.progress-bar {
flex: 1;
padding-left: 80px;
margin-top: 4px;
position: relative;
z-index: 1;
}
.progress-text {
position: absolute;
right: 0;
top: 0;
font-size: 12px;
color: #86909c;
}
.task-result {
display: flex;
margin: 10px 0;
@ -1011,14 +990,6 @@ const handleInspection7 = () => {
border-top: 1px dashed #f0f2f5;
}
.result-normal {
color: #00b42a;
}
.result-abnormal {
color: #f53f3f;
}
.task-actions {
display: flex;
justify-content: flex-end;

View File

@ -29,8 +29,7 @@
<div class="search-container">
<!-- 左侧统计数据和车辆图片组合 -->
<div class="stats-and-image">
<div class="vehicle-stats">
<div class="stats-container">
<!-- 车辆统计区域 -->
<div class="vehicle-stats">
<!-- 总车辆数 -->
<div class="stat-item">
@ -56,11 +55,11 @@
<div class="stat-value">{{ maintenanceVehicles }}</div>
<div class="stat-desc maintenance">预计2天后可用</div>
</div>
</div>
<!-- 车辆图片 -->
<img src="@/assets/images/car.png" class="img-car" alt="车辆图片" />
</div>
</div>
</div>
</div>
<!-- 右侧搜索区域 -->
<div class="search-integrated">
@ -399,12 +398,10 @@ const handleInspectionManagement3 = () => {
}
.search-box {
background-color: rgba(255, 255, 255, 0.95);
border-radius: 12px;
padding: 20px 24px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.5);
}
.search-label {
@ -416,18 +413,11 @@ const handleInspectionManagement3 = () => {
.stat-item {
flex: 1;
background-color: rgba(255, 255, 255, 0.95);
padding: 20px 28px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
min-width: 160px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.5);
}
.stat-item:hover {
transform: translateY(-5px) scale(1.02);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
border-color: rgba(255, 255, 255, 0.8);
}
.stat-value {
@ -446,7 +436,7 @@ const handleInspectionManagement3 = () => {
}
.stat-desc {
font-size: 13px;
font-size: 12px;
color: #606266;
opacity: 0.9;
}
@ -632,8 +622,8 @@ const handleInspectionManagement3 = () => {
color: #fff;
}
.img-car {
max-width: 350px;
max-height: 350px;
max-width: 400px;
max-height: 200px;
}
/* 导航栏样式 */
.navigation-tabs {

View File

@ -61,7 +61,7 @@
<div class="stat-label">本月派单总数</div>
<div class="stat-trend">较上月 <span class="trend-up"> 12%</span></div>
<div class="stat-icon">
<i class="el-icon-document"></i>
<img src="@/assets/images/paidan.png" alt="时间" class="stat-img" />
</div>
</div>
<div class="stat-card">
@ -69,7 +69,7 @@
<div class="stat-label">平均响应时间</div>
<div class="stat-trend">较上月 <span class="trend-down"> 5分钟</span></div>
<div class="stat-icon">
<i class="el-icon-clock"></i>
<img src="@/assets/images/shijian.png" alt="时间" class="stat-img" />
</div>
</div>
<div class="stat-card">
@ -77,7 +77,7 @@
<div class="stat-label">待接收工单</div>
<div class="stat-trend">较昨日 <span class="trend-up"> 2</span></div>
<div class="stat-icon warning">
<i class="el-icon-warning"></i>
<img src="@/assets/images/gongdan.png" alt="工单" class="stat-img" />
</div>
</div>
<div class="stat-card">
@ -85,7 +85,7 @@
<div class="stat-label">按时完成率</div>
<div class="stat-trend">较上月 <span class="trend-up"> 3%</span></div>
<div class="stat-icon success">
<i class="el-icon-check-circle"></i>
<img src="@/assets/images/wancheng.png" alt="完成" class="stat-img" />
</div>
</div>
</div>
@ -536,18 +536,25 @@ const handleInspectionManagement3 = () => {
.stat-card {
background-color: #fff;
border-radius: 8px;
padding: 20px;
border-radius: 12px;
padding: 24px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
position: relative;
overflow: hidden;
transition: all 0.3s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}
.stat-value {
font-size: 24px;
font-size: 28px;
font-weight: 600;
color: #1d2129;
margin-bottom: 8px;
line-height: 1.2;
}
.stat-label {
@ -571,27 +578,32 @@ const handleInspectionManagement3 = () => {
.stat-icon {
position: absolute;
top: 20px;
right: 20px;
width: 40px;
height: 40px;
border-radius: 8px;
top: 24px;
right: 24px;
width: 50px;
height: 50px;
border-radius: 12px;
background-color: #f0f7ff;
display: flex;
align-items: center;
justify-content: center;
color: #165dff;
font-size: 20px;
transition: all 0.3s ease;
}
.stat-icon.warning {
background-color: #fff7e6;
color: #fa8c16;
.stat-icon:hover {
transform: scale(1.05);
}
.stat-icon.success {
background-color: #f6ffed;
color: #52c41a;
/* 统计卡片图片样式 */
.stat-img {
width: 35px;
height: 35px;
object-fit: contain;
transition: all 0.3s ease;
}
.stat-icon:hover .stat-img {
transform: scale(1.1);
}
/* 表格样式 */

View File

@ -58,7 +58,7 @@
<!-- 任务卡片列表 -->
<div class="task-cards">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index" :class="task.statusClass">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index" :class="task.leftLineClass">
<!-- 顶部信息区域 -->
<div class="task-header">
<div class="task-title">
@ -69,7 +69,7 @@
</div>
</div>
<!-- 新增滚动内容容器 -->
<!-- 滚动内容容器 -->
<div class="task-content-scroll">
<div class="task-details">
<div class="detail-item">
@ -99,7 +99,7 @@
<span class="detail-value">{{ task.completeTime }}</span>
</div>
<!-- 增加一些示例数据来演示滚动效果 -->
<!-- 执行中状态的额外信息 -->
<div v-if="task.status === 'executing'" class="detail-item">
<span class="detail-label">开始时间</span>
<span class="detail-value">{{ task.startTime || '30分钟前' }}</span>
@ -187,7 +187,7 @@
<el-input v-model="createTaskForm.faultLocation" placeholder="例如A区102" />
</el-form-item>
<el-form-item label="上传图片(可选)*">
<el-form-item label="上传图片(可选)">
<div class="upload-container">
<div class="upload-box">
<i class="el-icon-plus avatar-uploader-icon"></i>
@ -240,18 +240,13 @@ const activeTab = ref('task');
// 根据故障类型获取对应的CSS类
const getFaultTypeClass = (faultType) => {
const typeMap = {
// 电力,设备故障为红色
'电力故障': 'electric',
'设备故障': 'equipment',
// 供水,设备损坏为黄色
'供水问题': 'water',
'设备损坏': 'damage',
// 其余默认使用基本样式(绿色)
'网络中断': '',
'制冷系统故障': '',
'安全问题': ''
'网络中断': 'network',
'制冷系统故障': 'cooling',
'安全问题': 'safety'
};
return typeMap[faultType] || '';
};
@ -263,13 +258,13 @@ const emergencyLevel = ref('all');
const planType = ref('all');
const executor = ref('all');
// 任务数据 - 添加了更多字段以展示滚动效果
// 任务数据 - 使用leftLineClass控制左侧状态线统一按钮样式
const tasks = ref([
{
title: '主配电室短路故障',
status: 'executing',
statusText: '抢修中',
statusClass: 'status-high',
leftLineClass: 'left-line-high', // 致命级-红色左侧线
priority: '致命',
reportTime: '10分钟前',
reporter: '李阳',
@ -284,10 +279,10 @@ const tasks = ref([
actionClass: 'follow-btn'
},
{
title: '主配电室短路故障',
title: '三楼卫生间漏水',
status: 'executing',
statusText: '抢修中',
statusClass: 'status-medium',
leftLineClass: 'left-line-medium', // 紧急级-黄色左侧线
priority: '紧急',
reportTime: '45分钟前',
reporter: '李阳',
@ -305,7 +300,7 @@ const tasks = ref([
title: '网络主干交换机故障',
status: 'completed',
statusText: '已完成',
statusClass: 'status-completed',
leftLineClass: 'left-line-completed', // 已完成-绿色左侧线
priority: '较危险',
reportTime: '1小时前',
reporter: '李阳',
@ -316,13 +311,13 @@ const tasks = ref([
completeTime: '2小时前',
remarks: '交换机电源模块故障,已更换备用模块',
actionText: '查看报告',
actionClass: 'view-btn'
actionClass: 'evaluate-btn'
},
{
title: '安全出口指示牌损坏',
status: 'pending',
statusText: '待处理',
statusClass: 'status-medium',
leftLineClass: 'left-line-medium', // 较危险级-黄色左侧线
priority: '较危险',
reportTime: '3小时前',
reporter: '李阳',
@ -338,13 +333,13 @@ const tasks = ref([
title: '制冷系统主压缩机故障',
status: 'executing',
statusText: '抢修中',
statusClass: 'status-high',
leftLineClass: 'left-line-high', // 致命级-红色左侧线
priority: '致命',
reportTime: '1小时前',
reporter: '李阳',
maintainer: '张明',
expectedCompleteTime: '45分钟内',
faultType: '设备故障',
faultType: '制冷系统故障',
faultLocation: '楼顶制冷机房',
startTime: '50分钟前',
progress: '30%',
@ -353,10 +348,10 @@ const tasks = ref([
actionClass: 'follow-btn'
},
{
title: '主配电室短路故障',
title: '地下室水泵压力不足',
status: 'executing',
statusText: '抢修中',
statusClass: 'status-medium',
leftLineClass: 'left-line-medium', // 紧急级-黄色左侧线
priority: '紧急',
reportTime: '45分钟前',
reporter: '李阳',
@ -374,8 +369,8 @@ const tasks = ref([
// 分页相关
const currentPage = ref(1);
const pageSize = ref(20);
const total = ref(6);
const pageSize = ref(8);
const total = ref(tasks.value.length);
// 状态排序映射
const statusOrder = {
@ -524,11 +519,10 @@ const handleInspection7 = () => {
min-height: 100vh;
}
/* 任务卡片样式修改 - 增加滚动功能 */
.task-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
@ -540,76 +534,61 @@ const handleInspection7 = () => {
transition: all 0.3s ease;
position: relative;
overflow: hidden;
/* 固定卡片高度 */
min-height: 280px;
display: flex;
flex-direction: column;
min-height: 300px;
}
/* 顶部装饰条样式 */
.task-card.status-high::before {
/* 左侧状态线样式 - 与报修管理页面保持一致 */
.task-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
top: 0;
bottom: 0;
width: 4px;
}
.task-card.status-medium::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
.left-line-high::before {
background-color: #ff4d4f;
}
.task-card.status-low::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
.left-line-medium::before {
background-color: #fa8c16;
}
.task-card.status-completed::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
.left-line-low::before {
background-color: #1677ff;
}
/* 添加滚动内容容器 */
.left-line-completed::before {
background-color: #52c41a;
}
/* 滚动内容容器 */
.task-content-scroll {
flex: 1;
overflow-y: auto;
padding-right: 8px; /* 为滚动条预留空间 */
margin-bottom: 10px;
/* 限制最大高度,超出则显示滚动条 */
max-height: 180px;
}
/* 滚动条样式保持不变 */
.task-content-scroll::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.task-content-scroll::-webkit-scrollbar-track {
background: #f1f1f1;
background: #f5f7fa;
border-radius: 3px;
}
.task-content-scroll::-webkit-scrollbar-thumb {
background: #c1c1c1;
background: #c0c4cc;
border-radius: 3px;
}
.task-content-scroll::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
background: #909399;
}
.task-header {
@ -638,16 +617,21 @@ const handleInspection7 = () => {
border: 1px solid transparent;
}
/* 不同故障类型的颜色 */
/* 电力,设备故障为红色 */
/* 故障类型标签样式 */
.task-type-tag {
background-color: #f6ffed;
color: #52c41a;
border-color: #b7eb8f;
}
.task-type-tag.electric,
.task-type-tag.equipment {
.task-type-tag.equipment,
.task-type-tag.cooling {
background-color: #fff2f0;
color: #ff4d4f;
border-color: #ffccc7;
}
/* 供水,设备损坏为黄色 */
.task-type-tag.water,
.task-type-tag.damage {
background-color: #fffbe6;
@ -655,13 +639,6 @@ const handleInspection7 = () => {
border-color: #ffe58f;
}
/* 其余为绿色 */
.task-type-tag {
background-color: #f6ffed;
color: #52c41a;
border-color: #b7eb8f;
}
.task-card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
@ -712,14 +689,11 @@ const handleInspection7 = () => {
z-index: 10;
}
.task-actions .el-button {
border-radius: 16px;
padding: 6px 16px;
}
/* 统一按钮样式 - 与报修管理页面保持一致 */
.action-btn {
font-size: 12px;
padding: 4px 12px;
font-size: 13px;
padding: 4px 10px;
border-radius: 16px;
}
.view-btn {
@ -734,6 +708,8 @@ const handleInspection7 = () => {
.follow-btn {
background-color: #165dff;
border-color: #165dff;
border-radius: 16px;
padding: 6px 16px;
}
.follow-btn:hover {
@ -744,6 +720,8 @@ const handleInspection7 = () => {
.assign-btn {
background-color: #ff7d00;
border-color: #ff7d00;
border-radius: 16px;
padding: 6px 16px;
}
.assign-btn:hover {
@ -751,6 +729,18 @@ const handleInspection7 = () => {
border-color: #e86a00;
}
.evaluate-btn {
background-color: #00b42a;
border-color: #00b42a;
border-radius: 16px;
padding: 6px 16px;
}
.evaluate-btn:hover {
background-color: #008718;
border-color: #008718;
}
/* 其他样式保持不变 */
.tabs-wrapper {
background-color: #fff;
@ -764,7 +754,7 @@ const handleInspection7 = () => {
background-color: #fff;
border-radius: 8px;
margin-bottom: 24px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
padding: 16px 24px;
}
@ -796,11 +786,25 @@ const handleInspection7 = () => {
background-color: #f2f3f5;
color: #303133;
border-color: #f2f3f5;
transition: all 0.2s ease;
border-radius: 4px;
}
.search-btn:hover {
background-color: #e5e6eb;
border-color: #e5e6eb;
}
.create-btn {
background-color: #165dff;
border-color: #165dff;
transition: all 0.2s ease;
border-radius: 4px;
}
.create-btn:hover {
background-color: #0e42d2;
border-color: #0e42d2;
}
.pagination-section {
@ -877,7 +881,7 @@ const handleInspection7 = () => {
color: #909399;
}
/* 弹窗和表单样式保持不变 */
/* 弹窗和表单样式 */
.beautiful-dialog {
border-radius: 12px;
overflow: hidden;
@ -889,6 +893,16 @@ const handleInspection7 = () => {
margin-bottom: 24px;
}
/* 弹窗按钮样式保持一致 */
.dialog-footer .el-button {
min-width: 80px;
height: 36px;
border-radius: 6px;
font-size: 14px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
margin: 0 8px;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.task-cards {

View File

@ -36,72 +36,45 @@
</div>
<div class="stats-grid">
<div class="stat-item total-personnel">
<div class="stat-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M16 12C16 14.2091 14.2091 16 12 16C9.79086 16 8 14.2091 8 12C8 9.79086 9.79086 8 12 8C14.2091 8 16 9.79086 16 12Z"
stroke="#165dff"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2Z"
stroke="#165dff"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="stat-value">{{ totalPersonnel }}</div>
<div class="stat-label">总人数</div>
<div class="stat-change">+2</div>
</div>
<div class="stat-item available-personnel">
<div class="stat-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 16V12M12 8H12.01M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z"
stroke="#19b949"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="stat-value">{{ availablePersonnel }}</div>
<div class="stat-label">在线可用</div>
<div class="stat-change">+2</div>
</div>
<!-- 总人数 -->
<div class="stat-item">
<div class="stat-value">{{ workingPersonnel }}</div>
<div class="stat-icon orange">
<img src="@/assets/images/renyuan.png" class="stat-icon-img" alt="总人数" />
</div>
<div class="stat-label">总人数</div>
<div class="stat-value">{{ totalPersonnel }}</div>
<div class="stat-desc">所有运维人员总数</div>
<div class="stat-change green">+1</div>
</div>
<!-- 在线可用 -->
<div class="stat-item">
<div class="stat-icon blue">
<img src="@/assets/images/zaixian.png" class="stat-icon-img" alt="在线可用" />
</div>
<div class="stat-label">在线可用</div>
<div class="stat-value">{{ availablePersonnel }}</div>
<div class="stat-desc">在线可以投入工作的人员</div>
<div class="stat-change green">+2</div>
</div>
<!-- 工作中 -->
<div class="stat-item">
<div class="stat-icon green">
<img src="@/assets/images/gongzuo.png" class="stat-icon-img" alt="工作中" />
</div>
<div class="stat-label">工作中</div>
<div class="stat-change">+1</div>
<div class="stat-value">{{ workingPersonnel }}</div>
<div class="stat-desc">工作中人数</div>
<div class="stat-change orange">1.2/</div>
</div>
<div class="stat-item resting-personnel">
<div class="stat-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M7 13a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0 1a5 5 0 1 1 0-10 5 5 0 0 1 0 10z"
stroke="#909399"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M17 13a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0 1a5 5 0 1 1 0-10 5 5 0 0 1 0 10z"
stroke="#909399"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<!-- 离线/休息 -->
<div class="stat-item">
<div class="stat-icon gray">
<img src="@/assets/images/lixian.png" class="stat-icon-img" alt="离线休息" />
</div>
<div class="stat-label">离线/休息</div>
<div class="stat-value">{{ restingPersonnel }}</div>
<div class="stat-label">离线休息</div>
<div class="stat-change">-1</div>
<div class="stat-desc">休假人员</div>
<div class="stat-change gray">休息离线的人员</div>
</div>
</div>
</div>
@ -516,7 +489,7 @@ const handleInspectionManagement3 = () => {
/* 左侧边栏样式 */
.sidebar {
width: 320px;
width: 400px;
flex-shrink: 0;
}
@ -539,6 +512,8 @@ const handleInspectionManagement3 = () => {
/* 图表容器 */
.chart-container {
border: 1px solid #f0f0f0;
border-radius: 20%;
margin-bottom: 32px;
display: flex;
flex-direction: column;
@ -555,57 +530,88 @@ const handleInspectionManagement3 = () => {
.stats-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
gap: 16px; /* 项之间的间距 */
}
/* 单个统计项:纵向居中,卡片化 */
.stat-item {
background-color: #f8fafc;
border-radius: 10px;
padding: 16px 12px;
background-color: #fff;
border-radius: 8px;
padding: 16px;
text-align: center;
border: 1px solid #f0f0f0;
transition: all 0.3s ease;
}
.stat-item:hover {
background-color: #ffffff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
transform: translateY(-1px);
}
.stat-value {
font-size: 24px;
font-weight: 700;
color: #2c3e50;
margin-bottom: 6px;
line-height: 1.2;
}
.stat-label {
font-size: 13px;
color: #606266;
margin-bottom: 4px;
font-weight: 500;
}
.stat-change {
font-size: 12px;
color: #52c41a;
font-weight: 500;
display: inline-flex;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03);
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
}
.stat-change::before {
content: '↗';
font-size: 10px;
/* 图标容器:圆形背景 + 颜色区分 */
.stat-icon {
width: 40px;
height: 40px;
border-radius: 50%; /* 圆形背景 */
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 8px;
}
/* 不同图标背景色 */
.stat-icon.orange {
background-color: #fff2e8;
}
.stat-icon.blue {
background-color: #e6f4ff;
}
.stat-icon.green {
background-color: #f6ffed;
}
.stat-icon.gray {
background-color: #f5f5f5;
}
/* 图标尺寸 */
.stat-icon-img {
width: 24px;
height: 24px;
object-fit: contain;
}
/* 标题:小字号 + 浅灰色 */
.stat-label {
font-size: 14px;
color: #666;
margin-bottom: 4px;
}
/* 数值:大字号 + 深灰色 + 加粗 */
.stat-value {
font-size: 20px;
font-weight: bold;
color: #333;
margin-bottom: 4px;
}
/* 描述:更小字号 + 浅灰色 */
.stat-desc {
font-size: 12px;
color: #999;
margin-bottom: 6px;
}
/* 变化/额外说明:彩色小字号 */
.stat-change {
font-size: 12px;
color: #52c41a;
}
.stat-change.green {
color: #00b42a;
} /* 绿色(增长) */
.stat-change.orange {
color: #ff7d00;
} /* 橙色(效率) */
.stat-change.gray {
color: #999;
} /* 灰色(说明) */
/* 主内容区域 */
.main-content {

View File

@ -3,22 +3,23 @@
<div class="inspection-tasks">
<div class="navigation-tabs">
<div class="nav-tab" @click="handleInspection1">待办事项</div>
<div class="nav-tab" @click="handleInspection2">巡检管理</div>
<div class="nav-tab active" @click="handleInspection3">试验管理</div>
<div class="nav-tab active" @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>
<!-- 页面标题 -->
<TitleComponent title="实验管理系统" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent>
<TitleComponent title="运维巡检管理" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent>
<!-- 选项卡 -->
<div class="tabs-wrapper">
<div style="display: flex; align-items: center; gap: 10px">
<el-button type="primary" @click="handleInspectionManagement1">实验计划</el-button>
<el-button type="primary" @click="handleInspectionManagement2">实验任务</el-button>
<el-button type="primary" @click="handleInspectionManagement3">实验记录</el-button>
<el-button type="primary" @click="handleInspectionManagement1">巡检计划</el-button>
<el-button type="primary" @click="handleInspectionManagement2">巡检任务</el-button>
<el-button type="primary" @click="handleInspectionManagement3">巡检记录</el-button>
</div>
</div>
@ -50,7 +51,7 @@
</el-select>
</div>
<div class="filter-actions">
<el-button type="primary" class="search-btn" @click="handleSearch"> 搜索 </el-button>
<el-button type="primary" class="search-btn">搜索</el-button>
<el-button type="primary" icon="el-icon-plus" class="create-btn" @click="handleCreateTask"> 手动创建任务 </el-button>
</div>
</div>
@ -58,12 +59,13 @@
<!-- 任务卡片列表 -->
<div class="task-cards">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index" :class="task.cardClass">
<div class="task-header">
<div class="task-title">
{{ task.title }}
</div>
<div class="task-status" :class="task.statusClass">
<div class="task-status" :class="task.tagClass">
<!-- 标签专用类名控制标签样式 -->
{{ task.statusText }}
</div>
</div>
@ -199,13 +201,14 @@ const taskStatus = ref('');
const planType = ref('');
const executor = ref('');
// 任务数据
// 任务数据 - 分离了卡片类和标签类
const tasks = ref([
{
title: '生产服务器日常巡检',
status: 'pending',
statusText: '待执行',
statusClass: 'status-pending',
cardClass: 'card-pending', // 卡片专用类(控制阴影和左侧线)
tagClass: 'tag-pending', // 标签专用类(控制标签样式)
planTime: '2025-06-16 08:30',
target: '生产服务器集群(12台)',
executor: '张明',
@ -217,7 +220,8 @@ const tasks = ref([
title: '机房环境检查',
status: 'delayed',
statusText: '已延期',
statusClass: 'status-delayed',
cardClass: 'card-delayed',
tagClass: 'tag-delayed',
planTime: '2025-06-16 08:30',
target: '机房温度、湿度、电源',
executor: '李华',
@ -230,7 +234,8 @@ const tasks = ref([
title: '网络设备安全巡检',
status: 'executing',
statusText: '执行中',
statusClass: 'status-executing',
cardClass: 'card-executing',
tagClass: 'tag-executing',
planTime: '2025-06-16 09:30',
target: '核心交换机、防火墙',
executor: '王强',
@ -244,7 +249,8 @@ const tasks = ref([
title: '数据库性能巡检',
status: 'completed',
statusText: '已完成',
statusClass: 'status-completed',
cardClass: 'card-completed',
tagClass: 'tag-completed',
planTime: '2025-06-16 10:30',
target: '生产数据库集群(2组)',
executor: '赵伟',
@ -258,7 +264,8 @@ const tasks = ref([
title: '生产服务器日常巡检',
status: 'pending',
statusText: '待执行',
statusClass: 'status-pending',
cardClass: 'card-pending',
tagClass: 'tag-pending',
planTime: '2025-06-16 13:30',
target: '生产服务器集群(12台)',
executor: '张明',
@ -270,7 +277,8 @@ const tasks = ref([
title: '机房环境检查',
status: 'delayed',
statusText: '已延期',
statusClass: 'status-delayed',
cardClass: 'card-delayed',
tagClass: 'tag-delayed',
planTime: '2025-06-16 14:00',
target: '机房温度、湿度、电源',
executor: '李华',
@ -283,7 +291,8 @@ const tasks = ref([
title: '网络设备安全巡检',
status: 'executing',
statusText: '执行中',
statusClass: 'status-executing',
cardClass: 'card-executing',
tagClass: 'tag-executing',
planTime: '2025-06-16 15:00',
target: '核心交换机、防火墙',
executor: '王强',
@ -297,7 +306,8 @@ const tasks = ref([
title: '数据库性能巡检',
status: 'completed',
statusText: '已完成',
statusClass: 'status-completed',
cardClass: 'card-completed',
tagClass: 'tag-completed',
planTime: '2025-06-16 16:00',
target: '生产数据库集群(2组)',
executor: '赵伟',
@ -408,13 +418,14 @@ const handleView = (task) => {
};
const handleInspectionManagement1 = () => {
router.push('/rili/shiyanguanli');
router.push('/rili/InspectionManagement');
};
const handleInspectionManagement2 = () => {
router.push('/rili/shiyanrenwu');
router.push('/rili/xunjianrenwu');
};
const handleInspectionManagement3 = () => {
router.push('/rili/shiyanjilu');
router.push('/rili/xunjianjihua');
};
const handleInspection1 = () => {
router.push('/rili/rili');
@ -455,37 +466,6 @@ const handleInspection7 = () => {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.custom-tabs {
border-bottom: none;
padding-top: 20px;
}
.custom-tabs .el-tabs__header {
margin: 0 -20px 0 -20px;
padding: 0 20px;
border-bottom: 1px solid #e4e7ed;
}
.custom-tabs .el-tabs__nav-wrap::after {
height: 0;
}
.custom-tabs .el-tabs__item {
font-size: 14px;
color: #606266;
padding: 12px 20px;
margin-right: 20px;
border-bottom: 2px solid transparent;
}
.custom-tabs .el-tabs__item.is-active {
color: #409eff;
border-bottom-color: #409eff;
}
.custom-tabs .el-tabs__item:hover {
color: #409eff;
}
/* 筛选栏样式 */
.filter-bar {
background-color: #fff;
@ -512,22 +492,10 @@ const handleInspection7 = () => {
height: 36px;
}
.filter-bar .el-select .el-input__inner {
border-radius: 4px;
border-color: #dcdfe6;
transition: all 0.2s ease;
}
.filter-bar .el-select .el-input__inner:focus {
border-color: #165dff;
box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1);
}
.filter-actions {
margin-left: auto;
display: flex;
gap: 12px;
flex-shrink: 0;
gap: 10px;
}
.search-btn {
@ -537,90 +505,76 @@ const handleInspection7 = () => {
transition: all 0.2s ease;
}
.search-btn:hover {
background-color: #e5e6eb;
color: #303133;
border-color: #e5e6eb;
}
.create-btn {
background-color: #165dff;
border-color: #165dff;
transition: all 0.2s ease;
}
.create-btn:hover {
background-color: #0e42d2;
border-color: #0e42d2;
}
/* 任务卡片样式 */
.task-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.task-card {
background-color: #fff;
border-radius: 16px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
padding: 16px 16px 60px 16px; /* 底部留出更多空间给按钮 */
transition: box-shadow 0.2s ease;
background-color: #fff; /* 确保卡片背景始终为白色 */
border-radius: 8px;
padding: 16px 16px 60px 24px; /* 左侧留空间给状态线 */
position: relative;
overflow: hidden;
min-height: 280px; /* 确保有足够高度显示所有内容 */
}
.task-actions {
display: flex;
justify-content: flex-end;
align-items: center;
padding-top: 12px;
border-top: 1px solid #f0f2f5;
position: absolute;
bottom: 16px;
right: 16px;
left: 16px;
background-color: #fff;
padding: 12px 0 0 0;
z-index: 10;
}
.task-actions .el-button {
border-radius: 16px;
padding: 6px 16px;
min-height: 280px;
transition: all 0.3s ease;
}
/* 卡片左侧状态竖线 - 仅用于左侧标识 */
.task-card::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
width: 6px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.05);
}
.task-card.status-pending::before {
/* 卡片阴影样式 - 与状态关联但不影响背景色 */
.card-pending {
box-shadow: 0 4px 16px rgba(22, 119, 255, 0.15);
}
.card-delayed {
box-shadow: 0 4px 16px rgba(255, 77, 79, 0.15);
}
.card-executing {
box-shadow: 0 4px 16px rgba(250, 140, 22, 0.15);
}
.card-completed {
box-shadow: 0 4px 16px rgba(82, 196, 26, 0.15);
}
/* 左侧状态线颜色 */
.card-pending::before {
background-color: #1677ff;
}
.task-card.status-delayed::before {
.card-delayed::before {
background-color: #ff4d4f;
}
.task-card.status-executing::before {
.card-executing::before {
background-color: #fa8c16;
}
.task-card.status-completed::before {
.card-completed::before {
background-color: #52c41a;
}
/* 卡片悬停效果 */
.task-card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1), 0 4px 16px rgba(0, 0, 0, 0.05);
}
.task-header {
@ -639,37 +593,34 @@ const handleInspection7 = () => {
line-height: 1.4;
}
/* 状态标签样式 - 仅标签有背景色 */
.task-status {
padding: 4px 12px;
border-radius: 16px;
padding: 4px 10px;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
border: 1px solid transparent;
}
/* 待执行状态 - 蓝色 */
.status-pending {
.tag-pending {
background-color: #e6f7ff;
color: #1677ff;
border-color: #91d5ff;
}
/* 已延期状态 - 红色 */
.status-delayed {
.tag-delayed {
background-color: #fff2f0;
color: #ff4d4f;
border-color: #ffccc7;
}
/* 执行中状态 - 黄色 */
.status-executing {
.tag-executing {
background-color: #fffbe6;
color: #fa8c16;
border-color: #ffe58f;
}
/* 已完成状态 - 绿色 */
.status-completed {
.tag-completed {
background-color: #f6ffed;
color: #52c41a;
border-color: #b7eb8f;
@ -721,14 +672,6 @@ const handleInspection7 = () => {
z-index: 1;
}
.progress-text {
position: absolute;
right: 0;
top: 0;
font-size: 12px;
color: #86909c;
}
.task-result {
display: flex;
margin: 10px 0;
@ -769,51 +712,26 @@ const handleInspection7 = () => {
color: #165dff;
}
.view-btn:hover {
color: #0e42d2;
background-color: #e8f3ff;
}
.start-btn {
background-color: #165dff;
border-color: #165dff;
}
.start-btn:hover {
background-color: #0e42d2;
border-color: #0e42d2;
}
.reschedule-btn {
background-color: #ff7d00;
border-color: #ff7d00;
}
.reschedule-btn:hover {
background-color: #e86a00;
border-color: #e86a00;
}
.complete-btn {
background-color: #00b42a;
border-color: #00b42a;
}
.complete-btn:hover {
background-color: #008718;
border-color: #008718;
}
.report-btn {
background-color: #86909c;
border-color: #86909c;
}
.report-btn:hover {
background-color: #6b7785;
border-color: #6b7785;
}
/* 分页区域样式 */
.pagination-section {
display: flex;
@ -821,53 +739,6 @@ const handleInspection7 = () => {
margin-top: 20px;
}
.pagination-controls .el-pagination {
margin: 0;
}
.pagination-controls .el-pagination button,
.pagination-controls .el-pagination .el-pager li {
min-width: 36px;
height: 36px;
line-height: 36px;
border-radius: 4px;
}
.pagination-controls .el-pagination .el-pager li.active {
background-color: #165dff;
color: #fff;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.task-cards {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
}
@media (max-width: 768px) {
.inspection-tasks {
padding: 16px;
}
.filter-container {
flex-direction: column;
align-items: stretch;
}
.filter-actions {
margin-left: 0;
justify-content: flex-end;
}
.filter-bar .el-select {
width: 100%;
}
.task-cards {
grid-template-columns: 1fr;
}
}
/* 导航栏样式 */
.navigation-tabs {
display: flex;
@ -905,8 +776,25 @@ const handleInspection7 = () => {
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3);
}
.nav-tab {
cursor: pointer;
user-select: none;
/* 响应式设计 */
@media (max-width: 1200px) {
.task-cards {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
}
@media (max-width: 768px) {
.inspection-tasks {
padding: 16px;
}
.filter-container {
flex-direction: column;
align-items: stretch;
}
.task-cards {
grid-template-columns: 1fr;
}
}
</style>

View File

@ -783,9 +783,7 @@ const handleInspectionManagement3 = () => {
background-color: #f5f7fa;
border-radius: 6px;
padding: 16px;
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.stat-card:hover {

View File

@ -10,6 +10,7 @@
<div class="nav-tab" @click="handleInspection6">工单管理</div>
<div class="nav-tab" @click="handleInspection7">运维组织</div>
</div>
<!-- 页面标题 -->
<TitleComponent title="运维巡检管理" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent>
@ -58,12 +59,12 @@
<!-- 任务卡片列表 -->
<div class="task-cards">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index">
<div class="task-card" v-for="(task, index) in pagedTasks" :key="index" :class="task.statusClass">
<div class="task-header">
<div class="task-title">
{{ task.title }}
</div>
<div class="task-status" :class="task.statusClass">
<div class="task-status" :class="task.tagClass">
{{ task.statusText }}
</div>
</div>
@ -199,13 +200,14 @@ const taskStatus = ref('');
const planType = ref('');
const executor = ref('');
// 任务数据
// 任务数据 - 分离卡片状态类和标签状态类
const tasks = ref([
{
title: '生产服务器日常巡检',
status: 'pending',
statusText: '待执行',
statusClass: 'status-pending',
statusClass: 'card-pending', // 仅用于卡片左侧线和阴影
tagClass: 'tag-pending', // 仅用于标签样式
planTime: '2025-06-16 08:30',
target: '生产服务器集群(12台)',
executor: '张明',
@ -217,7 +219,8 @@ const tasks = ref([
title: '机房环境检查',
status: 'delayed',
statusText: '已延期',
statusClass: 'status-delayed',
statusClass: 'card-delayed',
tagClass: 'tag-delayed',
planTime: '2025-06-16 08:30',
target: '机房温度、湿度、电源',
executor: '李华',
@ -230,7 +233,8 @@ const tasks = ref([
title: '网络设备安全巡检',
status: 'executing',
statusText: '执行中',
statusClass: 'status-executing',
statusClass: 'card-executing',
tagClass: 'tag-executing',
planTime: '2025-06-16 09:30',
target: '核心交换机、防火墙',
executor: '王强',
@ -244,7 +248,8 @@ const tasks = ref([
title: '数据库性能巡检',
status: 'completed',
statusText: '已完成',
statusClass: 'status-completed',
statusClass: 'card-completed',
tagClass: 'tag-completed',
planTime: '2025-06-16 10:30',
target: '生产数据库集群(2组)',
executor: '赵伟',
@ -258,7 +263,8 @@ const tasks = ref([
title: '生产服务器日常巡检',
status: 'pending',
statusText: '待执行',
statusClass: 'status-pending',
statusClass: 'card-pending',
tagClass: 'tag-pending',
planTime: '2025-06-16 13:30',
target: '生产服务器集群(12台)',
executor: '张明',
@ -270,7 +276,8 @@ const tasks = ref([
title: '机房环境检查',
status: 'delayed',
statusText: '已延期',
statusClass: 'status-delayed',
statusClass: 'card-delayed',
tagClass: 'tag-delayed',
planTime: '2025-06-16 14:00',
target: '机房温度、湿度、电源',
executor: '李华',
@ -283,7 +290,8 @@ const tasks = ref([
title: '网络设备安全巡检',
status: 'executing',
statusText: '执行中',
statusClass: 'status-executing',
statusClass: 'card-executing',
tagClass: 'tag-executing',
planTime: '2025-06-16 15:00',
target: '核心交换机、防火墙',
executor: '王强',
@ -297,7 +305,8 @@ const tasks = ref([
title: '数据库性能巡检',
status: 'completed',
statusText: '已完成',
statusClass: 'status-completed',
statusClass: 'card-completed',
tagClass: 'tag-completed',
planTime: '2025-06-16 16:00',
target: '生产数据库集群(2组)',
executor: '赵伟',
@ -456,37 +465,6 @@ const handleInspection7 = () => {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.custom-tabs {
border-bottom: none;
padding-top: 20px;
}
.custom-tabs .el-tabs__header {
margin: 0 -20px 0 -20px;
padding: 0 20px;
border-bottom: 1px solid #e4e7ed;
}
.custom-tabs .el-tabs__nav-wrap::after {
height: 0;
}
.custom-tabs .el-tabs__item {
font-size: 14px;
color: #606266;
padding: 12px 20px;
margin-right: 20px;
border-bottom: 2px solid transparent;
}
.custom-tabs .el-tabs__item.is-active {
color: #409eff;
border-bottom-color: #409eff;
}
.custom-tabs .el-tabs__item:hover {
color: #409eff;
}
/* 筛选栏样式 */
.filter-bar {
background-color: #fff;
@ -513,17 +491,6 @@ const handleInspection7 = () => {
height: 36px;
}
.filter-bar .el-select .el-input__inner {
border-radius: 4px;
border-color: #dcdfe6;
transition: all 0.2s ease;
}
.filter-bar .el-select .el-input__inner:focus {
border-color: #165dff;
box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1);
}
.filter-actions {
margin-left: auto;
display: flex;
@ -534,92 +501,74 @@ const handleInspection7 = () => {
background-color: #f2f3f5;
color: #303133;
border-color: #f2f3f5;
transition: all 0.2s ease;
}
.search-btn:hover {
background-color: #e5e6eb;
color: #303133;
border-color: #e5e6eb;
}
.create-btn {
background-color: #165dff;
border-color: #165dff;
transition: all 0.2s ease;
}
.create-btn:hover {
background-color: #0e42d2;
border-color: #0e42d2;
}
/* 任务卡片样式 */
.task-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.task-card {
background-color: #fff;
background-color: #fff; /* 强制卡片背景为白色 */
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
padding: 16px 16px 60px 16px; /* 底部留出更多空间给按钮 */
transition: box-shadow 0.2s ease;
padding: 16px 16px 60px 24px; /* 左侧留空间给状态线 */
position: relative;
overflow: hidden;
min-height: 280px; /* 确保有足够高度显示所有内容 */
min-height: 280px;
transition: all 0.3s ease;
}
.task-actions {
display: flex;
justify-content: flex-end;
align-items: center;
padding-top: 12px;
border-top: 1px solid #f0f2f5;
position: absolute;
bottom: 16px;
right: 16px;
left: 16px;
background-color: #fff;
padding: 12px 0 0 0;
z-index: 10;
}
.task-actions .el-button {
border-radius: 16px;
padding: 6px 16px;
}
/* 卡片左侧状态竖线 */
.task-card::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
width: 6px; /* 加宽状态线 */
box-shadow: 0 0 8px rgba(0, 0, 0, 0.05);
}
.task-card.status-pending::before {
/* 卡片状态类 - 仅控制左侧线和阴影 */
.card-pending::before {
background-color: #1677ff;
}
.task-card.status-delayed::before {
.card-delayed::before {
background-color: #ff4d4f;
}
.task-card.status-executing::before {
.card-executing::before {
background-color: #fa8c16;
}
.task-card.status-completed::before {
.card-completed::before {
background-color: #52c41a;
}
/* 卡片阴影效果 */
.card-pending {
box-shadow: 0 4px 16px rgba(22, 119, 255, 0.15);
}
.card-delayed {
box-shadow: 0 4px 16px rgba(255, 77, 79, 0.15);
}
.card-executing {
box-shadow: 0 4px 16px rgba(250, 140, 22, 0.15);
}
.card-completed {
box-shadow: 0 4px 16px rgba(82, 196, 26, 0.15);
}
.task-card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}
.task-header {
@ -635,43 +584,39 @@ const handleInspection7 = () => {
font-size: 16px;
font-weight: 500;
color: #1d2129;
line-height: 1.4;
}
/* 状态标签样式 - 仅作用于标签本身 */
.task-status {
padding: 4px 10px;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
border: 1px solid transparent;
}
/* 待执行状态 - 蓝色 */
.status-pending {
/* 标签状态 - 仅控制标签样式 */
.tag-pending {
background-color: #e6f7ff;
color: #1677ff;
border-color: #91d5ff;
border: 1px solid #91d5ff;
}
/* 已延期状态 - 红色 */
.status-delayed {
.tag-delayed {
background-color: #fff2f0;
color: #ff4d4f;
border-color: #ffccc7;
border: 1px solid #ffccc7;
}
/* 执行中状态 - 黄色 */
.status-executing {
.tag-executing {
background-color: #fffbe6;
color: #fa8c16;
border-color: #ffe58f;
border: 1px solid #ffe58f;
}
/* 已完成状态 - 绿色 */
.status-completed {
.tag-completed {
background-color: #f6ffed;
color: #52c41a;
border-color: #b7eb8f;
border: 1px solid #b7eb8f;
}
.task-details {
@ -709,23 +654,12 @@ const handleInspection7 = () => {
margin: 10px 0;
padding-top: 8px;
border-top: 1px dashed #f0f2f5;
z-index: 1;
}
.progress-bar {
flex: 1;
padding-left: 80px;
margin-top: 4px;
position: relative;
z-index: 1;
}
.progress-text {
position: absolute;
right: 0;
top: 0;
font-size: 12px;
color: #86909c;
}
.task-result {
@ -755,7 +689,6 @@ const handleInspection7 = () => {
right: 16px;
left: 16px;
background-color: #fff;
padding: 12px 0 0 0;
z-index: 10;
}
@ -768,51 +701,26 @@ const handleInspection7 = () => {
color: #165dff;
}
.view-btn:hover {
color: #0e42d2;
background-color: #e8f3ff;
}
.start-btn {
background-color: #165dff;
border-color: #165dff;
}
.start-btn:hover {
background-color: #0e42d2;
border-color: #0e42d2;
}
.reschedule-btn {
background-color: #ff7d00;
border-color: #ff7d00;
}
.reschedule-btn:hover {
background-color: #e86a00;
border-color: #e86a00;
}
.complete-btn {
background-color: #00b42a;
border-color: #00b42a;
}
.complete-btn:hover {
background-color: #008718;
border-color: #008718;
}
.report-btn {
background-color: #86909c;
border-color: #86909c;
}
.report-btn:hover {
background-color: #6b7785;
border-color: #6b7785;
}
/* 分页区域样式 */
.pagination-section {
display: flex;
@ -820,53 +728,6 @@ const handleInspection7 = () => {
margin-top: 20px;
}
.pagination-controls .el-pagination {
margin: 0;
}
.pagination-controls .el-pagination button,
.pagination-controls .el-pagination .el-pager li {
min-width: 36px;
height: 36px;
line-height: 36px;
border-radius: 4px;
}
.pagination-controls .el-pagination .el-pager li.active {
background-color: #165dff;
color: #fff;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.task-cards {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
}
@media (max-width: 768px) {
.inspection-tasks {
padding: 16px;
}
.filter-container {
flex-direction: column;
align-items: stretch;
}
.filter-actions {
margin-left: 0;
justify-content: flex-end;
}
.filter-bar .el-select {
width: 100%;
}
.task-cards {
grid-template-columns: 1fr;
}
}
/* 导航栏样式 */
.navigation-tabs {
display: flex;
@ -904,8 +765,25 @@ const handleInspection7 = () => {
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3);
}
.nav-tab {
cursor: pointer;
user-select: none;
/* 响应式设计 */
@media (max-width: 1200px) {
.task-cards {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
}
@media (max-width: 768px) {
.inspection-tasks {
padding: 16px;
}
.filter-container {
flex-direction: column;
align-items: stretch;
}
.task-cards {
grid-template-columns: 1fr;
}
}
</style>