801 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			801 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | ||
|   <div>
 | ||
|     <div class="inspection-tasks">
 | ||
|       <div class="navigation-tabs">
 | ||
|         <div class="nav-tab" @click="handleInspection1">待办事项</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>
 | ||
| 
 | ||
|       <!-- 选项卡 -->
 | ||
|       <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>
 | ||
|         </div>
 | ||
|       </div>
 | ||
| 
 | ||
|       <!-- 筛选栏 -->
 | ||
|       <div class="filter-bar">
 | ||
|         <div class="filter-container">
 | ||
|           <div class="filter-item">
 | ||
|             <el-select v-model="taskStatus" placeholder="任务状态">
 | ||
|               <el-option label="待执行" value="pending"></el-option>
 | ||
|               <el-option label="执行中" value="executing"></el-option>
 | ||
|               <el-option label="已延期" value="delayed"></el-option>
 | ||
|               <el-option label="已完成" value="completed"></el-option>
 | ||
|             </el-select>
 | ||
|           </div>
 | ||
|           <div class="filter-item">
 | ||
|             <el-select v-model="planType" placeholder="全部计划">
 | ||
|               <el-option label="每日巡检计划" value="daily"></el-option>
 | ||
|               <el-option label="每周巡检计划" value="weekly"></el-option>
 | ||
|               <el-option label="每月巡检计划" value="monthly"></el-option>
 | ||
|               <el-option label="每季度巡检计划" value="quarterly"></el-option>
 | ||
|             </el-select>
 | ||
|           </div>
 | ||
|           <div class="filter-item">
 | ||
|             <el-select v-model="executor" placeholder="执行人">
 | ||
|               <el-option label="全部人员" value="all"></el-option>
 | ||
|               <el-option label="张明" value="zhangming"></el-option>
 | ||
|               <el-option label="李华" value="lihua"></el-option>
 | ||
|               <el-option label="王强" value="wangqiang"></el-option>
 | ||
|             </el-select>
 | ||
|           </div>
 | ||
|           <div class="filter-actions">
 | ||
|             <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>
 | ||
|       </div>
 | ||
| 
 | ||
|       <!-- 任务卡片列表 -->
 | ||
|       <div class="task-cards">
 | ||
|         <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.tagClass">
 | ||
|               <!-- 标签专用类名,控制标签样式 -->
 | ||
|               {{ task.statusText }}
 | ||
|             </div>
 | ||
|           </div>
 | ||
| 
 | ||
|           <div class="task-details">
 | ||
|             <div class="detail-item">
 | ||
|               <span class="detail-label">计划时间</span>
 | ||
|               <span class="detail-value">{{ task.planTime }}</span>
 | ||
|             </div>
 | ||
|             <div class="detail-item">
 | ||
|               <span class="detail-label">巡检对象</span>
 | ||
|               <span class="detail-value">{{ task.target }}</span>
 | ||
|             </div>
 | ||
|             <div class="detail-item">
 | ||
|               <span class="detail-label">执行人</span>
 | ||
|               <span class="detail-value">{{ task.executor }}</span>
 | ||
|             </div>
 | ||
|             <div class="detail-item">
 | ||
|               <span class="detail-label">关联计划</span>
 | ||
|               <span class="detail-value">{{ task.relatedPlan }}</span>
 | ||
|             </div>
 | ||
| 
 | ||
|             <!-- 特定状态的额外信息 -->
 | ||
|             <div v-if="task.status === 'delayed'" class="delay-reason">
 | ||
|               <span class="detail-label">延期原因</span>
 | ||
|               <span class="detail-value">{{ task.delayReason }}</span>
 | ||
|             </div>
 | ||
| 
 | ||
|             <div v-if="task.status === 'executing'" class="progress-container">
 | ||
|               <span class="detail-label">完成进度</span>
 | ||
|               <div class="progress-bar">
 | ||
|                 <el-progress :percentage="task.progress" stroke-width="6" :stroke-color="task.progressColor"></el-progress>
 | ||
|               </div>
 | ||
|             </div>
 | ||
| 
 | ||
|             <div v-if="task.status === 'completed'" class="task-result">
 | ||
|               <span class="detail-label">结果</span>
 | ||
|               <span class="detail-value" :class="task.resultClass">{{ task.result }}</span>
 | ||
|             </div>
 | ||
|           </div>
 | ||
| 
 | ||
|           <div class="task-actions">
 | ||
