Merge remote-tracking branch 'origin/feature/v5.0/5.0.5' into feature/v5.0/5.0.5
13 files modified
1 files added
| | |
| | | <svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| | | <g id="Group 1321315688"> |
| | | <g id="Frame" clip-path="url(#clip0_1238_1817)"> |
| | | <g id="Frame_2" clip-path="url(#clip1_1238_1817)"> |
| | | <path id="Vector" d="M4.83697 10.163H3.10692V8.43298H1.37593V11.029H3.10692V11.894H4.83697V11.029H6.56795V8.43298H4.83697V10.163ZM12.625 8.43298H7.43298V13.625H12.625V8.43298ZM10.894 10.164V11.8949H9.16303V10.163L10.894 10.164ZM12.625 2.375H7.43298V7.56982H12.625V2.375ZM10.894 4.10598V5.83697H9.16303V4.10598H10.894ZM6.56702 2.375H1.375V7.56982H6.56795L6.56702 2.375ZM4.83604 4.10598V5.83697H3.10692V4.10598H4.83604ZM3.10692 11.894H1.37593V13.625H3.10692V11.894ZM6.56795 11.894H4.83697V13.625H6.56795V11.894Z" fill="#212121"/> |
| | | <g id="Group 1321316147"> |
| | | <g id="Frame" clip-path="url(#clip0_1360_1927)"> |
| | | <g id="Frame_2" clip-path="url(#clip1_1360_1927)"> |
| | | <path id="Vector" d="M4.83697 10.163H3.10692V8.43298H1.37593V11.029H3.10692V11.894H4.83697V11.029H6.56795V8.43298H4.83697V10.163ZM12.625 8.43298H7.43298V13.625H12.625V8.43298ZM10.894 10.164V11.8949H9.16303V10.163L10.894 10.164ZM12.625 2.375H7.43298V7.56982H12.625V2.375ZM10.894 4.10598V5.83697H9.16303V4.10598H10.894ZM6.56702 2.375H1.375V7.56982H6.56795L6.56702 2.375ZM4.83604 4.10598V5.83697H3.10692V4.10598H4.83604ZM3.10692 11.894H1.37593V13.625H3.10692V11.894ZM6.56795 11.894H4.83697V13.625H6.56795V11.894Z" fill="#1B94FF"/> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | <defs> |
| | | <clipPath id="clip0_1238_1817"> |
| | | <clipPath id="clip0_1360_1927"> |
| | | <rect width="11" height="11" fill="white" transform="translate(1.5 2.13086)"/> |
| | | </clipPath> |
| | | <clipPath id="clip1_1238_1817"> |
| | | <clipPath id="clip1_1360_1927"> |
| | | <rect width="12" height="12" fill="white" transform="matrix(-1 0 0 1 13 2)"/> |
| | | </clipPath> |
| | | </defs> |
| New file |
| | |
| | | <svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| | | <g id="Group 1321315688"> |
| | | <g id="Frame" clip-path="url(#clip0_1238_1817)"> |
| | | <g id="Frame_2" clip-path="url(#clip1_1238_1817)"> |
| | | <path id="Vector" d="M4.83697 10.163H3.10692V8.43298H1.37593V11.029H3.10692V11.894H4.83697V11.029H6.56795V8.43298H4.83697V10.163ZM12.625 8.43298H7.43298V13.625H12.625V8.43298ZM10.894 10.164V11.8949H9.16303V10.163L10.894 10.164ZM12.625 2.375H7.43298V7.56982H12.625V2.375ZM10.894 4.10598V5.83697H9.16303V4.10598H10.894ZM6.56702 2.375H1.375V7.56982H6.56795L6.56702 2.375ZM4.83604 4.10598V5.83697H3.10692V4.10598H4.83604ZM3.10692 11.894H1.37593V13.625H3.10692V11.894ZM6.56795 11.894H4.83697V13.625H6.56795V11.894Z" fill="#212121"/> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | <defs> |
| | | <clipPath id="clip0_1238_1817"> |
| | | <rect width="11" height="11" fill="white" transform="translate(1.5 2.13086)"/> |
| | | </clipPath> |
| | | <clipPath id="clip1_1238_1817"> |
| | | <rect width="12" height="12" fill="white" transform="matrix(-1 0 0 1 13 2)"/> |
| | | </clipPath> |
| | | </defs> |
| | | </svg> |
| | |
| | | |
| | | async function initMap () { |
| | | if (viewer) return |
| | | publicCesiumInstance = new PublicCesium({ dom: 'viewer-container' }) |
| | | publicCesiumInstance = new PublicCesium({ dom: 'viewer-container',layerMode: 4 }) |
| | | viewer = publicCesiumInstance.getViewer() |
| | | |
| | | initViewer(viewer) |
| | |
| | | |
| | | // 定位到点位 |
| | | const points = [[lng, lat]] // 确保格式为二维数组 |
| | | flyVisual(points, viewer, 4) |
| | | flyVisual({ positionsData:points, viewer,multiple: 10 }) |
| | | } |
| | | |
| | | /** |
| | |
| | | height: 50, |
| | | }, |
| | | }) |
| | | |
| | | flyVisual( |
| | | pointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)]), |
| | | flyVisual({ |
| | | positionsData:pointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)]), |
| | | viewer, |
| | | 20 |
| | | ) |
| | | multiple: 20 |
| | | }) |
| | | } |
| | | |
| | | function removePreviewLine () { |
| | |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | <el-dropdown class="avue-tags__menu"> |
| | | <el-button type="primary"> |
| | | <el-button type="primary" style="background: #409eff;border-color: #409eff"> |
| | | {{ $t('tagsView.menu') }} |
| | | <i class="el-icon-arrow-down el-icon--right"></i> |
| | | </el-button> |
| | |
| | | export function flyVisual({ positionsData, viewer, multiple = 4, pitch = -90 }) { |
| | | if (!Array.isArray(positionsData) || positionsData.length === 0) return |
| | | |
| | | // 如果是一个点,加两个点方便后续生成外包围盒 |
| | | if (positionsData.length === 1){ |
| | | const [lon,lat,height] = positionsData[0] |
| | | positionsData = [[lon+0.001,lat+0.001,height],[lon-0.001,lat-0.001,height],[lon,lat,height]] |
| | | } |
| | | const positions = positionsData.map(([lon, lat, height]) => |
| | | Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height || 0)) |
| | | ) |
| | |
| | | range: boundingSphere.radius * multiple, |
| | | }, |
| | | complete: () => { |
| | | // 飞行完成后检查相机高度是否小于最高点 |
| | | // 飞行完成后检查相机高度是否小于最高点,如果小于直接飞到最高点 |
| | | const cameraHeight = Cesium.Cartographic.fromCartesian(viewer.camera.position).height |
| | | if (cameraHeight < maxHeight) { |
| | | viewer.camera.flyTo({ |
| | |
| | | flatMode: false, |
| | | terrain: false, |
| | | mapFilter: true, |
| | | layerMode: 4 |
| | | }); |
| | | viewer = publicCesiumInstance.getViewer(); |
| | | viewerRef.value = viewer; |
| | |
| | | <!-- 文件夹 --> |
| | | <div v-if="switchFolders" class="dataTable"> |
| | | <el-table |
| | | |
| | | class="custom-header custom-body" |
| | | v-loading="loadings" |
| | | element-loading-text="" |
| | |
| | | }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column property="name" label="任务名称" show-overflow-tooltip /> |
| | | <el-table-column property="recordName" label="任务名称" show-overflow-tooltip /> |
| | | <el-table-column property="regionName" label="所属区域"> |
| | | <template #default="scope"> |
| | | <span>{{scope.row.city_name ? scope.row.city_name :'--'}},{{scope.row.area_name ? scope.row.area_name :'--'}}</span> |
| | |
| | | <!-- 表格部分 --> |
| | | <div class="dataTable" v-else> |
| | | <el-table |
| | | border |
| | | v-loading="loadings" |
| | | element-loading-text="" |
| | | :data="tableData" |
| | |
| | | flatMode: false, |
| | | terrain: false, |
| | | mapFilter: true, |
| | | layerMode: 4 |
| | | }); |
| | | viewer = viewInstance.value.getViewer(); |
| | | viewerRef.value = viewer; |
| | |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | .el-tag:first-child{ |
| | | margin-bottom: 5px;} |
| | | } |
| | | |
| | | .onlineStatus { |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" ref="crud" @row-del="rowDel" |
| | | v-model="form" :permission="permissionList" @row-update="rowUpdate" @row-save="rowSave" :before-open="beforeOpen" |
| | | @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange" |
| | | @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad"> |
| | | <avue-crud |
| | | :option="option" |
| | | :table-loading="loading" |
| | | :data="data" |
| | | v-model:page="page" |
| | | ref="crud" |
| | | @row-del="rowDel" |
| | | v-model="form" |
| | | :permission="permissionList" |
| | | @row-update="rowUpdate" |
| | | @row-save="rowSave" |
| | | :before-open="beforeOpen" |
| | | :before-close="beforeClose" |
| | | @search-change="searchChange" |
| | | @search-reset="searchReset" |
| | | @selection-change="selectionChange" |
| | | @current-change="currentChange" |
| | | @size-change="sizeChange" |
| | | @refresh-change="refreshChange" |
| | | @on-load="onLoad" |
| | | > |
| | | <template #menu-left> |
| | | <!-- <el-button |
| | | type="danger" |
| | |
| | | {{ formatSeconds(row.processingTime) }} |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-button type="primary" text icon="el-icon-guide" |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="el-icon-guide" |
| | | v-if="permission.odm_task_handle && scope.row.taskId == null" |
| | | @click.stop="atHandle(scope.row, scope.index)">立即启动 |
| | | @click.stop="atHandle(scope.row, scope.index)" |
| | | >立即启动 |
| | | </el-button> |
| | | <el-button type="primary" text icon="el-icon-refresh-right" |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="el-icon-refresh-right" |
| | | v-if="(permission.odm_task_handle && scope.row.status == 30) || scope.row.status == 50" |
| | | @click.stop="restartHandle(scope.row, scope.index)">重新启动 |
| | | @click.stop="restartHandle(scope.row, scope.index)" |
| | | >重新启动 |
| | | </el-button> |
| | | </template> |
| | | </avue-crud> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList, remove, update, add, createOdmTask, restartOdmTask } from '@/api/odm/task' |
| | | import { tourStrategies } from 'element-plus' |
| | | import { mapGetters } from 'vuex' |
| | | import { getList, remove, update, add, createOdmTask, restartOdmTask } from '@/api/odm/task'; |
| | | import { tourStrategies } from 'element-plus'; |
| | | import { mapGetters } from 'vuex'; |
| | | |
| | | export default { |
| | | data () { |
| | |
| | | label: '任务名称', |
| | | prop: 'taskName', |
| | | search: true, |
| | | labelWidth: 130, |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | //labelWidth: 130, |
| | | searchPlaceholder: "任务名称", |
| | | searchPlaceholder: '任务名称', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | |
| | | searchLabelWidth: 100, |
| | | //width: 100, |
| | | labelWidth: 130, |
| | | searchPlaceholder: "任务类型", |
| | | searchPlaceholder: '任务类型', |
| | | dicData: [ |
| | | { |
| | | label: '航测', |
| | |
| | | value: 4, |
| | | }, |
| | | ], |
| | | change: (value) => { |
| | | change: value => { |
| | | this.searchChange({ ...this.query,waylineType:value.value}, () => {}); |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: '机场名称', |
| | | prop: 'airportName', |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | labelWidth: 130, |
| | | //search: true, |
| | | }, |
| | | { |
| | |
| | | search: true, |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | searchPlaceholder: "任务状态", |
| | | searchPlaceholder: '任务状态', |
| | | labelWidth: 130, |
| | | width: 90, |
| | | dicData: [ |
| | | { label: '待启动', value: 0 }, |
| | |
| | | { label: '已完成', value: 40 }, |
| | | { label: '已取消', value: 50 }, |
| | | ], |
| | | change: (value) => { |
| | | change: value => { |
| | | this.searchChange({ ...this.query,status:value.value}, () => {}); |
| | | } |
| | | }, |
| | | }, |
| | | |
| | | { |
| | |
| | | { |
| | | label: '完成时间', |
| | | prop: 'completedTime', |
| | | type: "date", |
| | | type: 'date', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | searchPlaceholder: "任务完成时间", |
| | | searchPlaceholder: '任务完成时间', |
| | | labelWidth: 130, |
| | | search: true, |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | //valueFormat: 'YYYY-MM-DD', |
| | | width: 160, |
| | | change: (value) => { |
| | | change: value => { |
| | | this.searchChange({ ...this.query,completedTime:value.value}, () => {}); |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | data: [], |
| | | } |
| | | isClickSearch: true, |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapGetters(['permission']), |
| | |
| | | viewBtn: this.validData(this.permission.odm_task_view, true), |
| | | delBtn: this.validData(this.permission.odm_task_delete, true), |
| | | // editBtn: this.validData(this.permission.workspace_edit, true), |
| | | } |
| | | }; |
| | | }, |
| | | ids () { |
| | | let ids = [] |
| | | let ids = []; |
| | | this.selectionList.forEach(ele => { |
| | | ids.push(ele.id) |
| | | }) |
| | | return ids.join(',') |
| | | ids.push(ele.id); |
| | | }); |
| | | return ids.join(','); |
| | | }, |
| | | }, |
| | | methods: { |
| | |
| | | atHandle (row) { |
| | | createOdmTask(row.waylineJobId, row.gsd).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | // 重启启动 |
| | | restartHandle (row) { |
| | |
| | | this.$message({ |
| | | type: 'error', |
| | | message: '该航线任务已删除,无法进行重启启动!', |
| | | }) |
| | | return |
| | | }); |
| | | return; |
| | | } |
| | | restartOdmTask(row.taskId).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | // 时间格式化 |
| | | formatSeconds (value) { |
| | | // 如果value不是数字或者小于0,则直接返回'00:00:00' |
| | | if (isNaN(value) || value < 0) { |
| | | return '00:00:00' |
| | | return '00:00:00'; |
| | | } |
| | | |
| | | // 计算小时、分钟和秒 |
| | | let seconds = Math.floor(value / 1000) |
| | | let minutes = Math.floor(seconds / 60) |
| | | let hours = Math.floor(minutes / 60) |
| | | let seconds = Math.floor(value / 1000); |
| | | let minutes = Math.floor(seconds / 60); |
| | | let hours = Math.floor(minutes / 60); |
| | | |
| | | // 格式化为两位数字的字符串 |
| | | seconds %= 60 |
| | | minutes %= 60 |
| | | seconds %= 60; |
| | | minutes %= 60; |
| | | |
| | | const formattedTime = `${this.padZero(hours)}:${this.padZero(minutes)}:${this.padZero( |
| | | seconds |
| | | )}` |
| | | )}`; |
| | | |
| | | // 返回格式化后的时间字符串 |
| | | return formattedTime |
| | | return formattedTime; |
| | | }, |
| | | // 函数用于在数字不足两位数时,在前面补零 |
| | | padZero (value) { |
| | | return String(value).padStart(2, '0') |
| | | return String(value).padStart(2, '0'); |
| | | }, |
| | | rowSave (row, done, loading) { |
| | | add(row).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | rowUpdate (row, index, done, loading) { |
| | | update(row).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | rowDel (row) { |
| | | this.$confirm('确定将选择数据删除?', { |
| | |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(row.id) |
| | | return remove(row.id); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | }) |
| | | }); |
| | | }); |
| | | }, |
| | | searchReset () { |
| | | this.query = {} |
| | | this.onLoad(this.page) |
| | | this.query = {}; |
| | | this.onLoad(this.page); |
| | | }, |
| | | searchChange (params, done) { |
| | | this.query = params |
| | | this.page.currentPage = 1 |
| | | this.onLoad(this.page, params) |
| | | done() |
| | | if (!this.isClickSearch) return; |
| | | |
| | | this.query = params; |
| | | this.page.currentPage = 1; |
| | | this.onLoad(this.page, params); |
| | | done(); |
| | | }, |
| | | selectionChange (list) { |
| | | this.selectionList = list |
| | | this.selectionList = list; |
| | | }, |
| | | selectionClear () { |
| | | this.selectionList = [] |
| | | this.$refs.crud.toggleSelection() |
| | | this.selectionList = []; |
| | | this.$refs.crud.toggleSelection(); |
| | | }, |
| | | handleDelete () { |
| | | if (this.selectionList.length === 0) { |
| | | this.$message.warning('请选择至少一条数据') |
| | | return |
| | | this.$message.warning('请选择至少一条数据'); |
| | | return; |
| | | } |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(this.ids) |
| | | return remove(this.ids); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | this.$refs.crud.toggleSelection() |
| | | }) |
| | | }); |
| | | this.$refs.crud.toggleSelection(); |
| | | }); |
| | | }, |
| | | beforeOpen (done, type) { |
| | | // if (['edit', 'view'].includes(type)) { |
| | |
| | | // this.form = res.data.data; |
| | | // }); |
| | | // } |
| | | done() |
| | | this.isClickSearch = false; |
| | | |
| | | done(); |
| | | }, |
| | | |
| | | beforeClose(done, type) { |
| | | this.isClickSearch = true; |
| | | |
| | | done(); |
| | | }, |
| | | |
| | | currentChange (currentPage) { |
| | | this.page.currentPage = currentPage |
| | | this.page.currentPage = currentPage; |
| | | }, |
| | | sizeChange (pageSize) { |
| | | this.page.pageSize = pageSize |
| | | this.page.pageSize = pageSize; |
| | | }, |
| | | refreshChange () { |
| | | this.onLoad(this.page, this.query) |
| | | this.onLoad(this.page, this.query); |
| | | }, |
| | | onLoad (page, params = {}) { |
| | | const { releaseTimeRange } = this.query |
| | | const { releaseTimeRange } = this.query; |
| | | |
| | | let values = { |
| | | ...params, |
| | | ...this.query, |
| | | } |
| | | }; |
| | | if (releaseTimeRange) { |
| | | values = { |
| | | ...values, |
| | | releaseTime_datege: releaseTimeRange[0], |
| | | releaseTime_datelt: releaseTimeRange[1], |
| | | }; |
| | | values.releaseTimeRange = null; |
| | | } |
| | | values.releaseTimeRange = null |
| | | } |
| | | this.loading = true |
| | | this.loading = true; |
| | | getList(page.currentPage, page.pageSize, values).then(res => { |
| | | const data = res.data.data |
| | | this.page.total = data.total |
| | | this.data = data.records |
| | | this.loading = false |
| | | this.selectionClear() |
| | | }) |
| | | const data = res.data.data; |
| | | this.page.total = data.total; |
| | | this.data = data.records; |
| | | this.loading = false; |
| | | this.selectionClear(); |
| | | }); |
| | | }, |
| | | }, |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | |
| | | }); |
| | | // 校验手机号 |
| | | const validatePhone = () => { |
| | | const phoneRegex = /^1[3-9]\d{9}$/; |
| | | if (!phoneRegex.test(userInfo.value.phone)) { |
| | | ElMessage.error('请输入正确的手机号码'); |
| | | return false; |
| | | const phone = userInfo.value.phone |
| | | if (!phone) return true |
| | | const phoneRegex = /^1[3-9]\d{9}$/ |
| | | if (!phoneRegex.test(phone)) { |
| | | ElMessage.error('请输入正确的手机号码') |
| | | return false |
| | | } |
| | | return true; |
| | | }; |
| | | return true |
| | | } |
| | | // 校验邮箱 |
| | | const validateEmail = () => { |
| | | if (!userInfo.value.email) return true // 允许为空 |
| | |
| | | |
| | | align: 'center', |
| | | border: true, |
| | | stripe: true, |
| | | stripe: false, |
| | | searchShow: true, |
| | | searchBtnText: '搜索', |
| | | searchMenuSpan: 6, |
| | |
| | | </div> |
| | | |
| | | <!-- 表格部分 --> |
| | | <avue-crud class="ztzf-public-general-avue-crud" ref="avueCrud" v-model="tableData" :option="option" |
| | | :data="tableData" v-model:page="page" @size-change="sizeChange" @current-change="handleCurrentChange" |
| | | @refresh-change="refreshChange" :table-loading="loading" @selection-change="handleSelectionChange" |
| | | :permission="permissionList" v-if="activeTab === tab.name"> |
| | | <avue-crud |
| | | class="ztzf-public-general-avue-crud" |
| | | ref="avueCrud" |
| | | v-model="tableData" |
| | | :option="option" |
| | | :data="tableData" |
| | | v-model:page="page" |
| | | @size-change="sizeChange" |
| | | @current-change="handleCurrentChange" |
| | | @refresh-change="refreshChange" |
| | | :table-loading="loading" |
| | | @selection-change="handleSelectionChange" |
| | | :permission="permissionList" |
| | | v-if="activeTab === tab.name" |
| | | > |
| | | <template #orderNumber="{ row }"> |
| | | <el-tooltip-copy :content="row.orderNumber" :showCopyText="true" textAlign="left"> |
| | | {{ row.orderNumber }} |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="工单类型" prop="type"> |
| | | |
| | | <el-select @change="handleTypeChange" v-model="form.type" placeholder="请选择工单类型" class="full-width" > |
| | | <el-select |
| | | @change="handleTypeChange" |
| | | v-model="form.type" |
| | | placeholder="请选择工单类型" |
| | | class="full-width" |
| | | > |
| | | <el-option |
| | | v-for="item in types" |
| | | :key="item.value" |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | |
| | | <el-button type="danger" :loading="submitLoading" @click="submitForm">发布</el-button> |
| | | <el-button type="infoprimary" plain :loading="draftLoading" @click="saveDraft" |
| | | >存草稿</el-button |
| | | > |
| | | |
| | | |
| | | <el-button @click="handleCancel">取 消</el-button> |
| | | </div> |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- 工单详情对话框 --> |
| | | <el-dialog class="custom-dialog" align-center v-model="detailVisible" title="工单详情" width="80%" append-to-body> |
| | | <el-dialog |
| | | class="custom-dialog" |
| | | align-center |
| | | v-model="detailVisible" |
| | | title="工单详情" |
| | | width="80%" |
| | | append-to-body |
| | | > |
| | | <div class="detail-container"> |
| | | <div class="detail-top-title"> |
| | | <div class="event-title-center event-orderNumber"> |
| | |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | <span |
| | | v-if="currentDetail.status === 0 &&(row.label1 === '关联算法' || row.label1 === '工单名称')" |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | (row.label1 === '关联算法' || row.label1 === '工单名称') |
| | | " |
| | | class="required-label" |
| | | > |
| | | <span class="required-star">*</span>{{ row.label1 }} |
| | |
| | | <!-- 添加必填星号的标签 --> |
| | | |
| | | <span |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label2 === '工单内容' |
| | | " |
| | | v-if="currentDetail.status === 0 && row.label2 === '工单内容'" |
| | | class="required-label" |
| | | > |
| | | <span class="required-star">*</span>{{ row.label2 }} |
| | |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修改工单类型和工单内容的显示 --> |
| | | |
| | | |
| | | <template |
| | | v-if=" |
| | |
| | | <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> |
| | | </div> |
| | |
| | | <!-- 图片和地图部分 --> |
| | | <div class="media-section"> |
| | | <el-row :gutter="20"> |
| | | |
| | | <el-col :span="12"> |
| | | <div class="media-box"> |
| | | <div class="media-title">事件图片</div> |
| | |
| | | </div> |
| | | </template> |
| | | <template v-else> |
| | | <div class="media-title">地图标记事件点 |
| | | <el-popover v-if="currentDetail.status === 3 || currentDetail.status === 0" |
| | | <div class="media-title"> |
| | | 地图标记事件点 |
| | | <el-popover |
| | | v-if="currentDetail.status === 3 || currentDetail.status === 0" |
| | | popper-class="custom-qrcode-popover" |
| | | :width="120" |
| | | :visible="currentDetail.showQR && detailVisible" |
| | | placement="top" |
| | | title="" |
| | | trigger="click" |
| | | |
| | | trigger="hover" |
| | | > |
| | | <template #reference> |
| | | <img @click.stop="handleQRCode(currentDetail)" class="QRCodeImg" src="@/assets/images/dataCenter/qrCode.svg" alt="" title="事件导航" /> |
| | | <img |
| | | @mouseenter="currentDetail.showQR = true" |
| | | @mouseleave="currentDetail.showQR = false" |
| | | class="QRCodeImg" |
| | | src="@/assets/images/dataCenter/qrCode.svg" |
| | | alt="" |
| | | title="事件导航" |
| | | /> |
| | | </template> |
| | | <div class="qrcode-content"> |
| | | <CreateQRcode v-if="currentDetail.showQR && detailVisible" :latAndLon="currentDetail.location"></CreateQRcode> |
| | | <CreateQRcode |
| | | v-if="currentDetail.showQR && detailVisible" |
| | | :latAndLon="currentDetail.location" |
| | | ></CreateQRcode> |
| | | </div> |
| | | </el-popover> |
| | | </div> |
| | |
| | | </template> |
| | | </div> |
| | | </el-col> |
| | | |
| | | |
| | | </el-row> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <div class="dialog-footer1"> |
| | | <div |
| | | class="leftBtn" |
| | | :class="currentIndex === 0 ? 'disableds' : ''" |
| | | @click="leftClick" |
| | | > |
| | | <div class="leftBtn" :class="currentIndex === 0 ? 'disableds' : ''" @click="leftClick"> |
| | | 上一页 |
| | | </div> |
| | | <div class="btngroups"> |
| | |
| | | <el-form :model="dispatchForm" :rules="dispatchRules" ref="dispatchForm" label-width="100px"> |
| | | <el-form-item label="选择部门" prop="department"> |
| | | <el-select |
| | | |
| | | v-model="dispatchForm.department" |
| | | placeholder="请选择部门" |
| | | @change="handleDispatchDepartmentChange" |
| | |
| | | getStepInfo, |
| | | getReviewById, |
| | | getCreateEventJob, |
| | | } from '@/api/tickets/ticket' |
| | | } from '@/api/tickets/ticket'; |
| | | import { getSFDictionaryTree } from '@/api/job/task'; |
| | | import { export_json_to_excel } from '@/utils/exportExcel' |
| | | import geoJson from '@/assets/geoJson.json' |
| | | import { mapGetters } from 'vuex' |
| | | import { getAdcodeObj } from '@/utils/disposeData' |
| | | import elTooltipCopy from '@/components/ElTooltipCopy.vue' |
| | | import getBaseConfig from '@/buildConfig/config' |
| | | import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue' |
| | | const { envName } = getBaseConfig() |
| | | import { export_json_to_excel } from '@/utils/exportExcel'; |
| | | import geoJson from '@/assets/geoJson.json'; |
| | | import { mapGetters } from 'vuex'; |
| | | import { getAdcodeObj } from '@/utils/disposeData'; |
| | | import elTooltipCopy from '@/components/ElTooltipCopy.vue'; |
| | | import getBaseConfig from '@/buildConfig/config'; |
| | | import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue'; |
| | | const { envName } = getBaseConfig(); |
| | | 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 { |
| | |
| | | tableData: [], |
| | | option: { |
| | | border: true, |
| | | stripe: true, |
| | | stripe: false, |
| | | selection: true, // 添加多选功能 |
| | | index: true, // 保留序号功能 |
| | | indexLabel: '序号', |
| | |
| | | }, |
| | | |
| | | mounted() { |
| | | |
| | | this.getAlgorithmList() |
| | | this.getAlgorithmList(); |
| | | |
| | | const href = this.$route.href; |
| | | if (this.$route?.query?.status !== undefined && this.$route?.query?.status !== null) { |
| | |
| | | this.filters.keyword = orderNumber; |
| | | this.$nextTick(() => { |
| | | this.isShowInfo = true; |
| | | const find = this.$store.state.tags.bsTagList.find(i => i.path === '/tickets/ticket') |
| | | find && (find.query = {}) |
| | | const find = this.$store.state.tags.bsTagList.find(i => i.path === '/tickets/ticket'); |
| | | find && (find.query = {}); |
| | | }); |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | { label: '任务发起人', value: this.currentDetail.creator }, |
| | | { label: '当前状态', value: this.mapStatus(this.currentDetail.status) }, |
| | | { label: '事件地址', value: this.currentDetail.address || this.currentDetail.latAndLon }, // 包含经纬度信息 |
| | | { label: '关联算法', |
| | | { |
| | | label: '关联算法', |
| | | value: |
| | | this.algorithms.find(t => t.value === this.currentDetail.aiType)?.label || |
| | | this.currentDetail.aiType || |
| | | '/', |
| | | |
| | | }, |
| | | { label: '发起单位', value: this.currentDetail.department }, |
| | | { label: '发起任务时间', value: this.currentDetail.startTime }, |
| | |
| | | } |
| | | |
| | | return formattedFields; |
| | | |
| | | }, |
| | | dynamicFixedStatuses() { |
| | | // 直接使用接口返回的 stepInfos |
| | |
| | | |
| | | methods: { |
| | | handleCheck(data, { checkedKeys, checkedNodes }) { |
| | | this.checkedKeys = checkedKeys |
| | | this.checkedKeys = checkedKeys; |
| | | // 获取所有选中节点的 dictKey |
| | | const selectedDictKeys = checkedNodes.map(node => node.dictKey).filter(Boolean) |
| | | this.filters.type = selectedDictKeys |
| | | const selectedDictKeys = checkedNodes.map(node => node.dictKey).filter(Boolean); |
| | | this.filters.type = selectedDictKeys; |
| | | this.fetchTableData(); |
| | | }, |
| | | // 算法 |
| | | getAlgorithmList() { |
| | | getSFDictionaryTree({code:'SF'}).then((res) => { |
| | | getSFDictionaryTree({ code: 'SF' }).then(res => { |
| | | if (res.data.code === 200) { |
| | | const result = res.data.data[0].children |
| | | const result = res.data.data[0].children; |
| | | // 过滤第一层数据 |
| | | const filteredData = result.map(item => { |
| | | // 过滤第二层数据 |
| | | const children = item.children?.map(child => ({ |
| | | ...child, |
| | | children: [] // 清空第三层数据 |
| | | })) |
| | | children: [], // 清空第三层数据 |
| | | })); |
| | | return { |
| | | ...item, |
| | | children: children || [] |
| | | children: children || [], |
| | | }; |
| | | }); |
| | | this.dataList = filteredData; |
| | | } |
| | | }) |
| | | this.dataList = filteredData |
| | | } |
| | | }) |
| | | }); |
| | | }, |
| | | |
| | | handleSFNodeClick(data) { |
| | | console.log(data.dictKey, '666666666') |
| | | this.filters.type = '' |
| | | this.filters.algorithm = '' |
| | | this.filters.type = data.dictKey |
| | | console.log(data.dictKey, '666666666'); |
| | | this.filters.type = ''; |
| | | this.filters.algorithm = ''; |
| | | this.filters.type = data.dictKey; |
| | | // 更新列表请求 |
| | | this.fetchTableData(); |
| | | }, |
| | | handleClear() { |
| | | this.dictKey = '' |
| | | this.filters.algorithm = '' |
| | | this.filters.type = '' |
| | | this.dictKey = ''; |
| | | this.filters.algorithm = ''; |
| | | this.filters.type = ''; |
| | | this.fetchTableData(); |
| | | }, |
| | | handleCellClick(row, column) { |
| | |
| | | this.currentDetail.processingDetail = this.currentDetail.content; |
| | | this.handleViewDetail(this.currentDetail); |
| | | |
| | | |
| | | // 如果使用地图组件,需要更新地图标记 |
| | | this.$nextTick(() => { |
| | | if (this.$refs.MapContainer && this.currentDetail.location) { |
| | |
| | | }); |
| | | }, |
| | | async handleQRCode (val){ |
| | | val.showQR = !val.showQR |
| | | val.showQR = !val.showQR; |
| | | }, |
| | | async loadAMapScripts() { |
| | | try { |
| | |
| | | |
| | | const columnType = this.findObject(this.option.column, 'type'); |
| | | columnType.dicData = this.types; |
| | | this.allAlgorithms = info |
| | | this.allAlgorithms = info; |
| | | |
| | | console.log('工单类型',this.types); |
| | | console.log('关联算法',this.allAlgorithms ); |
| | |
| | | value: item.dict_key, |
| | | })) || []; |
| | | |
| | | this.algorithms2 = _.cloneDeep(this.algorithms) |
| | | this.algorithms2 = _.cloneDeep(this.algorithms); |
| | | |
| | | // 构建用户ID和名称的映射关系 |
| | | this.userNameToIdMap = {}; |
| | |
| | | }, |
| | | // 工单类型变化时触发 |
| | | handleTypeChange(typeValue) { |
| | | this.form.algorithm = [] |
| | | this.form.algorithm = []; |
| | | if (!typeValue) { |
| | | // 未选择类型时清空算法列表 |
| | | this.algorithms2 = []; |
| | | return; |
| | | } |
| | | |
| | | const matchedCategory = this.allAlgorithms.find( |
| | | category => category.dict_key === typeValue |
| | | ); |
| | | const matchedCategory = this.allAlgorithms.find(category => category.dict_key === typeValue); |
| | | |
| | | if (!matchedCategory || !matchedCategory.algorithms || matchedCategory.algorithms.length === 0) { |
| | | if ( |
| | | !matchedCategory || |
| | | !matchedCategory.algorithms || |
| | | matchedCategory.algorithms.length === 0 |
| | | ) { |
| | | // 无匹配的算法时清空 |
| | | this.algorithms2 = []; |
| | | this.$message.info('该工单类型暂无关联算法'); |
| | |
| | | label: algo.dict_value, |
| | | value: algo.dict_key, |
| | | dict_key: algo.dict_key, |
| | | dict_value: algo.dict_value |
| | | dict_value: algo.dict_value, |
| | | })); |
| | | |
| | | }, |
| | | |
| | | async fetchTableData() { |
| | |
| | | |
| | | console.log('this.currentDetail', this.currentDetail); |
| | | this.detailVisible = true; |
| | | this.handleTypeChange(this.currentDetail.type) |
| | | this.handleTypeChange(this.currentDetail.type); |
| | | console.log('this.currentDetail.location',this.currentDetail.location); |
| | | |
| | | this.$nextTick(() => { |
| | |
| | | this.dispatchDialogVisible = true; |
| | | |
| | | console.log('受理',this.currentDetail); |
| | | |
| | | }, |
| | | hasProcessingBtnPermission() { |
| | | // undefined 或 false 都返回 false,只有 true 返回 true |
| | |
| | | content: this.currentDetail.content, // 使用 content 替代原来的 remark |
| | | createDept: this.dispatchForm.department, // 派发部门 ID |
| | | updateUser: this.dispatchForm.handler, // 处理人 ID |
| | | aiType:this.currentDetail.aiType |
| | | aiType: this.currentDetail.aiType, |
| | | }; |
| | | console.log('派发',data); |
| | | |
| | |
| | | activated() { |
| | | this.handleReset(); |
| | | }, |
| | | |
| | | }; |
| | | </script> |
| | | <style lang="scss"> |
| | | .custom-dialog { max-height: 96vh; } |
| | | .custom-dialog { |
| | | max-height: 96vh; |
| | | } |
| | | .custom-qrcode-popover { |
| | | min-width: 120px !important; |
| | | } |
| | | </style> |
| | | <style lang="scss" scoped> |
| | | |
| | | ::v-deep(.el-tabs) { |
| | | height: 100%; |
| | | display: flex; |
| | |
| | | color: #fff; |
| | | cursor: pointer; |
| | | opacity: 0.8; |
| | | |
| | | } |
| | | |
| | | .disableds { |
| | |
| | | height: pxToVh(78) !important; |
| | | } |
| | | // 选中日期样式 |
| | | .el-calendar-table td.is-selected { |
| | | .el-calendar-table td.is-selected.is-today { |
| | | .el-calendar-day { |
| | | outline: 2px solid #409eff; |
| | | outline-offset: -2px; |