From 80cca114a9211b1510c9777f5a597d429efe90da Mon Sep 17 00:00:00 2001
From: dhr <2216804034@qq.com>
Date: Tue, 23 Sep 2025 20:36:47 +0800
Subject: [PATCH] 0922
---
.env.development | 2 +-
src/api/zhinengxunjian/baoxiou/index.ts | 8 +
src/api/zhinengxunjian/gongdan/index.ts | 57 +
src/api/zhinengxunjian/jiedian/index.ts | 57 +
src/api/zhinengxunjian/qiangxiu/index.ts | 57 +
src/utils/request.ts | 8 +-
.../zhinengxunjian/InspectionManagement.vue | 4 +-
src/views/zhinengxunjian/baoxiuguanli.vue | 1034 ++++++++---
src/views/zhinengxunjian/baoxiujilu.vue | 1172 ++++++++++--
src/views/zhinengxunjian/gongdanliebiao.vue | 1131 +++++++++---
src/views/zhinengxunjian/index.vue | 2 +-
src/views/zhinengxunjian/paidanjilu.vue | 74 +-
src/views/zhinengxunjian/qiangxiuguanli.vue | 1629 ++++++++++++++---
src/views/zhinengxunjian/qiangxiujilu.vue | 1049 +++++++++--
src/views/zhinengxunjian/shiyanguanli.vue | 4 +-
src/views/zhinengxunjian/shiyanjilu.vue | 2 +-
src/views/zhinengxunjian/shiyanrenwu.vue | 4 +-
src/views/zhinengxunjian/xunjianjihua.vue | 4 +-
src/views/zhinengxunjian/xunjianrenwu.vue | 4 +-
19 files changed, 5107 insertions(+), 1195 deletions(-)
create mode 100644 src/api/zhinengxunjian/gongdan/index.ts
create mode 100644 src/api/zhinengxunjian/jiedian/index.ts
create mode 100644 src/api/zhinengxunjian/qiangxiu/index.ts
diff --git a/.env.development b/.env.development
index f7ff9da..f9304df 100644
--- a/.env.development
+++ b/.env.development
@@ -5,7 +5,7 @@ VITE_APP_TITLE = 新能源场站智慧运维平台
VITE_APP_ENV = 'development'
# 开发环境
-VITE_APP_BASE_API = 'http://192.168.110.149:18899'
+VITE_APP_BASE_API = 'http://192.168.110.210:18899'
# 应用访问路径 例如使用前缀 /admin/
VITE_APP_CONTEXT_PATH = '/'
diff --git a/src/api/zhinengxunjian/baoxiou/index.ts b/src/api/zhinengxunjian/baoxiou/index.ts
index 4c0c107..0a680e3 100644
--- a/src/api/zhinengxunjian/baoxiou/index.ts
+++ b/src/api/zhinengxunjian/baoxiou/index.ts
@@ -47,3 +47,11 @@ export const uploadbaoxiu = (data) => {
data: data
});
};
+
+export const baoxiuRecord = (data) => {
+ return request({
+ url: '/ops/report/record',
+ method: 'get',
+ params: data
+ });
+};
diff --git a/src/api/zhinengxunjian/gongdan/index.ts b/src/api/zhinengxunjian/gongdan/index.ts
new file mode 100644
index 0000000..781d8d2
--- /dev/null
+++ b/src/api/zhinengxunjian/gongdan/index.ts
@@ -0,0 +1,57 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+//查询列表
+export const gongdanlist = (query) => {
+ return request({
+ url: '/ops/order/list',
+ method: 'get',
+ params: query
+ });
+};
+//新增待办事项
+export const addgongdan = (data) => {
+ return request({
+ url: '/ops/order',
+ method: 'post',
+ data: data
+ });
+};
+//修改待办事项
+export const updategongdan = (data) => {
+ return request({
+ url: '/ops/order',
+ method: 'put',
+ data: data
+ });
+};
+//删除待办事项
+
+export function delgongdan(ids) {
+ return request({
+ url: `/ops/order/${ids}`, // 拼接ids作为路径参数
+ method: 'delete'
+ });
+}
+
+export const gongdanDetail = (id) => {
+ return request({
+ url: `/ops/order/${id}`,
+ method: 'get'
+ });
+};
+
+export const uploadgongdan = (data) => {
+ return request({
+ url: '/resource/oss/upload',
+ method: 'post',
+ data: data
+ });
+};
+
+export const gongdanRecord = (data) => {
+ return request({
+ url: '/ops/order/record',
+ method: 'get',
+ params: data
+ });
+};
diff --git a/src/api/zhinengxunjian/jiedian/index.ts b/src/api/zhinengxunjian/jiedian/index.ts
new file mode 100644
index 0000000..c38b3ec
--- /dev/null
+++ b/src/api/zhinengxunjian/jiedian/index.ts
@@ -0,0 +1,57 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+//查询列表
+export const jiedianlist = (query) => {
+ return request({
+ url: '/ops/node/list',
+ method: 'get',
+ params: query
+ });
+};
+//新增待办事项
+export const addjiedian = (data) => {
+ return request({
+ url: '/ops/node',
+ method: 'post',
+ data: data
+ });
+};
+//修改待办事项
+export const updatejiedian = (data) => {
+ return request({
+ url: '/ops/node',
+ method: 'put',
+ data: data
+ });
+};
+//删除待办事项
+
+export function deljiedian(ids) {
+ return request({
+ url: `/ops/node/${ids}`, // 拼接ids作为路径参数
+ method: 'delete'
+ });
+}
+
+export const jiedianDetail = (id) => {
+ return request({
+ url: `/ops/node/${id}`,
+ method: 'get'
+ });
+};
+
+export const uploadjiedian = (data) => {
+ return request({
+ url: '/resource/oss/upload',
+ method: 'post',
+ data: data
+ });
+};
+
+export const jiedianRecord = (data) => {
+ return request({
+ url: '/ops/node/record',
+ method: 'get',
+ params: data
+ });
+};
diff --git a/src/api/zhinengxunjian/qiangxiu/index.ts b/src/api/zhinengxunjian/qiangxiu/index.ts
new file mode 100644
index 0000000..bb717c0
--- /dev/null
+++ b/src/api/zhinengxunjian/qiangxiu/index.ts
@@ -0,0 +1,57 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+//查询列表
+export const qiangxiulist = (query) => {
+ return request({
+ url: '/ops/repair/list',
+ method: 'get',
+ params: query
+ });
+};
+//新增待办事项
+export const addqiangxiu = (data) => {
+ return request({
+ url: '/ops/repair',
+ method: 'post',
+ data: data
+ });
+};
+//修改待办事项
+export const updateqiangxiu = (data) => {
+ return request({
+ url: '/ops/repair',
+ method: 'put',
+ data: data
+ });
+};
+//删除待办事项
+
+export function delqiangxiu(ids) {
+ return request({
+ url: `/ops/repair/${ids}`, // 拼接ids作为路径参数
+ method: 'delete'
+ });
+}
+
+export const qiangxiuDetail = (id) => {
+ return request({
+ url: `/ops/repair/${id}`,
+ method: 'get'
+ });
+};
+
+export const uploadqiangxiu = (data) => {
+ return request({
+ url: '/resource/oss/upload',
+ method: 'post',
+ data: data
+ });
+};
+
+export const qiangxiuRecord = (data) => {
+ return request({
+ url: '/ops/repair/record',
+ method: 'get',
+ params: data
+ });
+};
diff --git a/src/utils/request.ts b/src/utils/request.ts
index f3b06ad..ca0e341 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -23,12 +23,18 @@ export const globalHeaders = () => {
};
};
+// 设置默认请求头
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
+axios.defaults.headers['Accept'] = 'application/json, text/plain, */*';
axios.defaults.headers['clientid'] = import.meta.env.VITE_APP_CLIENT_ID;
// 创建 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
- timeout: 50000
+ timeout: 50000,
+ headers: {
+ 'Content-Type': 'application/json;charset=utf-8',
+ 'Accept': 'application/json, text/plain, */*'
+ }
});
// 请求拦截器
diff --git a/src/views/zhinengxunjian/InspectionManagement.vue b/src/views/zhinengxunjian/InspectionManagement.vue
index 8ab639d..aaab44b 100644
--- a/src/views/zhinengxunjian/InspectionManagement.vue
+++ b/src/views/zhinengxunjian/InspectionManagement.vue
@@ -48,8 +48,8 @@
- 搜索
- 手动创建计划
+ 搜索
+ 手动创建计划
diff --git a/src/views/zhinengxunjian/baoxiuguanli.vue b/src/views/zhinengxunjian/baoxiuguanli.vue
index 58c6ad7..08cb703 100644
--- a/src/views/zhinengxunjian/baoxiuguanli.vue
+++ b/src/views/zhinengxunjian/baoxiuguanli.vue
@@ -34,24 +34,21 @@
-
-
-
- 搜索
- 手动创建任务
+ 搜索
+ 手动创建任务
@@ -72,7 +69,7 @@
报修时间
- {{ task.reportTime }}
+ {{ task.createTime }}
报修人
@@ -82,11 +79,7 @@
维修人
{{ task.maintainer }}
-
-
- 预计完成
- {{ task.expectedCompleteTime }}
-
+
状态
{{ task.statusText }}
@@ -159,12 +152,6 @@
-
-
-
-
-
-
@@ -173,29 +160,9 @@
-
-
-
-
-
-
点击或拖拽图片至此处上传
-
支持JPG、PNG格式,最多3张
-
-
-
-
已选择{{ createTaskForm.fileList.length }}张图片,将在提交时上传
@@ -222,7 +189,196 @@
+
+
+
+
+
+
+
+
+
任务基本信息
+
+
+
+ 任务ID:
+ {{ detailData.id || '-' }}
+
+
+ 任务名称:
+ {{ detailData.name || '未命名' }}
+
+
+
+
+ 任务状态:
+ {{ getStatusText(detailData.status) }}
+
+
+ 任务等级:
+ {{ getPriorityText(detailData.level) }}
+
+
+
+
+ 任务类型:
+ {{ detailData.type === '1' ? '硬件故障' : detailData.type === '2' ? '软件故障' : '-' }}
+
+
+ 报修时间:
+ {{ formatDate(detailData.createTime) }}
+
+
+
+
+
+
+
+
报修人信息
+
+
+
+ 报修人:
+ {{ detailData.reportName || '-' }}
+
+
+ 联系人:
+ {{ detailData.reportName || '-' }}
+
+
+
+
+ 联系电话:
+ {{ detailData.reportPhone || '-' }}
+
+
+ 维修人:
+ {{ detailData.sendPersonVo?.userName || '-' }}
+
+
+
+
+
+
+
+
报修详情
+
+
+
+ 故障位置:
+ {{ detailData.position || '-' }}
+
+
+
+
+ 详细描述:
+ {{ detailData.reportInfo || '-' }}
+
+
+
+
+
+ 完成时间:
+ {{ formatDate(detailData.completeTime) }}
+
+
+
+
+
+
+
+
故障图片
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -230,9 +386,9 @@
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 { baoxiulist, baoxiuDetail, updatebaoxiu, addbaoxiu } from '@/api/zhinengxunjian/baoxiou/index';
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
-import { ElMessage } from 'element-plus';
+import { ElMessage, ElLoading } from 'element-plus';
// 激活的选项卡
const activeTab = ref('task');
@@ -241,6 +397,17 @@ const taskStatus = ref('');
const planType = ref('');
const executor = ref('');
+// 详情弹窗相关
+const detailDialogVisible = ref(false);
+const detailData = ref(null);
+const isDetailLoading = ref(false);
+
+// 关闭详情弹窗
+const handleCloseDetailDialog = () => {
+ detailDialogVisible.value = false;
+ detailData.value = null;
+};
+
// 任务数据 - 初始为空数组
const tasks = ref([]);
@@ -250,6 +417,14 @@ const pageSize = ref(8);
const total = ref(0);
const loading = ref(false);
+// 分配任务弹窗相关
+const assignDialogVisible = ref(false);
+const assignTaskForm = ref({ taskId: '', sendPerson: '' });
+const assignTaskRules = {
+ sendPerson: [{ required: true, message: '请选择维修人', trigger: 'change' }]
+};
+const assignTaskFormRef = ref(null);
+
// 获取报修任务列表
defineExpose({ getTaskList });
async function getTaskList() {
@@ -274,16 +449,24 @@ async function getTaskList() {
leftLineClass: getLeftLineClass(item.status, item.level),
priorityClass: getPriorityClass(item.level),
priority: getPriorityText(item.level),
- reportTime: formatDate(item.reportTime),
+ // 修复报修时间字段名,使用与模板一致的createTime
+ createTime: formatDate(item.createTime || item.reportTime),
+ // 修复报修人字段,使用reportName
reporter: item.reportName || '未知报修人',
- maintainer: item.sendPerson ? `维修人ID: ${item.sendPerson}` : '未分配',
- expectedCompleteTime: getExpectedCompleteTime(item.status),
+ // 修复维修人字段,从sendPersonVo对象中获取用户名
+ maintainer: item.sendPersonVo?.userName || '未分配',
+
completeTime: item.completeTime ? formatDate(item.completeTime) : '',
actionText: getActionText(item.status),
actionClass: getActionClass(item.status),
reportInfo: item.reportInfo,
position: item.position,
- fileUrl: item.fileUrl
+ fileUrl: item.fileUrl,
+
+ reportPhone: item.reportPhone || '',
+ type: item.type || '',
+ // 保留原始数据用于详情查看
+ sendPersonVo: item.sendPersonVo
}));
} else {
tasks.value = [];
@@ -371,20 +554,6 @@ function getActionClass(status) {
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 '';
@@ -438,7 +607,7 @@ const createTaskForm = ref({
faultLocation: '',
contactPerson: '',
contactPhone: '',
- sendPerson: '', // 指派维修人
+ sendPerson: '未分配维修人', // 指派维修人
file: '' // 上传的文件列表
});
@@ -449,8 +618,7 @@ 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' }],
- sendPerson: [{ required: true, message: '请选择维修人', trigger: 'change' }]
+ contactPhone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }]
};
// 用户列表(维修人)
@@ -464,9 +632,9 @@ const getUsersList = async () => {
const res = await xunjianUserlist();
// 根据接口返回格式,成功码是200,用户数据在rows数组中
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
- // 映射用户数据,使用id作为value,userName作为显示名称
+ // 映射用户数据,将id转换为字符串以避免大整数精度问题
usersList.value = res.rows.map((user) => ({
- id: user.id,
+ id: String(user.id),
name: user.userName
}));
} else {
@@ -481,86 +649,7 @@ const getUsersList = async () => {
}
};
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 = async () => {
createTaskDialogVisible.value = true;
@@ -580,21 +669,6 @@ const handleSaveTask = async () => {
// 先验证表单
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,
@@ -602,11 +676,10 @@ const handleSaveTask = async () => {
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
+ fileId: createTaskForm.value.file,
reportName: createTaskForm.value.contactPerson,
reportPhone: createTaskForm.value.contactPhone
};
@@ -683,52 +756,6 @@ function mapPriorityLevel(priority) {
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;
@@ -749,15 +776,275 @@ const handleCurrentChange = (val) => {
};
// 查看任务详情
-const handleView = (task) => {
- console.log('查看任务详情:', task);
+const handleView = async (task) => {
+ try {
+ if (!task || !task.id) {
+ ElMessage.warning('任务ID不存在,请刷新页面重试');
+ console.error('任务缺少有效id,任务数据:', task);
+ return;
+ }
+
+ isDetailLoading.value = true;
+ detailData.value = null;
+
+ const loading = ElLoading.service({
+ lock: true,
+ text: '加载详情中...',
+ background: 'rgba(255, 255, 255, 0.7)'
+ });
+
+ try {
+ const response = await baoxiuDetail(task.id);
+
+ // 注意:这里使用code === 200判断成功,与项目中其他详情接口保持一致
+ if (response.code === 200 && response.data) {
+ detailData.value = response.data;
+ detailDialogVisible.value = true;
+ } else {
+ const errorMsg = response.msg || '未知错误';
+ console.error(`获取任务详情失败: ${errorMsg}`);
+ ElMessage.error(`获取任务详情失败:${errorMsg}`);
+ }
+ } finally {
+ loading.close();
+ isDetailLoading.value = false;
+ }
+ } catch (error) {
+ console.error('获取任务详情出错:', error);
+ ElMessage.error('获取任务详情出错,请重试');
+ }
+};
+// 拆分逗号分隔的图片URL为数组
+const splitImageUrls = (urlString) => {
+ if (!urlString) return [];
+ // 拆分并过滤空字符串(处理可能的首尾逗号或连续逗号)
+ return urlString.split(',').filter((url) => url.trim().length > 0);
};
-// 处理选项卡点击
-const handleTabClick = () => {
- currentPage.value = 1;
+// 处理图片加载失败
+const handleImageError = (event, index) => {
+ // 可以设置一个默认图片占位符
+ event.target.src = '';
+ console.error(`图片加载失败: 索引 ${index}`);
};
+// 处理任务操作按钮点击事件
+const handleAction = async (task) => {
+ try {
+ if (!task || !task.id) {
+ ElMessage.warning('任务ID不存在,请刷新页面重试');
+ console.error('任务缺少有效id,任务数据:', task);
+ return;
+ }
+
+ // 点击分配按钮:打开分配弹窗
+ if (task.actionText === '分配') {
+ // 重置表单并设置任务ID
+ assignTaskForm.value = { taskId: task.id, sendPerson: '' };
+ assignDialogVisible.value = true;
+
+ // 打开弹窗时获取用户列表
+ if (usersList.value.length === 0) {
+ await getUsersList();
+ }
+ if (usersList.value.length === 0) {
+ ElMessage.error('无可用维修人员,请先配置维修人员信息');
+ assignDialogVisible.value = false;
+ }
+ }
+
+ // 点击跟进按钮:原有逻辑
+ else if (task.actionText === '跟进') {
+ resultDialogVisible.value = true;
+ currentTaskId.value = task.id;
+ }
+
+ // 其他操作(如评价)
+ else {
+ console.log('其他操作:', task.actionText);
+ }
+ } catch (error) {
+ console.error('任务操作失败:', error, '当前任务数据:', task);
+ ElMessage.error('操作失败,请联系技术支持');
+ }
+};
+
+// 提交分配任务
+const handleSubmitAssign = async () => {
+ if (!assignTaskFormRef.value) return;
+
+ try {
+ await assignTaskFormRef.value.validate();
+
+ // 找到原始任务数据
+ const originalTask = tasks.value.find((t) => t.id === assignTaskForm.value.taskId);
+ if (!originalTask) {
+ ElMessage.warning('未找到任务完整数据,请刷新重试');
+ return;
+ }
+
+ // 找到选中的维修人员
+ const selectedUser = usersList.value.find((u) => u.id === assignTaskForm.value.sendPerson);
+ if (!selectedUser) {
+ ElMessage.error('未找到选中的维修人员');
+ return;
+ }
+
+ // 构造更新参数
+ const updateData = {
+ id: assignTaskForm.value.taskId,
+ status: '2', // 处理中状态
+ sendPerson: selectedUser.id,
+ sendPersonName: selectedUser.name,
+ sendPersonVo: {
+ id: selectedUser.id,
+ userName: selectedUser.name
+ },
+ // 包含后端所需的其他必要字段
+ name: originalTask.title,
+ type: mapRepairType(originalTask.type || 'all'),
+ level: mapPriorityLevel(originalTask.priority),
+ reportName: originalTask.reporter,
+ reportPhone: originalTask.reportPhone || '',
+ position: originalTask.position || '',
+ reportInfo: originalTask.reportInfo || '',
+ projectId: 1
+ };
+
+ // 调用接口更新
+ const response = await updatebaoxiu(updateData);
+ if (response.code === 200) {
+ ElMessage.success(`任务已分配给【${selectedUser.name}】,状态更新为处理中`);
+ assignDialogVisible.value = false;
+ getTaskList(); // 刷新列表
+ } else {
+ const errorMsg = response.msg || '未知错误';
+ console.error(`任务分配失败:${errorMsg},请求参数:`, updateData);
+ ElMessage.error(`分配失败:${errorMsg}`);
+ }
+ } catch (error) {
+ if (error instanceof Error) {
+ ElMessage.error(`操作失败:${error.message}`);
+ } else if (error !== false) {
+ ElMessage.error('操作失败:未知错误');
+ }
+ }
+};
+
+// 关闭分配弹窗
+const handleCloseAssign = () => {
+ assignDialogVisible.value = false;
+ if (assignTaskFormRef.value) {
+ assignTaskFormRef.value.clearValidate();
+ }
+};
+
+// 结果输入弹窗相关状态
+const resultDialogVisible = ref(false);
+const currentTaskId = ref('');
+const reportFinal = ref('');
+
+// 处理结果表单验证规则
+const resultFormRules = {
+ reportFinal: [
+ {
+ required: true,
+ message: '请输入处理结果',
+ trigger: 'blur'
+ },
+ {
+ min: 5,
+ max: 500,
+ message: '处理结果长度在 5 到 500 个字符之间',
+ trigger: 'blur'
+ }
+ ]
+};
+
+// 表单引用
+const resultFormRef = ref(null);
+
+// 保存结果
+const handleSaveResult = async () => {
+ try {
+ if (!currentTaskId.value) {
+ ElMessage.warning('任务ID不存在');
+ return;
+ }
+
+ if (!reportFinal.value.trim()) {
+ ElMessage.warning('请输入处理结果');
+ return;
+ }
+
+ // 1. 查找当前任务的完整数据
+ const originalTask = tasks.value.find((t) => t.id === currentTaskId.value);
+ if (!originalTask) {
+ ElMessage.warning('未找到任务完整数据,请刷新重试');
+ console.error('未找到任务完整数据,任务ID:', currentTaskId.value);
+ return;
+ }
+
+ // 2. 生成当前时间作为完成时间
+ const now = new Date();
+ const year = now.getFullYear();
+ const month = String(now.getMonth() + 1).padStart(2, '0');
+ const day = String(now.getDate()).padStart(2, '0');
+ const hours = String(now.getHours()).padStart(2, '0');
+ const minutes = String(now.getMinutes()).padStart(2, '0');
+ const seconds = String(now.getSeconds()).padStart(2, '0');
+ const reportFinishTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+
+ // 3. 构造完整的更新参数(与任务分配时使用相同的参数集)
+ const updateData = {
+ // ① 任务基础标识(必传)
+ id: currentTaskId.value, // 任务ID(核心主键)
+
+ // ② 状态流转参数(必传)
+ status: '3', // 状态:3=已完成
+ statusText: '已完成', // 状态文本
+ reportFinal: reportFinal.value, // 处理结果
+ reportFinishTime: reportFinishTime, // 完成时间
+ completeTime: reportFinishTime, // 完成时间(向后兼容字段)
+
+ // ③ 复用原始任务数据中的所有必要字段
+ name: originalTask.title, // 任务名称(原始任务标题)
+ type: mapRepairType(originalTask.type || 'all'), // 任务类型(映射为后端需要的格式)
+ level: mapPriorityLevel(originalTask.priority), // 优先级(映射为后端需要的格式)
+ reportName: originalTask.reporter, // 报修人姓名
+ reportPhone: originalTask.reportPhone || '', // 报修人电话
+ position: originalTask.position || '', // 故障位置
+ reportInfo: originalTask.reportInfo || '', // 报修详情
+
+ // ④ 维修人员信息(保留原有分配的维修人员)
+ sendPerson: originalTask.sendPersonVo?.id || '', // 维修人员ID
+ sendPersonName: originalTask.sendPersonVo?.userName || '', // 维修人员姓名
+ sendPersonVo: originalTask.sendPersonVo || {}, // 维修人员完整信息
+
+ // ⑤ 其他必要参数
+ pageNum: currentPage.value, // 分页参数
+ pageSize: pageSize.value,
+ projectId: 1 // 项目ID
+ };
+
+ const response = await updatebaoxiu(updateData);
+
+ if (response.code === 200) {
+ ElMessage.success('处理结果已保存');
+ resultDialogVisible.value = false;
+ reportFinal.value = '';
+ currentTaskId.value = '';
+ getTaskList();
+ } else {
+ const errorMsg = response.msg || '未知错误';
+ console.error(`保存处理结果失败: ${errorMsg}`);
+ ElMessage.error(`保存处理结果失败:${errorMsg}`);
+ }
+ } catch (error) {
+ console.error('保存处理结果失败:', error);
+ ElMessage.error('保存失败,请重试');
+ }
+};
const handleInspectionManagement1 = () => {
router.push('/rili/baoxiuguanli');
};
@@ -801,73 +1088,6 @@ onMounted(async () => {
min-height: 100vh;
}
-/* 上传图片区域样式 */
-.upload-container {
- width: 100%;
-}
-
-.upload-box {
- border: 2px dashed #dcdfe6;
- border-radius: 8px;
- padding: 40px 20px;
- text-align: center;
- cursor: pointer;
- background-color: #f8f9fa;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- position: relative;
- overflow: hidden;
-}
-
-.upload-box::before {
- content: '';
- position: absolute;
- top: 0;
- left: -100%;
- width: 100%;
- height: 100%;
- background: linear-gradient(90deg, transparent, rgba(64, 158, 255, 0.1), transparent);
- transition: all 0.6s ease;
-}
-
-.upload-box:hover {
- border-color: #409eff;
- background-color: #ecf5ff;
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
-}
-
-.upload-box:hover::before {
- left: 100%;
-}
-
-.avatar-uploader-icon {
- font-size: 40px;
- color: #c0c4cc;
- margin-bottom: 12px;
- transition: color 0.3s;
-}
-
-.upload-box:hover .avatar-uploader-icon {
- color: #409eff;
-}
-
-.upload-text {
- font-size: 14px;
- color: #606266;
- font-weight: 500;
- margin-bottom: 6px;
- transition: color 0.3s;
-}
-
-.upload-box:hover .upload-text {
- color: #409eff;
-}
-
-.upload-hint {
- font-size: 12px;
- color: #909399;
-}
-
/* 美化弹窗样式 */
.beautiful-dialog {
border-radius: 12px;
@@ -917,6 +1137,124 @@ onMounted(async () => {
border-top: 1px solid #f0f2f5;
text-align: center;
}
+.custom-experiment-dialog .el-dialog__body {
+ max-height: 60vh;
+ overflow-y: auto;
+ padding: 24px;
+}
+
+/* 详情卡片样式 */
+.detail-card {
+ background-color: #fff;
+ border-radius: 8px;
+ padding: 20px;
+ margin-bottom: 20px;
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+ border: 1px solid #f0f2f5;
+}
+
+.card-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #1d2129;
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 2px solid #409eff;
+}
+
+.card-content {
+ padding: 0 4px;
+}
+
+/* 信息行和信息项样式 */
+.info-row {
+ display: flex;
+ margin-bottom: 16px;
+ flex-wrap: wrap;
+}
+
+.info-item {
+ flex: 0 0 50%;
+ margin-bottom: 12px;
+ display: flex;
+ align-items: flex-start;
+}
+
+.info-item.full-width {
+ flex: 0 0 100%;
+}
+
+.info-label {
+ font-weight: 500;
+ color: #86909c;
+ margin-right: 8px;
+ min-width: 80px;
+ flex-shrink: 0;
+}
+
+.info-value {
+ color: #4e5969;
+ flex: 1;
+ word-break: break-all;
+ font-size: 14px;
+}
+
+/* 故障原因样式 */
+.fail-reason {
+ color: #ff4d4f;
+ font-weight: 500;
+}
+
+/* 加载状态 */
+.skeleton-loading {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.skeleton-card {
+ background-color: #f5f5f5;
+ border-radius: 8px;
+ padding: 16px;
+}
+
+.skeleton-header {
+ height: 20px;
+ width: 30%;
+ background-color: #e0e0e0;
+ border-radius: 4px;
+ margin-bottom: 12px;
+}
+
+.skeleton-content {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.skeleton-row {
+ height: 16px;
+ background-color: #e0e0e0;
+ border-radius: 4px;
+}
+
+/* 无数据提示 */
+.no-info {
+ text-align: center;
+ color: #909399;
+ padding: 60px 20px;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+ .custom-experiment-dialog {
+ width: 95% !important;
+ }
+
+ .info-item {
+ flex: 0 0 100%;
+ }
+}
/* 美化表单样式 */
.elegant-form .el-form-item {
@@ -1048,10 +1386,6 @@ onMounted(async () => {
.elegant-form .el-form-item {
margin-bottom: 20px;
}
-
- .upload-box {
- padding: 30px 15px;
- }
}
/* 选项卡样式 */
@@ -1369,24 +1703,6 @@ onMounted(async () => {
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 {
@@ -1458,4 +1774,120 @@ onMounted(async () => {
cursor: pointer;
user-select: none;
}
+
+/* 详情弹窗样式 */
+.custom-experiment-dialog {
+ .detail-content {
+ max-height: 60vh;
+ overflow-y: auto;
+ padding-right: 10px;
+ }
+
+ .detail-section {
+ margin-bottom: 24px;
+ }
+
+ .section-title {
+ font-size: 16px;
+ font-weight: 500;
+ color: #303133;
+ margin-bottom: 16px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid #f0f2f5;
+ }
+
+ .detail-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16px;
+ }
+
+ .detail-item {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .detail-label {
+ font-size: 14px;
+ color: #909399;
+ margin-bottom: 4px;
+ }
+
+ .detail-value {
+ font-size: 14px;
+ color: #303133;
+ }
+
+ .detail-textarea {
+ margin-bottom: 16px;
+ }
+
+ .detail-text {
+ font-size: 14px;
+ color: #303133;
+ line-height: 1.6;
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ }
+
+ /* 多图片展示容器样式 */
+ .images-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 16px;
+ margin-top: 12px;
+ padding: 10px;
+ background-color: #f9f9f9;
+ border-radius: 8px;
+ }
+
+ /* 单个图片项样式 */
+ .image-item {
+ flex: 0 0 auto;
+ width: 200px; /* 固定宽度 */
+ height: 160px; /* 固定高度 */
+ border-radius: 6px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ transition: transform 0.3s ease;
+ }
+
+ .image-item:hover {
+ transform: scale(1.03);
+ }
+
+ /* 图片样式 */
+ .detail-image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover; /* 保持比例填充容器 */
+ display: block;
+ }
+
+ /* 图片加载失败样式 */
+ .detail-image[src=''] {
+ background-color: #f0f0f0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #999;
+ font-size: 12px;
+ }
+
+ .no-info {
+ text-align: center;
+ color: #909399;
+ padding: 40px 0;
+ }
+}
+
+@media (max-width: 768px) {
+ .custom-experiment-dialog {
+ width: 90% !important;
+
+ .detail-grid {
+ grid-template-columns: 1fr;
+ }
+ }
+}
diff --git a/src/views/zhinengxunjian/baoxiujilu.vue b/src/views/zhinengxunjian/baoxiujilu.vue
index bd22772..8ff61e1 100644
--- a/src/views/zhinengxunjian/baoxiujilu.vue
+++ b/src/views/zhinengxunjian/baoxiujilu.vue
@@ -28,16 +28,16 @@
-
-
-
+
+
+
-
-
-
+
+
+
@@ -58,7 +58,7 @@
/>
- 搜索
+ 搜索
@@ -68,8 +68,8 @@
本月报修数
-
24
-
较上月 +4.2%
+
{{ statsLoading ? '加载中...' : statsData.byzbxs }}
+
较上月:{{ statsData.bxsjszzzl }}

@@ -79,8 +79,8 @@
平均处理时长
-
3.5小时
-
较上月 -0.6小时
+
{{ statsLoading ? '加载中...' : statsData.pjclsc }}
+
较上月:{{ statsData.clscjszzzl }}

@@ -90,7 +90,7 @@
待处理报修
-
15
+
{{ statsLoading ? '加载中...' : statsData.dclbx }}
需及时处理
@@ -101,8 +101,8 @@
完成率
-
92%
-
较上月 +2.1%
+
{{ statsLoading ? '加载中...' : statsData.wcl }}%
+
{{ statsData.wcljszzzl }}%

@@ -112,24 +112,44 @@
-
-
-
-
-
-
-
+
+
+ {{ scope.row.id }}
+
+
+ {{ scope.row.reportInfo }}
+
+
+ {{ scope.row.reportName }}
+
+
+ {{ formatDate(scope.row.createTime) }}
+
+
- {{ scope.row.status }}
+ {{ scope.row.sendPersonVo ? scope.row.sendPersonVo.userName : '未分配' }}
+
+
+
+
+ {{ getStatusText(scope.row.status) }}
+
+
+
+
+ {{ scope.row.reportFinishTime ? formatDate(scope.row.reportFinishTime) : '--' }}
+
+
+
+
+ {{ scope.row.reportFinal || '--' }}
-
-
详情
-
- {{ scope.row.actionText }}
+
+ {{ getActionText(scope.row.status) }}
@@ -153,13 +173,210 @@
+
+
+
+
+
+
+
+
+
+
任务基本信息
+
+
+
+ 任务ID:
+ {{ detailData.id || '-' }}
+
+
+ 任务名称:
+ {{ detailData.name || '未命名' }}
+
+
+
+
+ 任务状态:
+ {{ getStatusText(detailData.status) }}
+
+
+ 任务等级:
+ {{ getPriorityText(detailData.level) }}
+
+
+
+
+ 任务类型:
+ {{ detailData.type === '1' ? '硬件故障' : detailData.type === '2' ? '软件故障' : '-' }}
+
+
+ 报修时间:
+ {{ formatDate(detailData.createTime) }}
+
+
+
+
+
+
+
+
报修人信息
+
+
+
+ 报修人:
+ {{ detailData.reportName || '-' }}
+
+
+ 联系人:
+ {{ detailData.reportName || '-' }}
+
+
+
+
+ 联系电话:
+ {{ detailData.reportPhone || '-' }}
+
+
+ 维修人:
+ {{ detailData.sendPersonVo?.userName || '-' }}
+
+
+
+
+
+
+
+
报修详情
+
+
+
+ 故障位置:
+ {{ detailData.position || '-' }}
+
+
+
+
+ 详细描述:
+ {{ detailData.reportInfo || '-' }}
+
+
+
+
+
+ 完成时间:
+ {{ formatDate(detailData.completeTime) }}
+
+
+
+
+
+
+
+
故障图片
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
加载中...
+
+
+
+
+
-
diff --git a/src/views/zhinengxunjian/shiyanguanli.vue b/src/views/zhinengxunjian/shiyanguanli.vue
index c5d072b..10ca273 100644
--- a/src/views/zhinengxunjian/shiyanguanli.vue
+++ b/src/views/zhinengxunjian/shiyanguanli.vue
@@ -49,8 +49,8 @@
>
- 搜索
- 新增实验记录
+ 搜索
+ 新增实验记录
diff --git a/src/views/zhinengxunjian/shiyanjilu.vue b/src/views/zhinengxunjian/shiyanjilu.vue
index 584bdfa..8903a9a 100644
--- a/src/views/zhinengxunjian/shiyanjilu.vue
+++ b/src/views/zhinengxunjian/shiyanjilu.vue
@@ -54,7 +54,7 @@
class="date-picker"
>
-
搜索
+
搜索
diff --git a/src/views/zhinengxunjian/shiyanrenwu.vue b/src/views/zhinengxunjian/shiyanrenwu.vue
index b4fcced..684be72 100644
--- a/src/views/zhinengxunjian/shiyanrenwu.vue
+++ b/src/views/zhinengxunjian/shiyanrenwu.vue
@@ -49,8 +49,8 @@
- 搜索
- 手动创建任务
+ 搜索
+ 手动创建任务
diff --git a/src/views/zhinengxunjian/xunjianjihua.vue b/src/views/zhinengxunjian/xunjianjihua.vue
index b7df85b..c011be8 100644
--- a/src/views/zhinengxunjian/xunjianjihua.vue
+++ b/src/views/zhinengxunjian/xunjianjihua.vue
@@ -12,7 +12,7 @@
@@ -54,7 +54,7 @@
>
- 搜索
+ 搜索
diff --git a/src/views/zhinengxunjian/xunjianrenwu.vue b/src/views/zhinengxunjian/xunjianrenwu.vue
index b982e51..3360946 100644
--- a/src/views/zhinengxunjian/xunjianrenwu.vue
+++ b/src/views/zhinengxunjian/xunjianrenwu.vue
@@ -42,8 +42,8 @@
- 搜索
- 手动创建任务
+ 搜索
+ 手动创建任务