| | |
| | | <div class="detail-container"> |
| | | <div class="event-title-center">{{ currentDetail.orderName || '事件名称' }}</div> |
| | | <div v-if="totalTime" class="event-total-time" |
| | | style="text-align:center;color:#666;font-size:15px;margin-bottom:12px;"> |
| | | style="text-align: center; color: #666; font-size: 15px; margin-bottom: 12px"> |
| | | 总耗时:{{ totalTime }} |
| | | </div> |
| | | <!-- 工单状态流程 --> |
| | |
| | | <div class="steps-titles"> |
| | | <div v-for="(status, index) in stepStatusList" :key="index" :class="{ |
| | | 'step-title': true, |
| | | 'active': index <= stepStatusList.indexOf(String(currentDetail.status)) |
| | | active: index <= stepStatusList.indexOf(String(currentDetail.status)), |
| | | }"> |
| | | {{ mapStatus(status) }} |
| | | </div> |
| | |
| | | {{ getStepHandler(status) }} |
| | | </span> |
| | | <div class="step-description" v-if="getStepTime(status)"> |
| | | <span |
| | | style="position: absolute; right: 80%; top: 50%; transform: translateY(-50%); width: 100px; margin-left: 4px; color: #666; font-size: 12px;"> |
| | | <span style=" |
| | | position: absolute; |
| | | right: 80%; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 100px; |
| | | margin-left: 4px; |
| | | color: #666; |
| | | font-size: 12px; |
| | | "> |
| | | 耗时:{{ getStepTime(status) }} |
| | | </span> |
| | | </div> |
| | |
| | | </div> |
| | | |
| | | <!-- 基本信息表格 --> |
| | | <el-table :show-header="false" :data="formattedDetailFields" border style="width: 100%; margin-bottom: 20px;"> |
| | | <el-table :show-header="false" :data="formattedDetailFields" border style="width: 100%; margin-bottom: 20px"> |
| | | <el-table-column prop="label1" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <template v-if="currentDetail.status === 0 && row.label1 === '工单名称' && hasProcessingBtnPermission()"> |
| | | <template v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label1 === '工单名称' && |
| | | hasProcessingBtnPermission() |
| | | "> |
| | | <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" class="required-input" /> |
| | | </template> |
| | | <template v-else>{{ row.value1 }}</template> |
| | |
| | | <el-table-column prop="label2" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | <span v-if="currentDetail.status === 0 && (row.label2 === '工单类型' || row.label2 === '工单内容')" |
| | | class="required-label"> |
| | | <span v-if=" |
| | | currentDetail.status === 0 && |
| | | (row.label2 === '工单类型' || row.label2 === '工单内容') |
| | | " class="required-label"> |
| | | <span class="required-star">*</span>{{ row.label2 }} |
| | | </span> |
| | | <span v-else>{{ row.label2 }}</span> |
| | |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修改工单类型和工单内容的显示 --> |
| | | <template v-if="currentDetail.status === 0 && row.label2 === '工单类型' && hasProcessingBtnPermission()"> |
| | | <template v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label2 === '工单类型' && |
| | | hasProcessingBtnPermission() |
| | | "> |
| | | <el-select v-model="currentDetail.type" placeholder="请选择工单类型" class="required-input"> |
| | | <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 0 && row.label2 === '工单内容' && hasProcessingBtnPermission()"> |
| | | <template v-else-if=" |
| | | currentDetail.status === 0 && |
| | | row.label2 === '工单内容' && |
| | | hasProcessingBtnPermission() |
| | | "> |
| | | <el-input type="textarea" v-model="currentDetail.content" placeholder="请输入工单内容" |
| | | class="required-input" /> |
| | | </template> |
| | |
| | | <div class="section-title"> |
| | | <!-- 处理中状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <span class="required-label"> |
| | | <span class="required-star">*</span>事件处理详情 |
| | | </span> |
| | | <span class="required-label"> <span class="required-star">*</span>事件处理详情 </span> |
| | | </template> |
| | | <template v-else> |
| | | 事件处理详情 |
| | | </template> |
| | | <template v-else> 事件处理详情 </template> |
| | | </div> |
| | | <!-- 处理中状态显示输入框 --> |
| | | <template v-if="currentDetail.status === 3 && hasProcessedAndOverBtnPermission()"> |
| | | <el-input type="textarea" v-model="currentDetail.processingDetail" placeholder="请输入事件处理详情" :rows="4" |
| | | style="width: 100%; margin-bottom: 10px;" /> |
| | | style="width: 100%; margin-bottom: 10px" /> |
| | | </template> |
| | | <!-- 已完成和已完结状态显示只读文本 --> |
| | | <template v-else> |
| | |
| | | </div> |
| | | |
| | | <!-- 上传图片 --> |
| | | <div v-if="[3].includes(currentDetail.status)" class="form-section" style="margin-bottom: 32px;"> |
| | | <div v-if="[3].includes(currentDetail.status)" class="form-section" style="margin-bottom: 32px"> |
| | | <div class="section-title" v-if="hasProcessedAndOverBtnPermission()"> |
| | | <!-- 已完成状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <span class="required-label"> |
| | | <span class="required-star">*</span>上传图片 |
| | | </span> |
| | | <span class="required-label"> <span class="required-star">*</span>上传图片 </span> |
| | | </template> |
| | | <template v-else> |
| | | 上传图片 |
| | | </template> |
| | | <template v-else> 上传图片 </template> |
| | | </div> |
| | | <el-upload v-if="hasProcessedAndOverBtnPermission()" ref="upload" :action="'#'" :auto-upload="false" |
| | | list-type="picture-card" :on-change="handleFileChange" :on-remove="handleUploadRemove" |
| | |
| | | <i class="el-icon-plus">+</i> |
| | | </template> |
| | | </el-upload> |
| | | <div class="el-upload__tip" style="margin-top: 12px;" v-if="hasProcessedAndOverBtnPermission()"> |
| | | <div class="el-upload__tip" style="margin-top: 12px" v-if="hasProcessedAndOverBtnPermission()"> |
| | | (上传照片即可完结工单,只能上传jpg、jpeg、png照片,且不超过5M) |
| | | </div> |
| | | </div> |
| | |
| | | <div class="media-content"> |
| | | <el-image v-if="currentDetail.mediaUrl" :src="getThumbUrl(currentDetail.mediaUrl)" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.mediaUrl)]" fit="contain" |
| | | style="width: 700px; height: 520px; cursor: pointer;"> |
| | | style="width: 700px; height: 520px; cursor: pointer"> |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | | <i class="el-icon-picture-outline"></i> |
| | |
| | | <template v-else> |
| | | <div class="media-title">地图标记事件点</div> |
| | | <div class="media-content"> |
| | | <map-container v-if='detailVisible' ref="MapContainer"></map-container> |
| | | <map-container v-if="detailVisible" ref="MapContainer"></map-container> |
| | | </div> |
| | | </template> |
| | | </div> |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- 添加在其他 dialog 组件之后 --> |
| | | <el-dialog v-model="reviewDialogVisible" title="批量审核" width="70%" append-to-body custom-class="review-dialog" |
| | | <el-dialog v-model="reviewDialogVisible" title="批量审核" width="1100" append-to-body custom-class="review-dialog" |
| | | @close="cancleBatchReject"> |
| | | <div class="review-container"> |
| | | <div class="review-image-wrapper"> |
| | |
| | | </div> |
| | | |
| | | <div class="review-image-container"> |
| | | <el-image v-if="currentReviewImage" :src="getThumbUrl(currentReviewImage)" fit="fill" |
| | | <!-- <el-image v-if="currentReviewImage" :src="getThumbUrl(currentReviewImage)" fit="fill" |
| | | :preview-src-list="getImageList()" :initial-index="currentImageIndex - 1" class="preview-image" |
| | | style="cursor: pointer;"> |
| | | style="cursor: pointer"> --> |
| | | <el-image v-if="currentReviewImage" :src="getPreviewUrl(currentReviewImage)" fit="fill" |
| | | :initial-index="currentImageIndex - 1" class="preview-image" style="cursor: pointer"> |
| | | <template #error> |
| | | <div class="image-error"> |
| | | <i class="el-icon-picture-outline"></i> |
| | |
| | | getstatusCount, |
| | | getStepInfo, |
| | | getReviewById, |
| | | getCreateEventJob |
| | | getCreateEventJob, |
| | | } from '@/api/tickets/ticket' |
| | | import { export_json_to_excel } from '@/utils/exportExcel' |
| | | import geoJson from '@/assets/geoJson.json' |
| | |
| | | import { mapGetters } from 'vuex' |
| | | import { getAdcodeObj } from '@/utils/disposeData' |
| | | function regExp (label, name) { |
| | | var reg = new RegExp(label + "=([^&]*)(&|$)", "g") |
| | | return name.match(reg)[0].split("=")[1] |
| | | var reg = new RegExp(label + '=([^&]*)(&|$)', 'g') |
| | | return name.match(reg)[0].split('=')[1] |
| | | } |
| | | |
| | | export default { |
| | | name: "TicketPage", |
| | | name: 'TicketPage', |
| | | data () { |
| | | return { |
| | | submitLoading: false, // 新增loading状态 |
| | |
| | | dispatchLoading: false, |
| | | completeLoading: false, |
| | | finalizeLoading: false, |
| | | activeTab: "all", |
| | | activeTab: 'all', |
| | | // tabs 只保留静态结构,不做权限判断 |
| | | tabs: [ |
| | | { label: "全部工单", name: "all", value: null, count: 0 }, |
| | | { label: "待审核", name: "pending", value: 2, count: 0 }, |
| | | { label: "待处理", name: "processing", value: 0, count: 0 }, |
| | | { label: "处理中", name: "inProgress", value: 3, count: 0 }, |
| | | { label: "已完成", name: "completed", value: 4, count: 0 }, |
| | | { label: '全部工单', name: 'all', value: null, count: 0 }, |
| | | { label: '待审核', name: 'pending', value: 2, count: 0 }, |
| | | { label: '待处理', name: 'processing', value: 0, count: 0 }, |
| | | { label: '处理中', name: 'inProgress', value: 3, count: 0 }, |
| | | { label: '已完成', name: 'completed', value: 4, count: 0 }, |
| | | // { label: "已完结", name: "closed", value: 5, count: 0 }, |
| | | { label: "我发起的工单", name: "myTickets", value: null, count: 0 }, |
| | | { label: '我发起的工单', name: 'myTickets', value: null, count: 0 }, |
| | | ], |
| | | filters: { |
| | | keyword: "", |
| | | department: "", |
| | | type: "", |
| | | keyword: '', |
| | | department: '', |
| | | type: '', |
| | | dateRange: [], |
| | | status: "", |
| | | algorithm: "", // 新增算法筛选字段 |
| | | isReview: "", // 添加复核状态筛选字段 |
| | | status: '', |
| | | algorithm: '', // 新增算法筛选字段 |
| | | isReview: '', // 添加复核状态筛选字段 |
| | | }, |
| | | departments: [], |
| | | types: [], |
| | | handlers: [ |
| | | { label: "处理人A", value: "handlerA" }, |
| | | { label: "处理人B", value: "handlerB" }, |
| | | { label: '处理人A', value: 'handlerA' }, |
| | | { label: '处理人B', value: 'handlerB' }, |
| | | ], |
| | | |
| | | algorithms: [], |
| | | statuses: [ |
| | | { label: "待审核", value: "2" }, |
| | | { label: "待处理", value: "0" }, |
| | | { label: "处理中", value: "3" }, |
| | | { label: "已完成", value: "4" }, |
| | | { label: "已完结", value: "5" }, |
| | | { label: '待审核', value: '2' }, |
| | | { label: '待处理', value: '0' }, |
| | | { label: '处理中', value: '3' }, |
| | | { label: '已完成', value: '4' }, |
| | | ], |
| | | reviewStatuses: [ |
| | | { label: "否", value: 0 }, |
| | | { label: "是", value: 1 } |
| | | { label: '否', value: 0 }, |
| | | { label: '是', value: 1 }, |
| | | ], |
| | | tableData: [], |
| | | option: { |
| | | border: true, |
| | | stripe: true, |
| | | selection: true, // 添加多选功能 |
| | | index: true, // 保留序号功能 |
| | | index: true, // 保留序号功能 |
| | | indexLabel: '序号', |
| | | indexWidth: 60, |
| | | menuWidth: 150, |
| | |
| | | page: true, |
| | | column: [ |
| | | // { label: "序号", prop: "id", width: 70 }, |
| | | { label: "工单编号", prop: "orderNumber", width: 120, overHidden: true, tooltip: true }, |
| | | { label: "工单名称", prop: "orderName", width: 150, overHidden: true, tooltip: true }, |
| | | { label: "所属单位", prop: "department", overHidden: true, tooltip: true }, |
| | | { label: "发起时间", prop: "startTime", width: 160 }, |
| | | { label: "关联算法", prop: "aiType", width: 150, overHidden: true, tooltip: true }, |
| | | { label: "工单类型", prop: "type", width: 130, overHidden: true, tooltip: true }, |
| | | { label: '工单编号', prop: 'orderNumber', width: 120, overHidden: true, tooltip: true }, |
| | | { label: '工单名称', prop: 'orderName', width: 150, overHidden: true, tooltip: true }, |
| | | { label: '所属单位', prop: 'department', overHidden: true, tooltip: true }, |
| | | { label: '发起时间', prop: 'startTime', width: 160 }, |
| | | { label: '关联算法', prop: 'aiType', width: 150, overHidden: true, tooltip: true }, |
| | | { |
| | | label: "工单内容", |
| | | prop: "content", |
| | | label: '工单类型', |
| | | prop: 'type', |
| | | width: 130, |
| | | overHidden: true, |
| | | tooltip: true, |
| | | type: 'select', |
| | | dicData: [], |
| | | }, |
| | | { |
| | | label: '工单内容', |
| | | prop: 'content', |
| | | slot: true, |
| | | width: 152, |
| | | overHidden: true |
| | | overHidden: true, |
| | | }, |
| | | { label: "创建人", prop: "creator", width: 100 }, |
| | | { label: "处理人", prop: "handler", width: 100 }, |
| | | { label: '创建人', prop: 'creator', width: 100 }, |
| | | { label: '处理人', prop: 'handler', width: 100 }, |
| | | { |
| | | slot: true, |
| | | hide: false, |
| | | label: "复核状态", |
| | | prop: "isReview", |
| | | label: '复核状态', |
| | | prop: 'isReview', |
| | | width: 90, |
| | | }, |
| | | { label: "工单状态", prop: "status", slot: true, width: 90 }, |
| | | |
| | | { label: '工单状态', prop: 'status', slot: true, width: 90 }, |
| | | ], |
| | | }, |
| | | page: { |
| | | total: 0, |
| | | currentPage: 1, |
| | | pageSize: 10, |
| | | pageSizes: [10, 20, 30] |
| | | pageSizes: [10, 20, 30], |
| | | }, |
| | | dialogVisible: false, |
| | | detailVisible: false, |
| | |
| | | department: '', |
| | | handler: '', |
| | | algorithm: [], // 关联算法改为数组 |
| | | location: [], // 将存储为[经度, 纬度, 地址]格式 |
| | | location: [], // 将存储为[经度, 纬度, 地址]格式 |
| | | address: '', |
| | | photos: [], |
| | | content: '', // 新增字段,用于存储后端返回的 content |
| | |
| | | handler: [{ required: true, message: '请选择处理人员', trigger: 'change' }], |
| | | content: [{ required: true, message: '请输入工单内容', trigger: 'blur' }], |
| | | algorithm: [{ required: true, message: '请选择关联算法', trigger: 'change' }], |
| | | location: [{ |
| | | validator: (rule, value, callback) => { |
| | | if (!value || value.length < 2) { |
| | | callback(new Error('请选择位置信息')) |
| | | } else { |
| | | callback() |
| | | } |
| | | location: [ |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!value || value.length < 2) { |
| | | callback(new Error('请选择位置信息')) |
| | | } else { |
| | | callback() |
| | | } |
| | | }, |
| | | trigger: 'blur', |
| | | }, |
| | | trigger: 'blur' |
| | | }], |
| | | photos: [{ |
| | | validator: (rule, value, callback) => { |
| | | if (!this.form.photos || this.form.photos.length === 0) { |
| | | callback(new Error('请上传工单图片')) |
| | | } else { |
| | | callback() |
| | | } |
| | | ], |
| | | photos: [ |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!this.form.photos || this.form.photos.length === 0) { |
| | | callback(new Error('请上传工单图片')) |
| | | } else { |
| | | callback() |
| | | } |
| | | }, |
| | | trigger: 'change', |
| | | }, |
| | | trigger: 'change' |
| | | }], |
| | | ], |
| | | }, |
| | | departmentUsers: {}, |
| | | loading: false, |
| | |
| | | handler: [{ required: true, message: '请选择处理人', trigger: 'change' }], |
| | | }, // 新增:派发表单验证规则 |
| | | stepInfos: [], // 新增:存储步骤信息 |
| | | fixedStatuses: ["2", "0", "3", "4", "5"], // 固定的五个状态 |
| | | fixedStatuses: ['2', '0', '3', '4', '5'], // 固定的五个状态 |
| | | userNameToIdMap: {}, // 新增用户名到ID的映射 |
| | | workType: 0, // 新增:当前工单work_type |
| | | selections: [], // 添加选中行数据数组 |
| | |
| | | }, |
| | | mounted () { |
| | | const href = this.$route.href |
| | | let curQueryParams = {} |
| | | |
| | | if (href.split("?").length > 0) { |
| | | const [orderNumber] = href.split("?")[1].split("&") |
| | | if (href.indexOf('?') != -1 && href.split('?').length > 0) { |
| | | curQueryParams = (href.split('?')[1].split('&')).reduce((pre, cur) => { |
| | | let newArr = cur.split('=') |
| | | |
| | | const order = regExp('orderNumber', orderNumber) |
| | | if (order) { |
| | | this.filters.keyword = order |
| | | pre[newArr[0]] = newArr[1] |
| | | |
| | | return pre |
| | | }, {}) |
| | | |
| | | const { orderNumber = undefined, day = undefined } = curQueryParams |
| | | |
| | | // 日历传值 |
| | | if (day) { |
| | | const date = new Date(day + 'T00:00:00+08:00') |
| | | const dateArray = [date, date] |
| | | const handler = { |
| | | get (target, prop) { |
| | | if (typeof prop === 'string' && /^\d+$/.test(prop)) { |
| | | const index = parseInt(prop) |
| | | const dateObj = target[index] |
| | | return dateObj.toDateString() + ' 00:00:00 GMT+0800 (中国标准时间)' |
| | | } |
| | | return Reflect.get(target, prop) |
| | | }, |
| | | } |
| | | |
| | | const proxyArray = new Proxy(dateArray, handler) |
| | | this.filters.dateRange = proxyArray |
| | | } |
| | | |
| | | if (orderNumber) { |
| | | this.filters.keyword = orderNumber |
| | | |
| | | this.$nextTick(() => { |
| | | this.isShowInfo = true |
| | | }) |
| | | } |
| | | } |
| | | |
| | | |
| | | this.fetchTabCounts() // 新增:初始化时获取 tab 数据 |
| | | this.fetchTableData() |
| | |
| | | return this.tableData.length > 0 ? this.tableData[0] : null |
| | | }, |
| | | availableHandlers () { |
| | | return this.form.department ? (this.departmentUsers[this.form.department] || []) : [] |
| | | return this.form.department ? this.departmentUsers[this.form.department] || [] : [] |
| | | }, |
| | | availableDispatchHandlers () { |
| | | return this.dispatchForm.department ? (this.departmentUsers[this.dispatchForm.department] || []) : [] |
| | | return this.dispatchForm.department |
| | | ? this.departmentUsers[this.dispatchForm.department] || [] |
| | | : [] |
| | | }, |
| | | detailTableData () { |
| | | return [ |
| | | { |
| | | label: "工单名称", |
| | | label: '工单名称', |
| | | value: this.currentDetail.orderName, |
| | | editable: this.currentDetail.status === 0, |
| | | type: "input", |
| | | type: 'input', |
| | | }, |
| | | { |
| | | label: "关键任务", |
| | | label: '关键任务', |
| | | value: this.currentDetail.keyData, |
| | | editable: false, |
| | | }, |
| | | { |
| | | label: "任务发起人", |
| | | label: '任务发起人', |
| | | value: this.currentDetail.creator, |
| | | editable: false, |
| | | }, |
| | | { |
| | | label: "当前状态", |
| | | label: '当前状态', |
| | | value: this.mapStatus(this.currentDetail.status), |
| | | editable: false, |
| | | }, |
| | | { |
| | | label: "事件地址", |
| | | label: '事件地址', |
| | | value: this.currentDetail.address, |
| | | editable: false, |
| | | }, |
| | | { |
| | | label: "工单类型", |
| | | label: '工单类型', |
| | | value: this.currentDetail.type, |
| | | editable: this.currentDetail.status === 0, |
| | | type: "select", |
| | | type: 'select', |
| | | options: this.types, |
| | | }, |
| | | { |
| | | label: "关联算法", |
| | | label: '关联算法', |
| | | value: this.currentDetail.aiType, |
| | | editable: false, |
| | | }, |
| | | { |
| | | label: "发起单位", |
| | | label: '发起单位', |
| | | value: this.currentDetail.department, |
| | | editable: false, |
| | | }, |
| | | { |
| | | label: "发起任务时间", |
| | | label: '发起任务时间', |
| | | value: this.currentDetail.startTime, |
| | | editable: false, |
| | | }, |
| | | { |
| | | label: "工单内容", |
| | | label: '工单内容', |
| | | value: this.currentDetail.content, |
| | | editable: this.currentDetail.status === 0, |
| | | type: "textarea", |
| | | type: 'textarea', |
| | | }, |
| | | ] |
| | | }, |
| | | detailFields () { |
| | | return [ |
| | | { label: "工单名称", value: this.currentDetail.orderName, editable: this.currentDetail.status === 0, type: "input" }, |
| | | { label: "关键任务", value: this.currentDetail.keyData, editable: false }, |
| | | { label: "任务发起人", value: this.currentDetail.creator, editable: false }, |
| | | { label: "当前状态", value: this.mapStatus(this.currentDetail.status), editable: false }, |
| | | { label: "事件地址", value: this.currentDetail.address, editable: false }, |
| | | { label: "工单类型", value: this.currentDetail.type, editable: this.currentDetail.status === 0, type: "select", options: this.types }, |
| | | { label: "关联算法", value: this.currentDetail.aiType, editable: false }, |
| | | { label: "发起单位", value: this.currentDetail.department, editable: false }, |
| | | { label: "发起任务时间", value: this.currentDetail.startTime, editable: false }, |
| | | { label: "工单内容", value: this.currentDetail.content, editable: this.currentDetail.status === 0, type: "textarea" }, |
| | | { |
| | | label: '工单名称', |
| | | value: this.currentDetail.orderName, |
| | | editable: this.currentDetail.status === 0, |
| | | type: 'input', |
| | | }, |
| | | { label: '关键任务', value: this.currentDetail.keyData, editable: false }, |
| | | { label: '任务发起人', value: this.currentDetail.creator, editable: false }, |
| | | { label: '当前状态', value: this.mapStatus(this.currentDetail.status), editable: false }, |
| | | { label: '事件地址', value: this.currentDetail.address, editable: false }, |
| | | { |
| | | label: '工单类型', |
| | | value: this.currentDetail.type, |
| | | editable: this.currentDetail.status === 0, |
| | | type: 'select', |
| | | options: this.types, |
| | | }, |
| | | { label: '关联算法', value: this.currentDetail.aiType, editable: false }, |
| | | { label: '发起单位', value: this.currentDetail.department, editable: false }, |
| | | { label: '发起任务时间', value: this.currentDetail.startTime, editable: false }, |
| | | { |
| | | label: '工单内容', |
| | | value: this.currentDetail.content, |
| | | editable: this.currentDetail.status === 0, |
| | | type: 'textarea', |
| | | }, |
| | | ] |
| | | }, |
| | | formattedDetailFields () { |
| | | const fields = [ |
| | | { label: "工单名称", value: this.currentDetail.orderName }, |
| | | { label: "工单类型", value: this.currentDetail.type }, |
| | | { label: "关联任务", value: this.currentDetail.job_name || '/' }, |
| | | { label: "任务发起人", value: this.currentDetail.creator }, |
| | | { label: "当前状态", value: this.mapStatus(this.currentDetail.status) }, |
| | | { label: "事件地址", value: this.currentDetail.address }, // 包含经纬度信息 |
| | | { label: "关联算法", value: this.currentDetail.aiType }, |
| | | { label: "发起单位", value: this.currentDetail.department }, |
| | | { label: "发起任务时间", value: this.currentDetail.startTime }, |
| | | { label: "工单内容", value: this.currentDetail.content }, |
| | | { label: '工单名称', value: this.currentDetail.orderName }, |
| | | { |
| | | label: '工单类型', |
| | | // 修改这里:使用 types 数组查找对应的 label |
| | | value: this.types.find(t => t.value === this.currentDetail.type)?.label || this.currentDetail.type || '/' |
| | | }, |
| | | { label: '关联任务', value: this.currentDetail.job_name || '/' }, |
| | | { label: '任务发起人', value: this.currentDetail.creator }, |
| | | { label: '当前状态', value: this.mapStatus(this.currentDetail.status) }, |
| | | { label: '事件地址', value: this.currentDetail.address }, // 包含经纬度信息 |
| | | { label: '关联算法', value: this.currentDetail.aiType }, |
| | | { label: '发起单位', value: this.currentDetail.department }, |
| | | { label: '发起任务时间', value: this.currentDetail.startTime }, |
| | | { label: '工单内容', value: this.currentDetail.content }, |
| | | ] |
| | | |
| | | // 将字段分成两列 |
| | | const formattedFields = [] |
| | | for (let i = 0; i < fields.length; i += 2) { |
| | | formattedFields.push({ |
| | | label1: fields[i]?.label || "", |
| | | value1: fields[i]?.value || "暂无数据", |
| | | label2: fields[i + 1]?.label || "", |
| | | value2: fields[i + 1]?.value || "暂无数据", |
| | | label1: fields[i]?.label || '', |
| | | value1: fields[i]?.value || '暂无数据', |
| | | label2: fields[i + 1]?.label || '', |
| | | value2: fields[i + 1]?.value || '暂无数据', |
| | | }) |
| | | } |
| | | return formattedFields |
| | |
| | | const tabStatus = this.permission?.tickets_tab_status === true |
| | | const tabPending = this.permission?.tickets_tab_pending === true |
| | | const tabMyTickets = this.permission?.tickets_tab_mytickets === true |
| | | return this.tabs.map(tab => { |
| | | if (tab.name === 'all') { |
| | | return { ...tab, isShow: true } |
| | | } |
| | | if (tab.name === 'pending') { |
| | | return { ...tab, isShow: tabPending } |
| | | } |
| | | if (['processing', 'inProgress', 'completed', 'closed'].includes(tab.name)) { |
| | | return { ...tab, isShow: tabStatus } |
| | | } |
| | | if (tab.name === 'myTickets') { |
| | | return { ...tab, isShow: tabMyTickets } |
| | | } |
| | | return { ...tab, isShow: false } |
| | | }).filter(tab => tab.isShow) |
| | | return this.tabs |
| | | .map(tab => { |
| | | if (tab.name === 'all') { |
| | | return { ...tab, isShow: true } |
| | | } |
| | | if (tab.name === 'pending') { |
| | | return { ...tab, isShow: tabPending } |
| | | } |
| | | if (['processing', 'inProgress', 'completed', 'closed'].includes(tab.name)) { |
| | | return { ...tab, isShow: tabStatus } |
| | | } |
| | | if (tab.name === 'myTickets') { |
| | | return { ...tab, isShow: tabMyTickets } |
| | | } |
| | | return { ...tab, isShow: false } |
| | | }) |
| | | .filter(tab => tab.isShow) |
| | | }, |
| | | permissionList () { |
| | | // 可根据实际后端权限key调整 |
| | | return { |
| | | addBtn: this.validData(this.permission.tickets_add, false), |
| | | delBtn: this.validData(this.permission.tickets_delete, false), |
| | | exportBtn: this.validData(this.permission.tickets_export, false,), |
| | | exportBtn: this.validData(this.permission.tickets_export, false), |
| | | reviewBtn: this.validData(this.permission.tickets_review, false), |
| | | } |
| | | }, |
| | |
| | | // “我发起的工单”tab用默认流程,其它tab用接口返回的stepInfos |
| | | if (this.activeTab === 'myTickets') { |
| | | if (this.workType === 1) { |
| | | return ["3", "4", "5"] |
| | | return ['3', '4', '5'] |
| | | } |
| | | return this.fixedStatuses |
| | | } |
| | |
| | | }, |
| | | |
| | | showIsReviewText () { |
| | | return (row) => { |
| | | return row => { |
| | | if (['4', '5'].includes(String(row.status))) return row.isReview === 1 ? '是' : '否' |
| | | |
| | | return '/' |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | methods: { |
| | | async loadAMapScripts () { |
| | |
| | | await this.$confirm('确认审核通过当前工单?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | type: 'warning', |
| | | }) |
| | | |
| | | const data = { |
| | |
| | | value: key, |
| | | })) |
| | | |
| | | const columnType = this.findObject(this.option.column, 'type') |
| | | columnType.dicData = this.types |
| | | |
| | | // 确保算法数据的映射一致 |
| | | this.algorithms = ai_type.map(item => ({ |
| | | dict_key: item.dict_key, |
| | | dict_value: item.dict_value, |
| | | // 同时添加 label 和 value 以兼容两处使用 |
| | | label: item.dict_value, |
| | | value: item.dict_key |
| | | })) |
| | | this.algorithms = |
| | | ai_type?.map(item => ({ |
| | | dict_key: item.dict_key, |
| | | dict_value: item.dict_value, |
| | | // 同时添加 label 和 value 以兼容两处使用 |
| | | label: item.dict_value, |
| | | value: item.dict_key, |
| | | })) || [] |
| | | |
| | | // 构建用户ID和名称的映射关系 |
| | | this.userNameToIdMap = {} |
| | |
| | | const currentTab = this.tabs.find(tab => tab.name === this.activeTab) |
| | | const params = { |
| | | word_order_type: this.filters.type || undefined, |
| | | status: currentTab?.name === 'myTickets' ? undefined : |
| | | this.filters.status !== "" ? Number(this.filters.status) : |
| | | currentTab?.value, |
| | | status: |
| | | currentTab?.name === 'myTickets' |
| | | ? undefined |
| | | : this.filters.status !== '' |
| | | ? Number(this.filters.status) |
| | | : currentTab?.value, |
| | | event_name: this.filters.keyword || undefined, |
| | | dept_id: this.filters.department || undefined, |
| | | start_date: this.filters.dateRange?.[0] ? this.formatDate(this.filters.dateRange[0]) : undefined, |
| | | end_date: this.filters.dateRange?.[1] ? this.formatDate(this.filters.dateRange[1]).replace("00:00:00", "23:59:59") : undefined, |
| | | current: Number(this.page.currentPage), // 使用当前页码 |
| | | size: Number(this.page.pageSize), // 使用每页条数 |
| | | start_date: this.filters.dateRange?.[0] |
| | | ? this.formatDate(this.filters.dateRange[0]) |
| | | : undefined, |
| | | end_date: this.filters.dateRange?.[1] |
| | | ? this.formatDate(this.filters.dateRange[1]).replace('00:00:00', '23:59:59') |
| | | : undefined, |
| | | current: Number(this.page.currentPage), // 使用当前页码 |
| | | size: Number(this.page.pageSize), // 使用每页条数 |
| | | ai_type: this.filters.algorithm || undefined, // 添加算法参数 |
| | | // 添加 is_draft 参数,仅在"我发起的"标签页时设置为1 |
| | | is_draft: currentTab?.name === 'myTickets' ? 1 : undefined, |
| | |
| | | id: item.id, |
| | | orderNumber: item.event_num, // 修改这里:优先使用 event_num |
| | | orderName: item.event_name, |
| | | department: this.departments.find(d => d.value === item.dept_id)?.label || item.dept_name, |
| | | department: |
| | | this.departments.find(d => d.value === item.dept_id)?.label || item.dept_name, |
| | | startTime: item.create_time, |
| | | aiType: item.ai_types, |
| | | content: item.content, // 将后端返回的 content 映射为 content |
| | | type: this.types.find(t => t.value === item.work_order_type_dict_key)?.label, |
| | | keyData: (!isNaN(longitude) && !isNaN(latitude)) |
| | | ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` |
| | | : '未知位置', |
| | | type: item.work_order_type_dict_key, |
| | | keyData: |
| | | !isNaN(longitude) && !isNaN(latitude) |
| | | ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` |
| | | : '未知位置', |
| | | address: item.address, |
| | | creator: item.create_user, |
| | | handler: item.update_user || '未分配', |
| | | status: Number(item.status || 0), |
| | | // 保存原始字段 |
| | | photo_url: item.photo_url || '', // 保存原始 photo_url |
| | | video_url: item.video_url || '', // 保存原始 video_url |
| | | location: (!isNaN(longitude) && !isNaN(latitude)) ? [longitude, latitude] : null, |
| | | photo_url: item.photo_url || '', // 保存原始 photo_url |
| | | video_url: item.video_url || '', // 保存原始 video_url |
| | | location: !isNaN(longitude) && !isNaN(latitude) ? [longitude, latitude] : null, |
| | | processing_details: item.processing_details || '', // 添加处理详情字段 |
| | | update_photo_url: item.update_photo_url || '', // 添加处理图片字段 |
| | | work_type: item.work_type !== undefined ? Number(item.work_type) : 0, // 保留work_type字段并转为数字 |
| | |
| | | } |
| | | await this.fetchTabCounts() |
| | | } catch (error) { |
| | | this.$message.error(error.message || "获取数据失败") |
| | | this.$message.error(error.message || '获取数据失败') |
| | | this.tableData = [] |
| | | this.page.total = 0 |
| | | } finally { |
| | |
| | | const submitData = { |
| | | eventName: this.form.name, |
| | | content: this.form.content, |
| | | workType: "1", |
| | | workType: '1', |
| | | longitude: lng, |
| | | latitude: lat, |
| | | address: this.form.address, |
| | |
| | | aiType: Array.isArray(this.form.algorithm) ? this.form.algorithm : [this.form.algorithm], // 传数组 |
| | | updateUser: this.form.handler, |
| | | createDept: this.form.department, |
| | | isDraft: 0 |
| | | isDraft: 0, |
| | | } |
| | | |
| | | if (this.form.id) { |
| | |
| | | } else { |
| | | this.$message.error(error.message || '工单创建失败,请稍后重试') |
| | | } |
| | | } |
| | | finally { |
| | | } finally { |
| | | this.submitLoading = false |
| | | } |
| | | }, |
| | |
| | | id: this.form.id, |
| | | eventName: this.form.name || undefined, |
| | | content: this.form.content || undefined, |
| | | workType: "1", |
| | | workType: '1', |
| | | longitude: lng, |
| | | latitude: lat, |
| | | address: this.form.address || undefined, |
| | | workOrderTypeDictKey: this.form.type || undefined, |
| | | aiType: this.form.algorithm && this.form.algorithm.length > 0 |
| | | ? this.form.algorithm |
| | | : undefined, // 传数组 |
| | | aiType: |
| | | this.form.algorithm && this.form.algorithm.length > 0 ? this.form.algorithm : undefined, // 传数组 |
| | | updateUser: handlerValue, |
| | | createDept: this.form.department || undefined, |
| | | isDraft: 1 |
| | | isDraft: 1, |
| | | } |
| | | |
| | | // 草稿时也至少需要工单名称 |
| | |
| | | } |
| | | |
| | | // 过滤掉所有 undefined 的字段 |
| | | Object.keys(submitData).forEach(key => |
| | | submitData[key] === undefined && delete submitData[key] |
| | | Object.keys(submitData).forEach( |
| | | key => submitData[key] === undefined && delete submitData[key] |
| | | ) |
| | | |
| | | let file = null |
| | |
| | | } |
| | | } catch (error) { |
| | | this.$message.error(error.message || '保存草稿失败,请稍后重试') |
| | | } |
| | | finally { |
| | | } finally { |
| | | this.draftLoading = false |
| | | } |
| | | }, |
| | |
| | | this.form.location = [ |
| | | Number(locationValue[0]), |
| | | Number(locationValue[1]), |
| | | locationValue[2] || '' |
| | | locationValue[2] || '', |
| | | ] |
| | | this.form.address = locationValue[2] || '' |
| | | } else { |
| | |
| | | formatDate (date) { |
| | | if (!date) return undefined |
| | | const d = new Date(date) |
| | | return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} 00:00:00` |
| | | return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String( |
| | | d.getDate() |
| | | ).padStart(2, '0')} 00:00:00` |
| | | }, |
| | | |
| | | mapStatus (status) { |
| | | const statusTextMap = { |
| | | "-1": "草稿", // 添加草稿状态 |
| | | "2": "待审核", |
| | | "0": "待处理", |
| | | "3": "处理中", |
| | | "4": "已完成", |
| | | "5": "已完结" |
| | | '-1': '草稿', // 添加草稿状态 |
| | | 2: '待审核', |
| | | 0: '待处理', |
| | | 3: '处理中', |
| | | 4: '已完成', |
| | | } |
| | | return statusTextMap[status] || "未知状态" |
| | | return statusTextMap[status] || '未知状态' |
| | | }, |
| | | |
| | | getStatusTagType (status) { |
| | | // 草稿不加颜色 |
| | | if (status === -1 || status === "-1") return '' |
| | | if (status === -1 || status === '-1') return '' |
| | | // 状态颜色映射 |
| | | const colorMap = { |
| | | "0": "#ffb6b6", // 待处理-淡红 |
| | | "3": "#e57373", // 处理中-更淡红 |
| | | "2": "#faad14", // 待审核-橙色 |
| | | "4": "#a0cfff", // 已完成-淡蓝 |
| | | "5": "#67c23a", // 已完结-绿色 |
| | | 0: '#ffb6b6', // 待处理-淡红 |
| | | 3: '#e57373', // 处理中-更淡红 |
| | | 2: '#faad14', // 待审核-橙色 |
| | | 4: '#a0cfff', // 已完成-淡蓝 |
| | | } |
| | | return colorMap[String(status)] || '' |
| | | }, |
| | |
| | | |
| | | handleReset () { |
| | | this.filters = { |
| | | keyword: "", |
| | | department: "", |
| | | type: "", |
| | | keyword: '', |
| | | department: '', |
| | | type: '', |
| | | dateRange: [], |
| | | status: "", |
| | | algorithm: "", // 重置时清空算法筛选 |
| | | isReview: "", // 重置时清空复核状态 |
| | | status: '', |
| | | algorithm: '', // 重置时清空算法筛选 |
| | | isReview: '', // 重置时清空复核状态 |
| | | } |
| | | this.page.currentPage = 1 |
| | | this.fetchTableData() |
| | |
| | | department: '', |
| | | handler: '', |
| | | algorithm: [], // 关联算法改为数组 |
| | | location: [], // 将存储为[经度, 纬度, 地址]格式 |
| | | location: [], // 将存储为[经度, 纬度, 地址]格式 |
| | | address: '', |
| | | content: '', |
| | | photos: [], |
| | |
| | | }, |
| | | |
| | | async handleViewDetail (row) { |
| | | |
| | | // 先设置workType,直接从row读取 |
| | | this.workType = row.work_type !== undefined ? Number(row.work_type) : 0 |
| | | |
| | |
| | | create_time: step.create_time, |
| | | })) |
| | | } else { |
| | | const statusArr = this.workType === 1 ? ["3", "4", "5"] : this.fixedStatuses |
| | | const statusArr = this.workType === 1 ? ['3', '4', '5'] : this.fixedStatuses |
| | | this.stepInfos = statusArr.map(status => { |
| | | const step = steps.find(s => String(s.status) === String(status)) |
| | | return { |
| | |
| | | this.currentDetail.status = row.status |
| | | } catch (error) { |
| | | if (this.activeTab === 'myTickets') { |
| | | const statusArr = this.workType === 1 ? ["3", "4", "5"] : this.fixedStatuses |
| | | const statusArr = this.workType === 1 ? ['3', '4', '5'] : this.fixedStatuses |
| | | this.stepInfos = statusArr.map(status => ({ |
| | | status, |
| | | name: status === row.status ? row.handler || '未分配' : '未处理', |
| | |
| | | const areaCode = this.userInfo.detail.areaCode |
| | | const subAreaCode = areaCode ? areaCode.substring(0, 6) : '' |
| | | getAdcodeObj(geoJson, 'adcode', subAreaCode) |
| | | this.$message.info("地图选址功能暂未实现") |
| | | this.$message.info('地图选址功能暂未实现') |
| | | }, |
| | | |
| | | handlePreview (file) { |
| | |
| | | 关联算法: item.aiType || '', |
| | | 工单内容: item.address || '', |
| | | 工单类型: item.type || '', |
| | | 经纬度: item.location ? `${item.location[0].toFixed(6)}, ${item.location[1].toFixed(6)}` : '', |
| | | 经纬度: item.location |
| | | ? `${item.location[0].toFixed(6)}, ${item.location[1].toFixed(6)}` |
| | | : '', |
| | | 创建人: item.creator || '', |
| | | 处理人: item.handler || '', |
| | | 工单状态: this.mapStatus(item.status) |
| | | 工单状态: this.mapStatus(item.status), |
| | | })) |
| | | } else { |
| | | // 原有的导出全部数据的逻辑 |
| | |
| | | // 使用与查询列表相同的参数构造逻辑 |
| | | const params = { |
| | | word_order_type: this.filters.type || undefined, |
| | | status: currentTab?.name === 'myTickets' ? undefined : |
| | | this.filters.status !== "" ? Number(this.filters.status) : |
| | | currentTab?.value, // 使用当前tab的状态值 |
| | | status: |
| | | currentTab?.name === 'myTickets' |
| | | ? undefined |
| | | : this.filters.status !== '' |
| | | ? Number(this.filters.status) |
| | | : currentTab?.value, // 使用当前tab的状态值 |
| | | keyword: this.filters.keyword || undefined, |
| | | dept_id: this.filters.department || undefined, |
| | | start_date: this.filters.dateRange?.[0] ? this.formatDate(this.filters.dateRange[0]) : undefined, |
| | | end_date: this.filters.dateRange?.[1] ? this.formatDate(this.filters.dateRange[1]) : undefined, |
| | | start_date: this.filters.dateRange?.[0] |
| | | ? this.formatDate(this.filters.dateRange[0]) |
| | | : undefined, |
| | | end_date: this.filters.dateRange?.[1] |
| | | ? this.formatDate(this.filters.dateRange[1]) |
| | | : undefined, |
| | | current: 1, |
| | | size: 10 |
| | | size: 10, |
| | | } |
| | | |
| | | const response = await getList(params) |
| | |
| | | // 使用与查询列表相同的过滤逻辑 |
| | | let filteredRecords = records |
| | | if (currentTab?.name === 'myTickets') { |
| | | filteredRecords = records.filter(item => |
| | | String(item.create_user_id) === String(item.user_id) |
| | | filteredRecords = records.filter( |
| | | item => String(item.create_user_id) === String(item.user_id) |
| | | ) |
| | | } |
| | | |
| | |
| | | 发起时间: item.create_time || '', |
| | | 关联算法: item.ai_types || '', |
| | | 工单内容: item.address || '', |
| | | 工单类型: this.types.find(t => t.value === item.work_order_type_dict_key)?.label || '', |
| | | 经纬度: (!isNaN(longitude) && !isNaN(latitude)) ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` : '', |
| | | 工单类型: |
| | | this.types.find(t => t.value === item.work_order_type_dict_key)?.label || '', |
| | | 经纬度: |
| | | !isNaN(longitude) && !isNaN(latitude) |
| | | ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` |
| | | : '', |
| | | 创建人: item.create_user || '', |
| | | 处理人: item.update_user || '', |
| | | 工单状态: this.mapStatus(Number(item.status || 0)) |
| | | 工单状态: this.mapStatus(Number(item.status || 0)), |
| | | } |
| | | }) |
| | | } |
| | |
| | | '经纬度', |
| | | '创建人', |
| | | '处理人', |
| | | '工单状态' |
| | | '工单状态', |
| | | ] |
| | | |
| | | export_json_to_excel(headers, exportData, '工单数据') |
| | |
| | | // 保持最新的文件列表 |
| | | this.form.photos = fileList.map(item => ({ |
| | | ...item, |
| | | existingUrl: item.url && !item.raw ? item.url : null // 标记已存在的图片URL |
| | | existingUrl: item.url && !item.raw ? item.url : null, // 标记已存在的图片URL |
| | | })) |
| | | this.currentDetail.photos = this.form.photos |
| | | }, |
| | |
| | | if (this.currentDetail.status !== 3) { |
| | | this.$message.warning('只有处理中状态的工单可以提交处理详情') |
| | | return |
| | | |
| | | } |
| | | |
| | | try { |
| | |
| | | } |
| | | }, |
| | | markAsCompleted () { |
| | | this.$message.success("工单已标记为完成") |
| | | this.$message.success('工单已标记为完成') |
| | | }, |
| | | async completeTicket () { |
| | | if (this.completeLoading) return |
| | |
| | | return |
| | | } |
| | | |
| | | |
| | | const data = { |
| | | id: this.currentDetail.id, |
| | | status: this.currentDetail.status, |
| | | processingDetails: this.currentDetail.processingDetail, |
| | | eventNum: this.currentDetail.orderNumber |
| | | eventNum: this.currentDetail.orderNumber, |
| | | } |
| | | |
| | | // 如果有上传的图片,添加到请求中 |
| | |
| | | return |
| | | } |
| | | this.dispatchLoading = true |
| | | this.$refs.dispatchForm.validate(async (valid) => { |
| | | this.$refs.dispatchForm.validate(async valid => { |
| | | if (valid) { |
| | | try { |
| | | const data = { |
| | |
| | | createDept: this.dispatchForm.department, // 派发部门 ID |
| | | updateUser: this.dispatchForm.handler, // 处理人 ID |
| | | } |
| | | |
| | | |
| | | const file = this.currentDetail.file || null // 如果没有文件,则为 null |
| | | |
| | |
| | | console.log('编辑原始数据:', row) |
| | | |
| | | // 尝试从row.dept_id或通过部门名称查找对应的部门ID |
| | | let deptId = row.dept_id // 优先使用原始数据中的dept_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 => |
| | | dept.label && dept.label.trim() === row.department.trim() |
| | | const deptInfo = this.departments.find( |
| | | dept => dept.label && dept.label.trim() === row.department.trim() |
| | | ) |
| | | deptId = deptInfo?.value |
| | | } |
| | | |
| | | // 获取工单类型值 - 从types中找到匹配的值 |
| | | const typeValue = this.types.find(t => t.label === row.type)?.value || row.work_order_type_dict_key |
| | | const typeValue = |
| | | this.types.find(t => t.label === row.type)?.value || row.work_order_type_dict_key |
| | | |
| | | // 获取处理人ID - 使用userNameToIdMap映射 |
| | | const handlerId = this.userNameToIdMap[row.handler] || row.handler |
| | |
| | | 原始处理人: row.handler, |
| | | 处理人ID: handlerId, |
| | | 原始工单类型: row.type, |
| | | 映射后类型值: typeValue |
| | | 映射后类型值: typeValue, |
| | | }) |
| | | |
| | | // 修改算法数组的处理逻辑 |
| | |
| | | } |
| | | |
| | | // 确保算法值与选项匹配 |
| | | algorithmArr = algorithmArr.map(item => { |
| | | // 如果是字符串值,尝试找到对应的 dict_key |
| | | if (typeof item === 'string') { |
| | | const matchedAlgorithm = this.algorithms.find( |
| | | algo => algo.dict_value === item || algo.dict_key === item |
| | | ) |
| | | return matchedAlgorithm ? matchedAlgorithm.dict_key : item |
| | | } |
| | | return item |
| | | }).filter(Boolean) // 过滤掉无效值 |
| | | algorithmArr = algorithmArr |
| | | .map(item => { |
| | | // 如果是字符串值,尝试找到对应的 dict_key |
| | | if (typeof item === 'string') { |
| | | const matchedAlgorithm = this.algorithms.find( |
| | | algo => algo.dict_value === item || algo.dict_key === item |
| | | ) |
| | | return matchedAlgorithm ? matchedAlgorithm.dict_key : item |
| | | } |
| | | return item |
| | | }) |
| | | .filter(Boolean) // 过滤掉无效值 |
| | | |
| | | console.log('算法处理:', { |
| | | 原始值: row.aiType, |
| | |
| | | department: deptId, |
| | | handler: handlerId, |
| | | algorithm: algorithmArr, |
| | | location: Array.isArray(row.location) && row.location.length >= 2 |
| | | ? [Number(row.location[0]), Number(row.location[1])] |
| | | : [], |
| | | location: |
| | | Array.isArray(row.location) && row.location.length >= 2 |
| | | ? [Number(row.location[0]), Number(row.location[1])] |
| | | : [], |
| | | address: row.address || '', |
| | | content: row.content, |
| | | photos: [], |
| | |
| | | if (Array.isArray(row.location) && row.location.length >= 2) { |
| | | let [lng, lat] = this.disposeLocation(false, row) |
| | | |
| | | curLocation = [ |
| | | lng, |
| | | lat, |
| | | row.location[2] || row.address || '' |
| | | ] |
| | | curLocation = [lng, lat, row.location[2] || row.address || ''] |
| | | } |
| | | |
| | | this.form.location = curLocation |
| | |
| | | // 如果有图片,添加到表单中 |
| | | if (row.photo_url) { |
| | | // 创建一个带有必要信息的文件对象 |
| | | this.form.photos = [{ |
| | | name: 'existing-photo.jpg', // 添加默认扩展名 |
| | | url: row.photo_url, // 用于预览的URL |
| | | status: 'success', // 标记为已上传成功 |
| | | raw: null, // 初始化为null |
| | | existingUrl: row.photo_url // 保存原始URL,用于区分是否为已存在的图片 |
| | | }] |
| | | this.form.photos = [ |
| | | { |
| | | name: 'existing-photo.jpg', // 添加默认扩展名 |
| | | url: row.photo_url, // 用于预览的URL |
| | | status: 'success', // 标记为已上传成功 |
| | | raw: null, // 初始化为null |
| | | existingUrl: row.photo_url, // 保存原始URL,用于区分是否为已存在的图片 |
| | | }, |
| | | ] |
| | | } |
| | | |
| | | // 调试输出 |
| | | console.log('编辑表单数据:', { |
| | | 原始算法值: row.aiType, |
| | | 处理后算法值: algorithmArr, |
| | | 表单数据: this.form |
| | | 表单数据: this.form, |
| | | }) |
| | | |
| | | this.dialogVisible = true |
| | |
| | | this.$confirm('确认删除该工单?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(async () => { |
| | | try { |
| | | const response = await flowEvent({ |
| | | id: row.id, |
| | | status: 0, |
| | | isDelete: 1 |
| | | }) |
| | | type: 'warning', |
| | | }) |
| | | .then(async () => { |
| | | try { |
| | | const response = await flowEvent({ |
| | | id: row.id, |
| | | status: 0, |
| | | isDelete: 1, |
| | | }) |
| | | |
| | | if (response.data.code === 0) { |
| | | this.$message.success('删除成功') |
| | | this.fetchTableData() |
| | | } else { |
| | | throw new Error(response.data.msg || '删除失败') |
| | | if (response.data.code === 0) { |
| | | this.$message.success('删除成功') |
| | | this.fetchTableData() |
| | | } else { |
| | | throw new Error(response.data.msg || '删除失败') |
| | | } |
| | | } catch (error) { |
| | | console.error('删除失败:', error) |
| | | this.$message.error(error.message || '删除失败,请稍后重试') |
| | | } |
| | | } catch (error) { |
| | | console.error('删除失败:', error) |
| | | this.$message.error(error.message || '删除失败,请稍后重试') |
| | | } |
| | | }).catch(() => { }) |
| | | }) |
| | | .catch(() => { }) |
| | | }, |
| | | |
| | | // 添加选择变化处理方法 |
| | |
| | | await this.$confirm('确认审核通过当前工单?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | type: 'warning', |
| | | }) |
| | | |
| | | const data = { |
| | |
| | | // 刷新表格数据 |
| | | // this.fetchTableData(); |
| | | this.selections = newSelections |
| | | |
| | | } else { |
| | | throw new Error(response.data.msg || '审核失败') |
| | | } |
| | |
| | | await this.$confirm('确认该工单审核不通过?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | type: 'warning', |
| | | }) |
| | | |
| | | const data = { |
| | |
| | | |
| | | // 获取所有图片列表用于预览 |
| | | getImageList () { |
| | | return this.selections |
| | | .map(item => this.getPreviewUrl(item.photo_url)) |
| | | .filter(url => url) // 过滤掉空值 |
| | | return this.selections.map(item => this.getPreviewUrl(item.photo_url)).filter(url => url) // 过滤掉空值 |
| | | }, |
| | | |
| | | // 处理图片点击 |
| | |
| | | reCheckConfirm (key) { |
| | | const that = this |
| | | if (key == 1) { |
| | | getReviewById(this.reCheckData.id).then(res => { |
| | | this.reCheckDialog = false |
| | | this.page.currentPage = 1 |
| | | this.fetchTableData() |
| | | this.fetchTabCounts() |
| | | getReviewById(that.reCheckData.id).then(res => { |
| | | that.reCheckDialog = false |
| | | that.page.currentPage = 1 |
| | | that.fetchTableData() |
| | | that.fetchTabCounts() |
| | | }) |
| | | } else { |
| | | |
| | | const loading = ElLoading.service({ |
| | | lock: true, |
| | | text: '复核任务创建中……', |
| | | background: 'rgba(0, 0, 0, 0.7)', |
| | | }) |
| | | |
| | | function closeConfirm () { |
| | | that.reCheckDialog = false |
| | | that.page.currentPage = 1 |
| | | that.fetchTableData() |
| | | that.fetchTabCounts() |
| | | loading.close() |
| | | } |
| | | |
| | | // 获取时间的接口 |
| | | getCreateEventJob(that.reCheckData.id).then(res => { |
| | | loading.close() |
| | | |
| | | ElMessageBox.confirm(`预计复核执行时间为${res.data.data}`, '提示', { |
| | | confirmButtonText: '确定', |
| | | showCancelButton: false, // 关键配置 |
| | | type: 'warning' |
| | | closeOnClickModal: false, |
| | | closeOnPressEscape: false, |
| | | type: 'warning', |
| | | }).then(() => { |
| | | this.reCheckDialog = false |
| | | this.page.currentPage = 1 |
| | | this.fetchTableData() |
| | | this.fetchTabCounts() |
| | | closeConfirm() |
| | | }).catch(() => { |
| | | closeConfirm() |
| | | }) |
| | | }).catch(() => { |
| | | closeConfirm() |
| | | }) |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | |
| | | |
| | | // 添加删除按钮样式 |
| | | .danger-button { |
| | | color: #F56C6C; |
| | | color: #f56c6c; |
| | | } |
| | | |
| | | .danger-button:hover { |
| | |
| | | :deep(.el-dialog__body) { |
| | | padding: 0; |
| | | background-color: #f5f7fa; |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | display: inline-block; |
| | | |
| | | .required-star { |
| | | color: #F56C6C; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | |
| | | :deep(.el-input__inner), |
| | | :deep(.el-textarea__inner) { |
| | | &:focus { |
| | | border-color: #409EFF; |
| | | border-color: #409eff; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | </style> |