| | |
| | | <basic-container> |
| | | <el-tabs v-model="activeTab" @tab-click="handleTabChange"> |
| | | <el-tab-pane v-for="tab in filteredTabs" :key="tab.name" :label="`${tab.label} (${tab.count})`" :name="tab.name"> |
| | | <div class="tab-content"> |
| | | <basic-main-content> |
| | | <!-- 查询条件筛选栏 --> |
| | | <div class="filter-bar"> |
| | | <el-input v-model="filters.keyword" placeholder="请输入关键字" class="filter-item" clearable |
| | |
| | | <!-- 表格部分 --> |
| | | <avue-crud ref="avueCrud" v-model="tableData" :option="option" :data="tableData" v-model:page="page" |
| | | @size-change="sizeChange" @current-change="handleCurrentChange" :table-loading="loading" |
| | | @selection-change="handleSelectionChange" :permission="permissionList"> |
| | | @selection-change="handleSelectionChange" :permission="permissionList" v-if="activeTab === tab.name"> |
| | | <template #menu-left> |
| | | <el-button v-if="(activeTab === 'all' || activeTab === 'myTickets') && permissionList.addBtn" |
| | | type="primary" icon="el-icon-plus" @click="handleAdd">新建工单</el-button> |
| | |
| | | <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button> |
| | | </template> |
| | | |
| | | <el-button v-if="row.status === 4 && row.isReview !== 1" type="text" icon="el-icon-check" |
| | | @click="reCheck(row)">复核</el-button> |
| | | <template v-if="permission.tickets_repeat_review"> |
| | | <el-button v-if="row.status === 4 && row.isReview !== 1" type="text" icon="el-icon-check" |
| | | @click="reCheck(row)">复核</el-button> |
| | | </template> |
| | | |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <span :style="getStatusTagType(row.status) ? 'color:' + getStatusTagType(row.status) : ''"> |
| | |
| | | <span>{{ showIsReviewText(row) }}</span> |
| | | </template> |
| | | </avue-crud> |
| | | </div> |
| | | </basic-main-content> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- 新建工单对话框 --> |
| | | <el-dialog v-model="dialogVisible" title="新建工单" width="70%" :close-on-click-modal="false" @close="resetForm"> |
| | | <el-dialog v-model="dialogVisible" v-if="dialogVisible" title="新建工单" width="70%" :close-on-click-modal="false" |
| | | @close="resetForm"> |
| | | <el-form :model="form" :rules="rules" ref="form" label-width="90px" class="create-ticket-form"> |
| | | <div class="form-section"> |
| | | <el-row :gutter="16"> |
| | |
| | | <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="create-upload"> |
| | | :file-list="popupShowImage(form.photos)" :limit="1" accept="image/*" class="create-upload"> |
| | | <template v-if="form.photos.length < 1"> |
| | | <i class="el-icon-plus">+</i> |
| | | <!-- <i class="el-icon-plus">+</i> --> |
| | | <div class="el-icon-plus"> |
| | | <span>+</span> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | |
| | | <div class="upload-tip">需上传含有地址信息的照片(jpg、jpeg、png),且不超过5M</div> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | <!-- 工单详情对话框 --> |
| | | <el-dialog v-model="detailVisible" title="工单详情" width="80%" append-to-body> |
| | | <div class="detail-container"> |
| | | <div class="event-title-center">{{ currentDetail.orderName || '事件名称' }}</div> |
| | | <div class="detail-top-title"> <div class="event-title-center event-orderNumber">{{ currentDetail.orderNumber || '工单编号' }}</div> |
| | | <div class="event-title-center">{{ currentDetail.orderName || '事件名称' }}</div></div> |
| | | <div v-if="totalTime" class="event-total-time"> |
| | | 总耗时:{{ totalTime }} |
| | | </div> |
| | |
| | | :before-upload="beforeUpload" :file-list="currentDetail.photos || []" :limit="1" accept="image/*" |
| | | class="detail-upload"> |
| | | <template v-if="!currentDetail.photos || currentDetail.photos.length < 1"> |
| | | <i class="el-icon-plus">+</i> |
| | | <!-- <i class="el-icon-plus">+</i> --> |
| | | <div class="el-icon-plus"> |
| | | <span>+</span> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <div class="el-upload__tip" v-if="hasProcessedAndOverBtnPermission()"> |
| | |
| | | @close="reCheckDialog = false"> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="reCheckConfirm(1)">人工复核</el-button> |
| | | <el-button type="primary" @click="reCheckConfirm(2)">AI复核</el-button> |
| | | <el-button type="primary" @click="reCheckConfirm(2)">无人机复核</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getSmallImg,getShowImg } from '@/utils/util'; |
| | | import { ElMessageBox, ElLoading } from 'element-plus' |
| | | import { calculateDefaultRange } from '@/utils/util' |
| | | import { gcj02ToWgs84, wgs84ToGcj02 } from '@/utils/coordinateTransformation' |
| | |
| | | } 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) { |
| | |
| | | addBtn: false, |
| | | menu: true, |
| | | page: true, |
| | | |
| | | height: 'auto', |
| | | calcHeight: 196, |
| | | |
| | | column: [ |
| | | // { label: "序号", prop: "id", width: 70 }, |
| | | { label: '工单编号', prop: 'orderNumber', width: 120, overHidden: true, tooltip: true }, |
| | |
| | | |
| | | mounted () { |
| | | const href = this.$route.href |
| | | if (this.$route?.query?.status !== undefined && this.$route?.query?.status !== null){ |
| | | this.filters.status = this.$route?.query?.status + '' |
| | | this.$router.replace({}) |
| | | } |
| | | |
| | | let curQueryParams = {} |
| | | |
| | | if (href.indexOf('?') != -1 && href.split('?').length > 0) { |
| | |
| | | return '/' |
| | | } |
| | | }, |
| | | |
| | | popupShowImage () { |
| | | return (list) => { |
| | | |
| | | return list.map(item => ({ |
| | | ...item, |
| | | url: getShowImg(item.url) |
| | | })) |
| | | } |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | |
| | | if (response.data.code === 0) { |
| | | this.$message.success('草稿保存成功') |
| | | this.dialogVisible = false |
| | | this.form={ |
| | | name: '', |
| | | type: '', |
| | | department: '', |
| | | handler: '', |
| | | algorithm: [], // 关联算法改为数组 |
| | | location: [], // 将存储为[经度, 纬度, 地址]格式 |
| | | address: '', |
| | | photos: [], |
| | | content: '', // 新增字段,用于存储后端返回的 content |
| | | }, |
| | | this.fetchTableData() |
| | | } else { |
| | | throw new Error(response.data.msg || '保存失败') |
| | |
| | | |
| | | handleLocationChange (val) { |
| | | let locationValue = val.value |
| | | console.log('handleLocationChange', locationValue) |
| | | if (locationValue && locationValue.length >= 2) { |
| | | // 兼容第三项为地址 |
| | | this.form.location = [ |
| | | Number(locationValue[0]), |
| | | Number(locationValue[1]), |
| | | locationValue[2] || '', |
| | | ] |
| | | const [lng, lat] = gcj02ToWgs84(locationValue[0], locationValue[1]) |
| | | this.form.location = [Number(lng), Number(lat), locationValue[2] || '',] |
| | | this.form.address = locationValue[2] || '' |
| | | } else { |
| | | this.form.location = [] |
| | |
| | | |
| | | handleAdd () { |
| | | this.dialogVisible = true |
| | | this.mapParams.center = null |
| | | this.form.location = [] |
| | | }, |
| | | |
| | | resetForm () { |
| | |
| | | }, |
| | | |
| | | async handleViewDetail (row) { |
| | | |
| | | // 找到当前行在tableData中的索引 |
| | | this.currentIndex = this.tableData.findIndex(item => item.id === row.id) |
| | | // 先设置workType,直接从row读取 |
| | |
| | | }) |
| | | } |
| | | this.currentDetail.status = row.status |
| | | |
| | | |
| | | } catch (error) { |
| | | if (this.activeTab === 'myTickets') { |
| | | const statusArr = this.workType === 1 ? ['3', '4'] : this.fixedStatuses |
| | |
| | | } |
| | | |
| | | this.currentDetail = detailData |
| | | console.log('this.currentDetail',this.currentDetail); |
| | | this.detailVisible = true |
| | | this.$nextTick(() => { |
| | | if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) { |
| | |
| | | address: row.address || '', |
| | | content: row.content, |
| | | photos: [], |
| | | |
| | | } |
| | | |
| | | let curLocation = [] |
| | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | :deep() { |
| | | .avue-crud__body { |
| | | .el-form { |
| | | height: 655px; |
| | | overflow: auto; |
| | | ::v-deep(.el-tabs) { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .el-tabs__header { |
| | | order: 1; |
| | | } |
| | | |
| | | .el-tabs__content { |
| | | order: 2; |
| | | } |
| | | |
| | | .el-tabs__content { |
| | | height: 0; |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .el-tab-pane { |
| | | height: 0; |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .filter-bar { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | flex-wrap: wrap; |
| | | gap: 8px; // 使用 gap 统一设置间距 |
| | | |
| | | .filter-item { |
| | | width: 160px; // 减小宽度 |
| | | } |
| | | |
| | | .date-picker { |
| | | width: 240px; // 日期选择器宽度适当调整 |
| | | } |
| | | |
| | | .el-button { |
| | | margin-left: 0; // 覆盖 element-ui 默认的按钮间距 |
| | | } |
| | | } |
| | | |
| | |
| | | margin-bottom: 12px |
| | | } |
| | | |
| | | .tab-content { |
| | | padding: 10px; |
| | | } |
| | | |
| | | .filter-bar { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | flex-wrap: wrap; |
| | | gap: 8px; // 使用 gap 统一设置间距 |
| | | |
| | | .filter-item { |
| | | width: 160px; // 减小宽度 |
| | | } |
| | | |
| | | .date-picker { |
| | | width: 240px; // 日期选择器宽度适当调整 |
| | | } |
| | | |
| | | .el-button { |
| | | margin-left: 0; // 覆盖 element-ui 默认的按钮间距 |
| | | } |
| | | } |
| | | |
| | | .action-bar { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .el-tabs { |
| | | :deep(.el-tabs__content) { |
| | | overflow: visible; |
| | | } |
| | | } |
| | | |
| | | .tab-content { |
| | | min-height: 200px; |
| | | } |
| | | |
| | | .detail-form { |
| | | :deep(.el-form-item) { |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | :deep(.el-form-item__label) { |
| | | color: #606266; |
| | | font-weight: normal; |
| | | } |
| | | |
| | | :deep(.el-form-item__content) { |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | .el-dialog { |
| | |
| | | |
| | | .detail-container { |
| | | padding: 20px; |
| | | .detail-top-title { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | .event-orderNumber{ |
| | | margin-right: 10px;} |
| | | } |
| | | } |
| | | |
| | | .status-flow { |