|             <el-button type="text" class="action-btn view-btn" @click="handleView(task)"> 详情 </el-button>
 | ||
|             <el-button type="primary" :class="task.actionClass" @click="handleAction(task)">
 | ||
|               {{ task.actionText }}
 | ||
|             </el-button>
 | ||
|           </div>
 | ||
|         </div>
 | ||
|       </div>
 | ||
| 
 | ||
|       <!-- 分页区域 -->
 | ||
|       <div class="pagination-section">
 | ||
|         <div class="pagination-controls">
 | ||
|           <el-pagination
 | ||
|             @size-change="handleSizeChange"
 | ||
|             @current-change="handleCurrentChange"
 | ||
|             :current-page="currentPage"
 | ||
|             :page-sizes="[8, 12, 16, 20]"
 | ||
|             :page-size="pageSize"
 | ||
|             layout="prev, pager, next, jumper"
 | ||
|             :total="total"
 | ||
|             background
 | ||
|           >
 | ||
|           </el-pagination>
 | ||
|         </div>
 | ||
|       </div>
 | ||
| 
 | ||
|       <!-- 添加新任务弹窗 -->
 | ||
|       <el-dialog v-model="createTaskDialogVisible" title="添加新任务" width="500px" :before-close="handleCancelCreateTask">
 | ||
|         <el-form ref="createTaskFormRef" :model="createTaskForm" :rules="createTaskRules" label-width="80px">
 | ||
|           <el-form-item label="任务名称" prop="taskName">
 | ||
|             <el-input v-model="createTaskForm.taskName" placeholder="输入任务名称" />
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <el-form-item label="巡检对象" prop="inspectionTarget">
 | ||
|             <el-input v-model="createTaskForm.inspectionTarget" placeholder="输入巡检内容" />
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <el-form-item label="时间" prop="timeRange">
 | ||
|             <el-date-picker
 | ||
|               v-model="createTaskForm.timeRange"
 | ||
|               type="datetimerange"
 | ||
|               start-placeholder="开始时间"
 | ||
|               end-placeholder="结束时间"
 | ||
|               format="YYYY-MM-DD HH:mm"
 | ||
|               value-format="YYYY-MM-DD HH:mm"
 | ||
|               placeholder="选择时间范围"
 | ||
|             />
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <el-form-item label="关联计划">
 | ||
|             <el-select v-model="createTaskForm.relatedPlan" placeholder="选择关联计划">
 | ||
|               <el-option label="全部计划" value="all" />
 | ||
|               <el-option label="每日巡检计划" value="daily" />
 | ||
|               <el-option label="每周巡检计划" value="weekly" />
 | ||
|               <el-option label="每月巡检计划" value="monthly" />
 | ||
|               <el-option label="每季度巡检计划" value="quarterly" />
 | ||
|             </el-select>
 | ||
|           </el-form-item>
 | ||
| 
 | ||
|           <el-form-item label="执行人">
 | ||
|             <el-select v-model="createTaskForm.executor" placeholder="选择执行人">
 | ||
|               <el-option label="全部人员" value="all" />
 | ||
|               <el-option label="张明" value="zhangming" />
 | ||
|               <el-option label="李华" value="lihua" />
 | ||
|               <el-option label="王强" value="wangqiang" />
 | ||
|               <el-option label="赵伟" value="zhaowei" />
 | ||
|             </el-select>
 | ||
|           </el-form-item>
 | ||
|         </el-form>
 | ||
| 
 | ||
|         <template #footer>
 | ||
|           <span class="dialog-footer">
 | ||
|             <el-button @click="handleCancelCreateTask">取消</el-button>
 | ||
|             <el-button type="primary" @click="handleSaveTask">保存任务</el-button>
 | ||
|           </span>
 | ||
|         </template>
 | ||
|       </el-dialog>
 | ||
|     </div>
 | ||
|   </div>
 | ||
| </template>
 | ||
| 
 | ||
| <script setup>
 | ||
| import { ref, computed } from 'vue';
 | ||
| import router from '@/router';
 | ||
| import TitleComponent from './TitleComponent.vue';
 | ||
| 
 | ||
| // 激活的选项卡
 | ||
| const activeTab = ref('task');
 | ||
| 
 | ||
| // 筛选条件
 | ||
| const taskStatus = ref('');
 | ||
| const planType = ref('');
 | ||
| const executor = ref('');
 | ||
| 
 | ||
| // 任务数据 - 分离了卡片类和标签类
 | ||
