Files
td_official/src/views/dhr_demo/InspectionManagement.vue
2025-09-13 18:43:26 +08:00

773 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<div class="operation-inspection">
<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-item">
<el-select v-model="planType" placeholder="计划类型" clearable>
<el-option label="全部类型" value="all"></el-option>
<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="status" placeholder="全部状态" clearable>
<el-option label="全部状态" value="all"></el-option>
<el-option label="启用中" value="enabled"></el-option>
<el-option label="已停用" value="disabled"></el-option>
</el-select>
</div>
<div class="filter-item">
<el-select v-model="inspectionObject" placeholder="巡检对象" clearable>
<el-option label="全部对象" value="all"></el-option>
<el-option label="服务器" value="server"></el-option>
<el-option label="网络设备" value="network"></el-option>
<el-option label="应用系统" value="application"></el-option>
<el-option label="基础设施" value="infrastructure"></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="handleCreate">手动创建计划</el-button>
</div>
</div>
<!-- 表格 -->
<div class="table-wrapper">
<el-table :data="pagedTableData" stripe style="width: 100%" highlight-current-row class="custom-table">
<el-table-column align="center" prop="name" label="计划名称" style="width: 14.2%"></el-table-column>
<el-table-column align="center" prop="type" label="类型" style="width: 14.2%"></el-table-column>
<el-table-column align="center" prop="object" label="巡检对象" style="width: 14.2%"></el-table-column>
<el-table-column align="center" prop="frequency" label="频率" style="width: 14.2%"></el-table-column>
<el-table-column align="center" prop="status" label="状态" style="width: 14.2%">
<template #default="scope">
<el-tag :type="scope.row.status === 'enabled' ? 'success' : 'info'" class="status-tag">
{{ scope.row.status === 'enabled' ? '启用中' : '已停用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="responsible" label="负责人" style="width: 14.2%"></el-table-column>
<el-table-column align="center" label="操作" style="width: 14.2%" fixed="right">
<template #default="scope">
<el-button type="text" @click="handleEdit(scope.row)" size="small" class="action-btn">编辑</el-button>
<el-button type="text" @click="handleDetail(scope.row)" size="small" class="action-btn">详情</el-button>
<el-button
type="text"
:disabled="scope.row.status === 'disabled'"
@click="handleEnable(scope.row)"
size="small"
class="action-btn"
:class="{ 'text-success': scope.row.status === 'disabled' }"
>
{{ scope.row.status === 'enabled' ? '停用' : '启用' }}
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页区域 -->
<div class="pagination-section">
<div class="pagination-info">
显示第{{ (currentPage - 1) * pageSize + 1 }}{{ Math.min(currentPage * pageSize, total) }}共有{{ total }}条记录
</div>
<div class="pagination-controls">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
background
>
</el-pagination>
</div>
</div>
</div>
<!-- 创建计划弹窗 -->
<el-dialog v-model="dialogVisible" title="新建巡检计划" width="700px" class="create-plan-dialog" center :show-close="true">
<el-form :model="createForm" :rules="createFormRules" ref="createFormRef" label-width="150px" class="custom-form">
<el-form-item label="计划名称*" prop="planName" class="form-item-large">
<el-input v-model="createForm.planName" placeholder="请输入计划名称" class="custom-input" />
</el-form-item>
<div class="form-row">
<el-form-item label="计划类型*" prop="planType" class="form-item-half">
<el-select v-model="createForm.planType" placeholder="请选择计划类型" class="custom-select">
<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="巡检对象类型*" prop="objectType" class="form-item-half">
<el-select v-model="createForm.objectType" placeholder="请选择对象类型" class="custom-select">
<el-option label="服务器" value="server" />
<el-option label="网络设备" value="network" />
<el-option label="应用系统" value="application" />
<el-option label="基础设施" value="infrastructure" />
</el-select>
</el-form-item>
</div>
<div class="form-row">
<el-form-item label="开始日期*" prop="startDate" class="form-item-half">
<el-date-picker
v-model="createForm.startDate"
type="date"
placeholder="选择日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
class="custom-date-picker"
/>
</el-form-item>
<el-form-item label="结束日期*" prop="endDate" class="form-item-half">
<el-date-picker
v-model="createForm.endDate"
type="date"
placeholder="选择日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
class="custom-date-picker"
/>
</el-form-item>
</div>
<el-form-item label="巡检频率*" class="form-item-large">
<div style="display: flex; align-items: center; gap: 20px">
<el-radio-group v-model="createForm.frequencyType" class="frequency-radio-group">
<el-radio label="daily">每天</el-radio>
<el-radio label="weekly">每周</el-radio>
<el-radio label="monthly">每月</el-radio>
</el-radio-group>
<!-- 每周选择框 - 变小并排在单选框后面 -->
<el-select
v-if="createForm.frequencyType === 'weekly'"
v-model="createForm.weekday"
placeholder="选择周几"
class="custom-select-small"
style="width: 100px"
>
<el-option label="周一" value="1" />
<el-option label="周二" value="2" />
<el-option label="周三" value="3" />
<el-option label="周四" value="4" />
<el-option label="周五" value="5" />
<el-option label="周六" value="6" />
<el-option label="周日" value="0" />
</el-select>
<!-- 每月选择框 - 变小并排在单选框后面 -->
<el-select
v-if="createForm.frequencyType === 'monthly'"
v-model="createForm.monthday"
placeholder="选择几号"
class="custom-select-small"
style="width: 100px"
>
<template v-for="day in 31" :key="day">
<el-option :label="day + '号'" :value="day" />
</template>
</el-select>
</div>
</el-form-item>
<div class="form-row" s>
<el-form-item label="计划开始时间*" prop="startTime" class="form-item-half">
<el-time-picker v-model="createForm.startTime" placeholder="选择时间" format="HH:mm" value-format="HH:mm" class="custom-time-picker" />
</el-form-item>
<el-form-item label="预计时长(分钟)" class="form-item-half">
<el-input v-model.number="createForm.estimatedDuration" class="custom-input" />
</el-form-item>
</div>
<el-form-item label="负责人*" prop="responsiblePerson" class="form-item-large">
<el-select v-model="createForm.responsiblePerson" placeholder="请选择负责人" class="custom-select">
<el-option label="张明" value="zhangming" />
<el-option label="李华" value="lihua" />
<el-option label="王强" value="wangqiang" />
</el-select>
</el-form-item>
<el-form-item label="巡检项*" class="form-item-large">
<el-checkbox-group v-model="createForm.inspectionItems" style="border: 0.1 solid black; padding: 5px">
<el-checkbox label="CPU使用率检查" />
<el-checkbox label="内存使用情况" />
<el-checkbox label="磁盘空间检查" />
<el-checkbox label="网络连接状态" />
<el-checkbox label="系统日志检查" />
</el-checkbox-group>
</el-form-item>
<el-form-item label="备注说明" prop="remarks" class="form-item-large">
<el-input v-model="createForm.remarks" type="textarea" placeholder="请输入备注" rows="3" class="custom-textarea" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="cancelCreatePlan">取消</el-button>
<el-button type="primary" @click="submitCreatePlan">新增任务</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
// 表单引用
const createFormRef = ref(null);
import { ref, computed, reactive } from 'vue';
import router from '@/router';
import TitleComponent from '@/views/demo/components/TitleComponent.vue';
// 激活的选项卡
const activeTab = ref('plan');
// 计划类型
const planType = ref('all');
// 状态
const status = ref('all');
// 巡检对象
const inspectionObject = ref('all');
// 原始表格数据
const rawTableData = ref([
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
{
name: '网络设备安全巡检 2025-04-15',
type: '每周巡检',
object: '网络设备',
frequency: '每天10:30',
status: 'enabled',
responsible: '张明'
},
{
name: '数据库性能巡检 2025-03-03',
type: '每月巡检',
object: '应用系统',
frequency: '每月1日14:00',
status: 'disabled',
responsible: '张明'
},
{
name: '机房环境季度检查',
type: '每季度巡检',
object: '基础设备',
frequency: '每季度第一个月5号',
status: 'enabled',
responsible: '张明'
},
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
{
name: '生产服务器每日巡检 2025-05-14',
type: '每日巡检',
object: '服务器',
frequency: '每天8:30',
status: 'enabled',
responsible: '张明'
},
// 增加更多数据用于测试分页
{
name: '应用系统安全检查',
type: '每周巡检',
object: '应用系统',
frequency: '每周五16:00',
status: 'enabled',
responsible: '李华'
},
{
name: '网络带宽监控',
type: '每日巡检',
object: '网络设备',
frequency: '每天12:00',
status: 'enabled',
responsible: '王强'
}
]);
// 当前页码
const currentPage = ref(1);
// 每页条数 - 与分页控件默认值保持一致
const pageSize = ref(10);
// 总条数 - 从原始数据计算得出
const total = ref(rawTableData.value.length);
// 计算属性:根据当前页码和每页条数获取分页后的数据
const pagedTableData = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return rawTableData.value.slice(startIndex, endIndex);
});
// 每页条数改变
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1; // 重置到第一页
};
// 当前页码改变
const handleCurrentChange = (val) => {
currentPage.value = val;
};
// 编辑
const handleEdit = (row) => {
console.log('编辑', row);
};
// 详情
const handleDetail = (row) => {
console.log('详情', row);
};
// 启用/停用
const handleEnable = (row) => {
row.status = row.status === 'enabled' ? 'disabled' : 'enabled';
};
// 选项卡切换
const handleTabChange = (newTab, oldTab) => {
// 可以在这里添加选项卡切换时的逻辑
console.log('选项卡切换:', newTab, oldTab);
return true;
};
// 创建计划弹窗相关
const dialogVisible = ref(false);
const createForm = reactive({
planName: '',
planType: '',
objectType: '',
startDate: '',
endDate: '',
frequencyType: 'daily',
frequencyValue: '',
weekday: '', // 存储周几
monthday: '', // 存储几号
startTime: '',
estimatedDuration: 60,
responsiblePerson: '',
inspectionItems: [],
remarks: ''
});
// 创建计划表单验证规则
const createFormRules = computed(() => ({
planName: [{ required: true, message: '请输入计划名称', trigger: 'blur' }],
planType: [{ required: true, message: '请选择计划类型', trigger: 'change' }],
objectType: [{ required: true, message: '请选择对象类型', trigger: 'change' }],
startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }],
startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
responsiblePerson: [{ required: true, message: '请选择负责人', trigger: 'change' }],
weekday: createForm.frequencyType === 'weekly' ? [{ required: true, message: '请选择周几', trigger: 'change' }] : [],
monthday: createForm.frequencyType === 'monthly' ? [{ required: true, message: '请选择几号', trigger: 'change' }] : []
}));
// 打开创建计划弹窗
const handleCreate = () => {
dialogVisible.value = true;
};
// 提交创建计划
const submitCreatePlan = () => {
console.log('提交创建计划:', createForm);
// 这里可以添加实际的创建计划逻辑
dialogVisible.value = false;
// 重置表单
Object.keys(createForm).forEach((key) => {
if (Array.isArray(createForm[key])) {
createForm[key] = [];
} else if (key === 'estimatedDuration') {
createForm[key] = 60;
} else if (key === 'frequencyType') {
createForm[key] = 'daily';
} else {
createForm[key] = '';
}
});
};
// 取消创建计划
const cancelCreatePlan = () => {
dialogVisible.value = false;
// 重置表单
Object.keys(createForm).forEach((key) => {
if (Array.isArray(createForm[key])) {
createForm[key] = [];
} else if (key === 'estimatedDuration') {
createForm[key] = 60;
} else if (key === 'frequencyType') {
createForm[key] = 'daily';
} else {
createForm[key] = '';
}
});
};
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');
};
const handleInspectionManagement1 = () => {
router.push('/rili/InspectionManagement');
};
const handleInspectionManagement2 = () => {
router.push('/rili/xunjianrenwu');
};
const handleInspectionManagement3 = () => {
router.push('/rili/xunjianjihua');
};
</script>
<style scoped>
/* 样式保持不变 */
.operation-inspection {
padding: 20px;
background-color: #f5f7fa;
min-height: 100vh;
}
/* 标题区域样式 */
.title-section {
background-color: #fff;
padding: 20px;
border-radius: 8px;
margin-bottom: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.page-title {
font-size: 24px;
font-weight: 600;
color: #303133;
margin: 0 0 8px 0;
}
.page-subtitle {
font-size: 14px;
color: #909399;
margin: 0;
}
/* 选项卡样式 */
.tabs-wrapper {
background-color: #fff;
padding: 20px;
border-radius: 8px;
margin-bottom: 16px;
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;
padding: 20px;
border-radius: 8px;
margin-bottom: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 16px;
}
.filter-item {
flex-shrink: 0;
}
.filter-bar .el-select {
width: 150px;
height: 36px;
}
.filter-actions {
margin-left: auto;
display: flex;
gap: 10px;
}
.search-btn,
.create-btn {
height: 36px;
border-radius: 4px;
}
/* 表格样式 */
.table-wrapper {
background-color: #fff;
padding: 20px;
border-radius: 8px;
margin-bottom: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.custom-table {
border: 1px solid #ebeef5;
border-radius: 4px;
overflow: hidden;
}
.custom-table th {
background-color: #fafafa;
font-weight: 500;
color: #606266;
text-align: left;
padding: 12px 16px;
border-bottom: 1px solid #ebeef5;
}
.custom-table td {
padding: 12px 16px;
border-bottom: 1px solid #ebeef5;
color: #303133;
}
.custom-table tr:hover {
background-color: #f5f7fa;
}
.custom-table tr.current-row {
background-color: #ecf5ff;
}
.status-tag {
padding: 4px 8px;
font-size: 12px;
border-radius: 4px;
}
.action-btn {
color: #409eff;
font-size: 12px;
padding: 4px 8px;
}
.action-btn:hover {
color: #66b1ff;
background-color: #ecf5ff;
}
/* 分页区域样式 */
.pagination-section {
background-color: #fff;
padding: 16px 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
display: flex;
justify-content: space-between;
align-items: center;
}
.pagination-info {
font-size: 14px;
color: #606266;
}
.pagination-controls .el-pagination {
margin: 0;
}
.pagination-controls .el-pagination__sizes {
margin-right: 20px;
}
.pagination-controls .el-pagination button {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 4px;
}
.pagination-controls .el-pagination .el-pager li {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 4px;
}
.pagination-controls .el-pagination .el-pager li.active {
background-color: #409eff;
color: #fff;
}
/* 导航栏样式 */
.navigation-tabs {
display: flex;
margin-bottom: 20px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
padding: 2px;
}
.nav-tab {
padding: 12px 24px;
cursor: pointer;
transition: all 0.3s ease;
border-radius: 4px;
font-size: 14px;
color: #606266;
border-right: 1px solid #f0f0f0;
flex: 1;
text-align: center;
}
.nav-tab:last-child {
border-right: none;
}
.nav-tab:hover {
color: #409eff;
background-color: #ecf5ff;
}
.nav-tab.active {
background-color: #409eff;
color: #fff;
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3);
}
.nav-tab {
cursor: pointer;
user-select: none;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.filter-bar {
flex-direction: column;
align-items: stretch;
}
.filter-actions {
margin-left: 0;
justify-content: flex-end;
}
}
</style>