From df42fa7e97c4a93caa17b2aed5aecdc768d8bbd7 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Tue, 15 Apr 2025 21:57:46 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/drone/drone-web-manage
---
src/views/tickets/ticket.vue | 460 ++++++++++++++++++++++++++++++++-------------------------
1 files changed, 256 insertions(+), 204 deletions(-)
diff --git a/src/views/tickets/ticket.vue b/src/views/tickets/ticket.vue
index e63ce87..673180f 100644
--- a/src/views/tickets/ticket.vue
+++ b/src/views/tickets/ticket.vue
@@ -32,18 +32,10 @@
@size-change="sizeChange" @current-change="handleCurrentChange" :table-loading="loading"
@selection-change="handleSelectionChange">
<template #menu-left>
- <el-button
- v-if="activeTab === 'all' || activeTab === 'myTickets'"
- type="primary"
- icon="el-icon-plus"
- @click="handleAdd"
- >新建工单</el-button>
- <el-button
- v-if="activeTab === 'pending'"
- type="success"
- icon="el-icon-check"
- @click="openReviewDialog"
- >批量审核</el-button>
+ <el-button v-if="activeTab === 'all' || activeTab === 'myTickets'" type="primary" icon="el-icon-plus"
+ @click="handleAdd">新建工单</el-button>
+ <el-button v-if="activeTab === 'pending'" type="success" icon="el-icon-check"
+ @click="openReviewDialog">批量审核</el-button>
<el-button type="success" plain icon="el-icon-download" @click="exportData">导出</el-button>
</template>
<template #menu="{ row }">
@@ -89,14 +81,16 @@
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="所属部门" prop="department">
- <el-select v-model="form.department" placeholder="请选择所属部门" @change="handleDepartmentChange" class="full-width">
+ <el-select v-model="form.department" placeholder="请选择所属部门" @change="handleDepartmentChange"
+ class="full-width">
<el-option v-for="dept in departments" :key="dept.value" :label="dept.label" :value="dept.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="处理人员" prop="handler">
- <el-select v-model="form.handler" placeholder="请先选择所属部门" :disabled="!form.department" class="full-width">
+ <el-select v-model="form.handler" placeholder="请先选择所属部门" :disabled="!form.department"
+ class="full-width">
<el-option v-for="user in availableHandlers" :key="user.id" :label="user.name" :value="user.id" />
</el-select>
</el-form-item>
@@ -114,7 +108,8 @@
<el-col :span="12">
<el-form-item label="选择位置" prop="location" required>
<div class="location-wrapper">
- <avue-input-map v-model="form.location" :params="mapParams" @change="handleLocationChange" type="button">
+ <avue-input-map v-model="form.location" :params="mapParams" @change="handleLocationChange"
+ type="button">
<el-button type="primary" plain class="map-button">
<i class="el-icon-map-location"></i> 地图选点
</el-button>
@@ -133,18 +128,9 @@
</el-col>
<el-col :span="12">
<el-form-item label="附件图片" prop="photos" required class="upload-wrapper">
- <el-upload ref="upload"
- :action="'#'"
- :auto-upload="false"
- list-type="picture-card"
- :on-change="handleFileChange"
- :on-remove="handleUploadRemove"
- :before-upload="beforeUpload"
- :file-list="form.photos"
- :limit="1"
- accept="image/*"
- class="uploader"
- >
+ <el-upload ref="upload" :action="'#'" :auto-upload="false" list-type="picture-card"
+ :on-change="handleFileChange" :on-remove="handleUploadRemove" :before-upload="beforeUpload"
+ :file-list="form.photos" :limit="1" accept="image/*" class="uploader">
<i class="el-icon-plus"></i>
</el-upload>
<div class="upload-tip">支持jpg/png格式图片,单张不超过5MB</div>
@@ -169,18 +155,11 @@
<div class="custom-steps-container">
<!-- 标题行 -->
<div class="steps-titles">
- <div
- class="step-title"
- :class="{ active: true }"
- >
+ <div class="step-title" :class="{ active: true }">
发起任务
</div>
- <div
- v-for="(status, index) in dynamicFixedStatuses"
- :key="index"
- :class="{ active: Number(currentDetail.status) >= Number(status) }"
- class="step-title"
- >
+ <div v-for="(status, index) in dynamicFixedStatuses" :key="index"
+ :class="{ active: Number(currentDetail.status) >= Number(status) }" class="step-title">
{{ mapStatus(status) }}
</div>
</div>
@@ -203,7 +182,7 @@
{{ getStepHandler(status) }}
</span>
<div class="step-description" v-if="getStepTime(status)">
- <span style=" position: absolute;
+ <span style=" position: absolute;
right: 80%;
top: 50%;
transform: translateY(-50%);
@@ -212,7 +191,7 @@
color: #666;
font-size: 12px;">耗时:{{ getStepTime(status) }}</span>
</div>
- <div class="step-description" >
+ <div class="step-description">
{{ getStepCreateTime(status) }}
</div>
</template>
@@ -407,62 +386,49 @@
</el-dialog>
<!-- 添加在其他 dialog 组件之后 -->
-<el-dialog v-model="reviewDialogVisible" title="批量审核" width="70%" append-to-body custom-class="review-dialog">
- <div class="review-container">
- <!-- 图片浏览区域 -->
- <div class="review-image-wrapper">
- <!-- 左箭头 -->
- <div v-show="selections.length > 1" class="arrow-button left" @click="handlePrevImage">
- <el-icon><ArrowLeft /></el-icon>
+ <el-dialog v-model="reviewDialogVisible" title="批量审核" width="70%" append-to-body custom-class="review-dialog">
+ <div class="review-container">
+ <div class="review-image-wrapper">
+ <!-- 修改左右箭头的显示条件 -->
+ <div v-if="selections.length > 1 && currentReviewImage" class="arrow-button left" @click="handlePrevImage">
+ <i class="el-icon-arrow-left"></i>
+ </div>
+
+ <div class="review-image-container">
+ <el-image v-if="currentReviewImage" :src="currentReviewImage" fit="cover" :preview-src-list="getImageList()"
+ :initial-index="currentImageIndex - 1" class="preview-image">
+ <template #error>
+ <div class="image-error">
+ <i class="el-icon-picture-outline"></i>
+ <span>图片加载失败</span>
+ </div>
+ </template>
+ </el-image>
+ <div v-else class="no-image">暂无图片</div>
+ </div>
+
+ <!-- 修改右箭头的显示条件 -->
+ <div v-if="selections.length > 1 && currentReviewImage" class="arrow-button right" @click="handleNextImage">
+ <i class="el-icon-arrow-right"></i>
+ </div>
+ </div>
+
+ <!-- 修改分页器的显示条件 -->
+ <div class="review-pagination" v-if="selections.length > 1 && currentReviewImage">
+ <el-pagination small layout="prev, pager, next" hide-on-single-page :total="selections.length"
+ :current-page="currentImageIndex" :page-size="1" @current-change="handleImagePageChange">
+ </el-pagination>
+ </div>
</div>
- <!-- 图片显示区域 -->
- <div class="review-image-container">
- <el-image
- :src="currentReviewImage"
- fit="cover"
- :preview-src-list="getImageList()"
- :initial-index="currentImageIndex - 1"
- class="preview-image"
- >
- <template #error>
- <div class="image-error">
- <i class="el-icon-picture-outline"></i>
- <span>图片加载失败</span>
- </div>
- </template>
- </el-image>
- </div>
-
- <!-- 右箭头 -->
- <div v-show="selections.length > 1" class="arrow-button right" @click="handleNextImage">
- <el-icon><ArrowRight /></el-icon>
- </div>
- </div>
-
- <!-- 分页指示器 -->
- <div class="review-pagination" v-if="selections.length > 1">
- <el-pagination
- small
- layout="prev, pager, next"
- hide-on-single-page
- :total="selections.length"
- :current-page.sync="currentImageIndex"
- :page-size="1"
- @current-change="handleImagePageChange"
- >
- </el-pagination>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="handleBatchApprove">通过</el-button>
- <el-button type="danger" @click="handleBatchReject">不通过</el-button>
- <el-button @click="reviewDialogVisible = false">取消</el-button>
- </div>
- </template>
-</el-dialog>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="handleBatchApprove">通过</el-button>
+ <el-button type="danger" @click="handleBatchReject">不通过</el-button>
+ <el-button @click="cancleBatchReject">取消</el-button>
+ </div>
+ </template>
+ </el-dialog>
</basic-container>
</template>
@@ -573,7 +539,7 @@
handler: [{ required: true, message: '请选择处理人员', trigger: 'change' }],
content: [{ required: true, message: '请输入工单内容', trigger: 'blur' }],
algorithm: [{ required: true, message: '请选择关联算法', trigger: 'change' }],
- location: [{
+ location: [{
validator: (rule, value, callback) => {
if (!value || value.length < 2) {
callback(new Error('请选择位置信息'));
@@ -583,7 +549,7 @@
},
trigger: 'change'
}],
- photos: [{
+ photos: [{
validator: (rule, value, callback) => {
if (!this.form.photos || this.form.photos.length === 0) {
callback(new Error('请上传工单图片'));
@@ -777,42 +743,64 @@
}
},
async handleBatchApprove() {
- try {
- await this.$confirm('确认批量审核通过选中的工单?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- });
+ try {
+ if (this.selections.length === 0) {
+ this.$message.warning('没有选中的工单');
+ return;
+ }
- const promises = this.selections.map(async (item) => {
+ const currentItem = this.selections[this.currentImageIndex - 1];
+ if (!currentItem) {
+ this.$message.warning('当前工单数据无效');
+ return;
+ }
+
+ await this.$confirm('确认审核通过当前工单?', '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ });
+
const data = {
- id: item.id,
- status: item.status,
- isPass: 0, // 0 表示通过
- eventNum: item.orderNumber,
- eventName: item.orderName,
- eventType: item.type,
+ id: currentItem.id,
+ status: currentItem.status,
+ isPass: 0,
+ eventNum: currentItem.orderNumber,
+ eventName: currentItem.orderName,
+ eventType: currentItem.type,
};
- return flowEvent(data);
- });
- const results = await Promise.all(promises);
- const successCount = results.filter(res => res.data.code === 0).length;
-
- if (successCount > 0) {
- this.$message.success(`成功审核通过 ${successCount} 个工单`);
- // 清空选择
- this.clearSelection();
- // 刷新数据
- this.fetchTableData();
- } else {
- throw new Error('批量审核失败');
+ const response = await flowEvent(data);
+ if (response.data.code === 0) {
+ this.$message.success('工单审核通过');
+
+ // 创建新的数组而不是修改原数组
+ const newSelections = [...this.selections];
+ newSelections.splice(this.currentImageIndex - 1, 1);
+ this.selections = newSelections;
+
+ // 修正索引并更新图片
+ if (this.selections.length > 0) {
+ if (this.currentImageIndex > this.selections.length) {
+ this.currentImageIndex = this.selections.length;
+ }
+ this.updateCurrentReviewImage();
+ } else {
+ this.reviewDialogVisible = false;
+ this.currentImageIndex = 1;
+ this.currentReviewImage = '';
+ }
+
+ // 刷新表格数据
+ this.fetchTableData();
+ } else {
+ throw new Error(response.data.msg || '审核失败');
+ }
+ } catch (error) {
+ if (error === 'cancel') return;
+ this.$message.error(error.message || '审核失败,请稍后重试');
}
- } catch (error) {
- if (error === 'cancel') return;
- this.$message.error(error.message || '批量审核失败,请稍后重试');
- }
- },
+ },
async fetchDropdownData() {
try {
const response = await getTicketInfo();
@@ -939,7 +927,7 @@
try {
// 提交时需要完整验证
await this.$refs.form.validate();
-
+
// 验证位置信息
if (!this.form.location || this.form.location.length < 2) {
this.$message.warning('请在地图上选择位置');
@@ -1238,10 +1226,10 @@
},
getStepTime(status) {
- const step = this.stepInfos.find(step => step.status === status);
- // 如果 step 不存在或 step.time 为 0,返回 false
- return step && step.time && step.time !== '0' ? step.time : false;
-},
+ const step = this.stepInfos.find(step => step.status === status);
+ // 如果 step 不存在或 step.time 为 0,返回 false
+ return step && step.time && step.time !== '0' ? step.time : false;
+ },
getStepCreateTime(status) {
const step = this.stepInfos.find(step => step.status === status);
return step ? step.create_time : null;
@@ -1282,7 +1270,7 @@
// 修改导出方法,添加选中数据的处理
try {
this.loading = true;
-
+
// 如果有选中的数据,则只导出选中的数据
let exportData = [];
if (this.selections.length > 0) {
@@ -1421,7 +1409,7 @@
id: this.currentDetail.id,
status: this.currentDetail.status,
isPass: 0, // 0 表示通过
- eventNum: this.currentDetail.orderNumber,
+ eventNum: this.currentDetail.orderNumber,
eventName: this.currentDetail.orderName, // 工单名称
eventType: this.currentDetail.type, // 工单类型
departmentId: this.dispatchForm.department, // 派发部门 ID
@@ -1597,17 +1585,17 @@
// 添加编辑方法
handleEdit(row) {
console.log('编辑原始数据:', row);
-
+
// 尝试从row.dept_id或通过部门名称查找对应的部门ID
let deptId = row.dept_id; // 优先使用原始数据中的dept_id
-
+
// 如果没有dept_id,则通过部门名称查找
if (!deptId) {
// 输出所有可用的部门数据用于调试
console.log('可用部门列表:', this.departments);
console.log('当前部门名称:', row.department);
-
- const deptInfo = this.departments.find(dept =>
+
+ const deptInfo = this.departments.find(dept =>
dept.label && dept.label.trim() === row.department.trim()
);
deptId = deptInfo?.value;
@@ -1615,10 +1603,10 @@
// 获取工单类型值 - 从types中找到匹配的值
const typeValue = this.types.find(t => t.label === row.type)?.value || row.event_dict_key;
-
+
// 获取处理人ID - 使用userNameToIdMap映射
const handlerId = this.userNameToIdMap[row.handler] || row.handler;
-
+
console.log('数据映射:', {
部门名称: row.department,
找到的部门ID: deptId,
@@ -1721,8 +1709,22 @@
// 更新当前审核图片
updateCurrentReviewImage() {
- if (this.selections.length > 0 && this.currentImageIndex > 0) {
- const currentItem = this.selections[this.currentImageIndex - 1];
+ // 修正索引范围
+ if (!this.selections || this.selections.length === 0) {
+ this.currentReviewImage = '';
+ this.currentImageIndex = 1;
+ return;
+ }
+ // 如果当前索引超出范围,自动回退到最后一张
+ if (this.currentImageIndex > this.selections.length) {
+ this.currentImageIndex = this.selections.length;
+ }
+ if (this.currentImageIndex < 1) {
+ this.currentImageIndex = 1;
+ }
+ const index = this.currentImageIndex - 1;
+ if (index >= 0 && index < this.selections.length) {
+ const currentItem = this.selections[index];
this.currentReviewImage = currentItem.photo_url || '';
} else {
this.currentReviewImage = '';
@@ -1731,89 +1733,138 @@
// 处理图片分页变化
handleImagePageChange(page) {
- this.currentImageIndex = page;
- this.updateCurrentReviewImage();
+ if (page > 0 && page <= this.selections.length) {
+ this.currentImageIndex = page;
+ this.updateCurrentReviewImage();
+ }
},
// 批量审核通过
async handleBatchApprove() {
try {
- await this.$confirm('确认批量审核通过选中的工单?', '提示', {
+ if (this.selections.length === 0) {
+ this.$message.warning('没有选中的工单');
+ return;
+ }
+
+ const currentItem = this.selections[this.currentImageIndex - 1];
+ if (!currentItem) {
+ this.$message.warning('当前工单数据无效');
+ return;
+ }
+
+ await this.$confirm('确认审核通过当前工单?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
- const promises = this.selections.map(async (item) => {
- const data = {
- id: item.id,
- status: item.status,
- isPass: 0, // 0 表示通过
- eventNum: item.orderNumber,
- eventName: item.orderName,
- eventType: item.type,
- };
- return flowEvent(data);
- });
+ const data = {
+ id: currentItem.id,
+ status: currentItem.status,
+ isPass: 0,
+ eventNum: currentItem.orderNumber,
+ eventName: currentItem.orderName,
+ eventType: currentItem.type,
+ };
+ console.log('删除前:', this.selections)
+ const response = await flowEvent(data);
+ if (response.data.code === 0) {
+ this.$message.success('工单审核通过');
- const results = await Promise.all(promises);
- const successCount = results.filter(res => res.data.code === 0).length;
-
- if (successCount > 0) {
- this.$message.success(`成功审核通过 ${successCount} 个工单`);
- // 清空选择
- this.clearSelection();
- // 刷新数据
- this.fetchTableData();
- // 关闭审核对话框
- this.reviewDialogVisible = false;
+ // 创建新的数组而不是修改原数组
+ const newSelections = [...this.selections];
+ newSelections.splice(this.currentImageIndex - 1, 1);
+
+ // 修正索引并更新图片
+ if (newSelections.length > 0) {
+ if (this.currentImageIndex > this.selections.length) {
+ this.currentImageIndex = this.selections.length;
+ }
+ this.updateCurrentReviewImage();
+ } else {
+ this.reviewDialogVisible = false;
+ this.currentImageIndex = 1;
+ this.currentReviewImage = '';
+ this.fetchTableData();
+ }
+
+ // 刷新表格数据
+ // this.fetchTableData();
+ this.selections = newSelections;
+
} else {
- throw new Error('批量审核失败');
+ throw new Error(response.data.msg || '审核失败');
}
} catch (error) {
if (error === 'cancel') return;
- this.$message.error(error.message || '批量审核失败,请稍后重试');
+ this.$message.error(error.message || '审核失败,请稍后重试');
}
},
+ cancleBatchReject(){
+ reviewDialogVisible = false;
+ this.fetchTableData();
+ },
// 批量审核不通过
async handleBatchReject() {
try {
- await this.$confirm('确认批量审核不通过选中的工单?', '提示', {
+ if (this.selections.length === 0) {
+ this.$message.warning('没有选中的工单');
+ return;
+ }
+
+ const currentItem = this.selections[this.currentImageIndex - 1];
+ if (!currentItem) {
+ this.$message.warning('当前工单数据无效');
+ return;
+ }
+
+ await this.$confirm('确认驳回当前工单?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
- const promises = this.selections.map(async (item) => {
- const data = {
- id: item.id,
- status: item.status,
- isPass: 1, // 1 表示不通过
- eventNum: item.orderNumber,
- eventName: item.orderName,
- eventType: item.type,
- };
- return flowEvent(data);
- });
+ const data = {
+ id: currentItem.id,
+ status: currentItem.status,
+ isPass: 1,
+ eventNum: currentItem.orderNumber,
+ eventName: currentItem.orderName,
+ eventType: currentItem.type,
+ };
- const results = await Promise.all(promises);
- const successCount = results.filter(res => res.data.code === 0).length;
-
- if (successCount > 0) {
- this.$message.success(`成功审核不通过 ${successCount} 个工单`);
- // 清空选择
- this.clearSelection();
- // 刷新数据
- this.fetchTableData();
- // 关闭审核对话框
- this.reviewDialogVisible = false;
+ const response = await flowEvent(data);
+ if (response.data.code === 0) {
+ this.$message.success('工单已驊回');
+
+ // 创建新的数组而不是修改原数组
+ const newSelections = [...this.selections];
+ newSelections.splice(this.currentImageIndex - 1, 1);
+ this.selections = newSelections;
+
+ // 修正索引并更新图片
+ if (this.selections.length > 0) {
+ if (this.currentImageIndex > this.selections.length) {
+ this.currentImageIndex = this.selections.length;
+ }
+ this.updateCurrentReviewImage();
+ } else {
+ this.reviewDialogVisible = false;
+ this.currentImageIndex = 1;
+ this.currentReviewImage = '';
+ this.fetchTableData();
+ }
+
+ // 刷新表格数据
+ // this.fetchTableData();
} else {
- throw new Error('批量审核失败');
+ throw new Error(response.data.msg || '驳回失败');
}
} catch (error) {
if (error === 'cancel') return;
- this.$message.error(error.message || '批量审核失败,请稍后重试');
+ this.$message.error(error.message || '驳回失败,请稍后重试');
}
},
@@ -1947,13 +1998,14 @@
.location-wrapper {
width: 100%; // 修改为100%以适应父容器
height: auto; // 修改为auto以自适应内容
+
.map-button {
width: 100%; // 让按钮填满容器宽度
height: 36px; // 与其他输入框保持一致的高度
display: flex;
align-items: center;
justify-content: center;
-
+
i {
margin-right: 4px;
}
@@ -2030,13 +2082,13 @@
padding-top: 16px;
border-top: 1px solid #ebeef5;
- .el-button + .el-button {
+ .el-button+.el-button {
margin-left: 12px;
}
.el-button {
padding: 9px 20px;
-
+
&:last-child {
margin-left: 12px;
}
@@ -2253,7 +2305,7 @@
line-height: 1.5;
display: block;
text-align: left;
-
+
&:first-child {
font-weight: bold;
margin-bottom: 4px;
@@ -2310,7 +2362,7 @@
line-height: 1.5;
display: block;
text-align: center;
-
+
&:first-child {
font-weight: bold;
margin-bottom: 4px;
@@ -2346,7 +2398,7 @@
.review-container {
position: relative;
-
+
.review-image-wrapper {
position: relative;
display: flex;
@@ -2362,7 +2414,7 @@
display: flex;
align-items: center;
justify-content: center;
-
+
:deep(.el-image) {
width: 100%;
height: 100%;
@@ -2423,6 +2475,7 @@
background-color: #fff;
:deep(.el-pagination) {
+
.btn-prev,
.btn-next {
display: none;
@@ -2443,16 +2496,15 @@
align-items: center;
justify-content: center;
color: #909399;
-
+
i {
font-size: 48px;
margin-bottom: 16px;
}
-
+
span {
font-size: 16px;
}
}
}
-</style>
-```
\ No newline at end of file
+</style>
\ No newline at end of file
--
Gitblit v1.9.3