| const tasks = ref([
 | ||
|   {
 | ||
|     title: '生产服务器日常巡检',
 | ||
|     status: 'pending',
 | ||
|     statusText: '待执行',
 | ||
|     cardClass: 'card-pending', // 卡片专用类(控制阴影和左侧线)
 | ||
|     tagClass: 'tag-pending', // 标签专用类(控制标签样式)
 | ||
|     planTime: '2025-06-16 08:30',
 | ||
|     target: '生产服务器集群(12台)',
 | ||
|     executor: '张明',
 | ||
|     relatedPlan: '每日巡检计划',
 | ||
|     actionText: '开始执行',
 | ||
|     actionClass: 'start-btn'
 | ||
|   },
 | ||
|   {
 | ||
|     title: '机房环境检查',
 | ||
|     status: 'delayed',
 | ||
|     statusText: '已延期',
 | ||
|     cardClass: 'card-delayed',
 | ||
|     tagClass: 'tag-delayed',
 | ||
|     planTime: '2025-06-16 08:30',
 | ||
|     target: '机房温度、湿度、电源',
 | ||
|     executor: '李华',
 | ||
|     relatedPlan: '每周巡检计划',
 | ||
|     delayReason: '设备维修处理中',
 | ||
|     actionText: '重新安排',
 | ||
|     actionClass: 'reschedule-btn'
 | ||
|   },
 | ||
|   {
 | ||
|     title: '网络设备安全巡检',
 | ||
|     status: 'executing',
 | ||
|     statusText: '执行中',
 | ||
|     cardClass: 'card-executing',
 | ||
|     tagClass: 'tag-executing',
 | ||
|     planTime: '2025-06-16 09:30',
 | ||
|     target: '核心交换机、防火墙',
 | ||
|     executor: '王强',
 | ||
|     relatedPlan: '每周巡检计划',
 | ||
|     progress: 60,
 | ||
|     progressColor: '#FF7D00',
 | ||
|     actionText: '完成',
 | ||
|     actionClass: 'complete-btn'
 | ||
|   },
 | ||
|   {
 | ||
|     title: '数据库性能巡检',
 | ||
|     status: 'completed',
 | ||
|     statusText: '已完成',
 | ||
|     cardClass: 'card-completed',
 | ||
|     tagClass: 'tag-completed',
 | ||
|     planTime: '2025-06-16 10:30',
 | ||
|     target: '生产数据库集群(2组)',
 | ||
|     executor: '赵伟',
 | ||
|     relatedPlan: '每月巡检计划',
 | ||
|     result: '正常',
 | ||
|     resultClass: 'result-normal',
 | ||
|     actionText: '查看报告',
 | ||
|     actionClass: 'report-btn'
 | ||
|   },
 | ||
|   {
 | ||
|     title: '生产服务器日常巡检',
 | ||
|     status: 'pending',
 | ||
|     statusText: '待执行',
 | ||
|     cardClass: 'card-pending',
 | ||
|     tagClass: 'tag-pending',
 | ||
|     planTime: '2025-06-16 13:30',
 | ||
|     target: '生产服务器集群(12台)',
 | ||
|     executor: '张明',
 | ||
|     relatedPlan: '每日巡检计划',
 | ||
|     actionText: '开始执行',
 | ||
|     actionClass: 'start-btn'
 | ||
|   },
 | ||
|   {
 | ||
|     title: '机房环境检查',
 | ||
|     status: 'delayed',
 | ||
|     statusText: '已延期',
 | ||
|     cardClass: 'card-delayed',
 | ||
|     tagClass: 'tag-delayed',
 | ||
|     planTime: '2025-06-16 14:00',
 | ||
|     target: '机房温度、湿度、电源',
 | ||
|     executor: '李华',
 | ||
|     relatedPlan: '每周巡检计划',
 | ||
|     delayReason: '设备维修处理中',
 | ||
|     actionText: '重新安排',
 | ||
|     actionClass: 'reschedule-btn'
 | ||
|   },
 | ||
|   {
 | ||
|     title: '网络设备安全巡检',
 | ||
|     status: 'executing',
 | ||
|     statusText: '执行中',
 | ||
|     cardClass: 'card-executing',
 | ||
|     tagClass: 'tag-executing',
 | ||
|     planTime: '2025-06-16 15:00',
 | ||
|     target: '核心交换机、防火墙',
 | ||
|     executor: '王强',
 | ||
|     relatedPlan: '每周巡检计划',
 | ||
|     progress: 35,
 | ||
|     progressColor: '#FF7D00',
 | ||
|     actionText: '完成',
 | ||
|     actionClass: 'complete-btn'
 | ||
|   },
 | ||
|   {
 | ||
|     title: '数据库性能巡检',
 | ||
|     status: 'completed',
 | ||
|     statusText: '已完成',
 | ||
|     cardClass: 'card-completed',
 | ||
|     tagClass: 'tag-completed',
 | ||
|     planTime: '2025-06-16 16:00',
 | ||
|     target: '生产数据库集群(2组)',
 | ||
|     executor: '赵伟',
 | ||
|     relatedPlan: '每月巡检计划',
 | ||
|     result: '正常',
 | ||
|     resultClass: 'result-normal',
 | ||
|     actionText: '查看报告',
 | ||
|     actionClass: 'report-btn'
 | ||
|   }
 | ||
| ]);
 | ||
