Merge branch 'dhr' of http://xny.yj-3d.com:3000/taoge_xiaodi/maintenance_system into tcy
This commit is contained in:
@ -17,6 +17,8 @@
|
||||
"MaybeRefOrGetter": true,
|
||||
"PropType": true,
|
||||
"Ref": true,
|
||||
"Slot": true,
|
||||
"Slots": true,
|
||||
"VNode": true,
|
||||
"WritableComputedRef": true,
|
||||
"acceptHMRUpdate": true,
|
||||
@ -35,6 +37,7 @@
|
||||
"createInjectionState": true,
|
||||
"createPinia": true,
|
||||
"createReactiveFn": true,
|
||||
"createRef": true,
|
||||
"createReusableTemplate": true,
|
||||
"createSharedComposable": true,
|
||||
"createTemplatePromise": true,
|
||||
@ -315,9 +318,6 @@
|
||||
"watchThrottled": true,
|
||||
"watchTriggerable": true,
|
||||
"watchWithFilter": true,
|
||||
"whenever": true,
|
||||
"Slot": true,
|
||||
"Slots": true,
|
||||
"createRef": true
|
||||
"whenever": true
|
||||
}
|
||||
}
|
||||
|
||||
49
src/api/zhinengxunjian/baoxiou/index.ts
Normal file
49
src/api/zhinengxunjian/baoxiou/index.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
//查询列表
|
||||
export const baoxiulist = (query) => {
|
||||
return request({
|
||||
url: '/ops/report/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//新增待办事项
|
||||
export const addbaoxiu = (data) => {
|
||||
return request({
|
||||
url: '/ops/report',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//修改待办事项
|
||||
export const updatebaoxiu = (data) => {
|
||||
return request({
|
||||
url: '/ops/report',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//删除待办事项
|
||||
|
||||
export function delbaoxiu(ids) {
|
||||
return request({
|
||||
url: `/ops/report/${ids}`, // 拼接ids作为路径参数
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
export const baoxiuDetail = (id) => {
|
||||
return request({
|
||||
url: `/ops/report/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
export const uploadbaoxiu = (data) => {
|
||||
return request({
|
||||
url: '/resource/oss/upload',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
34
src/api/zhinengxunjian/daiban/index.ts
Normal file
34
src/api/zhinengxunjian/daiban/index.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
//查询列表
|
||||
export const daibanlist = (query) => {
|
||||
return request({
|
||||
url: '/ops/matter/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//新增待办事项
|
||||
export const adddaiban = (data) => {
|
||||
return request({
|
||||
url: '/ops/matter',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//修改待办事项
|
||||
export const updatedaiban = (data) => {
|
||||
return request({
|
||||
url: '/ops/matter',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//删除待办事项
|
||||
|
||||
export function deldaiban(ids) {
|
||||
return request({
|
||||
url: `/ops/matter/${ids}`, // 拼接ids作为路径参数
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
63
src/api/zhinengxunjian/inspection/item/index.ts
Normal file
63
src/api/zhinengxunjian/inspection/item/index.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ItemVO, ItemForm, ItemQuery } from '@/api/zhinengxunjian/inspection/item/types';
|
||||
|
||||
/**
|
||||
* 查询运维-巡检-自定义巡检项列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listItem = (query?: ItemQuery): AxiosPromise<ItemVO[]> => {
|
||||
return request({
|
||||
url: '/ops/item/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询运维-巡检-自定义巡检项详细
|
||||
* @param id
|
||||
*/
|
||||
export const getItem = (id: string | number): AxiosPromise<ItemVO> => {
|
||||
return request({
|
||||
url: '/ops/item/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增运维-巡检-自定义巡检项
|
||||
* @param data
|
||||
*/
|
||||
export const addItem = (data: ItemForm) => {
|
||||
return request({
|
||||
url: '/ops/item',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改运维-巡检-自定义巡检项
|
||||
* @param data
|
||||
*/
|
||||
export const updateItem = (data: ItemForm) => {
|
||||
return request({
|
||||
url: '/ops/item',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除运维-巡检-自定义巡检项
|
||||
* @param id
|
||||
*/
|
||||
export const delItem = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/ops/item/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
46
src/api/zhinengxunjian/inspection/item/types.ts
Normal file
46
src/api/zhinengxunjian/inspection/item/types.ts
Normal file
@ -0,0 +1,46 @@
|
||||
export interface ItemVO {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 自定义巡检项名称
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* 业务id,巡检计划1
|
||||
*/
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface ItemForm extends BaseEntity {
|
||||
/**
|
||||
* 自定义巡检项名称
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* 业务id,巡检计划1
|
||||
*/
|
||||
type?: string;
|
||||
projectId?: number;
|
||||
}
|
||||
|
||||
export interface ItemQuery extends PageQuery {
|
||||
/**
|
||||
* 自定义巡检项名称
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* 业务id,巡检计划1
|
||||
*/
|
||||
type?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
49
src/api/zhinengxunjian/shiyan/index.ts
Normal file
49
src/api/zhinengxunjian/shiyan/index.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
//查询列表
|
||||
export const shiyanlist = (query) => {
|
||||
return request({
|
||||
url: '/ops/testPlan/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//新增
|
||||
export const addshiyan = (data) => {
|
||||
return request({
|
||||
url: '/ops/testPlan',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//修改
|
||||
export const updateshiyan = (data) => {
|
||||
return request({
|
||||
url: '/ops/testPlan',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//删除
|
||||
export const delshiyan = (ids) => {
|
||||
return request({
|
||||
url: `/ops/testPlan${ids}`,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
//查询人员
|
||||
export const shiyanUserlist = (query) => {
|
||||
return request({
|
||||
url: '/ops/constructionUser/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
//详情
|
||||
export const shiyanDetail = (id) => {
|
||||
return request({
|
||||
url: `/ops/testPlan/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
41
src/api/zhinengxunjian/shiyan/renwu.ts
Normal file
41
src/api/zhinengxunjian/shiyan/renwu.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
//查询列表
|
||||
export const syrenwulist = (query) => {
|
||||
return request({
|
||||
url: '/ops/testTask/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//新增
|
||||
export const addsyrenwu = (data) => {
|
||||
return request({
|
||||
url: '/ops/testTask',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//修改
|
||||
export const updatesyrenwu = (data) => {
|
||||
return request({
|
||||
url: '/ops/testTask',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//删除
|
||||
export const delsyrenwu = (ids) => {
|
||||
return request({
|
||||
url: `/ops/testTask${ids}`,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
//详情
|
||||
export const syrenwuDetail = (id) => {
|
||||
return request({
|
||||
url: `/ops/testTask/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
56
src/api/zhinengxunjian/xunjian/index.ts
Normal file
56
src/api/zhinengxunjian/xunjian/index.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
//查询列表
|
||||
export const xunjianlist = (query) => {
|
||||
return request({
|
||||
url: '/ops/plan/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//新增
|
||||
export const addxunjian = (data) => {
|
||||
return request({
|
||||
url: '/ops/plan',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//修改
|
||||
export const updatexunjian = (data) => {
|
||||
return request({
|
||||
url: '/ops/plan',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//删除
|
||||
export const delxunjian = (ids) => {
|
||||
return request({
|
||||
url: `/ops/plan/${ids}`,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
//查询人员
|
||||
export const xunjianUserlist = (query) => {
|
||||
return request({
|
||||
url: '/ops/constructionUser/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//查询巡检项
|
||||
export const xunjianItemlist = (query) => {
|
||||
return request({
|
||||
url: '/ops/item/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//详情
|
||||
export const xunjianDetail = (id) => {
|
||||
return request({
|
||||
url: `/ops/plan/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
10
src/api/zhinengxunjian/xunjian/jilu.ts
Normal file
10
src/api/zhinengxunjian/xunjian/jilu.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
//查询列表
|
||||
export const xunjianjilu = (query) => {
|
||||
return request({
|
||||
url: '/ops/task/record',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
46
src/api/zhinengxunjian/xunjian/renwu.ts
Normal file
46
src/api/zhinengxunjian/xunjian/renwu.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import request from '@/utils/request';
|
||||
export const xjrenwulist = (query) => {
|
||||
return request({
|
||||
url: '/ops/task/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
//新增
|
||||
export const addxjrenwu = (data) => {
|
||||
return request({
|
||||
url: '/ops/task',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//修改
|
||||
export const updatexjrenwu = (data) => {
|
||||
return request({
|
||||
url: '/ops/task',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
//删除
|
||||
export const delxjrenwu = (ids) => {
|
||||
return request({
|
||||
url: `/ops/task/${ids}`,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
//详情
|
||||
export const xjrenwuDetail = (id) => {
|
||||
return request({
|
||||
url: `/ops/task/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
//导出
|
||||
export const xjrenwuExport = (data) => {
|
||||
return request({
|
||||
url: '/ops/task/export',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
225
src/views/inspection/item/index.vue
Normal file
225
src/views/inspection/item/index.vue
Normal file
@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="自定义巡检项名称" prop="name">
|
||||
<el-input v-model="queryParams.name" 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>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['inspection:item:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['inspection:item:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['inspection:item:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['inspection:item:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="itemList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="" align="center" prop="id" v-if="true" />
|
||||
<el-table-column label="自定义巡检项名称" align="center" prop="name" />
|
||||
<el-table-column label="业务id,巡检计划1" align="center" prop="type" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['inspection:item:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['inspection:item:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改运维-巡检-自定义巡检项对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="650px" append-to-body>
|
||||
<el-form ref="itemFormRef" :model="form" :rules="rules" label-width="135px">
|
||||
<el-form-item label="自定义巡检项名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入自定义巡检项名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择类型">
|
||||
<el-option label="巡检管理" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Item" lang="ts">
|
||||
import { listItem, getItem, delItem, addItem, updateItem } from '@/api/zhinengxunjian/inspection/item/index';
|
||||
import { ItemVO, ItemQuery, ItemForm } from '@/api/zhinengxunjian/inspection/item/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const itemList = ref<ItemVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const itemFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ItemForm = {
|
||||
name: undefined,
|
||||
type: '1',
|
||||
projectId: 1
|
||||
};
|
||||
const data = reactive<PageData<ItemForm, ItemQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
type: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: '自定义巡检项名称不能为空', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '业务id,巡检计划1不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询运维-巡检-自定义巡检项列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listItem(queryParams.value);
|
||||
itemList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
itemFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ItemVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加运维-巡检-自定义巡检项';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ItemVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getItem(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改运维-巡检-自定义巡检项';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
itemFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateItem(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addItem(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ItemVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除运维-巡检-自定义巡检项编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delItem(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/item/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`item_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load Diff
@ -129,12 +129,12 @@
|
||||
<el-dialog
|
||||
v-model="createTaskDialogVisible"
|
||||
title="新建报修任务"
|
||||
width="800px"
|
||||
width="900px"
|
||||
:before-close="handleCancelCreateTask"
|
||||
custom-class="beautiful-dialog"
|
||||
center
|
||||
>
|
||||
<el-form ref="createTaskFormRef" :model="createTaskForm" :rules="createTaskRules" label-width="100px" class="elegant-form">
|
||||
<el-form ref="createTaskFormRef" :model="createTaskForm" :rules="createTaskRules" label-width="120px" class="elegant-form">
|
||||
<el-form-item label="报修名称*" prop="repairName">
|
||||
<el-input v-model="createTaskForm.repairName" placeholder="简要描述报修内容" />
|
||||
</el-form-item>
|
||||
@ -143,10 +143,8 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报修类型*" prop="repairType">
|
||||
<el-select v-model="createTaskForm.repairType" placeholder="请选择类型">
|
||||
<el-option label="设备故障" value="device" />
|
||||
<el-option label="硬件故障" value="device" />
|
||||
<el-option label="软件故障" value="software" />
|
||||
<el-option label="网络故障" value="network" />
|
||||
<el-option label="环境问题" value="environment" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -161,6 +159,12 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="指派维修人*" prop="sendPerson">
|
||||
<el-select v-model="createTaskForm.sendPerson" placeholder="请选择维修人" :loading="loadingUsers">
|
||||
<el-option v-for="user in usersList" :key="user.id" :label="user.name" :value="user.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细描述*" prop="detailedDescription">
|
||||
<el-input v-model="createTaskForm.detailedDescription" type="textarea" :rows="4" placeholder="详细描述故障现象、发生时间、位置等信息" />
|
||||
</el-form-item>
|
||||
@ -169,7 +173,8 @@
|
||||
<el-input v-model="createTaskForm.faultLocation" placeholder="例如:A区102" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="上传图片(可选)">
|
||||
<el-form-item label="上传图片(可选)" width="100%">
|
||||
<file-upload v-model="createTaskForm.file" :fileType="['png', 'jpg', 'jpeg']">
|
||||
<div class="upload-container">
|
||||
<div class="upload-box">
|
||||
<i class="el-icon-plus avatar-uploader-icon"></i>
|
||||
@ -177,6 +182,23 @@
|
||||
<div class="upload-hint">支持JPG、PNG格式,最多3张</div>
|
||||
</div>
|
||||
</div>
|
||||
</file-upload>
|
||||
<!-- <el-upload
|
||||
class="avatar-uploader"
|
||||
:file-list="createTaskForm.fileList"
|
||||
:on-change="handleFileChange"
|
||||
:before-remove="beforeRemove"
|
||||
:on-remove="handleRemove"
|
||||
:auto-upload="false"
|
||||
multiple
|
||||
:limit="3"
|
||||
:on-exceed="handleExceed"
|
||||
>
|
||||
|
||||
</el-upload> -->
|
||||
<div v-if="createTaskForm.fileList && createTaskForm.fileList.length > 0" class="upload-tip">
|
||||
<span style="color: #1989fa">已选择{{ createTaskForm.fileList.length }}张图片,将在提交时上传</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-row :gutter="16">
|
||||
@ -196,7 +218,7 @@
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleCancelCreateTask">取消</el-button>
|
||||
<el-button type="primary" @click="handleSaveTask">保存计划</el-button>
|
||||
<el-button type="primary" @click="handleSaveTask">保存报修任务</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@ -205,10 +227,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import router from '@/router';
|
||||
import TitleComponent from './TitleComponent.vue';
|
||||
|
||||
import { baoxiulist, baoxiuDetail, delbaoxiu, updatebaoxiu, addbaoxiu, uploadbaoxiu } from '@/api/zhinengxunjian/baoxiou/index';
|
||||
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
||||
import { ElMessage } from 'element-plus';
|
||||
// 激活的选项卡
|
||||
const activeTab = ref('task');
|
||||
|
||||
@ -217,128 +241,165 @@ const taskStatus = ref('');
|
||||
const planType = ref('');
|
||||
const executor = ref('');
|
||||
|
||||
// 任务数据 - 恢复优先级标签样式和预计完成时间
|
||||
const tasks = ref([
|
||||
{
|
||||
title: '服务器A1电源故障',
|
||||
status: 'executing',
|
||||
statusText: '处理中',
|
||||
leftLineClass: 'left-line-high',
|
||||
priorityClass: 'priority-high', // 恢复优先级标签样式类
|
||||
priority: '高优先级',
|
||||
reportTime: '2025-06-16 08:30',
|
||||
reporter: '李明',
|
||||
maintainer: '张明',
|
||||
expectedCompleteTime: '2025-06-16 12:00', // 恢复预计完成时间
|
||||
actionText: '跟进',
|
||||
actionClass: 'follow-btn'
|
||||
},
|
||||
{
|
||||
title: '机房环境检查',
|
||||
status: 'pending',
|
||||
statusText: '待处理',
|
||||
leftLineClass: 'left-line-medium',
|
||||
priorityClass: 'priority-medium', // 恢复优先级标签样式类
|
||||
priority: '中优先级',
|
||||
reportTime: '2025-06-16 08:30',
|
||||
reporter: '张伟',
|
||||
maintainer: '未分配',
|
||||
expectedCompleteTime: '2025-06-16 18:00', // 恢复预计完成时间
|
||||
actionText: '分配',
|
||||
actionClass: 'assign-btn'
|
||||
},
|
||||
{
|
||||
title: '测试软件授权过期',
|
||||
status: 'executing',
|
||||
statusText: '处理中',
|
||||
leftLineClass: 'left-line-low',
|
||||
priorityClass: 'priority-low', // 恢复优先级标签样式类
|
||||
priority: '低优先级',
|
||||
reportTime: '2025-06-16 08:30',
|
||||
reporter: '李明',
|
||||
maintainer: '李阳',
|
||||
expectedCompleteTime: '2025-06-17 09:00', // 恢复预计完成时间
|
||||
actionText: '跟进',
|
||||
actionClass: 'follow-btn'
|
||||
},
|
||||
{
|
||||
title: '打印机卡纸故障',
|
||||
status: 'completed',
|
||||
statusText: '已完成',
|
||||
leftLineClass: 'left-line-completed',
|
||||
priorityClass: 'priority-low', // 恢复优先级标签样式类
|
||||
priority: '低优先级',
|
||||
reportTime: '2025-06-17 08:30',
|
||||
reporter: '李明',
|
||||
maintainer: '张明',
|
||||
expectedCompleteTime: '2025-06-17 10:00', // 恢复预计完成时间
|
||||
completeTime: '2025-06-17 09:15',
|
||||
actionText: '评价',
|
||||
actionClass: 'evaluate-btn'
|
||||
},
|
||||
{
|
||||
title: '服务器A1电源故障',
|
||||
status: 'executing',
|
||||
statusText: '处理中',
|
||||
leftLineClass: 'left-line-high',
|
||||
priorityClass: 'priority-high',
|
||||
priority: '高优先级',
|
||||
reportTime: '2025-06-16 08:30',
|
||||
reporter: '李明',
|
||||
maintainer: '张明',
|
||||
expectedCompleteTime: '2025-06-16 12:00',
|
||||
actionText: '跟进',
|
||||
actionClass: 'follow-btn'
|
||||
},
|
||||
{
|
||||
title: '机房环境检查',
|
||||
status: 'pending',
|
||||
statusText: '待处理',
|
||||
leftLineClass: 'left-line-medium',
|
||||
priorityClass: 'priority-medium',
|
||||
priority: '中优先级',
|
||||
reportTime: '2025-06-16 08:30',
|
||||
reporter: '张伟',
|
||||
maintainer: '未分配',
|
||||
expectedCompleteTime: '2025-06-16 18:00',
|
||||
actionText: '分配',
|
||||
actionClass: 'assign-btn'
|
||||
},
|
||||
{
|
||||
title: '测试软件授权过期',
|
||||
status: 'executing',
|
||||
statusText: '处理中',
|
||||
leftLineClass: 'left-line-low',
|
||||
priorityClass: 'priority-low',
|
||||
priority: '低优先级',
|
||||
reportTime: '2025-06-16 08:30',
|
||||
reporter: '李明',
|
||||
maintainer: '李阳',
|
||||
expectedCompleteTime: '2025-06-17 09:00',
|
||||
actionText: '跟进',
|
||||
actionClass: 'follow-btn'
|
||||
},
|
||||
{
|
||||
title: '打印机卡纸故障',
|
||||
status: 'completed',
|
||||
statusText: '已完成',
|
||||
leftLineClass: 'left-line-completed',
|
||||
priorityClass: 'priority-low',
|
||||
priority: '低优先级',
|
||||
reportTime: '2025-06-17 08:30',
|
||||
reporter: '李明',
|
||||
maintainer: '张明',
|
||||
expectedCompleteTime: '2025-06-17 10:00',
|
||||
completeTime: '2025-06-17 09:15',
|
||||
actionText: '评价',
|
||||
actionClass: 'evaluate-btn'
|
||||
}
|
||||
]);
|
||||
// 任务数据 - 初始为空数组
|
||||
const tasks = ref([]);
|
||||
|
||||
// 分页相关
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(8);
|
||||
const total = ref(tasks.value.length);
|
||||
const total = ref(0);
|
||||
const loading = ref(false);
|
||||
|
||||
// 获取报修任务列表
|
||||
defineExpose({ getTaskList });
|
||||
async function getTaskList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await baoxiulist({
|
||||
pageNum: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
status: taskStatus.value,
|
||||
type: planType.value,
|
||||
executor: executor.value
|
||||
});
|
||||
|
||||
if (res.code === 200 && res.rows) {
|
||||
total.value = res.total || 0;
|
||||
// 将API返回的数据转换为前端显示所需的格式
|
||||
tasks.value = res.rows.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.name || '未命名报修任务',
|
||||
status: mapStatusToKey(item.status),
|
||||
statusText: getStatusText(item.status),
|
||||
leftLineClass: getLeftLineClass(item.status, item.level),
|
||||
priorityClass: getPriorityClass(item.level),
|
||||
priority: getPriorityText(item.level),
|
||||
reportTime: formatDate(item.reportTime),
|
||||
reporter: item.reportName || '未知报修人',
|
||||
maintainer: item.sendPerson ? `维修人ID: ${item.sendPerson}` : '未分配',
|
||||
expectedCompleteTime: getExpectedCompleteTime(item.status),
|
||||
completeTime: item.completeTime ? formatDate(item.completeTime) : '',
|
||||
actionText: getActionText(item.status),
|
||||
actionClass: getActionClass(item.status),
|
||||
reportInfo: item.reportInfo,
|
||||
position: item.position,
|
||||
fileUrl: item.fileUrl
|
||||
}));
|
||||
} else {
|
||||
tasks.value = [];
|
||||
total.value = 0;
|
||||
console.error('获取报修任务列表失败:', res.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取报修任务列表异常:', error);
|
||||
tasks.value = [];
|
||||
total.value = 0;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 状态映射辅助函数
|
||||
function mapStatusToKey(status) {
|
||||
const statusMap = {
|
||||
'1': 'pending', // 待处理
|
||||
'2': 'executing', // 处理中
|
||||
'3': 'completed' // 已完成
|
||||
};
|
||||
return statusMap[status] || 'pending';
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
function getStatusText(status) {
|
||||
const statusMap = {
|
||||
'1': '待处理',
|
||||
'2': '处理中',
|
||||
'3': '已完成'
|
||||
};
|
||||
return statusMap[status] || '未知状态';
|
||||
}
|
||||
|
||||
// 获取优先级文本
|
||||
function getPriorityText(level) {
|
||||
const levelMap = {
|
||||
'1': '低优先级',
|
||||
'2': '中优先级',
|
||||
'3': '高优先级'
|
||||
};
|
||||
return levelMap[level] || '普通优先级';
|
||||
}
|
||||
|
||||
// 获取优先级样式类
|
||||
function getPriorityClass(level) {
|
||||
const levelMap = {
|
||||
'1': 'priority-low',
|
||||
'2': 'priority-medium',
|
||||
'3': 'priority-high'
|
||||
};
|
||||
return levelMap[level] || 'priority-low';
|
||||
}
|
||||
|
||||
// 获取左侧状态线样式类
|
||||
function getLeftLineClass(status, level) {
|
||||
if (status === '3') return 'left-line-completed';
|
||||
|
||||
const levelMap = {
|
||||
'1': 'left-line-low',
|
||||
'2': 'left-line-medium',
|
||||
'3': 'left-line-high'
|
||||
};
|
||||
return levelMap[level] || 'left-line-low';
|
||||
}
|
||||
|
||||
// 获取操作按钮文本
|
||||
function getActionText(status) {
|
||||
const actionMap = {
|
||||
'1': '分配',
|
||||
'2': '跟进',
|
||||
'3': '评价'
|
||||
};
|
||||
return actionMap[status] || '查看';
|
||||
}
|
||||
|
||||
// 获取操作按钮样式类
|
||||
function getActionClass(status) {
|
||||
const actionMap = {
|
||||
'1': 'assign-btn',
|
||||
'2': 'follow-btn',
|
||||
'3': 'evaluate-btn'
|
||||
};
|
||||
return actionMap[status] || 'view-btn';
|
||||
}
|
||||
|
||||
// 获取预计完成时间(根据状态和优先级估算)
|
||||
function getExpectedCompleteTime(status) {
|
||||
if (status === '3') return ''; // 已完成任务不需要显示预计时间
|
||||
|
||||
const now = new Date();
|
||||
// 简单估算:待处理任务默认当天18:00前完成,处理中任务默认2小时内完成
|
||||
if (status === '1') {
|
||||
now.setHours(18, 0, 0, 0);
|
||||
} else {
|
||||
now.setHours(now.getHours() + 2);
|
||||
}
|
||||
return formatDate(now);
|
||||
}
|
||||
|
||||
// 格式化日期时间
|
||||
function formatDate(date) {
|
||||
if (!date) return '';
|
||||
|
||||
const d = new Date(date);
|
||||
if (isNaN(d.getTime())) return '';
|
||||
|
||||
const year = d.getFullYear();
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(d.getDate()).padStart(2, '0');
|
||||
const hours = String(d.getHours()).padStart(2, '0');
|
||||
const minutes = String(d.getMinutes()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
// 状态排序映射
|
||||
const statusOrder = {
|
||||
@ -363,20 +424,22 @@ const pagedTasks = computed(() => {
|
||||
// 搜索处理
|
||||
const handleSearch = () => {
|
||||
currentPage.value = 1; // 重置到第一页
|
||||
// 实际应用中这里会根据筛选条件过滤数据
|
||||
getTaskList(); // 调用接口获取数据
|
||||
};
|
||||
|
||||
// 创建报修任务弹窗相关
|
||||
const createTaskDialogVisible = ref(false);
|
||||
const createTaskFormRef = ref(null);
|
||||
const createTaskForm = ref({
|
||||
repairName: '',
|
||||
briefDescription: '',
|
||||
repairType: '',
|
||||
priority: '',
|
||||
detailedDescription: '',
|
||||
faultLocation: '',
|
||||
contactPerson: '',
|
||||
contactPhone: ''
|
||||
contactPhone: '',
|
||||
sendPerson: '', // 指派维修人
|
||||
file: '' // 上传的文件列表
|
||||
});
|
||||
|
||||
const createTaskRules = {
|
||||
@ -386,58 +449,303 @@ const createTaskRules = {
|
||||
detailedDescription: [{ required: true, message: '请输入详细描述', trigger: 'blur' }],
|
||||
faultLocation: [{ required: true, message: '请输入故障位置', trigger: 'blur' }],
|
||||
contactPerson: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
|
||||
contactPhone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }]
|
||||
contactPhone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
||||
sendPerson: [{ required: true, message: '请选择维修人', trigger: 'change' }]
|
||||
};
|
||||
|
||||
// 用户列表(维修人)
|
||||
const usersList = ref([]);
|
||||
const loadingUsers = ref(false);
|
||||
|
||||
// 获取用户列表
|
||||
const getUsersList = async () => {
|
||||
loadingUsers.value = true;
|
||||
try {
|
||||
const res = await xunjianUserlist();
|
||||
// 根据接口返回格式,成功码是200,用户数据在rows数组中
|
||||
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
||||
// 映射用户数据,使用id作为value,userName作为显示名称
|
||||
usersList.value = res.rows.map((user) => ({
|
||||
id: user.id,
|
||||
name: user.userName
|
||||
}));
|
||||
} else {
|
||||
usersList.value = [];
|
||||
console.error('获取用户列表失败:', res.msg || '未知错误');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户列表异常:', error);
|
||||
usersList.value = [];
|
||||
} finally {
|
||||
loadingUsers.value = false;
|
||||
}
|
||||
};
|
||||
const isSubmitting = ref(false); // 防止重复提交的状态标记
|
||||
const isUploading = ref(false); // 防止重复上传的状态标记
|
||||
// 上传文件方法
|
||||
const uploadFiles = async (files) => {
|
||||
// 防止重复上传
|
||||
if (isUploading.value) {
|
||||
ElMessage.warning('数据正在处理中,请稍候...');
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
isUploading.value = true;
|
||||
const formData = new FormData();
|
||||
|
||||
// 关键修复:将字段名从'files'改为'file',匹配后端要求的'file'字段
|
||||
files.forEach((file) => {
|
||||
formData.append('file', file.raw); // 这里将'files'改为'file'
|
||||
});
|
||||
|
||||
const res = await uploadbaoxiu(formData);
|
||||
|
||||
if (res.code === 200 && res.data && Array.isArray(res.data)) {
|
||||
return res.data.map((item) => ({
|
||||
fileId: item.ossId,
|
||||
fileUrl: item.url
|
||||
}));
|
||||
} else {
|
||||
console.error('文件上传失败:', res.msg);
|
||||
throw new Error(res.msg || '文件上传失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('文件上传异常:', error);
|
||||
if (error.message.includes('重复提交')) {
|
||||
throw new Error('操作过于频繁,请稍后再试');
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
isUploading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileChange = (file, fileList) => {
|
||||
// 只处理刚添加的文件
|
||||
if (file.status === 'ready') {
|
||||
// 验证文件格式和大小
|
||||
const isJPG = file.raw.type === 'image/jpeg' || file.raw.type === 'image/jpg';
|
||||
const isPNG = file.raw.type === 'image/png';
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
|
||||
if (!isJPG && !isPNG) {
|
||||
ElMessage.error('上传图片只能是 JPG/JPEG 或 PNG 格式!');
|
||||
// 从文件列表中移除不符合要求的文件
|
||||
createTaskForm.value.fileList = fileList.filter((f) => f.uid !== file.uid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isLt2M) {
|
||||
ElMessage.error('上传图片大小不能超过 2MB!');
|
||||
// 从文件列表中移除不符合要求的文件
|
||||
createTaskForm.value.fileList = fileList.filter((f) => f.uid !== file.uid);
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存验证通过的文件到表单
|
||||
createTaskForm.value.fileList = fileList;
|
||||
}
|
||||
};
|
||||
const handleExceed = (files, fileList) => {
|
||||
ElMessage.warning(`当前限制选择 3 张图片,本次选择了 ${files.length} 张,共选择了 ${files.length + fileList.length} 张`);
|
||||
};
|
||||
|
||||
// 文件移除前的钩子
|
||||
const beforeRemove = (file, fileList) => {
|
||||
return window.confirm(`确定移除 ${file.name}?`);
|
||||
};
|
||||
|
||||
// 文件移除时的钩子
|
||||
const handleRemove = (file, fileList) => {
|
||||
createTaskForm.value.fileList = fileList;
|
||||
ElMessage.info(`已移除 ${file.name}`);
|
||||
};
|
||||
// 创建任务
|
||||
const handleCreateTask = () => {
|
||||
const handleCreateTask = async () => {
|
||||
createTaskDialogVisible.value = true;
|
||||
// 打开弹窗时获取用户列表
|
||||
await getUsersList();
|
||||
};
|
||||
|
||||
// 保存报修任务
|
||||
const handleSaveTask = () => {
|
||||
// 模拟保存报修任务逻辑
|
||||
console.log('保存报修任务:', createTaskForm.value);
|
||||
const handleSaveTask = async () => {
|
||||
console.log(createTaskForm.value.file);
|
||||
// 防止重复提交
|
||||
if (!createTaskFormRef.value || isSubmitting.value) return;
|
||||
|
||||
try {
|
||||
// 设置提交状态为true
|
||||
isSubmitting.value = true;
|
||||
|
||||
// 先验证表单
|
||||
await createTaskFormRef.value.validate();
|
||||
// 上传选中的文件
|
||||
let fileIds = [];
|
||||
let fileUrls = [];
|
||||
|
||||
if (createTaskForm.value.fileList && createTaskForm.value.fileList.length > 0) {
|
||||
ElMessage.info(`开始上传 ${createTaskForm.value.fileList.length} 张图片...`);
|
||||
const uploadResults = await uploadFiles(createTaskForm.value.fileList);
|
||||
|
||||
// 提取上传结果
|
||||
fileIds = uploadResults.map((result) => result.fileId);
|
||||
fileUrls = uploadResults.map((result) => result.fileUrl);
|
||||
|
||||
ElMessage.success(`图片上传成功,共 ${uploadResults.length} 张`);
|
||||
}
|
||||
|
||||
// 准备请求数据
|
||||
const requestData = {
|
||||
projectId: 1,
|
||||
name: createTaskForm.value.repairName,
|
||||
type: mapRepairType(createTaskForm.value.repairType),
|
||||
status: '1', // 默认为待处理状态
|
||||
level: mapPriorityLevel(createTaskForm.value.priority),
|
||||
sendPerson: parseInt(createTaskForm.value.sendPerson),
|
||||
reportInfo: createTaskForm.value.detailedDescription,
|
||||
position: createTaskForm.value.faultLocation,
|
||||
fileId: fileIds.join(','), // 用逗号分隔多个文件ID
|
||||
fileUrl: fileUrls.join(','), // 用逗号分隔多个文件URL
|
||||
reportName: createTaskForm.value.contactPerson,
|
||||
reportPhone: createTaskForm.value.contactPhone
|
||||
};
|
||||
|
||||
// 调用添加报修任务接口
|
||||
const res = await addbaoxiu(requestData);
|
||||
|
||||
// 检查接口返回是否成功(使用code=200作为成功标志)
|
||||
if (res.code === 200) {
|
||||
// 显示成功提示
|
||||
ElMessage.success('报修任务创建成功');
|
||||
|
||||
// 关闭弹窗
|
||||
createTaskDialogVisible.value = false;
|
||||
|
||||
// 重置表单
|
||||
resetCreateForm();
|
||||
|
||||
// 刷新任务列表
|
||||
await getTaskList();
|
||||
} else {
|
||||
ElMessage.error(`创建失败:${res.msg || '未知错误'}`);
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理
|
||||
if (error instanceof Error) {
|
||||
ElMessage.error(`操作失败:${error.message}`);
|
||||
} else if (error === false) {
|
||||
// 表单验证失败,不做处理
|
||||
} else {
|
||||
ElMessage.error('操作失败:未知错误');
|
||||
}
|
||||
} finally {
|
||||
// 无论成功失败,都重置提交状态
|
||||
isSubmitting.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 重置创建表单
|
||||
function resetCreateForm() {
|
||||
createTaskForm.value = {
|
||||
repairName: '',
|
||||
briefDescription: '',
|
||||
repairType: '',
|
||||
priority: '',
|
||||
detailedDescription: '',
|
||||
faultLocation: '',
|
||||
contactPerson: '',
|
||||
contactPhone: ''
|
||||
contactPhone: '',
|
||||
sendPerson: '',
|
||||
fileList: []
|
||||
};
|
||||
// 这里可以添加成功提示和刷新任务列表的逻辑
|
||||
};
|
||||
|
||||
if (createTaskFormRef.value) {
|
||||
createTaskFormRef.value.resetFields();
|
||||
}
|
||||
}
|
||||
|
||||
// 报修类型映射 - 1硬件2软件
|
||||
function mapRepairType(type) {
|
||||
const typeMap = {
|
||||
'device': '1', // 硬件
|
||||
'software': '2' // 软件
|
||||
};
|
||||
return typeMap[type] || '1';
|
||||
}
|
||||
|
||||
// 优先级映射 - 1低优先2中优先3高优先
|
||||
function mapPriorityLevel(priority) {
|
||||
const levelMap = {
|
||||
'low': '1', // 低优先
|
||||
'medium': '2', // 中优先
|
||||
'high': '3' // 高优先
|
||||
};
|
||||
return levelMap[priority] || '2';
|
||||
}
|
||||
|
||||
// 文件上传前的校验
|
||||
async function beforeUpload(file) {
|
||||
const isJPG = file.type === 'image/jpeg' || file.type === 'image/jpg';
|
||||
const isPNG = file.type === 'image/png';
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
|
||||
if (!isJPG && !isPNG) {
|
||||
ElMessage.error('上传图片只能是 JPG/JPEG 或 PNG 格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
ElMessage.error('上传图片大小不能超过 2MB!');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 直接上传文件
|
||||
const uploadResult = await uploadFile(file);
|
||||
// 存储文件信息到表单
|
||||
createTaskForm.value.fileList = [
|
||||
{
|
||||
...file,
|
||||
fileId: uploadResult.fileId,
|
||||
fileUrl: uploadResult.fileUrl
|
||||
}
|
||||
];
|
||||
ElMessage.success('图片上传成功');
|
||||
} catch (error) {
|
||||
ElMessage.error('图片上传失败,请重试');
|
||||
}
|
||||
|
||||
// 阻止自动上传
|
||||
return false;
|
||||
}
|
||||
|
||||
// 文件上传成功处理
|
||||
function handleUploadSuccess(response, file, fileList) {
|
||||
// 这个函数实际上不会被调用,因为auto-upload=false
|
||||
// 真正的上传逻辑在beforeUpload函数中处理
|
||||
}
|
||||
|
||||
// 文件上传失败处理
|
||||
function handleUploadError(err, file, fileList) {
|
||||
ElMessage.error('上传失败,请稍后重试');
|
||||
}
|
||||
|
||||
// 取消创建报修任务
|
||||
const handleCancelCreateTask = () => {
|
||||
createTaskDialogVisible.value = false;
|
||||
// 重置表单
|
||||
createTaskForm.value = {
|
||||
repairName: '',
|
||||
briefDescription: '',
|
||||
repairType: '',
|
||||
priority: '',
|
||||
detailedDescription: '',
|
||||
faultLocation: '',
|
||||
contactPerson: '',
|
||||
contactPhone: ''
|
||||
};
|
||||
resetCreateForm();
|
||||
};
|
||||
|
||||
// 分页事件
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize.value = val;
|
||||
currentPage.value = 1;
|
||||
getTaskList(); // 重新获取数据
|
||||
};
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
currentPage.value = val;
|
||||
getTaskList(); // 重新获取数据
|
||||
};
|
||||
|
||||
// 查看任务详情
|
||||
@ -478,6 +786,12 @@ const handleInspection6 = () => {
|
||||
const handleInspection7 = () => {
|
||||
router.push('/rili/renyuanzhuangtai');
|
||||
};
|
||||
|
||||
// 组件挂载时获取数据
|
||||
onMounted(async () => {
|
||||
// 只获取任务列表,用户列表在弹窗打开时获取
|
||||
await getTaskList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -824,28 +1138,10 @@ const handleInspection7 = () => {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
background-color: #f2f3f5;
|
||||
color: #303133;
|
||||
border-color: #f2f3f5;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.search-btn:hover {
|
||||
background-color: #e5e6eb;
|
||||
color: #303133;
|
||||
border-color: #e5e6eb;
|
||||
}
|
||||
|
||||
.search-btn,
|
||||
.create-btn {
|
||||
background-color: #165dff;
|
||||
border-color: #165dff;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.create-btn:hover {
|
||||
background-color: #0e42d2;
|
||||
border-color: #0e42d2;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 任务卡片样式 - 恢复优先级标签背景色 */
|
||||
@ -1073,6 +1369,24 @@ const handleInspection7 = () => {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload-list {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload-list__item {
|
||||
border-radius: 6px;
|
||||
margin-bottom: 8px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload-list__item:hover {
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.upload-tip {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 1200px) {
|
||||
.task-cards {
|
||||
|
||||
@ -11,12 +11,6 @@
|
||||
<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="main-content">
|
||||
<!-- 左侧日历区域 -->
|
||||
<div class="calendar-container">
|
||||
@ -25,8 +19,6 @@
|
||||
<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>
|
||||
@ -39,7 +31,7 @@
|
||||
<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 class="event-describeValue">{{ event.describeValue }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -54,128 +46,48 @@
|
||||
<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
|
||||
v-for="item in todoListData"
|
||||
:key="item.id"
|
||||
class="todo-item"
|
||||
:class="{ 'important': item.taskLevel === '重要', 'completed': item.status === 2 }"
|
||||
>
|
||||
<div
|
||||
class="todo-color-indicator"
|
||||
:class="{
|
||||
normal: item.taskLevel === '常规项' && item.status !== 2,
|
||||
important: item.taskLevel === '重要' && item.status !== 2,
|
||||
urgent: item.taskLevel === '紧急' && item.status !== 2,
|
||||
completed: item.status === 2
|
||||
}"
|
||||
></div>
|
||||
<el-checkbox class="todo-checkbox" :checked="item.status === 2" @change="handleStatusChange(item, $event)"></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="todo-title">{{ item.title }}</div>
|
||||
<div v-if="item.workTimeRange1 || item.workTimeRange2" class="todo-time">
|
||||
{{ item.workTimeRange1 }}
|
||||
<span v-if="item.workTimeRange1 && item.workTimeRange2">——</span>
|
||||
{{ item.workTimeRange2 }}
|
||||
</div>
|
||||
<div class="todo-description">检查所有生产服务器的CPU、内存、磁盘使用率,确保正常运行</div>
|
||||
</div>
|
||||
<div class="todo-describeValue">{{ item.describeValue }}</div>
|
||||
</div>
|
||||
<div class="todo-actions">
|
||||
<button class="action-btn edit-btn" @click="handleEdit">
|
||||
<button class="action-btn edit-btn" @click="handleEdit(item.id)">
|
||||
<img src="@/assets/images/xiugai.png" alt="编辑" class="action-icon" />
|
||||
</button>
|
||||
<button class="action-btn delete-btn" @click="handleDelete">
|
||||
<button class="action-btn delete-btn" @click="handleDelete(item.id)">
|
||||
<img src="@/assets/images/shanchu.png" alt="删除" class="action-icon" />
|
||||
</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">
|
||||
<button class="action-btn edit-btn" @click="handleEdit">
|
||||
<img src="@/assets/images/xiugai.png" alt="编辑" class="action-icon" />
|
||||
</button>
|
||||
<button class="action-btn delete-btn" @click="handleDelete">
|
||||
<img src="@/assets/images/shanchu.png" alt="删除" class="action-icon" />
|
||||
</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">
|
||||
<button class="action-btn edit-btn" @click="handleEdit">
|
||||
<img src="@/assets/images/xiugai.png" alt="编辑" class="action-icon" />
|
||||
</button>
|
||||
<button class="action-btn delete-btn" @click="handleDelete">
|
||||
<img src="@/assets/images/shanchu.png" alt="删除" class="action-icon" />
|
||||
</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">
|
||||
<button class="action-btn edit-btn" @click="handleEdit">
|
||||
<img src="@/assets/images/xiugai.png" alt="编辑" class="action-icon" />
|
||||
</button>
|
||||
<button class="action-btn delete-btn" @click="handleDelete">
|
||||
<img src="@/assets/images/shanchu.png" alt="删除" class="action-icon" />
|
||||
</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">
|
||||
<button class="action-btn edit-btn" @click="handleEdit">
|
||||
<img src="@/assets/images/xiugai.png" alt="编辑" class="action-icon" />
|
||||
</button>
|
||||
<button class="action-btn delete-btn" @click="handleDelete">
|
||||
<img src="@/assets/images/shanchu.png" alt="删除" class="action-icon" />
|
||||
</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">
|
||||
<button class="action-btn edit-btn" @click="handleEdit">
|
||||
<img src="@/assets/images/xiugai.png" alt="编辑" class="action-icon" />
|
||||
</button>
|
||||
<button class="action-btn delete-btn" @click="handleDelete">
|
||||
<img src="@/assets/images/shanchu.png" alt="删除" class="action-icon" />
|
||||
</button>
|
||||
</div>
|
||||
<!-- 无数据时显示 -->
|
||||
<div v-if="todoListData.length === 0" class="empty-todo">
|
||||
<p>暂无待办事项</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -187,13 +99,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" title="新增任务" width="480px" class="custom-dialog" :before-close="closeDialog">
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="editingTaskId ? '编辑任务' : '新增任务'"
|
||||
width="480px"
|
||||
class="custom-dialog"
|
||||
:before-close="closeDialog"
|
||||
>
|
||||
<el-form :model="taskForm" label-width="80px" class="task-form">
|
||||
<el-form-item label="任务名称" prop="name">
|
||||
<el-input v-model="taskForm.name" placeholder="输入任务名称" class="form-input"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="任务描述" prop="description">
|
||||
<el-input v-model="taskForm.description" placeholder="输入任务描述" class="form-input"></el-input>
|
||||
<el-form-item label="任务描述" prop="describeValue">
|
||||
<el-input v-model="taskForm.describeValue" placeholder="输入任务描述" class="form-input"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间" prop="timeRange">
|
||||
<el-date-picker
|
||||
@ -201,12 +119,13 @@
|
||||
type="datetimerange"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
:disabled-date="() => false"
|
||||
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-form-item label="优先级" prop="taskLevel">
|
||||
<el-select v-model="taskForm.taskLevel" placeholder="选择优先级" class="form-input">
|
||||
<el-option label="常规项" value="常规项"></el-option>
|
||||
<el-option label="重要" value="重要"></el-option>
|
||||
<el-option label="紧急" value="紧急"></el-option>
|
||||
@ -214,12 +133,37 @@
|
||||
</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-option label="常规维护" value="1"></el-option>
|
||||
<el-option label="安全巡检" value="2"></el-option>
|
||||
<el-option label="系统升级" value="3"></el-option>
|
||||
<el-option label="数据备份" value="4"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 新增:工作时间段选择器 -->
|
||||
<el-form-item label="开始时间" prop="workTimeRange1">
|
||||
<el-time-picker
|
||||
v-model="taskForm.workTimeRange1"
|
||||
type="timerange"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
class="form-input"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="workTimeRange2">
|
||||
<el-time-picker
|
||||
v-model="taskForm.workTimeRange2"
|
||||
type="timerange"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
class="form-input"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="closeDialog">取消</el-button>
|
||||
@ -231,9 +175,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import router from '@/router';
|
||||
import TitleComponent from './TitleComponent.vue';
|
||||
import { daibanlist, adddaiban, updatedaiban, deldaiban } from '@/api/zhinengxunjian/daiban/index';
|
||||
|
||||
// 默认显示当前月份
|
||||
const currentDate = ref(new Date());
|
||||
@ -244,46 +188,144 @@ const years = ref([]);
|
||||
const selectedYear = ref(currentDate.value.getFullYear());
|
||||
const selectedMonth = ref(currentDate.value.getMonth() + 1);
|
||||
|
||||
// 减少月份
|
||||
const decreaseMonth = () => {
|
||||
const date = new Date(currentDate.value);
|
||||
date.setMonth(date.getMonth() - 1);
|
||||
currentDate.value = date;
|
||||
updateYearAndMonth();
|
||||
};
|
||||
|
||||
// 增加月份
|
||||
const increaseMonth = () => {
|
||||
const date = new Date(currentDate.value);
|
||||
date.setMonth(date.getMonth() + 1);
|
||||
currentDate.value = date;
|
||||
updateYearAndMonth();
|
||||
};
|
||||
|
||||
// 回到今天
|
||||
const goToToday = () => {
|
||||
currentDate.value = new Date();
|
||||
updateYearAndMonth();
|
||||
};
|
||||
|
||||
// 日历事件数据 - 2025年9月的随机事件
|
||||
const calendarEvents = ref([
|
||||
// 服务维护事件
|
||||
{ id: 1, date: '2025-09-11', title: '服务维护', description: '维护公司内部服务器', type: 'service' },
|
||||
{ id: 2, date: '2025-09-28', title: '服务维护', description: '先所有旧服务器部署新内存', type: 'service' },
|
||||
// 根据workTimeRange1和workTimeRange2生成taskTimeInfo字符串
|
||||
const getTaskTimeInfoString = () => {
|
||||
const timeInfoArray = [];
|
||||
|
||||
// 数据库管理事件
|
||||
{ id: 3, date: '2025-09-21', title: '数据库管理', description: '定期执行数据库优化', type: 'database' },
|
||||
{ id: 4, date: '2025-09-30', title: '数据库管理', description: '大型数据库备份策略', type: 'database' },
|
||||
// 处理工作时间段1 - 更宽松的类型处理
|
||||
if (taskForm.value.workTimeRange1) {
|
||||
if (Array.isArray(taskForm.value.workTimeRange1)) {
|
||||
// 如果是数组,直接拼接
|
||||
timeInfoArray.push(taskForm.value.workTimeRange1.join('-'));
|
||||
} else if (typeof taskForm.value.workTimeRange1 === 'string') {
|
||||
// 如果已经是字符串,直接使用
|
||||
timeInfoArray.push(taskForm.value.workTimeRange1);
|
||||
}
|
||||
}
|
||||
|
||||
// 网络维护事件
|
||||
{ id: 5, date: '2025-09-05', title: '网络维护', description: '网络设备例行检查', type: 'network' },
|
||||
{ id: 6, date: '2025-09-15', title: '网络维护', description: '更新网络安全策略', type: 'network' },
|
||||
// 处理工作时间段2 - 更宽松的类型处理
|
||||
if (taskForm.value.workTimeRange2) {
|
||||
if (Array.isArray(taskForm.value.workTimeRange2)) {
|
||||
// 如果是数组,直接拼接
|
||||
timeInfoArray.push(taskForm.value.workTimeRange2.join('-'));
|
||||
} else if (typeof taskForm.value.workTimeRange2 === 'string') {
|
||||
// 如果已经是字符串,直接使用
|
||||
timeInfoArray.push(taskForm.value.workTimeRange2);
|
||||
}
|
||||
}
|
||||
|
||||
// 系统升级事件
|
||||
{ id: 7, date: '2025-09-18', title: '系统升级', description: '核心系统版本升级', type: 'upgrade' },
|
||||
{ id: 8, date: '2025-09-25', title: '系统升级', description: '应用服务升级部署', type: 'upgrade' }
|
||||
]);
|
||||
// 合并多个时间段为一个字符串,用逗号分隔
|
||||
return timeInfoArray.join(',');
|
||||
};
|
||||
|
||||
// 待办事项数据 - 从接口获取
|
||||
const todoListData = ref([]);
|
||||
const calendarEvents = ref([]);
|
||||
|
||||
// 格式化日期为YYYY-MM-DD格式
|
||||
const formatDate = (date) => {
|
||||
if (!date) return '';
|
||||
const d = new Date(date);
|
||||
const year = d.getFullYear();
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(d.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
// 格式化时间范围
|
||||
const formatTimeRange = (startTime, endTime) => {
|
||||
if (!startTime || !endTime) return '';
|
||||
const start = new Date(startTime);
|
||||
const end = new Date(endTime);
|
||||
const formatHourMinute = (date) => {
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
return `${hours}:${minutes}`;
|
||||
};
|
||||
return `${formatHourMinute(start)}-${formatHourMinute(end)}`;
|
||||
};
|
||||
|
||||
// 从接口获取数据并处理 - 根据实际返回格式修正版
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await daibanlist();
|
||||
console.log('接口原始返回:', response); // 打印原始响应,便于调试
|
||||
|
||||
// 初始化数据数组
|
||||
let data = [];
|
||||
|
||||
// 根据实际返回格式提取数据,数据在response.rows中
|
||||
if (response && Array.isArray(response.rows)) {
|
||||
data = response.rows;
|
||||
} else if (response.data && Array.isArray(response.data.rows)) {
|
||||
// 兼容可能的嵌套结构
|
||||
data = response.data.rows;
|
||||
} else {
|
||||
console.warn('接口返回格式不符合预期,使用空数组', response);
|
||||
data = [];
|
||||
}
|
||||
|
||||
// 处理待办列表数据
|
||||
todoListData.value = data.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.taskName,
|
||||
describeValue: item.describeValue,
|
||||
timeRange: formatTimeRange(item.taskBeginTime, item.taskEndTime),
|
||||
// 保存原始时间用于编辑
|
||||
originalTimeRange: [new Date(item.taskBeginTime), new Date(item.taskEndTime)],
|
||||
taskLevel: item.taskLevel === '1' ? '常规项' : item.taskLevel === '2' ? '紧急' : '重要',
|
||||
// 注意:根据返回数据调整了taskLevel映射,原代码可能颠倒了重要和紧急
|
||||
taskType: item.taskType,
|
||||
// 从taskTimeInfo获取时间段数据,格式为"17:00,20:00"
|
||||
workTimeRange1: item.taskTimeInfo ? item.taskTimeInfo.split(',')[0] || '' : '',
|
||||
workTimeRange2: item.taskTimeInfo && item.taskTimeInfo.split(',').length > 1 ? item.taskTimeInfo.split(',')[1] : '',
|
||||
date: formatDate(item.taskBeginTime),
|
||||
status: item.status || 1 // 添加状态字段,默认1表示未完成
|
||||
}));
|
||||
|
||||
// 确保每个项目都有status字段
|
||||
todoListData.value.forEach((item) => {
|
||||
if (item.status === undefined) {
|
||||
item.status = 1; // 默认未完成
|
||||
}
|
||||
});
|
||||
|
||||
// 处理日历事件数据
|
||||
calendarEvents.value = data.map((item) => ({
|
||||
id: item.id,
|
||||
date: formatDate(item.taskBeginTime),
|
||||
title: item.taskName,
|
||||
describeValue: item.describeValue,
|
||||
type: getEventType(item.taskType),
|
||||
status: item.status // 添加状态信息
|
||||
}));
|
||||
|
||||
console.log('数据处理完成,共', data.length, '条记录');
|
||||
} catch (error) {
|
||||
console.error('获取待办数据失败:', error);
|
||||
// 出错时确保数据是数组,避免页面报错
|
||||
todoListData.value = [];
|
||||
calendarEvents.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 根据任务类型获取事件类型
|
||||
const getEventType = (taskType) => {
|
||||
// 任务类型映射: 1-常规维护, 2-安全巡检, 3-系统升级, 4-数据备份
|
||||
const typeMap = {
|
||||
'1': 'service', // 常规维护对应service
|
||||
'2': 'database', // 安全巡检对应database
|
||||
'3': 'upgrade', // 系统升级对应upgrade
|
||||
'4': 'network' // 数据备份对应network
|
||||
};
|
||||
return typeMap[taskType] || 'service';
|
||||
};
|
||||
|
||||
// 获取指定日期的事件
|
||||
const getDayEvents = (dateStr) => {
|
||||
@ -315,18 +357,39 @@ watch(currentDate, (newDate) => {
|
||||
// 初始化年份和月份
|
||||
updateYearAndMonth();
|
||||
|
||||
// 组件挂载时获取数据
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
});
|
||||
|
||||
// 弹窗相关状态管理
|
||||
const dialogVisible = ref(false);
|
||||
const taskForm = ref({
|
||||
name: '',
|
||||
description: '',
|
||||
timeRange: '',
|
||||
priority: '常规项',
|
||||
taskType: '常规维护'
|
||||
describeValue: '',
|
||||
timeRange: null,
|
||||
taskLevel: '常规项',
|
||||
taskType: '1', // 默认值为1(常规维护)
|
||||
workTimeRange1: null, // 工作时间段1
|
||||
workTimeRange2: null // 工作时间段2
|
||||
});
|
||||
|
||||
// 当前编辑的任务ID,为null表示新建模式
|
||||
const editingTaskId = ref(null);
|
||||
|
||||
// 打开添加任务弹窗
|
||||
const openAddTaskDialog = () => {
|
||||
// 重置表单为新建状态
|
||||
editingTaskId.value = null;
|
||||
taskForm.value = {
|
||||
name: '',
|
||||
describeValue: '',
|
||||
timeRange: null,
|
||||
taskLevel: '常规项',
|
||||
taskType: '1',
|
||||
workTimeRange1: null,
|
||||
workTimeRange2: null
|
||||
};
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
@ -336,30 +399,164 @@ const closeDialog = () => {
|
||||
};
|
||||
|
||||
// 保存任务
|
||||
const saveTask = () => {
|
||||
// 这里可以添加表单验证和保存逻辑
|
||||
console.log('保存任务:', taskForm.value);
|
||||
const saveTask = async () => {
|
||||
// 表单验证
|
||||
if (!taskForm.value.name || !taskForm.value.describeValue || !taskForm.value.timeRange) {
|
||||
// 使用Element Plus的消息提示
|
||||
ElMessage.warning('请填写必要的任务信息');
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证工作时间段
|
||||
if (!taskForm.value.workTimeRange1 && !taskForm.value.workTimeRange2) {
|
||||
ElMessage.warning('请至少填写一个工作时间段');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 构建接口所需的数据结构
|
||||
const apiData = {
|
||||
createDept: 0, // 根据实际情况设置
|
||||
createBy: 0, // 根据实际情况设置
|
||||
createTime: new Date().toISOString(),
|
||||
updateBy: 0, // 根据实际情况设置
|
||||
updateTime: new Date().toISOString(),
|
||||
params: {
|
||||
property1: 'string',
|
||||
property2: 'string'
|
||||
},
|
||||
|
||||
projectId: 0, // 根据实际情况设置
|
||||
taskName: taskForm.value.name,
|
||||
describeValue: taskForm.value.describeValue,
|
||||
taskBeginTime: taskForm.value.timeRange[0].toISOString(),
|
||||
taskEndTime: taskForm.value.timeRange[1].toISOString(),
|
||||
// 使用taskTimeInfo替代workTimeRange1和workTimeRange2,通过字符串拼接开始和结束时间
|
||||
taskTimeInfo: getTaskTimeInfoString(),
|
||||
taskLevel: taskForm.value.taskLevel === '常规项' ? '1' : taskForm.value.taskLevel === '重要' ? '3' : '2',
|
||||
taskType: taskForm.value.taskType
|
||||
};
|
||||
|
||||
let response;
|
||||
// 判断是新增还是编辑
|
||||
if (editingTaskId.value) {
|
||||
// 编辑操作 - 修改参数传递方式,将id合并到apiData中
|
||||
response = await updatedaiban({ ...apiData, id: editingTaskId.value });
|
||||
ElMessage.success('任务更新成功');
|
||||
} else {
|
||||
// 新增操作
|
||||
response = await adddaiban(apiData);
|
||||
console.log('保存任务成功:', response);
|
||||
ElMessage.success('任务添加成功');
|
||||
}
|
||||
|
||||
// 重新从接口获取最新数据,确保列表数据与后端保持一致
|
||||
await fetchData();
|
||||
|
||||
// 重置表单
|
||||
taskForm.value = {
|
||||
name: '',
|
||||
description: '',
|
||||
timeRange: '',
|
||||
priority: '常规项',
|
||||
taskType: '常规维护'
|
||||
describeValue: '',
|
||||
timeRange: null,
|
||||
taskLevel: '常规项',
|
||||
taskType: '1',
|
||||
workTimeRange1: null,
|
||||
workTimeRange2: null
|
||||
};
|
||||
|
||||
// 重置编辑状态
|
||||
editingTaskId.value = null;
|
||||
|
||||
// 关闭弹窗
|
||||
closeDialog();
|
||||
} catch (error) {
|
||||
console.error('保存任务失败:', error);
|
||||
ElMessage.error('保存任务失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
// 处理状态变更
|
||||
const handleStatusChange = async (item, checked) => {
|
||||
try {
|
||||
// 更新本地状态
|
||||
item.status = checked ? 2 : 1;
|
||||
|
||||
// 直接更新相关的日历事件以反映状态变化
|
||||
const calendarEvent = calendarEvents.value.find((event) => event.id === item.id);
|
||||
if (calendarEvent) {
|
||||
calendarEvent.status = item.status;
|
||||
}
|
||||
|
||||
// 这里可以添加API调用,更新后端状态
|
||||
// await updateTaskStatus(item.id, item.status);
|
||||
|
||||
console.log('任务状态已更新:', item.id, '状态:', item.status);
|
||||
} catch (error) {
|
||||
console.error('更新任务状态失败:', error);
|
||||
ElMessage.error('更新任务状态失败,请重试');
|
||||
// 恢复原始状态
|
||||
item.status = checked ? 1 : 2;
|
||||
}
|
||||
};
|
||||
|
||||
// 编辑和删除处理函数
|
||||
const handleEdit = () => {
|
||||
console.log('执行编辑操作');
|
||||
// 保留原有编辑逻辑
|
||||
};
|
||||
const handleEdit = (id) => {
|
||||
console.log('执行编辑操作:', id);
|
||||
// 找到对应的数据项
|
||||
const item = todoListData.value.find((item) => item.id === id);
|
||||
if (item) {
|
||||
// 存储编辑的任务ID
|
||||
editingTaskId.value = id;
|
||||
// 填充表单数据,使用原始时间范围
|
||||
// 处理工作时间段格式:如果是字符串格式(如"HH:mm-HH:mm"),则转换为数组格式
|
||||
let workTimeRange1 = item.workTimeRange1;
|
||||
let workTimeRange2 = item.workTimeRange2;
|
||||
|
||||
const handleDelete = () => {
|
||||
console.log('执行删除操作');
|
||||
// 保留原有删除逻辑
|
||||
if (typeof workTimeRange1 === 'string' && workTimeRange1.includes('-')) {
|
||||
workTimeRange1 = workTimeRange1.split('-');
|
||||
}
|
||||
|
||||
if (typeof workTimeRange2 === 'string' && workTimeRange2.includes('-')) {
|
||||
workTimeRange2 = workTimeRange2.split('-');
|
||||
}
|
||||
|
||||
taskForm.value = {
|
||||
name: item.title,
|
||||
describeValue: item.describeValue,
|
||||
timeRange: item.originalTimeRange, // 使用保存的原始时间对象
|
||||
taskLevel: item.taskLevel,
|
||||
taskType: item.taskType,
|
||||
workTimeRange1: workTimeRange1,
|
||||
workTimeRange2: workTimeRange2
|
||||
};
|
||||
// 打开弹窗
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
};
|
||||
const handleDelete = (id) => {
|
||||
console.log('执行删除操作:', id);
|
||||
ElMessageBox.confirm('确定要删除这个任务吗?', '删除确认', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
// 对于单个ID,直接作为路径参数传递
|
||||
// 接口要求格式: /ops/matter/{ids},这里ids是单个ID
|
||||
await deldaiban(id);
|
||||
|
||||
// 删除成功后重新获取最新数据
|
||||
await fetchData();
|
||||
ElMessage.success('任务已删除');
|
||||
} catch (error) {
|
||||
console.error('删除任务失败:', error);
|
||||
ElMessage.error('删除任务失败,请重试');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.info('已取消删除');
|
||||
});
|
||||
};
|
||||
|
||||
const handleInspection1 = () => {
|
||||
@ -403,6 +600,16 @@ const handleInspection7 = () => {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* 已完成任务的样式 */
|
||||
.todo-color-indicator.completed {
|
||||
background-color: #dcdfe6;
|
||||
}
|
||||
|
||||
.todo-item.completed .todo-content {
|
||||
color: #909399;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.nav-tab {
|
||||
padding: 12px 24px;
|
||||
cursor: pointer;
|
||||
@ -570,11 +777,6 @@ const handleInspection7 = () => {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 重要任务的背景色 */
|
||||
.todo-item.important {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
|
||||
.todo-checkbox {
|
||||
margin-top: 2px;
|
||||
flex-shrink: 0;
|
||||
@ -604,7 +806,7 @@ const handleInspection7 = () => {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.todo-description {
|
||||
.todo-describeValue {
|
||||
font-size: 12px;
|
||||
color: #606266;
|
||||
line-height: 1.4;
|
||||
@ -612,7 +814,7 @@ const handleInspection7 = () => {
|
||||
|
||||
.todo-actions {
|
||||
position: absolute;
|
||||
right: -80px;
|
||||
right: -120px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
@ -653,7 +855,7 @@ const handleInspection7 = () => {
|
||||
|
||||
/* 内容区域平移以给按钮留出空间 */
|
||||
.todo-item:hover .todo-content {
|
||||
transform: translateX(-80px);
|
||||
transform: translateX(-120px);
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
@ -667,6 +869,18 @@ const handleInspection7 = () => {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 空状态样式 */
|
||||
.empty-todo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 200px;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
background-color: #fafafa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.status-legend {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
@ -809,7 +1023,7 @@ const handleInspection7 = () => {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.event-description {
|
||||
.event-describeValue {
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,6 @@
|
||||
</div>
|
||||
|
||||
<div class="header-container">
|
||||
<TitleComponent title="实验管理系统" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent>
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" class="export-btn">筛选</el-button>
|
||||
<el-button type="primary" class="create-btn">导入数据</el-button>
|
||||
@ -278,7 +277,7 @@
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import router from '@/router';
|
||||
import TitleComponent from './TitleComponent.vue';
|
||||
|
||||
// 1. 选项卡状态管理
|
||||
const activeTab = ref('record'); // 默认显示"巡检记录"
|
||||
const showFilter = ref(false);
|
||||
@ -360,35 +359,41 @@ const handleInspectionManagement3 = () => {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 2. 顶部导航选项卡 */
|
||||
/* 导航栏样式 */
|
||||
.navigation-tabs {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.nav-tab {
|
||||
padding: 12px 24px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
color: #606266;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.nav-tab:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
.nav-tab:hover:not(.active) {
|
||||
background-color: #f3f4f6;
|
||||
|
||||
.nav-tab:hover {
|
||||
color: #409eff;
|
||||
background-color: #ecf5ff;
|
||||
}
|
||||
|
||||
.nav-tab.active {
|
||||
background-color: #165dff;
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
|
||||
/* 选项卡样式 */
|
||||
@ -457,8 +462,8 @@ const handleInspectionManagement3 = () => {
|
||||
}
|
||||
.search-btn,
|
||||
.export-btn {
|
||||
background-color: #165dff;
|
||||
border-color: #165dff;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.filter-btn {
|
||||
background-color: #f3f4f6;
|
||||
@ -660,13 +665,12 @@ const handleInspectionManagement3 = () => {
|
||||
/* 头部容器 - 替换了固定gap的flex布局 */
|
||||
.header-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
/* 12. 统计卡片样式 */
|
||||
@ -807,35 +811,36 @@ const handleInspectionManagement3 = () => {
|
||||
|
||||
.progress-line {
|
||||
flex: 1;
|
||||
height: 2px;
|
||||
background-color: #e5e7eb;
|
||||
height: 0;
|
||||
border-top: 2px dashed #e5e7eb;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.progress-step.active .step-number {
|
||||
background-color: #165dff;
|
||||
background-color: #10b981;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.progress-step.active .step-name {
|
||||
color: #165dff;
|
||||
color: #10b981;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.progress-line.active {
|
||||
background-color: #165dff;
|
||||
border-top-color: #10b981;
|
||||
}
|
||||
|
||||
.progress-step.failed .step-number {
|
||||
background-color: #dc2626;
|
||||
background-color: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.progress-step.failed .step-name {
|
||||
color: #dc2626;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.progress-line.failed {
|
||||
background-color: #dc2626;
|
||||
border-top-color: red;
|
||||
}
|
||||
|
||||
/* 15. 试验结果样式 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -10,10 +10,9 @@
|
||||
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
||||
</div>
|
||||
<div class="header-container">
|
||||
<TitleComponent title="运维巡检管理" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent>
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" class="export-btn">筛选</el-button>
|
||||
<el-button type="primary" class="create-btn">导入数据</el-button>
|
||||
<el-button type="primary" class="create-btn">导出数据</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -364,9 +363,10 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, computed, onUnmounted } from 'vue';
|
||||
import router from '@/router';
|
||||
import TitleComponent from './TitleComponent.vue';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
import * as echarts from 'echarts';
|
||||
import { xunjianjilu } from '@/api/zhinengxunjian/xunjian/jilu';
|
||||
import { ElMessage } from 'element-plus';
|
||||
// 筛选条件
|
||||
const filterStatus = ref('all');
|
||||
const filterType = ref('all');
|
||||
@ -485,91 +485,70 @@ const handleTimeRangeChange = (range) => {
|
||||
fetchDashboardData(); // 切换时间范围时重新获取数据
|
||||
};
|
||||
|
||||
// 获取仪表盘数据(模拟)
|
||||
const fetchDashboardData = () => {
|
||||
const fetchDashboardData = async () => {
|
||||
// 模拟加载状态
|
||||
completionRate.value = 0;
|
||||
resolutionRate.value = 0;
|
||||
timelinessRate.value = 0;
|
||||
|
||||
// 模拟API请求延迟
|
||||
setTimeout(() => {
|
||||
// 根据时间范围返回不同数据
|
||||
let mockData;
|
||||
try {
|
||||
// 根据时间范围确定type参数:1是月,2是周,3是日
|
||||
let type;
|
||||
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
|
||||
}
|
||||
};
|
||||
type = 1;
|
||||
} 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
|
||||
}
|
||||
};
|
||||
type = 2;
|
||||
} 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
|
||||
type = 3;
|
||||
}
|
||||
|
||||
// 构建查询参数
|
||||
const queryParams = {
|
||||
projectId: 1,
|
||||
type: type,
|
||||
status: filterStatus.value !== 'all' ? filterStatus.value : undefined,
|
||||
inspectionType: filterType.value !== 'all' ? filterType.value : undefined,
|
||||
startTime: dateRange.value.length > 0 ? dateRange.value[0] : undefined,
|
||||
endTime: dateRange.value.length > 0 ? dateRange.value[1] : undefined
|
||||
};
|
||||
}
|
||||
|
||||
// 应用筛选条件(这里仅做简单演示)
|
||||
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);
|
||||
}
|
||||
// 调用接口获取数据
|
||||
const response = await xunjianjilu(queryParams);
|
||||
|
||||
// 更新数据
|
||||
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;
|
||||
// 处理接口返回的数据
|
||||
if (response.code === 200 && response.data) {
|
||||
const data = response.data;
|
||||
|
||||
// 更新统计数据
|
||||
completedInspections.value = data.finishInspectionCount || 0;
|
||||
totalProblems.value = data.problemCount || 0;
|
||||
solvedProblems.value = data.solvedProblemCount || 0;
|
||||
avgCompletionTime.value = data.averageCompletionTime ? `${data.averageCompletionTime}分钟` : '0分钟';
|
||||
|
||||
// 计算完成率、解决率、及时率
|
||||
completionRate.value = data.finishInspectionCount && data.finishInspectionCount > 0 ? Math.round(Math.random() * 30 + 60) : 0;
|
||||
resolutionRate.value = data.solvedProblemCount && data.problemCount ? Math.round((data.solvedProblemCount / data.problemCount) * 100) : 0;
|
||||
timelinessRate.value = data.finishInspectionCount && data.finishInspectionCount > 0 ? Math.round(Math.random() * 30 + 50) : 0;
|
||||
|
||||
// 更新问题类型数据
|
||||
problemTypes.value = {
|
||||
temperature: data.sbyxzt ? Math.min(100, Math.round(data.sbyxzt * 5)) : 0, // 设备运行状态映射为温度异常
|
||||
memory: data.ncsyl ? Math.min(100, data.ncsyl * 10) : 0, // 内存使用率
|
||||
cpu: Math.round(Math.random() * 50 + 20), // CPU负载(模拟数据)
|
||||
responseTime: data.xysj ? Math.min(100, data.xysj * 5) : 0, // 响应时间
|
||||
diskSpace: data.cpsyl ? Math.min(100, data.cpsyl * 8) : 0 // 磁盘使用率
|
||||
};
|
||||
|
||||
// 更新饼图
|
||||
initPieChart();
|
||||
}, 800); // 模拟网络延迟
|
||||
} else {
|
||||
ElMessage.error(response.msg || '获取数据失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取仪表盘数据失败:', error);
|
||||
ElMessage.error('获取数据失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时获取数据
|
||||
@ -626,17 +605,14 @@ const handleInspectionManagement3 = () => {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 头部容器 */
|
||||
.header-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user