This commit is contained in:
Teo
2025-09-17 18:41:53 +08:00
25 changed files with 28740 additions and 594 deletions

27652
b_changes.patch Normal file

File diff suppressed because one or more lines are too long

View File

@ -98,7 +98,6 @@ export interface MechanicalrewritingVO {
* 备注
*/
remark: string;
}
export interface MechanicalrewritingForm extends BaseEntity {
@ -201,11 +200,9 @@ export interface MechanicalrewritingForm extends BaseEntity {
* 备注
*/
remark?: string;
}
export interface MechanicalrewritingQuery extends PageQuery {
/**
* 项目ID
*/
@ -295,12 +292,13 @@ export interface MechanicalrewritingQuery extends PageQuery {
* 检验报告
*/
verificationReport?: string;
/**
* 工区
*/
workArea?: string;
/**
* 日期范围参数
*/
params?: any;
/**
* 日期范围参数
*/
params?: any;
}

View File

@ -1,6 +1,10 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { ConstructionSchedulePlanVO, ConstructionSchedulePlanForm, ConstructionSchedulePlanQuery } from '@/api/progress/constructionSchedulePlan/types';
import {
ConstructionSchedulePlanVO,
ConstructionSchedulePlanForm,
ConstructionSchedulePlanQuery
} from '@/api/progress/constructionSchedulePlan/types';
/**
* 查询施工进度计划列表
@ -71,3 +75,15 @@ export const getProjectStructure = (id: string | number | Array<string | number>
method: 'get'
});
};
/**
* 施工进度计划完成
* @param id
*/
export const finishConstructionSchedulePlan = (data: { id: string | number | Array<string | number>; finishDate: string }) => {
return request({
url: '/progress/constructionSchedulePlan/finish',
method: 'put',
data
});
};

View File

@ -75,7 +75,7 @@ export const addSafetyInspectionReview = (data: any) => {
method: 'post',
data: data
});
}
};
/**
* 新增安全巡检工单整改
* @param data
@ -86,4 +86,14 @@ export const addSafetyInspectionRectification = (data: any) => {
method: 'post',
data: data
});
}
};
/**
* 新增安全巡检工单整改
* @param data
*/
export const recordList = (id: any) => {
return request({
url: '/safety/safetyInspection/record/' + id,
method: 'get'
});
};

View File