| 
 | ||
| // 分页相关
 | ||
| const currentPage = ref(1);
 | ||
| const pageSize = ref(8);
 | ||
| const total = ref(tasks.value.length);
 | ||
| 
 | ||
| // 状态排序映射
 | ||
| const statusOrder = {
 | ||
|   pending: 0, // 待完成
 | ||
|   delayed: 1, // 已延期
 | ||
|   executing: 2, // 执行中
 | ||
|   completed: 3 // 已完成
 | ||
| };
 | ||
| 
 | ||
| // 分页处理后的数据(含排序)
 | ||
| const pagedTasks = computed(() => {
 | ||
|   // 先按状态排序
 | ||
|   const sortedTasks = [...tasks.value].sort((a, b) => {
 | ||
|     return statusOrder[a.status] - statusOrder[b.status];
 | ||
|   });
 | ||
| 
 | ||
|   // 再进行分页
 | ||
|   const startIndex = (currentPage.value - 1) * pageSize.value;
 | ||
|   const endIndex = startIndex + pageSize.value;
 | ||
|   return sortedTasks.slice(startIndex, endIndex);
 | ||
| });
 | ||
| 
 | ||
| // 搜索处理
 | ||
| const handleSearch = () => {
 | ||
|   currentPage.value = 1; // 重置到第一页
 | ||
|   // 实际应用中这里会根据筛选条件过滤数据
 | ||
| };
 | ||
| 
 | ||
| // 创建任务弹窗相关
 | ||
| const createTaskDialogVisible = ref(false);
 | ||
| const createTaskForm = ref({
 | ||
|   taskName: '',
 | ||
|   inspectionTarget: '',
 | ||
|   timeRange: [],
 | ||
|   relatedPlan: 'all',
 | ||
|   executor: 'all'
 | ||
| });
 | ||
| 
 | ||
| const createTaskRules = {
 | ||
|   taskName: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
 | ||
|   inspectionTarget: [{ required: true, message: '请输入巡检对象', trigger: 'blur' }],
 | ||
|   timeRange: [{ required: true, message: '请选择时间范围', trigger: 'change' }]
 | ||
| };
 | ||
| 
 | ||
| // 创建任务
 | ||
| const handleCreateTask = () => {
 | ||
|   createTaskDialogVisible.value = true;
 | ||
| };
 | ||
| 
 | ||
| // 保存任务
 | ||
| const handleSaveTask = () => {
 | ||
|   // 模拟保存任务逻辑
 | ||
|   console.log('保存任务:', createTaskForm.value);
 | ||
|   // 关闭弹窗
 | ||
|   createTaskDialogVisible.value = false;
 | ||
|   // 重置表单
 | ||
|   createTaskForm.value = {
 | ||
|     taskName: '',
 | ||
|     inspectionTarget: '',
 | ||
|     timeRange: [],
 | ||
|     relatedPlan: 'all',
 | ||
|     executor: 'all'
 | ||
|   };
 | ||
|   // 这里可以添加成功提示和刷新任务列表的逻辑
 | ||
| };
 | ||
| 
 | ||
| // 取消创建任务
 | ||
| const handleCancelCreateTask = () => {
 | ||
|   createTaskDialogVisible.value = false;
 | ||
|   // 重置表单
 | ||
|   createTaskForm.value = {
 | ||
|     taskName: '',
 | ||
|     inspectionTarget: '',
 | ||
|     timeRange: [],
 | ||
|     relatedPlan: 'all',
 | ||
|     executor: 'all'
 | ||
|   };
 | ||
| };
 | ||
| 
 | ||
| // 分页事件
 | ||
| const handleSizeChange = (val) => {
 | ||
|   pageSize.value = val;
 | ||
|   currentPage.value = 1;
 | ||
| };
 | ||
| 
 | ||
| const handleCurrentChange = (val) => {
 | ||
|   currentPage.value = val;
 | ||
| };
 | ||
| 
 | ||
| // 查看任务详情
 | ||
| const handleView = (task) => {
 | ||
|   console.log('查看任务详情:', task);
 | ||
| };
 | ||
| 
 | ||
| const handleInspectionManagement1 = () => {
 | ||
|   router.push('/rili/InspectionManagement');
 | ||
| };
 | ||
| 
 | ||
| const handleInspectionManagement2 = () => {
 | ||
|   router.push('/rili/xunjianrenwu');
 | ||
| };
 | ||
| const handleInspectionManagement3 = () => {
 | ||
|   router.push('/rili/xunjianjihua');
 | ||
| };
 | ||
| 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>
 | ||
| .inspection-tasks {
 | ||
|   padding: 20px;
 | ||
|   background-color: #f5f7fa;
 | ||
|   min-height: 100vh;
 | ||
| }
 | ||
| 
 | ||
| /* 选项卡样式 */
 | ||
| .tabs-wrapper {
 | ||
|   background-color: #fff;
 | ||
|   padding: 20px;
 | ||
|   border-radius: 8px;
 | ||
|   margin-bottom: 16px;
 | ||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
 | ||
| }
 | ||
| 
 | ||
| /* 筛选栏样式 */
 | ||
| .filter-bar {
 | ||
|   background-color: #fff;
 | ||
|   border-radius: 8px;
 | ||
|   margin-bottom: 24px;
 | ||
|   box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
 | ||
|   padding: 16px 24px;
 | ||
| }
 | ||
| 
 | ||
| .filter-container {
 | ||
|   display: flex;
 | ||
|   align-items: center;
 | ||
|   flex-wrap: wrap;
 | ||
|   gap: 16px;
 | ||
|   width: 100%;
 | ||
| }
 | ||
| 
 | ||
| .filter-item {
 | ||
|   flex-shrink: 0;
 | ||
| }
 | ||
| 
 | ||
| .filter-bar .el-select {
 | ||
|   width: 180px;
 | ||
|   height: 36px;
 | ||
| }
 | ||
| 
 | ||
| .filter-actions {
 | ||
|   margin-left: auto;
 | ||
|   display: flex;
 | ||
|   gap: 10px;
 | ||
| }
 | ||
| 
 | ||
| .search-btn {
 | ||
|   background-color: #f2f3f5;
 | ||
|   color: #303133;
 | ||
|   border-color: #f2f3f5;
 | ||
|   transition: all 0.2s ease;
 | ||
| }
 | ||
| 
 | ||
| .create-btn {
 | ||
|   background-color: #165dff;
 | ||
|   border-color: #165dff;
 | ||
|   transition: all 0.2s ease;
 | ||
| }
 | ||
| 
 | ||
| /* 任务卡片样式 */
 | ||
| .task-cards {
 | ||
|   display: grid;
 | ||
|   grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
 | ||
|   gap: 20px;
 | ||
|   margin-bottom: 30px;
 | ||
| }
 | ||
| 
 | ||
| .task-card {
 | ||
|   background-color: #fff; /* 确保卡片背景始终为白色 */
 | ||
|   border-radius: 8px;
 | ||
|   padding: 16px 16px 60px 24px; /* 左侧留空间给状态线 */
 | ||
|   position: relative;
 | ||
|   overflow: hidden;
 | ||
|   min-height: 280px;
 | ||
|   transition: all 0.3s ease;
 | ||
| }
 | ||
| 
 | ||
| /* 卡片左侧状态竖线 - 仅用于左侧标识 */
 | ||
| .task-card::before {
 | ||
|   content: '';
 | ||
|   position: absolute;
 | ||
|   left: 0;
 | ||
|   top: 0;
 | ||
|   bottom: 0;
 | ||
|   width: 6px;
 | ||
|   box-shadow: 0 0 8px rgba(0, 0, 0, 0.05);
 | ||
| }
 | ||
| 
 | ||
| /* 卡片阴影样式 - 与状态关联但不影响背景色 */
 | ||
| .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;
 | ||
| }
 | ||