@ -50,8 +50,8 @@ VXETable.config({
//本地保存飞机配置
import { setLocal } from './utils';
setLocal('dockAir', 'http://58.17.134.85:9512');
setLocal('aiUrl', 'http://58.17.134.85:9512');
setLocal('host', '121.37.237.116');
setLocal('aiUrl', 'http://58.17.134.85');
setLocal('host', '58.17.134.85');
setLocal('rtmpPort', '28451');
setLocal('rtcPort', '28453');
setLocal('dockSocketUrl', 'ws://58.17.134.85:9512/websocket');

View File

@ -95,8 +95,8 @@
</div>
<div class="task-actions">
<el-button type="text" size="small" class="action-btn view-btn" @click="handleView(task)"> 详情 </el-button>
<el-button type="primary" size="small" :class="task.actionClass" @click="handleAction(task)">
<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>
@ -853,7 +853,18 @@ const handleInspection7 = () => {
align-items: center;
padding-top: 12px;
border-top: 1px solid #f0f2f5;
margin-top: 12px;
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 {

View File

@ -1,184 +1,209 @@
<template>
<div class="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>
<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="header">
<TitleComponent title="运维待办事项" subtitle="管理每日、每周等的运维工作任务"></TitleComponent>
</div>
<!-- 标题栏 -->
<div class="header">
<TitleComponent title="运维待办事项" subtitle="管理每日、每周等的运维工作任务"></TitleComponent>
</div>
<div class="main-content">
<!-- 左侧日历区域 -->
<div class="calendar-container">
<div class="calendar-header">
<div class="calendar-title">待办月视图</div>
<div class="calendar-controls">
<!-- 年份月份选择 -->
<el-select v-model="selectedYear" placeholder="选择份" size="small" style="width: 80px; margin-right: 5px">
<el-option v-for="year in years" :key="year" :label="year.toString()" :value="year"></el-option>
</el-select>
<el-select v-model="selectedMonth" placeholder="选择月份" size="small" style="width: 80px; margin-right: 10px">
<el-option v-for="month in 12" :key="month" :label="month.toString()" :value="month"></el-option>
</el-select>
<!-- 月份切换按钮 -->
<el-button type="text" icon="el-icon-arrow-left" @click="decreaseMonth"></el-button>
<el-button type="text" icon="el-icon-arrow-right" @click="increaseMonth"></el-button>
<el-button type="primary" size="small">添加</el-button>
<el-button type="primary" size="small" @click="goToToday">今日</el-button>
<el-button type="text" icon="el-icon-plus"></el-button>
<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">添加</el-button>
<el-button type="primary" @click="goToToday">今日</el-button>
<el-button type="text" icon="el-icon-plus"></el-button>
</div>
</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-description">{{ event.description }}</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-description">{{ event.description }}</div>
</div>
</div>
</div>
</div>
</template>
</el-calendar>
</div>
<!-- 右侧表单区域 -->
<div class="form-container">
<div class="form-header">
<h2>今日待办</h2>
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAddTaskDialog">添加</el-button>
</template>
</el-calendar>
</div>
<!-- 待办事项列表 -->
<div class="todo-list">
<!-- 待办项1 - 常规维护 -->
<div class="todo-item">
<div class="todo-color-indicator normal"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">服务器例行检查</div>
<div class="todo-time">09:00-10:00 AM</div>
<!-- 右侧表单区域 -->
<div class="form-container">
<div class="form-header">
<h2>今日待办</h2>
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAddTaskDialog">添加</el-button>
</div>
<!-- 待办事项列表 -->
<div class="todo-list">
<!-- 待办项1 - 常规维护 -->
<div class="todo-item">
<div class="todo-color-indicator normal"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">服务器例行检查</div>
<div class="todo-time">09:00-10:00 AM</div>
</div>
<div class="todo-description">检查所有生产服务器的CPU内存磁盘使用率确保正常运行</div>
</div>
<div class="todo-actions">
<el-button type="primary" size="small" icon="el-icon-check">编辑</el-button>
<el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
</div>
</div>
<!-- 待办项2 - 重要 -->
<div class="todo-item important">
<div class="todo-color-indicator important"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">数据库备份</div>
<div class="todo-time">14:00-15:00 PM</div>
</div>
<div class="todo-description">主要数据库全备份并验证备份文件完整性</div>
</div>
<div class="todo-actions">
<el-button type="primary" size="small" icon="el-icon-check">编辑</el-button>
<el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
</div>
</div>
<!-- 待办项3 - 紧急 -->
<div class="todo-item">
<div class="todo-color-indicator urgent"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">网络设备固件更新</div>
<div class="todo-time">18:00-20:00 PM</div>
</div>
<div class="todo-description">更新核心交换机和防火墙固件需安排在业务低峰期</div>
</div>
<div class="todo-actions">
<el-button type="primary" size="small" icon="el-icon-check">编辑</el-button>
<el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
</div>
</div>
<!-- 待办项4 - 常规维护 -->
<div class="todo-item">
<div class="todo-color-indicator normal"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">服务器例行检查</div>
<div class="todo-time">08:00-09:00 AM</div>
</div>
<div class="todo-description">检查所有生产服务器的CPU内存磁盘使用率确保正常运行</div>
</div>
<div class="todo-actions">
<el-button type="primary" size="small" icon="el-icon-check">编辑</el-button>
<el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
</div>
</div>
<div class="todo-item">
<div class="todo-color-indicator normal"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">服务器例行检查</div>
<div class="todo-time">06:00-07:00 AM</div>
</div>
<div class="todo-description">检查所有生产服务器的CPU内存磁盘使用率确保正常运行</div>
</div>
<div class="todo-actions">
<el-button type="primary" size="small" icon="el-icon-check">编辑</el-button>
<el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
</div>
</div>
<div class="todo-item">
<div class="todo-color-indicator normal"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">服务器例行检查</div>
<div class="todo-time">06:00-07:00 AM</div>
</div>
<div class="todo-description">检查所有生产服务器的CPU内存磁盘使用率确保正常运行</div>
</div>
<div class="todo-actions">
<el-button type="primary" size="small" icon="el-icon-check">编辑</el-button>
<el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
</div>
<div class="todo-description">检查所有生产服务器的CPU内存磁盘使用率确保正常运行</div>
</div>
</div>
<!-- 待办项2 - 重要 -->
<div class="todo-item important">
<div class="todo-color-indicator important"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">数据库备份</div>
<div class="todo-time">14:00-15:00 PM</div>
</div>
<div class="todo-description">主要数据库全备份并验证备份文件完整性</div>
</div>
<div class="todo-actions">
<el-button type="text" icon="el-icon-edit"></el-button>
<el-button type="text" icon="el-icon-delete"></el-button>
</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>
<!-- 待办项3 - 紧急 -->
<div class="todo-item">
<div class="todo-color-indicator urgent"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">网络设备固件更新</div>
<div class="todo-time">18:00-20:00 PM</div>
</div>
<div class="todo-description">更新核心交换机和防火墙固件需安排在业务低峰期</div>
</div>
</div>
<!-- 待办项4 - 常规维护 -->
<div class="todo-item">
<div class="todo-color-indicator normal"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">服务器例行检查</div>
<div class="todo-time">08:00-09:00 AM</div>
</div>
<div class="todo-description">检查所有生产服务器的CPU内存磁盘使用率确保正常运行</div>
</div>
</div>
<!-- 待办项5 - 常规维护 -->
<div class="todo-item">
<div class="todo-color-indicator normal"></div>
<el-checkbox class="todo-checkbox"></el-checkbox>
<div class="todo-content">
<div class="todo-main">
<div class="todo-title">服务器例行检查</div>
<div class="todo-time">06:00-07:00 AM</div>
</div>
<div class="todo-description">检查所有生产服务器的CPU内存磁盘使用率确保正常运行</div>
</div>
</div>
</div>
<!-- 状态图例 - 标签形式 -->
<div class="status-legend">
<span class="status-tag normal">常规维护</span>
<span class="status-tag important">重要</span>
<span class="status-tag urgent">紧急</span>
</div>
</div>
<el-dialog v-model="dialogVisible" title="新增任务" 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="description">
<el-input v-model="taskForm.description" 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="结束时间"
class="form-input"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="优先级" prop="priority">
<el-select v-model="taskForm.priority" 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="常规维护"></el-option>
<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>
<template #footer>
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="saveTask">保存任务</el-button>
</template>
</el-dialog>
</div>
<el-dialog v-model="dialogVisible" title="新增任务" 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="description">
<el-input v-model="taskForm.description" 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="结束时间"
class="form-input"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="优先级" prop="priority">
<el-select v-model="taskForm.priority" 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="常规维护"></el-option>
<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>
<template #footer>
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="saveTask">保存任务</el-button>
</template>
</el-dialog>
</div>
</template>
@ -187,14 +212,14 @@ import { ref, computed, watch } from 'vue';
import router from '@/router';
import TitleComponent from '../demo/components/TitleComponent.vue';
// 生成年份选项生成2020-2029年的年份范围
const targetYear = 2025;
const years = ref(Array.from({ length: 10 }, (_, index) => 2020 + index));
const selectedYear = ref(targetYear);
const selectedMonth = ref(9);
// 默认显示当前月份
const currentDate = ref(new Date());
// 默认显示2025年9月
const currentDate = ref(new Date(targetYear, 8, 1));
// 为了保持兼容性,保留这些变量
const targetYear = 2025;
const years = ref([]);
const selectedYear = ref(currentDate.value.getFullYear());
const selectedMonth = ref(currentDate.value.getMonth() + 1);
// 减少月份
const decreaseMonth = () => {
@ -258,15 +283,13 @@ const updateYearAndMonth = () => {
selectedMonth.value = currentDate.value.getMonth() + 1;
};
// 监听年份和月份变化,更新日历显示
watch([selectedYear, selectedMonth], ([newYear, newMonth]) => {
const date = new Date(currentDate.value);
date.setFullYear(newYear);
date.setMonth(newMonth - 1);
currentDate.value = date;
// 监听日期变化,更新年份和月份
watch(currentDate, (newDate) => {
selectedYear.value = newDate.getFullYear();
selectedMonth.value = newDate.getMonth() + 1;
});
// 初始化年份和月份选择器
// 初始化年份和月份
updateYearAndMonth();
// 弹窗相关状态管理
@ -329,7 +352,8 @@ const handleInspection7 = () => {
</script>
<style scoped>
.container {
.box-container {
width: 100%;
padding: 20px;
background-color: #f5f7fa;
min-height: 100vh;
@ -397,15 +421,18 @@ const handleInspection7 = () => {
.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%;
}
/* 自定义弹窗样式 */
@ -463,14 +490,13 @@ const handleInspection7 = () => {
.el-select {
margin-right: 5px;
}
/* 表单区域样式 */
.form-container {
width: 400px;
flex: 0 0 360px; /* 调整宽度以匹配设计图,更贴合右侧区域宽度 */
background-color: #fff;
border-radius: 4px;
padding: 20px;
padding: 20px 20px 80px 20px; /* 增加底部内边距,为固定标签留出空间 */
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: relative; /* 设置为相对定位,使内部绝对定位元素相对于此容器定位 */
}
.form-header {
@ -494,7 +520,7 @@ const handleInspection7 = () => {
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
max-height: 400px;
max-height: 480px;
overflow-y: auto;
}
@ -507,6 +533,7 @@ const handleInspection7 = () => {
border-radius: 4px;
position: relative;
transition: all 0.3s ease;
overflow: hidden;
}
/* 重要任务的背景色 */
@ -521,6 +548,8 @@ const handleInspection7 = () => {
.todo-content {
flex: 1;
position: relative;
transition: all 0.3s ease;
}
.todo-main {
@ -549,42 +578,75 @@ const handleInspection7 = () => {
.todo-actions {
position: absolute;
right: 10px;
bottom: 10px;
right: -120px;
top: 0;
bottom: 0;
display: flex;
gap: 5px;
opacity: 0;
transition: all 0.3s ease;
}
.todo-actions .el-button {
height: 100%;
border-radius: 0;
border-right: 1px solid #fff;
}
.todo-actions .el-button:last-child {
border-right: none;
}
.todo-item:hover .todo-content {
transform: translateX(-120px);
}
.todo-item:hover .todo-actions {
opacity: 1;
right: 0;
}
.todo-actions .el-button {
padding: 4px 8px;
min-width: auto;
font-size: 12px;
}
/* 状态图例 - 标签形式 */
.status-legend {
display: flex;
gap: 10px;
padding-top: 15px;
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-block;
padding: 4px 12px;
border-radius: 16px;
font-size: 12px;
color: #fff;
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 14px;
color: #303133;
}
.status-tag.normal {
.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 {
.status-tag.important .color-block {
background-color: #faad14;
}
.status-tag.urgent {
.status-tag.urgent .color-block {
background-color: #ff4d4f;
}
@ -610,10 +672,12 @@ const handleInspection7 = () => {
background-color: #ff4d4f;
}
/* 自定义日历单元格样式 */
.custom-date-cell {
::v-deep .custom-date-cell {
width: 100%;
height: 100%;
padding: 5px;
text-align: center;
box-sizing: border-box; /* 确保内边距不撑大元素 */
}
/* 系统升级事件样式 */
@ -648,15 +712,21 @@ const handleInspection7 = () => {
width: 100%;
}
.el-calendar-table td {
/* 穿透作用域,强制设置日历单元格为正方形 */
::v-deep .el-calendar-table td {
padding: 2px;
vertical-align: top;
width: 120px; /* 强制宽度 */
height: 120px; /* 强制高度(与宽度一致) */
}
.el-calendar-day {
height: 120px;
::v-deep .el-calendar-day {
padding: 0; /* 移除默认内边距 */
width: 100%;
height: 100%;
border-radius: 4px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.date-day {

View File

@ -112,8 +112,8 @@
</div>
<div class="task-actions">
<el-button type="text" size="small" class="action-btn view-btn" @click="handleView(task)"> 详情 </el-button>
<el-button type="primary" size="small" :class="task.actionClass" @click="handleAction(task)">
<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>
@ -701,10 +701,20 @@ const handleInspection7 = () => {
display: flex;
justify-content: flex-end;
align-items: center;
padding-top: 16px;
padding-top: 12px;
border-top: 1px solid #f0f2f5;
margin-top: auto; /* 自动推到最底部 */
gap: 8px;
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;
}
.action-btn {

View File

@ -16,7 +16,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>
@ -31,58 +30,9 @@
<div class="sidebar">
<div class="stats-card">
<h3 class="stats-title">人员数据总览</h3>
<!-- 使用ECharts饼图替换原有的环形图 -->
<div class="chart-container">
<div class="gauge-chart">
<div class="doughnut-chart">
<!-- 动态镂空环形图 -->
<svg width="200" height="200" viewBox="0 0 200 200">
<!-- 环形背景 -->
<circle cx="100" cy="100" r="70" fill="none" stroke="#f0f2f5" stroke-width="12" class="background-circle" />
<!-- 在线可用部分 - 动态显示 -->
<circle
cx="100"
cy="100"
r="70"
fill="none"
stroke="#165dff"
stroke-width="12"
stroke-linecap="round"
:stroke-dasharray="circumference"
:stroke-dashoffset="onlineOffset"
transform="rotate(-90 100 100)"
class="progress-circle online-progress"
/>
<!-- 离线休息部分 - 动态显示 -->
<circle
cx="100"
cy="100"
r="70"
fill="none"
stroke="#40c9c6"
stroke-width="12"
stroke-linecap="round"
:stroke-dasharray="circumference"
:stroke-dashoffset="offlineOffset"
transform="rotate(-90 100 100)"
class="progress-circle offline-progress"
/>
</svg>
<div class="gauge-text">
<div class="gauge-percentage">{{ onlineRate }}%</div>
<div class="gauge-label">在线可用率</div>
</div>
</div>
</div>
<div class="chart-legend">
<div class="legend-item">
<span class="legend-color online"></span>
<span class="legend-text">在线可用人数 ({{ availablePersonnel }})</span>
</div>
<div class="legend-item">
<span class="legend-color offline"></span>
<span class="legend-text">离线休息人数 ({{ restingPersonnel }})</span>
</div>
</div>
<div ref="personnelChart" class="personnel-chart"></div>
</div>
<div class="stats-grid">
@ -112,30 +62,42 @@
<!-- 右侧人员列表区域带滚动条 -->
<div class="main-content">
<div class="scrollable-content">
<div class="personnel-grid">
<div v-for="(person, index) in personnelList" :key="index" class="person-card">
<div class="person-header">
<div class="avatar">
<img :src="person.avatar" alt="头像" class="avatar-img" />
<div class="status-indicator" :class="person.statusClass"></div>
<div class="scroll-wrapper">
<!-- 固定的顶部空间不随内容滚动 -->
<div class="fixed-top-space"></div>
<!-- 可滚动的内容区域 -->
<div class="scrollable-content">
<div class="scrollable-inner">
<div class="personnel-grid">
<div v-for="(person, index) in personnelList" :key="index" class="person-card">
<div class="person-header">
<div class="avatar">
<img src="@/assets/images/attendanceperson.png" class="avatar-img" />
<div class="status-indicator" :class="person.statusClass"></div>
</div>
<div class="person-info">
<div class="person-name">{{ person.name }}</div>
<div class="person-status">{{ person.statusText }}</div>
</div>
</div>
<div class="person-details">
<div class="detail-row">
<div class="detail-item">工号: {{ person.id }}</div>
<div class="detail-item">岗位: {{ person.position }}</div>
</div>
<div class="detail-row">
<div class="detail-item">班组: {{ person.team }}</div>
<div class="detail-item">今日完成: {{ person.completedTasks }}</div>
</div>
<div class="detail-row">
<div class="detail-item full-width">当前任务: {{ person.currentTask || '无' }}</div>
</div>
</div>
<div class="person-actions">
<el-button type="text" @click="viewDetails(person)" size="small" class="detail-btn">详情</el-button>
<el-button type="text" @click="assignTask(person)" size="small" class="assign-btn">指派</el-button>
</div>
</div>
<div class="person-info">
<div class="person-name">{{ person.name }}</div>
<div class="person-status">{{ person.statusText }}</div>
</div>
</div>
<div class="person-details">
<div class="detail-item">工号: {{ person.id }}</div>
<div class="detail-item">岗位: {{ person.position }}</div>
<div class="detail-item">班组: {{ person.team }}</div>
<div class="detail-item">今日完成: {{ person.completedTasks }}</div>
<div class="detail-item" v-if="person.currentTask">当前任务: {{ person.currentTask }}</div>
<div class="detail-item" v-else>当前任务: </div>
</div>
<div class="person-actions">
<el-button type="text" @click="viewDetails(person)" size="small" class="detail-btn">详情</el-button>
<el-button type="text" @click="assignTask(person)" size="small" class="assign-btn">指派</el-button>
</div>
</div>
</div>
@ -147,33 +109,32 @@
</template>
<script setup>
import { ref, watch } from 'vue';
import { ref, watch, onMounted } from 'vue';
import router from '@/router';
import TitleComponent from '@/views/demo/components/TitleComponent.vue';
import * as echarts from 'echarts';
// 激活的选项卡
const activeTab = ref('personnel');
// 统计数据
// 统计数据(保持原有数据不变)
const totalPersonnel = ref(36);
const availablePersonnel = ref(18);
const workingPersonnel = ref(12);
const restingPersonnel = ref(6);
const onlineRate = ref(82);
// 环形图相关计算
const radius = 70;
const circumference = 2 * Math.PI * radius;
const onlineOffset = ref(circumference - (onlineRate.value / 100) * circumference);
const offlineOffset = ref(circumference - ((100 - onlineRate.value) / 100) * circumference);
// 人员状态数据 - 使用原有数据结构
const personnelStatusData = {
'在线可用': availablePersonnel.value,
'离线休息': restingPersonnel.value
};
// 监听onlineRate变化更新环形图
watch(onlineRate, (newRate) => {
onlineOffset.value = circumference - (newRate / 100) * circumference;
offlineOffset.value = circumference - ((100 - newRate) / 100) * circumference;
});
// 初始化图表
const personnelChart = ref(null);
let chartInstance = null;
// 人员列表数据
// 人员列表数据(保持不变)
const personnelList = ref([
{
id: 'EMP-2023-001',
@ -276,10 +237,127 @@ const personnelList = ref([
}
]);
// 初始化饼图
const initChart = () => {
if (chartInstance) {
chartInstance.dispose();
}
chartInstance = echarts.init(personnelChart.value);
const names = Object.keys(personnelStatusData);
const values = Object.values(personnelStatusData).map((item) => Number(Number(item).toFixed(2)));
const sumValue = values.reduce((total, num) => total + num, 0);
// 设置图表配置 - 美化饼图样式,保持原有数据
const option = {
tooltip: {
trigger: 'item',
formatter: '{b}: {c}人 ({d}%)'
},
legend: {
show: true,
orient: 'horizontal',
bottom: 10,
itemWidth: 12,
itemHeight: 12,
textStyle: {
color: '#606266',
fontSize: 14
}
},
series: [
// 主饼图
{
name: '人员状态',
type: 'pie',
radius: ['40%', '70%'],
center: ['50%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 4,
borderColor: '#fff',
borderWidth: 2,
shadowBlur: 6,
shadowColor: 'rgba(0, 0, 0, 0.1)'
},
label: {
show: false,
position: 'outside',
formatter: '{d}%',
fontSize: 14,
fontWeight: 'bold',
color: '#303133',
lineHeight: 20
},
labelLine: {
show: true,
length: 15,
length2: 10,
lineStyle: {
width: 1
}
},
emphasis: {
scale: true,
scaleSize: 15
},
data: [
{
value: availablePersonnel.value,
name: '在线可用人数',
itemStyle: {
color: '#165dff'
}
},
{
value: restingPersonnel.value,
name: '离线休息人数',
itemStyle: {
color: '#40c9c6'
},
emphasis: {
itemStyle: {
shadowBlur: 15,
shadowColor: 'rgba(64, 201, 198, 0.4)'
}
}
}
]
}
]
};
chartInstance.setOption(option);
};
// 监听数据变化,更新图表
watch([availablePersonnel, workingPersonnel, restingPersonnel], () => {
// 更新人员状态数据
personnelStatusData['在线可用'] = availablePersonnel.value;
personnelStatusData['离线休息'] = restingPersonnel.value;
// 重新初始化图表
initChart();
});
// 页面加载完成后初始化图表
onMounted(() => {
initChart();
// 监听窗口大小变化,调整图表尺寸
window.addEventListener('resize', () => {
if (chartInstance) {
chartInstance.resize();
}
});
});
// 选项卡点击事件
const handleTabClick = (tab) => {
console.log('切换到选项卡:', tab.name);
// 根据选择的选项卡加载不同数据
if (tab.name === 'vehicles') {
// 加载车辆状态数据
} else if (tab.name === 'teams') {
@ -419,96 +497,9 @@ const handleInspectionManagement3 = () => {
padding: 10px 0;
}
.gauge-chart {
width: 200px;
height: 200px;
position: relative;
}
.doughnut-chart {
.personnel-chart {
width: 100%;
height: 100%;
position: relative;
}
.gauge-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.gauge-percentage {
font-size: 36px;
font-weight: 700;
color: #165dff;
line-height: 1;
}
.gauge-label {
font-size: 15px;
color: #606266;
margin-top: 6px;
font-weight: 500;
}
/* 环形图动画效果 */
.background-circle {
stroke: #f0f2f5;
}
.progress-circle {
transition: stroke-dashoffset 1s ease-in-out;
}
.online-progress {
stroke: #165dff;
filter: drop-shadow(0 0 6px rgba(22, 93, 255, 0.2));
}
.offline-progress {
stroke: #40c9c6;
filter: drop-shadow(0 0 6px rgba(64, 201, 198, 0.2));
}
/* 图例样式 */
.chart-legend {
margin-top: 16px;
display: flex;
flex-direction: column;
gap: 8px;
width: 100%;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 0;
}
.legend-color {
width: 12px;
height: 12px;
border-radius: 4px;
flex-shrink: 0;
}
.legend-color.online {
background-color: #165dff;
box-shadow: 0 2px 4px rgba(22, 93, 255, 0.3);
}
.legend-color.offline {
background-color: #40c9c6;
box-shadow: 0 2px 4px rgba(64, 201, 198, 0.3);
}
.legend-text {
font-size: 13px;
color: #606266;
font-weight: 500;
height: 300px;
}
/* 统计网格 */
@ -574,12 +565,50 @@ const handleInspectionManagement3 = () => {
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
overflow: hidden;
padding: 0 28px 28px 28px;
}
/* 滚动包装器 */
.scroll-wrapper {
height: 100%;
position: relative;
}
/* 固定的顶部空间,不随内容滚动 */
.fixed-top-space {
height: 40px;
flex-shrink: 0;
}
/* 可滚动的内容区域 */
.scrollable-content {
max-height: calc(100vh - 340px);
overflow-y: auto;
padding: 28px;
max-height: calc(120vh - 340px - 40px); /* 减去顶部固定空间的高度 */
overflow: auto;
scrollbar-width: thin;
scrollbar-color: rgba(150, 150, 150, 0.5) transparent;
}
/* 内容包装器 */
.content-wrapper {
padding: 0 28px 60px 28px;
}
/* Webkit浏览器自定义滚动条样式 */
.scrollable-content::-webkit-scrollbar {
width: 8px;
}
.scrollable-content::-webkit-scrollbar-track {
background: transparent;
border-radius: 4px;
}
.scrollable-content::-webkit-scrollbar-thumb {
background-color: rgba(150, 150, 150, 0.5);
border-radius: 4px;
border: 2px solid transparent;
background-clip: content-box;
}
.scrollable-content::-webkit-scrollbar-thumb:hover {
background-color: rgba(150, 150, 150, 0.8);
}
/* 增强内容区域标题样式 */
@ -595,17 +624,18 @@ const handleInspectionManagement3 = () => {
/* 人员网格 */
.personnel-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
.person-card {
border: 1px solid #f0f0f0;
border-radius: 12px;
padding: 20px;
border-radius: 8px;
padding: 16px;
transition: all 0.3s ease;
background-color: #ffffff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
min-height: 220px;
}
.person-card:hover {
@ -617,14 +647,14 @@ const handleInspectionManagement3 = () => {
.person-header {
display: flex;
align-items: center;
margin-bottom: 20px;
margin-bottom: 16px;
}
.avatar {
position: relative;
width: 64px;
height: 64px;
margin-right: 16px;
width: 56px;
height: 56px;
margin-right: 12px;
flex-shrink: 0;
}
@ -640,8 +670,8 @@ const handleInspectionManagement3 = () => {
position: absolute;
bottom: 0;
right: 0;
width: 18px;
height: 18px;
width: 16px;
height: 16px;
border-radius: 50%;
border: 3px solid #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
@ -664,17 +694,17 @@ const handleInspectionManagement3 = () => {
}
.person-name {
font-size: 18px;
font-size: 16px;
font-weight: 600;
color: #2c3e50;
margin-bottom: 6px;
margin-bottom: 4px;
line-height: 1.2;
}
.person-status {
font-size: 13px;
padding: 3px 10px;
border-radius: 15px;
font-size: 12px;
padding: 2px 8px;
border-radius: 12px;
display: inline-block;
font-weight: 500;
}
@ -695,28 +725,52 @@ const handleInspectionManagement3 = () => {
}
.person-details {
margin-bottom: 20px;
border-top: 1px dashed #f0f0f0;
padding-top: 16px;
margin-bottom: 16px;
border-top: none;
padding-top: 0;
}
.detail-row {
display: flex;
margin-bottom: 8px;
border-bottom: 1px dotted #f0f0f0;
padding-bottom: 8px;
}
.detail-row:last-child {
margin-bottom: 0;
border-bottom: none;
padding-bottom: 0;
}
.detail-item {
font-size: 13px;
color: #606266;
margin-bottom: 10px;
line-height: 1.6;
flex: 1;
padding: 0 8px;
}
.detail-item:first-child {
padding-left: 0;
}
.detail-item:last-child {
margin-bottom: 0;
padding-right: 0;
}
.detail-item.full-width {
flex: 1 0 100%;
padding: 0;
}
.person-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
border-top: 1px dashed #f0f0f0;
border-top: 1px solid #f0f0f0;
padding-top: 16px;
margin-top: 16px;
}
/* 美化按钮样式 */
@ -862,5 +916,9 @@ const handleInspectionManagement3 = () => {
.personnel-grid {
grid-template-columns: 1fr;
}
.personnel-chart {
height: 250px;
}
}
</style>

View File

@ -106,8 +106,8 @@
</div>
<div class="task-actions">
<el-button type="text" size="small" class="action-btn view-btn" @click="handleView(task)"> 详情 </el-button>
<el-button type="primary" size="small" :class="task.actionClass" @click="handleAction(task)">
<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>
@ -564,7 +564,7 @@ const handleInspection7 = () => {
.task-card {
background-color: #fff;
border-radius: 8px;
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;
@ -588,6 +588,11 @@ const handleInspection7 = () => {
z-index: 10;
}
.task-actions .el-button {
border-radius: 16px;
padding: 6px 16px;
}
.task-card::before {
content: '';
position: absolute;
@ -635,8 +640,8 @@ const handleInspection7 = () => {
}
.task-status {
padding: 4px 10px;
border-radius: 6px;
padding: 4px 12px;
border-radius: 16px;
font-size: 12px;
font-weight: 500;
border: 1px solid transparent;

View File

@ -55,7 +55,7 @@
></el-date-picker>
</div>
<div class="filter-actions">
<el-button type="primary" class="search-btn">搜索</el-button>
<el-button type="primary" class="search-btn" @click="fetchDashboardData">搜索</el-button>
</div>
</div>
@ -97,19 +97,19 @@
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div class="stat-card">
<p class="stat-label">本月完成巡检</p>
<p class="stat-value">42</p>
<p class="stat-value">{{ completedInspections }}</p>
</div>
<div class="stat-card">
<p class="stat-label">发现问题数</p>
<p class="stat-value">7</p>
<p class="stat-value">{{ totalProblems }}</p>
</div>
<div class="stat-card">
<p class="stat-label">已解决问题</p>
<p class="stat-value">5</p>
<p class="stat-value">{{ solvedProblems }}</p>
</div>
<div class="stat-card">
<p class="stat-label">平均完成时间</p>
<p class="stat-value">45分钟</p>
<p class="stat-value">{{ avgCompletionTime }}</p>
</div>
</div>
@ -117,56 +117,10 @@
<!-- 图表区域 -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 py-4">
<!-- 饼图 - 本月巡检完成情况 -->
<!-- 饼图 - 使用指定的ECharts配置 -->
<div class="md:col-span-1">
<p class="chart-title">本月完成巡检</p>
<div class="relative w-32 h-32 mx-auto">
<!-- 饼图使用SVG绘制 - 显示本月巡检完成情况 -->
<svg class="w-full h-full" viewBox="0 0 100 100">
<!-- 背景圆环 -->
<circle cx="50" cy="50" r="45" fill="none" stroke="#f3f4f6" stroke-width="10" />
<!-- 已完成部分 (72%) -->
<circle
cx="50"
cy="50"
r="45"
fill="none"
stroke="#10b981"
stroke-width="10"
stroke-dasharray="282.74"
stroke-dashoffset="113.1"
transform="rotate(-90 50 50)"
/>
<!-- 未完成部分 (28%) -->
<circle
cx="50"
cy="50"
r="45"
fill="none"
stroke="#f97316"
stroke-width="10"
stroke-dasharray="113.1"
stroke-dashoffset="0"
transform="rotate(-90 50 50)"
/>
</svg>
<!-- 饼图中心显示 -->
<div class="absolute inset-0 flex flex-col items-center justify-center">
<p class="text-sm text-gray-500">已解决问题</p>
<p class="text-lg font-bold text-gray-800">72%</p>
</div>
</div>
<!-- 饼图图例 -->
<div class="mt-3 flex justify-center space-x-4">
<div class="flex items-center">
<div class="w-3 h-3 rounded-full bg-green-500 mr-1"></div>
<span class="text-xs text-gray-600">已解决</span>
</div>
<div class="flex items-center">
<div class="w-3 h-3 rounded-full bg-orange-500 mr-1"></div>
<span class="text-xs text-gray-600">未解决</span>
</div>
</div>
<p class="chart-title">进度指标对比</p>
<div ref="pieChartRef" class="pie-chart-container"></div>
</div>
<!-- 进度条 -->
@ -175,28 +129,28 @@
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">完成率</span>
<span class="font-medium text-gray-800">68%</span>
<span class="font-medium text-gray-800">{{ completionRate }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-red-500 h-2 rounded-full" style="width: 68%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out" :style="{ width: completionRate + '%' }"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">解决率</span>
<span class="font-medium text-gray-800">72%</span>
<span class="font-medium text-gray-800">{{ resolutionRate }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-green-500 h-2 rounded-full" style="width: 72%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div class="bg-red-500 h-2 rounded-full transition-all duration-1500 ease-out" :style="{ width: resolutionRate + '%' }"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">及时率</span>
<span class="font-medium text-gray-800">60%</span>
<span class="font-medium text-gray-800">{{ timelinessRate }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-gray-500 h-2 rounded-full" style="width: 60%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div class="bg-green-500 h-2 rounded-full transition-all duration-1500 ease-out" :style="{ width: timelinessRate + '%' }"></div>
</div>
</div>
</div>
@ -212,46 +166,58 @@
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">温度异常率</span>
<span class="text-gray-500">85%</span>
<span class="text-gray-500">{{ problemTypes.temperature }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-blue-500 h-2 rounded-full" style="width: 85%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
:style="{ width: problemTypes.temperature + '%' }"
></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">内存使用率</span>
<span class="text-gray-500">62%</span>
<span class="text-gray-500">{{ problemTypes.memory }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-blue-500 h-2 rounded-full" style="width: 62%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
:style="{ width: problemTypes.memory + '%' }"
></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">CPU负载</span>
<span class="text-gray-500">45%</span>
<span class="text-gray-500">{{ problemTypes.cpu }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-blue-500 h-2 rounded-full" style="width: 45%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out" :style="{ width: problemTypes.cpu + '%' }"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">响应时间</span>
<span class="text-gray-500">30%</span>
<span class="text-gray-500">{{ problemTypes.responseTime }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-blue-500 h-2 rounded-full" style="width: 30%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
:style="{ width: problemTypes.responseTime + '%' }"
></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-600">磁盘空间状态</span>
<span class="text-gray-500">15%</span>
<span class="text-gray-500">{{ problemTypes.diskSpace }}%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-blue-500 h-2 rounded-full" style="width: 15%"></div>
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
:style="{ width: problemTypes.diskSpace + '%' }"
></div>
</div>
</div>
</div>
@ -271,7 +237,7 @@
<div class="card-body flex-1 overflow-y-auto scrollbar-thin">
<div class="inspection-results space-y-4">
<!-- 结果1正常 -->
<div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm">
<div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm hover:shadow-md transition-shadow">
<div class="flex justify-between items-start mb-4">
<h3 class="text-lg font-medium text-gray-800">数据库性能巡检</h3>
<span class="status-tag status-normal px-3 py-1 text-xs">正常</span>
@ -308,7 +274,7 @@
</div>
<!-- 结果2需关注 -->
<div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm">
<div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm hover:shadow-md transition-shadow">
<div class="flex justify-between items-start mb-4">
<h3 class="text-lg font-medium text-gray-800">生产服务器日常巡检</h3>
<span class="status-tag status-attention px-3 py-1 text-xs">需关注</span>
@ -352,7 +318,7 @@
</div>
<!-- 结果3有问题 -->
<div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm">
<div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm hover:shadow-md transition-shadow">
<div class="flex justify-between items-start mb-4">
<h3 class="text-lg font-medium text-gray-800">网络设备安全巡检</h3>
<span class="status-tag status-problem px-3 py-1 text-xs">有问题</span>
@ -396,9 +362,10 @@
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted, computed, onUnmounted } from 'vue';
import router from '@/router';
import TitleComponent from '@/views/demo/components/TitleComponent.vue';
import * as echarts from 'echarts';
// 筛选条件
const filterStatus = ref('all');
@ -408,13 +375,216 @@ const dateRange = ref([]);
// 时间范围选择
const timeRange = ref('month'); // 默认选中"月"
// 进度指标数据
const completionRate = ref(68); // 完成率
const resolutionRate = ref(72); // 解决率
const timelinessRate = ref(60); // 及时率
// 统计数据
const completedInspections = ref(42);
const totalProblems = ref(7);
const solvedProblems = ref(5);
const avgCompletionTime = ref('45分钟');
// 问题类型数据
const problemTypes = ref({
temperature: 85, // 温度异常率
memory: 62, // 内存使用率
cpu: 45, // CPU负载
responseTime: 30, // 响应时间
diskSpace: 15 // 磁盘空间状态
});
// ECharts 饼图相关
const pieChartRef = ref(null);
let pieChart = null;
// 计算平均完成度
const averageRate = computed(() => (completionRate.value + resolutionRate.value + timelinessRate.value) / 3);
// 初始化饼图 - 使用指定的option配置
const initPieChart = () => {
// 确保DOM元素已存在
if (!pieChartRef.value) return;
// 销毁已存在的实例
if (pieChart) {
pieChart.dispose();
}
// 创建新实例
pieChart = echarts.init(pieChartRef.value);
// 设置图表配置 - 使用指定的option
const option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: '进度指标',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
padAngle: 5,
itemStyle: {
borderRadius: 10
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold',
formatter: function (params) {
// 鼠标悬停时显示当前指标的百分比
return params.value + '%';
}
}
},
labelLine: {
show: false
},
data: [
{ value: completionRate.value, name: '完成率', itemStyle: { color: '#5470c6' } },
{ value: resolutionRate.value, name: '解决率', itemStyle: { color: '#f56c6c' } },
{ value: timelinessRate.value, name: '及时率', itemStyle: { color: '#67c23a' } }
]
}
]
};
// 设置配置项
pieChart.setOption(option);
// 响应窗口大小变化
const handleResize = () => {
if (pieChart) {
pieChart.resize();
}
};
window.addEventListener('resize', handleResize);
// 组件卸载时移除事件监听
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
};
// 时间范围切换函数
const handleTimeRangeChange = (range) => {
timeRange.value = range;
// 在实际应用中,这里应该根据选择的时间范围重新获取数据
console.log(`切换到${range}视图`);
fetchDashboardData(); // 切换时间范围重新获取数据
};
// 获取仪表盘数据(模拟)
const fetchDashboardData = () => {
// 模拟加载状态
completionRate.value = 0;
resolutionRate.value = 0;
timelinessRate.value = 0;
// 模拟API请求延迟
setTimeout(() => {
// 根据时间范围返回不同数据
let mockData;
if (timeRange.value === 'month') {
mockData = {
completionRate: 68,
resolutionRate: 72,
timelinessRate: 60,
completedInspections: 42,
totalProblems: 7,
solvedProblems: 5,
avgCompletionTime: '45分钟',
problemTypes: {
temperature: 85,
memory: 62,
cpu: 45,
responseTime: 30,
diskSpace: 15
}
};
} else if (timeRange.value === 'week') {
mockData = {
completionRate: 75,
resolutionRate: 80,
timelinessRate: 65,
completedInspections: 12,
totalProblems: 2,
solvedProblems: 2,
avgCompletionTime: '35分钟',
problemTypes: {
temperature: 70,
memory: 55,
cpu: 40,
responseTime: 25,
diskSpace: 10
}
};
} else {
// day
mockData = {
completionRate: 90,
resolutionRate: 100,
timelinessRate: 95,
completedInspections: 2,
totalProblems: 0,
solvedProblems: 0,
avgCompletionTime: '25分钟',
problemTypes: {
temperature: 30,
memory: 45,
cpu: 25,
responseTime: 10,
diskSpace: 5
}
};
}
// 应用筛选条件(这里仅做简单演示)
if (filterStatus.value === 'problem') {
mockData.totalProblems = Math.round(mockData.totalProblems * 1.5);
mockData.solvedProblems = Math.round(mockData.solvedProblems * 0.7);
mockData.resolutionRate = Math.round(mockData.resolutionRate * 0.8);
}
// 更新数据
completionRate.value = mockData.completionRate;
resolutionRate.value = mockData.resolutionRate;
timelinessRate.value = mockData.timelinessRate;
completedInspections.value = mockData.completedInspections;
totalProblems.value = mockData.totalProblems;
solvedProblems.value = mockData.solvedProblems;
avgCompletionTime.value = mockData.avgCompletionTime;
problemTypes.value = mockData.problemTypes;
// 更新饼图
initPieChart();
}, 800); // 模拟网络延迟
};
// 页面加载时获取数据
onMounted(() => {
fetchDashboardData();
});
// 组件卸载时销毁图表实例
onUnmounted(() => {
if (pieChart) {
pieChart.dispose();
pieChart = null;
}
});
// 导航方法
const handleInspection1 = () => {
router.push('/rili/rili');
@ -456,11 +626,12 @@ const handleInspectionManagement3 = () => {
min-height: 100vh;
}
/* 头部容器 - 替换了固定gap的flex布局 */
/* 头部容器 */
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.header-actions {
@ -603,7 +774,7 @@ const handleInspectionManagement3 = () => {
}
.card-body {
padding: 0 20px;
padding: 20px;
flex: 1; /* 内容区域占满剩余空间 */
}
@ -612,6 +783,14 @@ const handleInspectionManagement3 = () => {
background-color: #f5f7fa;
border-radius: 6px;
padding: 16px;
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
}
.stat-card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.stat-label {
@ -639,6 +818,14 @@ const handleInspectionManagement3 = () => {
font-size: 14px;
color: #606266;
margin: 0 0 8px 0;
text-align: center;
}
/* 饼图容器 */
.pie-chart-container {
width: 100%;
height: 300px;
margin: 0 auto;
}
/* 区域标题 */
@ -649,30 +836,6 @@ const handleInspectionManagement3 = () => {
margin: 0 0 12px 0;
}
/* 记录列表样式 */
.record-list {
margin: 0;
padding: 0;
}
.record-item {
padding: 16px 0;
}
.record-title {
font-size: 14px;
font-weight: 500;
color: #303133;
margin: 0;
}
.record-time,
.record-type {
font-size: 12px;
color: #909399;
margin: 4px 0 0 0;
}
/* 状态标签 */
.status-tag {
font-size: 12px;
@ -698,18 +861,6 @@ const handleInspectionManagement3 = () => {
border: 1px solid #ffe3e0;
}
/* 操作按钮 */
.action-btn {
color: #409eff;
font-size: 12px;
padding: 4px 8px;
}
.action-btn:hover {
color: #66b1ff;
background-color: #ecf5ff;
}
/* 滚动条样式优化 */
.scrollbar-thin {
scrollbar-width: thin;
@ -750,4 +901,25 @@ const handleInspectionManagement3 = () => {
justify-content: flex-end;
}
}
@media (max-width: 768px) {
.grid-cols-2 {
grid-template-columns: 1fr;
}
.md\:col-span-1,
.md\:col-span-2,
.md\:col-span-3 {
grid-column: span 1;
}
.md\:grid-cols-4,
.md\:grid-cols-3 {
grid-template-columns: 1fr 1fr;
}
.navigation-tabs {
justify-content: flex-start;
}
}
</style>

View File

@ -106,8 +106,8 @@
</div>
<div class="task-actions">
<el-button type="text" size="small" class="action-btn view-btn" @click="handleView(task)"> 详情 </el-button>
<el-button type="primary" size="small" :class="task.actionClass" @click="handleAction(task)">
<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>
@ -588,6 +588,10 @@ const handleInspection7 = () => {
z-index: 10;
}
.task-actions .el-button {
border-radius: 16px;
padding: 6px 16px;
}
.task-card::before {
content: '';
position: absolute;

View File

@ -8,6 +8,11 @@
<el-input v-model="form.devicename" placeholder="请输入设备名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工区" prop="workArea">
<el-input v-model="form.workArea" placeholder="请输入工区" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
@ -162,7 +167,8 @@ const form: any = ref({
qualificationId: undefined,
equipmentPhotoId: undefined,
verificationReportId: undefined,
remark: undefined
remark: undefined,
workArea: undefined
});
const rules = ref({
devicename: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
@ -245,7 +251,8 @@ const reset = () => {
equipmentPhotoId: undefined,
verificationReportId: undefined,
equipmentType: undefined,
remark: undefined
remark: undefined,
workArea: undefined
};
mechanicalrewritingFormRef.value?.resetFields();
};

View File

@ -10,6 +10,9 @@
<el-col :span="12">
<el-form-item label="设备名称">{{ formData.devicename }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工区">{{ formData.workArea }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备类型">{{ formData.deviceType }}</el-form-item>
</el-col>

View File

@ -7,7 +7,9 @@
<el-form-item label="设备名称" prop="devicename">
<el-input v-model="queryParams.devicename" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="工区" prop="workArea">
<el-input v-model="queryParams.workArea" placeholder="请输入工区" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
@ -53,7 +55,7 @@
<el-table-column label="新旧程度" align="center" prop="degree" />
<el-table-column label="车辆容量" align="center" prop="vehicleCapacity" />
<el-table-column label="车辆净重" align="center" prop="suttle" />
<el-table-column label="工区" align="center" prop="workArea" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" fixed="right" min-width="200" fixed-width>
<template #default="scope">
@ -160,6 +162,7 @@ const data = reactive<PageData<MechanicalrewritingForm, MechanicalrewritingQuery
qualification: undefined,
equipmentPhoto: undefined,
verificationReport: undefined,
workArea: undefined,
params: {}
},
rules: {

View File

@ -102,6 +102,15 @@
v-hasPermi="['progress:constructionSchedulePlan:remove']"
/>
</el-tooltip>
<el-button
v-if="scope.row.status != '4'"
link
type="primary"
@click="openFinishDialog(scope.row)"
v-hasPermi="['progress:constructionSchedulePlan:editFinish']"
>
确定
</el-button>
</template>
</el-table-column>
</el-table>
@ -162,6 +171,20 @@
</div>
</template>
</el-dialog>
<!-- 完成节点弹框 -->
<el-dialog :title="finishDialog.title" v-model="finishDialog.visible" width="400px" append-to-body>
<el-form ref="finishFormRef" :model="finishForm" :rules="finishRules" label-width="100px">
<el-form-item label="结束时间" prop="finishDate">
<el-date-picker v-model="finishForm.finishDate" type="date" value-format="YYYY-MM-DD" placeholder="选择结束时间" clearable />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFinish"> </el-button>
<el-button @click="finishDialog.visible = false"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@ -172,7 +195,8 @@ import {
delConstructionSchedulePlan,
addConstructionSchedulePlan,
updateConstructionSchedulePlan,
getProjectStructure
getProjectStructure,
finishConstructionSchedulePlan
} from '@/api/progress/constructionSchedulePlan';
import {
ConstructionSchedulePlanVO,
@ -204,6 +228,20 @@ const loading = ref(false);
const queryFormRef = ref<ElFormInstance>();
const constructionSchedulePlanFormRef = ref<ElFormInstance>();
const constructionSchedulePlanTableRef = ref<ElTableInstance>();
const finishDialog = reactive({
visible: false,
title: '设置完成时间',
row: null as ConstructionSchedulePlanVO | null
});
const finishForm = reactive({
finishDate: ''
});
const finishRules = {
finishDate: [{ required: true, message: '请选择结束时间', trigger: 'change' }]
};
const finishFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
@ -282,6 +320,24 @@ const cancel = () => {
reset();
dialog.visible = false;
};
const openFinishDialog = (row: ConstructionSchedulePlanVO) => {
finishDialog.visible = true;
finishDialog.row = row;
finishForm.finishDate = ''; // 清空之前的选择
};
const submitFinish = () => {
finishFormRef.value?.validate(async (valid) => {
if (valid && finishDialog.row) {
const res = await finishConstructionSchedulePlan({ id: finishDialog.row.id, finishDate: finishForm.finishDate });
if (res.code === 200) {
proxy.$modal.msgSuccess('操作成功');
getList();
finishDialog.visible = false;
}
}
});
};
const handleExport = async () => {
const ids = queryParams.value.projectId;

View File

@ -22,7 +22,13 @@
<div>
<div>
<span>租金</span>
<span>{{ proxy.formatPrice(detailInfo.rentSum) / 1000 }} 万元</span>
<span>{{
detailInfo.rentSum && !isNaN(detailInfo.rentSum)
? detailInfo.rentSum >= 10000
? proxy.formatPrice(detailInfo.rentSum / 10000) + ' 万元'
: proxy.formatPrice(detailInfo.rentSum) + ' 元'
: '0.00 元'
}}</span>
</div>
<el-icon :size="50" color="#3176ff">
<Postcard />

View File

@ -156,7 +156,7 @@ var lastTime = 0;
var scrolltimerTable = null;
var rotate = false;
const autoScrollTable = (time: number) => {
const autoScrollTable = (time: any, isAsc?: boolean) => {
const divData = document.getElementById('event_scroll');
if (time - lastTime < 25) {

View File

@ -22,7 +22,7 @@ export let pieOption = {
fontSize: 14,
fill: '#fff'
}
},
}
],
legend: {
show: true,
@ -62,7 +62,7 @@ export let pieOption = {
},
legend: {
top: 'bottom'
},
}
}
};
@ -76,12 +76,12 @@ export let barOption = {
top: 10,
right: 20,
textStyle: {
color: '#fff',
color: '#fff'
}
},
xAxis: {
type: 'category',
data: ['地块1', '地块2', '地块3', '地块4', '地块5', '地块6'],
data: [],
axisLabel: {
color: '#fff'
},
@ -97,30 +97,59 @@ export let barOption = {
type: 'value',
axisLabel: {
formatter: '{value}'
},
splitLine: {
show: false // 不显示分割线
}
},
grid: {
bottom: 0, // 距离容器底部的距离
containLabel: true // 确保坐标轴标签不被裁剪
},
tooltip: {
show: true,
backgroundColor: '',
trigger: 'axis',
// formatter: '{b0}{c0}万元',
formatter: (params: any) => {
// console.log(params);
const projectName = params[0].name;
// params 是数组,对应每条柱子
// return params.map((p: any) => `${p.name} <br/> ${p.seriesName}${Number(p.value).toFixed(2)} MW`).join('<br/>');
return (
`${projectName}<br/>` +
params
.slice(0, 2)
.map((p) => `${p.seriesName}${Number(p.value).toFixed(2)}`)
.join('<br/>')
);
},
textStyle: {
color: '#fff'
},
axisPointer: {
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow',
}
// borderColor: 'rgba(252, 217, 18, 1)'
},
series: [
{
name: '计划流转面积',
type: 'bar',
data: [],
barWidth: '20%',
barWidth: '10',
itemStyle: {
color: 'rgb(29, 253, 253)'
},
}
},
{
name: '已流转面积',
type: 'bar',
data: [],
barWidth: '20%',
barWidth: '10',
itemStyle: {
color: 'rgb(25, 181, 251)'
},
}
}
]
};
@ -129,7 +158,7 @@ export let mapOption = {
geo: {
map: 'ch',
roam: true,
aspectScale: Math.cos((47 * Math.PI) / 180),
aspectScale: Math.cos((47 * Math.PI) / 180)
},
series: [
{
@ -147,7 +176,7 @@ export let mapOption = {
{ name: 'i', value: [9.085994375000002, 47.55395822835779] },
{ name: 'j', value: [8.653968125000002, 47.47709530818285] },
{ name: 'k', value: [8.203158125000002, 47.44506909144329] }
],
]
}
]
};

View File

@ -41,6 +41,7 @@ let lineChart: any = null;
// 土地数据 折线图
const designAreaData = ref([]);
const transferAreaData = ref([]);
const barNames = ref([]);
// 饼图数据
let pieData = [
{ label: 'areaPercentage', name: '场区', value: 0 },
@ -66,12 +67,13 @@ const initPieChart = () => {
pieChart.setOption(pieOption);
};
// 初始化折线图
// 初始柱状图线图
const initLineChart = () => {
if (!lineChartRef.value) {
console.error('未找到折线图容器元素');
return;
}
barOption.xAxis.data = barNames.value;
barOption.series[0].data = designAreaData.value;
barOption.series[1].data = transferAreaData.value;
lineChart = echarts.init(lineChartRef.value, null, {
@ -88,6 +90,8 @@ const getScreenLandData = async () => {
const res = await getScreenLand(projectIdTwo);
const { data, code } = res;
if (code === 200) {
console.log(data);
barNames.value = res.data.map((item: any) => item.landName);
designAreaData.value = data.map((item: any) => Number(item.designArea));
transferAreaData.value = data.map((item: any) => Number(item.transferArea));
initLineChart();

View File

@ -28,7 +28,7 @@
><el-space wrap>
<div>
<span>
<image-preview :src="'http://58.17.134.85:8920' + safetyInspectionDetail?.path" width="200px" />
<image-preview v-if="safetyInspectionDetail?.path" :src="'http://58.17.134.85:8920' + safetyInspectionDetail?.path" width="200px" />
</span>
</div>
</el-space>

View File

@ -1,6 +1,14 @@
<template>
<!-- <el-card v-loading="loading" body-class="printMe"> -->
<div class="w75% m-a">
<el-select style="width: 300px; margin-bottom: 10px" v-model="teamId" placeholder="请选择历史版本">
<el-option
v-for="(item, i) of histroyList"
:key="i"
:label="'版本' + item.version"
:value="item.id"
@click="changeForeman(item.id)"
></el-option>
</el-select>
<div id="printMe" class="pos-relative">
<div class="resultIcon"><img :src="'/image/svg/' + inspectionType + '.png'" alt="" /></div>
<h2 style="text-align: center; margin-top: 5px; font-weight: bold">整改通知单</h2>
@ -114,8 +122,8 @@ const { quality_inspection_check_type, quality_inspection_status_type } = toRefs
);
interface Props {
qualityInspectionDetailId?: string | number;
jobKey: string;
}
const props = defineProps<Props>();
const safetyInspectionDetail = ref<QualityInspectionVO>();
const checkFileList = ref<any[]>();
@ -152,7 +160,8 @@ const handleExport = async () => {
};
onMounted(() => {
get();
getList();
get(props.qualityInspectionDetailId);
});
watch(
@ -161,7 +170,7 @@ watch(
if (newId !== oldId) {
checkFileList.value = undefined;
// rectificationFileList.value = undefined;
get();
get(props.qualityInspectionDetailId);
}
}
);

View File

@ -43,6 +43,9 @@
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['quality:qualityInspection:export']">导出</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['quality:qualityInspection:export']">导出</el-button>
</el-col> -->
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
@ -269,7 +272,6 @@ const getList = async () => {
total.value = res.data.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
@ -326,9 +328,11 @@ const handleUpdate = async (row?: QualityInspectionVO) => {
};
const currentId = ref<string | number>('');
const jobKey = ref<string | number>('');
/** 详情按钮操作 */
const handleDetail = async (row?: QualityInspectionVO) => {
const handleDetail = async (row) => {
currentId.value = row?.id;
jobKey.value = row?.jobKey;
dialog.details = true;
};

View File

@ -1,6 +1,15 @@
<template>
<!-- <el-card v-loading="loading" body-class="printMe"> -->
<div class="w75% m-a">
<el-select style="width: 300px; margin-bottom: 10px" v-model="teamId" placeholder="请选择历史版本">
<el-option
v-for="(item, i) of histroyList"
:key="i"
:label="'版本' + item.version"
:value="item.id"
@click="changeForeman(item.id)"
></el-option>
</el-select>
<div id="printMe" class="pos-relative">
<div class="resultIcon"><img :src="'/image/svg/' + inspectionType + '.png'" alt="" /></div>
<h2 style="text-align: center; margin-top: 5px; font-weight: bold">安全生产监督检查通知书</h2>
@ -126,13 +135,14 @@
<script setup lang="ts">
import { useUserStoreHook } from '@/store/modules/user';
import { SafetyInspectionVO } from '@/api/safety/safetyInspection/types';
import { getSafetyInspection } from '@/api/safety/safetyInspection';
import { getSafetyInspection, recordList } from '@/api/safety/safetyInspection';
import { downLoadOss, listByIds } from '@/api/system/oss';
import { OssVO } from '@/api/system/oss/types';
import { dayjs } from 'element-plus';
interface Props {
safetyInspectionId?: string | number;
jobKey?: string;
}
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -158,8 +168,17 @@ const inspectionType = computed(() => {
return imgName;
});
const get = async () => {
const teamId = ref('');
const histroyList = ref<any[]>();
// 获取列表
const getList = async () => {
var res = await recordList(props.jobKey);
histroyList.value = res.data;
};
const changeForeman = (id) => {
get(id);
};
const get = async (id) => {
loading.value = true;
const res = await getSafetyInspection({ id: props.safetyInspectionId });
if (res.data && res.code === 0) {
@ -175,8 +194,8 @@ const handleExport = async () => {
};
onMounted(() => {
console.log('🚀 ~ onMounted ~ props.safetyInspectionId:', props.safetyInspectionId);
get();
getList();
get(props.safetyInspectionId);
});
watch(
@ -185,7 +204,7 @@ watch(
if (newId !== oldId) {
checkFileList.value = undefined;
rectificationFileList.value = undefined;
get();
get(props.safetyInspectionId);
}
}
);

View File

@ -145,7 +145,7 @@
</template>
</el-dialog>
<el-dialog title="巡检工单详情" v-model="showDetailDialog" width="60vw">
<safety-inspection-detail-dialog :safety-inspection-id="currentSafetyInspectionId" />
<safety-inspection-detail-dialog :jobKey="jobKey" :safety-inspection-id="currentSafetyInspectionId" />
</el-dialog>
</div>
</template>