| .card-delayed::before {
 | ||
|   background-color: #ff4d4f;
 | ||
| }
 | ||
| .card-executing::before {
 | ||
|   background-color: #fa8c16;
 | ||
| }
 | ||
| .card-completed::before {
 | ||
|   background-color: #52c41a;
 | ||
| }
 | ||
| 
 | ||
| /* 卡片悬停效果 */
 | ||
| .task-card:hover {
 | ||
|   transform: translateY(-3px);
 | ||
|   box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1), 0 4px 16px rgba(0, 0, 0, 0.05);
 | ||
| }
 | ||
| 
 | ||
| .task-header {
 | ||
|   display: flex;
 | ||
|   justify-content: space-between;
 | ||
|   align-items: flex-start;
 | ||
|   margin-bottom: 16px;
 | ||
|   padding-bottom: 12px;
 | ||
|   border-bottom: 1px solid #f0f2f5;
 | ||
| }
 | ||
| 
 | ||
| .task-title {
 | ||
|   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;
 | ||
| }
 | ||
| 
 | ||
| .tag-pending {
 | ||
|   background-color: #e6f7ff;
 | ||
|   color: #1677ff;
 | ||
|   border-color: #91d5ff;
 | ||
| }
 | ||
| 
 | ||
| .tag-delayed {
 | ||
|   background-color: #fff2f0;
 | ||
|   color: #ff4d4f;
 | ||
|   border-color: #ffccc7;
 | ||
| }
 | ||
| 
 | ||
| .tag-executing {
 | ||
|   background-color: #fffbe6;
 | ||
|   color: #fa8c16;
 | ||
|   border-color: #ffe58f;
 | ||
| }
 | ||
| 
 | ||
| .tag-completed {
 | ||
|   background-color: #f6ffed;
 | ||
|   color: #52c41a;
 | ||
|   border-color: #b7eb8f;
 | ||
| }
 | ||
| 
 | ||
| .task-details {
 | ||
|   margin-bottom: 16px;
 | ||
| }
 | ||
| 
 | ||
| .detail-item {
 | ||
|   display: flex;
 | ||
|   margin-bottom: 10px;
 | ||
|   font-size: 13px;
 | ||
| }
 | ||
| 
 | ||
| .detail-label {
 | ||
|   flex: 0 0 80px;
 | ||
|   color: #86909c;
 | ||
| }
 | ||
| 
 | ||
| .detail-value {
 | ||
|   flex: 1;
 | ||
|   color: #4e5969;
 | ||
|   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;
 | ||
| }
 | ||
| 
 | ||
| .task-result {
 | ||
|   display: flex;
 | ||
|   margin: 10px 0;
 | ||
|   font-size: 13px;
 | ||
|   padding-top: 8px;
 | ||
|   border-top: 1px dashed #f0f2f5;
 | ||
| }
 | ||
| 
 | ||
| .result-normal {
 | ||
|   color: #00b42a;
 | ||
| }
 | ||
| 
 | ||
| .result-abnormal {
 | ||
|   color: #f53f3f;
 | ||
| }
 | ||
| 
 | ||
| .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;
 | ||
| }
 | ||
| 
 | ||
| .action-btn {
 | ||
|   font-size: 13px;
 | ||
|   padding: 4px 10px;
 | ||
| }
 | ||
| 
 | ||
| .view-btn {
 | ||
|   color: #165dff;
 | ||
| }
 | ||
| 
 | ||
| .start-btn {
 | ||
|   background-color: #165dff;
 | ||
|   border-color: #165dff;
 | ||
| }
 | ||
| 
 | ||
| .reschedule-btn {
 | ||
|   background-color: #ff7d00;
 | ||
|   border-color: #ff7d00;
 | ||
| }
 | ||
| 
 | ||
| .complete-btn {
 | ||
|   background-color: #00b42a;
 | ||
|   border-color: #00b42a;
 | ||
| }
 | ||
| 
 | ||
| .report-btn {
 | ||
|   background-color: #86909c;
 | ||
|   border-color: #86909c;
 | ||
| }
 | ||
| 
 | ||
| /* 分页区域样式 */
 | ||
| .pagination-section {
 | ||
|   display: flex;
 | ||
|   justify-content: center;
 | ||
|   margin-top: 20px;
 | ||
| }
 | ||
| 
 | ||
| /* 导航栏样式 */
 | ||
| .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);
 | ||
| }
 | ||
| 
 | ||
| /* 响应式设计 */
 | ||
| @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>
 |