无人机管理后台前端(已迁走)
罗广辉
2025-10-10 8bfd657326eb9d4bd9b63920cfe3bd362cea4445
Merge branch 'feature/v6.0/6.0.4' into prod
44 files modified
3 files added
1413 ■■■■■ changed files
.env.development 4 ●●●● patch | view | raw | blame | history
.env.localhost 2 ●●● patch | view | raw | blame | history
.env.production 2 ●●● patch | view | raw | blame | history
.env.test 2 ●●● patch | view | raw | blame | history
src/App.vue 1 ●●●● patch | view | raw | blame | history
src/api/logs.js 8 ●●●●● patch | view | raw | blame | history
src/assets/images/mh.svg 7 ●●●●● patch | view | raw | blame | history
src/assets/images/task/sign.svg 3 ●●●●● patch | view | raw | blame | history
src/assets/images/warn.svg 10 ●●●●● patch | view | raw | blame | history
src/hooks/useRouteLine/useRouteLine.js 23 ●●●●● patch | view | raw | blame | history
src/option/system/dict.js 2 ●●● patch | view | raw | blame | history
src/page/index/index.vue 47 ●●●● patch | view | raw | blame | history
src/page/index/top/index.vue 4 ●●●● patch | view | raw | blame | history
src/store/modules/common.js 14 ●●●●● patch | view | raw | blame | history
src/styles/element-ui.scss 32 ●●●●● patch | view | raw | blame | history
src/utils/cesium/publicCesium.js 28 ●●●● patch | view | raw | blame | history
src/views/algorithmMange/algorithmMange.vue 4 ●●●● patch | view | raw | blame | history
src/views/algorithmRepository/algorithmRepository.vue 16 ●●●●● patch | view | raw | blame | history
src/views/dataCenter/components/searchData.vue 2 ●●●●● patch | view | raw | blame | history
src/views/dataCenter/dataCenter.vue 2 ●●● patch | view | raw | blame | history
src/views/device/addDevice.vue 140 ●●●●● patch | view | raw | blame | history
src/views/device/airport.vue 165 ●●●● patch | view | raw | blame | history
src/views/device/components/devicePerShare.vue 9 ●●●●● patch | view | raw | blame | history
src/views/device/components/firmwareManage.vue 18 ●●●●● patch | view | raw | blame | history
src/views/device/devicePerMenu.vue 2 ●●●●● patch | view | raw | blame | history
src/views/device/fly.vue 8 ●●●● patch | view | raw | blame | history
src/views/job/components/DeviceJobDetails.vue 34 ●●●● patch | view | raw | blame | history
src/views/job/components/JobRelatedEvents.vue 9 ●●●● patch | view | raw | blame | history
src/views/job/components/SearchBox.vue 6 ●●●● patch | view | raw | blame | history
src/views/job/components/TaskIntermediateContent/TaskIntermediateContent.vue 5 ●●●●● patch | view | raw | blame | history
src/views/monitor/log/api.vue 10 ●●●● patch | view | raw | blame | history
src/views/monitor/log/flightLog.vue 258 ●●●● patch | view | raw | blame | history
src/views/resource/components/spotDetails.vue 44 ●●●● patch | view | raw | blame | history
src/views/resource/patchTypeManagement.vue 2 ●●● patch | view | raw | blame | history
src/views/resource/wayline.vue 2 ●●● patch | view | raw | blame | history
src/views/system/dept.vue 70 ●●●●● patch | view | raw | blame | history
src/views/system/helpCenter.vue 88 ●●●●● patch | view | raw | blame | history
src/views/system/menu.vue 1 ●●●● patch | view | raw | blame | history
src/views/system/sysConfig.vue 8 ●●●● patch | view | raw | blame | history
src/views/system/user.vue 4 ●●●● patch | view | raw | blame | history
src/views/system/userinfo.vue 2 ●●● patch | view | raw | blame | history
src/views/tickets/orderLog-copy1.vue 4 ●●●● patch | view | raw | blame | history
src/views/tickets/orderLog.vue 216 ●●●●● patch | view | raw | blame | history
src/views/tickets/ticket.vue 76 ●●●●● patch | view | raw | blame | history
src/views/wel/components/backlog.vue 10 ●●●● patch | view | raw | blame | history
src/views/wel/components/proportionStatic.vue 1 ●●●● patch | view | raw | blame | history
src/views/workspace/index.vue 8 ●●●● patch | view | raw | blame | history
.env.development
@@ -2,7 +2,7 @@
 # @Author       : yuan
 # @Date         : 2025-07-29 15:59:42
 # @LastEditors  : yuan
 # @LastEditTime : 2025-07-29 16:15:31
 # @LastEditTime : 2025-09-27 15:47:12
 # @FilePath     : \.env.development
 # @Description  :
 # Copyright 2025 OBKoro1, All Rights Reserved.
@@ -37,7 +37,7 @@
VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/minio/cloud-bucket
# 图片存放地址
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/all_terrain
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/
# 行政区划存放地址
VITE_APP_REGION_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_region
# 算法仓库图片地址
.env.localhost
@@ -26,7 +26,7 @@
VITE_APP_AIRLINE_URL = http://192.168.1.227:80/minio/cloud-bucket
# 图片存放地址
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/all_terrain
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/
# 行政区划存放地址
VITE_APP_REGION_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_region
.env.production
@@ -28,7 +28,7 @@
VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket
# 图片存放地址
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/all_terrain
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/
# 算法仓库图片地址
VITE_APP_PICTURE_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket
.env.test
@@ -26,7 +26,7 @@
VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/minio/cloud-bucket
# 图片存放地址
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/all_terrain
VITE_APP_TERRAIN_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_terrain/
# 算法仓库图片地址
VITE_APP_PICTURE_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket
src/App.vue
@@ -3,6 +3,7 @@
</template>
<script setup>
</script>
src/api/logs.js
@@ -101,6 +101,14 @@
    data
  })
}
// 删除日志
export const deleteDroneFlight = (data) => {
  return request({
    url: '/drone-device-core/log/droneFlightLog/deleteDroneFlight',
    method: 'post',
    data
  })
}
export const cancelStar = data => {
  return request({
    url: '/drone-device-core/log/favorite/cancel/'+data,
src/assets/images/mh.svg
New file
@@ -0,0 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame">
<path id="Vector" d="M17.133 20.3135H6.83691C6.51348 20.3135 6.25098 20.051 6.25098 19.7275C6.25098 19.4041 6.51348 19.1416 6.83691 19.1416H17.133C17.4564 19.1416 17.7189 19.4041 17.7189 19.7275C17.7189 20.051 17.4564 20.3135 17.133 20.3135Z" fill="#707070"/>
<path id="Vector_2" d="M12.0234 19.9943C11.7 19.9943 11.4375 19.7318 11.4375 19.4084V16.1436C11.4375 15.8201 11.7 15.5576 12.0234 15.5576C12.3469 15.5576 12.6094 15.8201 12.6094 16.1436V19.4084C12.6094 19.7318 12.3469 19.9943 12.0234 19.9943Z" fill="#707070"/>
<path id="Vector_3" d="M19.1181 3.2793H5.16338C3.64932 3.2793 2.4165 4.51211 2.4165 6.02617V13.9809C2.4165 15.4949 3.64932 16.7277 5.16338 16.7277H19.1181C20.6321 16.7277 21.8649 15.4949 21.8649 13.9809V6.02852C21.8649 4.51211 20.6321 3.2793 19.1181 3.2793ZM7.5001 13.0316C7.5001 13.3551 7.2376 13.6176 6.91416 13.6176C6.59072 13.6176 6.32822 13.3551 6.32822 13.0316V10.5941C6.32822 10.2707 6.59072 10.0082 6.91416 10.0082C7.2376 10.0082 7.5001 10.2707 7.5001 10.5941V13.0316ZM10.922 13.0316C10.922 13.3551 10.6595 13.6176 10.336 13.6176C10.0126 13.6176 9.7501 13.3551 9.7501 13.0316V8.6957C9.7501 8.37227 10.0126 8.10977 10.336 8.10977C10.6595 8.10977 10.922 8.37227 10.922 8.6957V13.0316ZM14.4142 13.0316C14.4142 13.3551 14.1517 13.6176 13.8282 13.6176C13.5048 13.6176 13.2423 13.3551 13.2423 13.0316V9.89102C13.2423 9.56758 13.5048 9.30508 13.8282 9.30508C14.1517 9.30508 14.4142 9.56758 14.4142 9.89102V13.0316ZM17.7188 13.0316C17.7188 13.3551 17.4563 13.6176 17.1329 13.6176C16.8095 13.6176 16.547 13.3551 16.547 13.0316V6.98477C16.547 6.66133 16.8095 6.39883 17.1329 6.39883C17.4563 6.39883 17.7188 6.66133 17.7188 6.98477V13.0316Z" fill="#707070"/>
</g>
</svg>
src/assets/images/task/sign.svg
New file
@@ -0,0 +1,3 @@
<svg width="23" height="32" viewBox="0 0 23 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.8446 13.609C22.4288 14.8094 22.4288 17.1906 20.8446 18.3911L4.81187 30.5402C2.83607 32.0374 3.49992e-07 30.6282 4.58352e-07 28.1492L1.52047e-06 3.85082C1.62883e-06 1.37183 2.83608 -0.0374351 4.81187 1.45977L20.8446 13.609Z" fill="#1B94FF"/>
</svg>
src/assets/images/warn.svg
New file
@@ -0,0 +1,10 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame" clip-path="url(#clip0_2023_1729)">
<path id="Vector" d="M10.9609 1.95508C5.96561 1.95508 1.91602 6.00424 1.91602 11C1.91602 15.9958 5.96561 20.0449 10.9609 20.0449C15.9563 20.0449 20.0059 15.9949 20.0059 11C20.0059 6.0051 15.9563 1.95508 10.9609 1.95508ZM10.9609 15.843C10.7528 15.8426 10.5495 15.7805 10.3767 15.6645C10.2038 15.5486 10.0692 15.3841 9.98987 15.1917C9.91052 14.9993 9.88998 14.7877 9.93084 14.5836C9.9717 14.3795 10.0721 14.1921 10.2194 14.0451C10.3668 13.8981 10.5543 13.7981 10.7585 13.7576C10.9626 13.7172 11.1742 13.7381 11.3664 13.8179C11.5587 13.8976 11.723 14.0326 11.8386 14.2056C11.9541 14.3787 12.0158 14.5822 12.0158 14.7903C12.0158 14.9287 11.9885 15.0658 11.9355 15.1936C11.8824 15.3215 11.8047 15.4376 11.7067 15.5354C11.6087 15.6332 11.4924 15.7107 11.3645 15.7635C11.2365 15.8163 11.0994 15.8433 10.9609 15.843ZM12.0158 11.2836C12.0119 11.5607 11.899 11.8252 11.7016 12.0198C11.5042 12.2143 11.2382 12.3234 10.961 12.3234C10.6839 12.3234 10.4179 12.2143 10.2205 12.0198C10.0231 11.8252 9.91022 11.5607 9.90627 11.2836V6.37313C9.91022 6.09599 10.0231 5.83154 10.2205 5.63696C10.4179 5.44238 10.6839 5.3333 10.961 5.3333C11.2382 5.3333 11.5042 5.44238 11.7016 5.63696C11.899 5.83154 12.0119 6.09599 12.0158 6.37313V11.2836Z" fill="#FF0000"/>
</g>
<defs>
<clipPath id="clip0_2023_1729">
<rect width="22" height="22" fill="white"/>
</clipPath>
</defs>
</svg>
src/hooks/useRouteLine/useRouteLine.js
@@ -13,6 +13,8 @@
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
import { flyVisual } from '@/utils/cesium/mapUtil'
import { useStore } from 'vuex'
let arrowLineMaterialProperty = new ArrowLineMaterialProperty({
    color: new Cesium.Color(128 / 255, 215 / 255, 255 / 255, 1),
    directionColor: new Cesium.Color(1, 1, 1, 1),
@@ -22,6 +24,7 @@
})
export function useRouteLine () {
    const store = useStore()
    let viewer = null
    let previewDataSource = null
@@ -162,15 +165,15 @@
            },
        })
            // 落点线
            ; (pointList || [])?.forEach((item, index) => {
                const topPosition = Cesium.Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude), Number(item.height))
                let setting = {
                    position: topPosition,
                    polyline: getPolyLine(viewer, { value: pointList }, index),
                }
                previewDataSource.entities.add(setting)
            })
        // 落点线
        ; (pointList || [])?.forEach((item, index) => {
            const topPosition = Cesium.Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude), Number(item.height))
            let setting = {
                position: topPosition,
                polyline: getPolyLine(viewer, { value: pointList }, index),
            }
            previewDataSource.entities.add(setting)
        })
        // 终点
        previewDataSource.entities.add({
@@ -191,6 +194,8 @@
                height: 50,
            },
        })
        // 获取最后一点高度
        store.commit('setLastHeight', Number(pointList[pointList.length - 1].height))
        flyVisual({
            positionsData:pointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)]),
            viewer,
src/option/system/dict.js
@@ -59,7 +59,7 @@
      label: '封存',
      prop: 'isSealed',
      type: 'switch',
      align: 'center',
      // align: 'center',
      width: 100,
      dicData: [
        {
src/page/index/index.vue
@@ -24,21 +24,20 @@
        </div>
      </div>
    </div>
    <GlobalWS/>
    <GlobalWS />
    <!-- <wechat></wechat> -->
  </div>
</template>
<script>
import index from '@/mixins/index'
import wechat from './wechat.vue'
import index from '@/mixins/index';
import wechat from './wechat.vue';
//import { validatenull } from 'utils/validate';
import { mapGetters } from 'vuex'
import tags from './tags.vue'
import search from './search.vue'
import logo from './logo.vue'
import top from './top/index.vue'
import sidebar from './sidebar/index.vue'
import { mapGetters } from 'vuex';
import tags from './tags.vue';
import search from './search.vue';
import logo from './logo.vue';
import top from './top/index.vue';
import sidebar from './sidebar/index.vue';
import GlobalWS from '@/page/index/GlobalWS.vue';
export default {
@@ -53,10 +52,10 @@
    wechat,
  },
  name: 'index',
  provide () {
  provide() {
    return {
      index: this,
    }
    };
  },
  computed: {
    ...mapGetters([
@@ -68,27 +67,27 @@
      'menu',
      'setting',
    ]),
    validSidebar () {
    validSidebar() {
      return !(
        (this.$route.meta || {}).menu === false || (this.$route.query || {}).menu === 'false'
      )
      );
    },
  },
  props: [],
  methods: {
    //打开菜单
    openMenu (item = {}) {
    openMenu(item = {}) {
      this.$store.dispatch('GetMenu', item.id).then(data => {
        if (data.length !== 0) {
          this.$router.$avueRouter.formatRoutes(data, true)
          this.$router.$avueRouter.formatRoutes(data, true);
          // 获取url里面的redirect
          const redirect = decodeURIComponent(this.$route.query.redirect || '')
          const redirect = decodeURIComponent(this.$route.query.redirect || '');
          if (redirect) {
            console.log('redirect', redirect)
            const [path, queryString] = redirect.split('?')
            const query = queryString ? Object.fromEntries(new URLSearchParams(queryString)) : {}
            this.$router.push({ path, query })
            console.log('redirect', redirect);
            const [path, queryString] = redirect.split('?');
            const query = queryString ? Object.fromEntries(new URLSearchParams(queryString)) : {};
            this.$router.push({ path, query });
          }
        }
        //当点击顶部菜单后默认打开第一个菜单
@@ -112,10 +111,10 @@
            }, itemActive.meta)
          });
        }*/
      })
      });
    },
  },
}
};
</script>
<style lang="scss" scoped>
@@ -134,6 +133,6 @@
  background: transparent;
  padding: 0 10px;
  --el-color-primary: rgba(20, 65, 255, 1);
    height: pxToVh(55);
  height: pxToVh(55);
}
</style>
src/page/index/top/index.vue
@@ -15,7 +15,7 @@
        <top-lock v-if="setting.lock"/>
        <top-qna />
        <top-full v-if="setting.fullscreen" title="全屏"/>
        <img class="gateway" @click="jumpMH" src="@/assets/images/mh.png" alt="进入门户" title="进入门户" width="20" height="20">
        <img class="gateway" @click="jumpMH" src="@/assets/images/mh.svg" alt="进入门户" title="进入门户" width="20" height="20">
      </div>
      <div class="top-user">
        <img class="top-bar__img" :src="userInfo.avatar "  alt=""/>
@@ -96,7 +96,7 @@
      this.$store.commit('SET_COLLAPSE')
    },
    logout () {
      this.$confirm(this.$t('logoutTip'), this.$t('tip'), {
      this.$confirm(this.$t('logoutTip'), this.$t('提示'), {
        confirmButtonText: this.$t('submitText'),
        cancelButtonText: this.$t('cancelText'),
        type: 'warning',
src/store/modules/common.js
@@ -15,22 +15,26 @@
    lockPasswd: getStore({ name: 'lockPasswd' }) || '',
    website: website,
    setting: website.setting,
    deviceUpdateKey: 0, //设备刷新key
    jobUpdateKey: 0, //任务刷新key
    downloadProgress:{
      htsjzx: 100, //数据中心
      htlsrwxq: 100, //历史任务详情
    },
    deviceUpdateKey: 0, //设备刷新key
    jobUpdateKey: 0, //任务刷新key
    lastHeight: 0, // 获取最后一点高度
  },
  mutations: {
    setLastHeight(state, data) {
      state.lastHeight = data
    },
    setDownloadProgress(state, data) {
      state.downloadProgress = data
    },
    deviceUpdateKeyAdd(state, data) {
      state.deviceUpdateKey = state.deviceUpdateKey + 1
    },
    jobUpdateKeyAdd(state, data) {
      state.jobUpdateKey = state.jobUpdateKey + 1
    },
    setDownloadProgress(state, data) {
      state.downloadProgress = data
    },
    SET_LANGUAGE: (state, language) => {
      state.language = language;
src/styles/element-ui.scss
@@ -98,7 +98,7 @@
      .el-dialog__headerbtn {
        position: absolute;
        left: 0;
        top: 14px;
        //top: 14px;
        .el-dialog__close {
          color: #fff;
@@ -111,12 +111,22 @@
}
.ztzf-drawer-body-basic-container {
  .el-drawer__header {
    margin-bottom: 0;
  }
  .el-drawer__body {
    display: flex;
    flex-direction: column;
  }
}
}
.ztzf-el-card__body {
   .el-card__body {
    .avue-form{
    padding: 0;}}
}
.ztzf-public-general-avue-crud {
  .el-table {
    tr {
@@ -170,12 +180,28 @@
.ztzf-form-mange {
  .el-form-item {
    width: 300px;
    :deep(.el-form-item__label) {
    .el-form-item__content {
      width: 100%;
    }
    .el-form-item__label {
      width: 120px;
    }
  }
}
.ztzf-form-search {
  .el-form-item {
    width: 100%;
    .el-form-item__label {
      width: 80px;
    }
    .el-form-item__content {
      display: flex;
      flex: 1;
    }
  }
}
.ztzf-table-mange {
  th.el-table__cell  {
    color: rgba(0, 0, 0, .85);
src/utils/cesium/publicCesium.js
@@ -143,8 +143,28 @@
        this.viewer?.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击
        if (terrain) {
            // 正则:第一位非0,第二位任意数字,后10位都是0
            const re = /^[1-9]\d0{10}$/
            let result = null
            // 1️⃣先判断 areaCode
            if (re.test(store.state.user.userInfo.detail.areaCode)) {
                result = store.state.user.userInfo.detail.areaCode.slice(0, 6)
            } else {
                // 2️⃣如果不满足,从 ancestors 里找
                const matchedItems = store.state.user.userInfo.detail.ancestors
                    .split(',')
                    .filter(item => re.test(item)) // 过滤出符合条件的
                // 取第一个符合条件的前6位(可以改成 last one 看需求)
                if (matchedItems.length > 0) {
                    result = matchedItems[0].slice(0, 6)
                }
            }
            try {
                Cesium.CesiumTerrainProvider.fromUrl(`${import.meta.env.VITE_APP_TERRAIN_URL}`, {
                Cesium.CesiumTerrainProvider.fromUrl(`${import.meta.env.VITE_APP_TERRAIN_URL}${result}`, {
                    requestVertexNormals: true, // 启用地形法线增强立体感
                    requestWaterMask: true, // 启用水体遮罩效果
                }).then(terrainProvider => {
@@ -209,7 +229,7 @@
    async switchContour (open) {
        if (open) {
            await this.boundary?.openContour()
        } else {
            this.boundary?.closeContour()
        }
@@ -752,7 +772,7 @@
            Cesium.Cartesian3.subtract(a, this.viewer?.camera.position, a),
            Cesium.Cartesian3.normalize(r, r),
            Cesium.Cartesian3.normalize(a, a)) : (r = c.direction,
            a = h.direction)
                a = h.direction)
        let d = Cesium.Cartesian3.dot(r, a)
            , p = 0
        return d < 1 && (p = Math.acos(d)),
@@ -781,7 +801,7 @@
                , r = Cesium.Math.acosClamped(-e)
            a > 0 && a > r && (a = r - Cesium.Math.EPSILON4),
                r = Cesium.Math.acosClamped(e),
            a < 0 && -a > r && (a = -r + Cesium.Math.EPSILON4)
                a < 0 && -a > r && (a = -r + Cesium.Math.EPSILON4)
        }
        return a
    }
src/views/algorithmMange/algorithmMange.vue
@@ -27,7 +27,7 @@
        <el-table-column prop="alg_type" label="算法类型" align="center"></el-table-column>
                <el-table-column prop="qua_rate" label="最低准确率" align="center">
          <template #header>
            <el-tooltip placement="bottom" effect="light" content="AI识别率高于最低准确率时会生成待审核状态的事件">
            <el-tooltip placement="top" effect="dark" content="AI识别率高于最低准确率时会生成待审核状态的事件">
              <el-icon><QuestionFilled /></el-icon>
            </el-tooltip>
            <span>最低准确率</span>
@@ -35,7 +35,7 @@
        </el-table-column>
                <el-table-column prop="pass_rate" label="最高准确率" align="center">
          <template #header>
            <el-tooltip placement="bottom" effect="light" content="AI识别率高于最高准确率时会生成待处理状态的事件">
            <el-tooltip placement="top" effect="dark" content="AI识别率高于最高准确率时会生成待处理状态的事件">
              <el-icon><QuestionFilled /></el-icon>
            </el-tooltip>
            <span>最高准确率</span>
src/views/algorithmRepository/algorithmRepository.vue
@@ -55,9 +55,10 @@
            </div>
          </div>
          <div class="search-btn">
            <el-button type="primary" icon="el-icon-back" @click="goback">返回</el-button>
            <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
            <el-button icon="el-icon-delete" @click="handleReset">清空</el-button>
            <el-button type="primary" icon="el-icon-back" @click="goback">返回</el-button>
          </div>
        </div>
@@ -181,7 +182,7 @@
// { areaCode: userAreaCode.value }
  selectDeviceList().then(res => {
    jcoptions.value = res.data.data;
    console.log('机巢数',jcoptions.value );
    
  });
};
@@ -199,7 +200,7 @@
  getList();
};
const handleSearch = () => {
// console.log('taskData',taskData.value);
if(taskData.value === null){
    params.value.start_date = null; // 重置开始日期参数
  params.value.end_date = null; // 重置结束日期参数
@@ -242,16 +243,17 @@
<style scoped lang="scss">
.algorithContainer {
height: 100%;
overflow: auto;
height: calc(100vh - 130px);
}
.algorithItem {
  // padding: 20px;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  // gap: 13px;
  text-align: center;
  vertical-align: middle;
  .item {
    height: 267px;
    display: flex;
src/views/dataCenter/components/searchData.vue
@@ -347,6 +347,8 @@
function cancelDownload() {
  cancelDownloadApi({ type:'htsjzx' }).then(res =>{
    ElMessage.success('取消成功')
  }).catch(e =>{
    EventBus.emit('useGlobalWS-messageHandler', {biz_code: 'DOWNLOAD_PROGRESS',data:{status: 'CANCELLED',type:'htsjzx'}})
  })
}
// 切换文件夹
src/views/dataCenter/dataCenter.vue
@@ -18,7 +18,7 @@
      <!-- 文件夹 -->
      <div v-if="switchFolders" class="dataTable">
            <el-table
            border
         class="custom-header custom-body"
          v-loading="loadings"
          element-loading-text=""
src/views/device/addDevice.vue
@@ -11,7 +11,7 @@
                    @click.stop="copyInfo(scope.row, scope.index)" v-if="userInfo.role_name.includes('admin')">复制
                </el-button>
            </template>
        </avue-crud>F
        </avue-crud>
    </basic-container>
</template>
@@ -126,7 +126,7 @@
                        ],
                    },
                    {
                        label: '所属单位',
                        label: '所属部门',
                        prop: 'dept_name',
                        addDisplay: false,
                        editDisplay: false,
@@ -136,13 +136,13 @@
                        rules: [
                        {
                            required: true,
                            message: '请输入所属单位',
                            message: '请输入所属部门',
                            trigger: 'blur',
                        },
                        ],
                    },
                    {
                        label: '所属单位',
                        label: '所属部门',
                        prop: 'dept_id',
                        hide: true,
                        type: 'tree',
@@ -158,7 +158,7 @@
                        rules: [
                        {
                            required: true,
                            message: '请输入所属单位',
                            message: '请输入所属部门',
                            trigger: 'blur',
                        },
                        ],
@@ -214,66 +214,32 @@
                        width: 200,
                    },
                    {
                        label: '设备位置',
                        prop: 'area_code',
                        type: 'cascader',
                        labelWidth: 130,
                        searchSpan: 4,
                        hide: true,
                        search: true,
                        // overHidden: true,
                        editDisplay: true,
                        viewDisplay: true,
                        checkStrictly: true,
                        props: {
                        label: 'title',
                        value: 'value',
                        emitPath: false,
                        multiple: false,
                        expandTrigger: 'hover',
                        },
                        dataType: 'string',
                        rules: [
                      label: '设备位置',
                      prop: 'area_code',
                      // type: 'cascader',
                      type: 'tree',
                      labelWidth: 130,
                      searchSpan: 4,
                      hide: true,
                      search: true,
                      // overHidden: true,
                      editDisplay: true,
                      viewDisplay: true,
                      checkStrictly: true,
                      defaultExpandAll: true,
                      dicData: [],
                      props: {
                        label: 'name',
                        value: 'id',
                        children: 'childrens',
                      },
                      rules: [
                        {
                            required: true,
                            message: '请选择设备位置',
                            trigger: 'change',
                          required: true,
                          message: '请选择设备位置',
                          trigger: 'change',
                        },
                        ],
                        lazy: true,
                        lazyLoad (node, resolve) {
                        let level = node.level
                        let list = []
                        let callback = () => {
                            resolve(
                            (list || []).map(ele => ({
                                ...ele,
                                value: ele.value,
                                leaf: level >= 2,
                            }))
                            )
                        }
                        if (level === 0) {
                            getLazyTree('000000000000').then(res => {
                            list = res.data.data
                            callback()
                            })
                        } else if (level === 1) {
                            getLazyTree(node.value).then(res => {
                            list = res.data.data
                            callback()
                            })
                        } else if (level === 2) {
                            getLazyTree(node.value).then(res => {
                            list = res.data.data
                            callback()
                            })
                        } else {
                            callback()
                        }
                        },
                      ],
                    },
                    {
                        label: '创建时间',
@@ -370,6 +336,12 @@
        await this.getRegionTreeList();
        await this.getSystemNamesList();
    },
    mounted() {
      getRegionTreeAll({ parentCode: this.userInfo.detail.areaCode }).then(res => {
        const column = this.findObject(this.option.column, 'area_code');
        column.dicData = res.data.data ? [res.data.data] : [];
      });
    },
    methods: {
        async getRegionTreeList(code) {
            try {
@@ -400,20 +372,20 @@
                this.systemNamesList = [];
            }
        },
        beforeOpen (type, row, index) {
            if (type === 'add') {
                this.form = {
                    workspace_name: '',
                    platform_name: '',
                    dept_name: '',
                    bind_code: '',
                    type: 0,
                    workspace_desc: '',
                    area_name: '',
                    area_code: '',
                }
            }
        },
        // beforeOpen (type, row, index) {
        //     if (type === 'add') {
        //         this.form = {
        //             workspace_name: '',
        //             platform_name: '',
        //             dept_name: '',
        //             bind_code: '',
        //             type: 0,
        //             workspace_desc: '',
        //             area_name: '',
        //             area_code: '',
        //         }
        //     }
        // },
        async getXZQHList(area_code) {
            try {
                const res = await getLazyTree(area_code);
@@ -606,12 +578,24 @@
            }
        },
        beforeOpen (done, type) {
            if (type === 'add') {
              this.form = {
                workspace_name: '',
                platform_name: '',
                dept_name: '',
                bind_code: '',
                type: 0,
                workspace_desc: '',
                area_name: '',
                area_code: '',
              }
            }
            if (['edit', 'view'].includes(type)) {
                getDetail(this.form.id).then(async res => {
                    const data = res.data.data
                     this.form = {
                        ...data,
                        area_code: await this.getFullAreaCode(data.area_code),
                        // area_code: await this.getFullAreaCode(data.area_code),
                     }
                })
            }
src/views/device/airport.vue
@@ -10,7 +10,8 @@
        </el-button>
      </template>
      <template #dept_name="{ row }">
        <el-tag>{{ row.dept_name }}</el-tag>
        <el-tag v-if="row.dept_name">{{ row.dept_name }}</el-tag>
        <span v-else>/</span>
      </template>
      <template #status="{ row }">
        <div v-if="row.status == true" class="onlineStatus">
@@ -126,14 +127,16 @@
      <el-input v-model="operate_password" disabled></el-input>
    </el-dialog>
    <el-dialog title="注销" class="zx-cancel" append-to-body v-model="cancenOperate" width="460px">
      <div style="display: flex;justify-content: center;margin-bottom: 10px;">注销
        <span style="color:cornflowerblue;font-weight: bolder;margin: 0px 4px;">
    <el-dialog title="注销" class="ztzf-dialog-mange zx-cancel" append-to-body v-model="cancenOperate" width="560px">
      <div class="txt-contain">
        <img :src="warnSvg" />注销
        <span class="name">
          {{ cancelSNName }}
        </span> 设备可能会影响相关数据,确认注销吗?</div>
        <div style="display: flex;justify-content: center;color:red;font-size: 12px;">*删除相关图片、视频、事件</div>
        </span> 设备可能会影响相关数据,确认注销吗?
      </div>
      <div class="delete-txt">*删除相关图片、视频、事件</div>
      <template #footer>
        <span class="dialog-footer" style="display: flex;justify-content: center;">
        <span class="dialog-footer">
          <el-button @click="cancenOperate = false">取 消</el-button>
          <el-button type="primary" @click="cancenOperateDo">确 定</el-button>
        </span>
@@ -186,7 +189,7 @@
      </template>
    </el-dialog>
    <el-drawer class="ztzf-drawer-body-basic-container" title="机场授权管理" size="60%" append-to-body
    <el-drawer class="ztzf-drawer-body-basic-container ztzf-el-card__body" title="机场授权管理" size="60%" append-to-body
      v-model="devicePerShareVisible" :direction="'rtl'">
      <DevicePerShare ref="devicePerShare" />
    </el-drawer>
@@ -200,6 +203,7 @@
<script>
import { ElMessage, ElMessageBox } from 'element-plus'
import { getRegionTreeAll } from '@/api/job/task';
import { pxToRem } from '@/utils/rem'
import {
  getList,
@@ -225,6 +229,8 @@
import DockControlPanel from './components/DockControlPanel.vue'
import { getWebsocketUrl } from '@/utils/websocket/config';
import ConnectWebSocket from '@/utils/websocket';
import warnSvg from '@/assets/images/warn.svg'
export default {
  components: {
    FirmwareManage,
@@ -232,6 +238,8 @@
    DockControlPanel,
  },
  data () {
    // const self = this
    const validatePass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入密码'))
@@ -254,6 +262,7 @@
        password: [{ required: true, validator: validatePass, trigger: 'blur' }],
        password2: [{ required: true, validator: validatePass2, trigger: 'blur' }],
      },
      warnSvg: warnSvg,
      cancelSNName: '',
      cancenOperate: false,
      cancenOperateRow: {},
@@ -322,7 +331,7 @@
        grid: false,
        height: 'auto',
        calcHeight: 180,
        calcHeight: 20,
        column: [
          {
@@ -390,7 +399,8 @@
          {
            label: '设备位置',
            prop: 'area_code',
            type: 'cascader',
            // type: 'cascader',
            type: 'tree',
            labelWidth: 145,
            searchSpan: 4,
            hide: true,
@@ -399,15 +409,13 @@
            editDisplay: true,
            viewDisplay: true,
            checkStrictly: true,
            defaultExpandAll: true,
            dicData: [],
            props: {
              label: 'title',
              value: 'value',
              emitPath: false,
              multiple: false,
              expandTrigger: 'hover',
              label: 'name',
              value: 'id',
              children: 'childrens',
            },
            dataType: 'string',
            rules: [
              {
                required: true,
@@ -415,39 +423,6 @@
                trigger: 'change',
              },
            ],
            lazy: true,
            lazyLoad (node, resolve) {
              let level = node.level
              let list = []
              let callback = () => {
                resolve(
                  (list || []).map(ele => ({
                    ...ele,
                    value: ele.value,
                    leaf: level >= 2,
                  }))
                )
              }
              if (level === 0) {
                getLazyTree('000000000000').then(res => {
                  list = res.data.data
                  callback()
                })
              } else if (level === 1) {
                getLazyTree(node.value).then(res => {
                  list = res.data.data
                  callback()
                })
              } else if (level === 2) {
                getLazyTree(node.value).then(res => {
                  list = res.data.data
                  callback()
                })
              } else {
                callback()
              }
            },
          },
          {
            label: '设备名称',
@@ -573,30 +548,32 @@
            viewDisplay: false,
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'dept_name',
            addDisplay: false,
            editDisplay: false,
            viewDisplay: false,
            align: 'center',
            labelWidth: 145,
            width: 180,
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'dept_id',
            hide: true,
            type: 'tree',
            defaultExpandAll: true,
            search: true,
            searchSpan: 4,
            labelWidth: 145,
            defaultExpandAll: true,
            dicUrl: '/blade-system/dept/getTree',
            props: {
              label: 'name',
@@ -605,7 +582,7 @@
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],
@@ -784,8 +761,9 @@
      },
    }
  },
  computed: {
    ...mapGetters(['permission']),
    ...mapGetters(['permission', 'userInfo']),
    permissionList () {
      return {
        addBtn: this.validData(this.permission.air_add, true),
@@ -813,7 +791,10 @@
    })
  },
  mounted() {
    getRegionTreeAll({ parentCode: this.userInfo.detail.areaCode }).then(res => {
      const column = this.findObject(this.option.column, 'area_code');
      column.dicData = res.data.data ? [res.data.data] : [];
    });
  },
  methods: {
    getDockModeText (value) {
@@ -1348,6 +1329,7 @@
        })
    },
    async getFullAreaCode (areaCode) {
      console.log('getFullAreaCode', areaCode)
      if (!areaCode) return ''
      const code = areaCode.toString()
@@ -1369,10 +1351,9 @@
      if (['edit', 'view'].includes(type)) {
        getDetail(this.form.id).then(async res => {
          const data = res.data.data
          this.form = {
            ...data,
            area_code: await this.getFullAreaCode(data.area_code),
            // area_code: await this.getFullAreaCode(data.area_code),
            area_name: this.form.area_name,
            cnmode_code: this.getDockModeText(this.form.mode_code),
            domainTxt: data.domain === 0 ? '无人机' : data.domain === 3 ? '机巢' : '未知',
@@ -1442,23 +1423,23 @@
        resolve(data)
      })
    },
    rowDel (row) {
      this.$confirm('确定将选择数据删除?', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          return remove(row.id)
        })
        .then(() => {
          this.onLoad(this.page)
          this.$message({
            type: 'success',
            message: '操作成功!',
          })
        })
    },
    // rowDel (row) {
    //   this.$confirm('确定将选择数据删除?', {
    //     confirmButtonText: '确定',
    //     cancelButtonText: '取消',
    //     type: 'warning',
    //   })
    //     .then(() => {
    //       return remove(row.id)
    //     })
    //     .then(() => {
    //       this.onLoad(this.page)
    //       this.$message({
    //         type: 'success',
    //         message: '操作成功!',
    //       })
    //     })
    // },
    // 设置无人机操作密码
    setOperatePasswordConfirm () {
      var that = this
@@ -1583,5 +1564,37 @@
  right: 30px;
}
.force-center-dialog .el-dialog {
}
.zx-cancel {
  .txt-contain {
    display: flex;
    justify-content: center;
    margin-bottom: 20px;
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 400;
    font-size: 14px;
    img {
      width: 20px;
      height: 20px;
    }
    .name {
      color: #0E8BFF;
      margin-left: 6px;
      margin-right: 6px;
    }
  }
  .delete-txt {
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 400;
    display: flex;
    justify-content: center;
    color: #FF0000;
    font-size: 12px;
    margin-bottom: 20px;
  }
}
</style>
src/views/device/components/devicePerShare.vue
@@ -39,6 +39,7 @@
        index: true,
        viewBtn: true,
        addBtn: true,
        editBtn: false,
        selection: true,
        excelBtn: false,
        dialogClickModal: false,
@@ -51,7 +52,7 @@
          {
            label: '授权单位',
            prop: 'deptId',
            labelWidth: 130,
            // labelWidth: 100,
            type: 'tree',
            dicData: [],
            props: {
@@ -74,7 +75,7 @@
          {
            label: '授权单位',
            prop: 'deptName',
            labelWidth: 130,
            // labelWidth: 100,
            addDisplay: false,
            editDisabled: true,
            search: true,
@@ -119,7 +120,7 @@
            editDisplay: false,
            span: 24,
            row: true,
            width: 160,
            width: 200,
            format: 'YYYY-MM-DD HH:mm:ss',
          },
        ],
@@ -134,7 +135,7 @@
        addBtn: this.validData(this.permission.airport_add, true),
        viewBtn: this.validData(this.permission.airport_view, true),
        delBtn: this.validData(this.permission.airport_delete, true),
        editBtn: this.validData(this.permission.airport_edit, true),
        editBtn: this.validData(this.permission.airport_edit, false),
      }
    },
    ids () {
src/views/device/components/firmwareManage.vue
@@ -28,7 +28,7 @@
    <el-dialog title="固件上传" class="ztzf-dialog-mange" append-to-body v-model="firmwareUploadBox" width="40%" height="60%">
      <el-form
        ref="form"
        class="ztzf-form-mange"
        class="ztzf-form-search"
        :model="importForm"
        v-loading="loadingForm"
        style="width: 80%; margin-left: 10%"
@@ -39,7 +39,7 @@
        </el-form-item>
        <!-- 上传 -->
        <el-form-item label="固件文件" label-width="80px" prop="file">
        <el-form-item label="固件文件" prop="file">
          <el-upload
            class="upload-demo"
            action="#"
@@ -50,7 +50,7 @@
            :before-upload="beforeUploadFile"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text" style="height: 50px"><em>点击上传</em></div>
            <div class="el-upload__text" style="height: 50px"> <el-button>点击上传</el-button></div>
          </el-upload>
        </el-form-item>
        <el-form-item label="是否可用" prop="status">
@@ -59,14 +59,14 @@
            <el-option label="否" value="0"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="说明" label-width="80px" prop="release_note">
        <el-form-item label="说明" prop="release_note">
          <el-input type="textarea" v-model="importForm.release_note" clearable></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
        <el-button type="primary" @click="onConfirm">确定</el-button>
        <el-button @click="onCancel">取消</el-button>
        <el-button type="primary" @click="onConfirm" icon="el-icon-circle-check">确定</el-button>
        <el-button @click="onCancel" icon="el-icon-circle-close">取消</el-button>
        </div>
      </template>
    </el-dialog>
@@ -434,4 +434,8 @@
  /* color: aqua; */
}
</style>
<style scoped lang="scss"></style>
<style scoped lang="scss">
.upload-demo {
  height: 30px;
}
</style>
src/views/device/devicePerMenu.vue
@@ -77,6 +77,8 @@
          },
          {
            label: '绑定菜单',
            searchSpan: 5,
            span: 24,
            prop: 'menu_id',
            type: 'tree',
            dicUrl: '/blade-system/menu/deviceButtons',
src/views/device/fly.vue
@@ -201,7 +201,7 @@
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'dept_name',
            addDisplay: false,
            editDisplay: false,
@@ -210,13 +210,13 @@
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'dept_id',
            hide: true,
            type: 'tree',
@@ -230,7 +230,7 @@
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],
src/views/job/components/DeviceJobDetails.vue
@@ -4,7 +4,7 @@
        :width="pxToRem(1800)" :close-on-click-modal="false" :destroy-on-close="true">
        <div class="content">
            <div class="contentLeft">
                <div class="machineTableDetailsTitle"><span>详情</span></div>
                <div class="machineTableDetailsTitle"><img src="/src/assets/images/task/sign.svg" alt=""><span>详情</span></div>
                <div class="infoBox">
                    <div class="itemBoxLeft">
                        <div v-for="(item, index) in infoList" :key="index" class="itemCon">
@@ -29,11 +29,14 @@
                </div>
                <JobRelatedEvents :jobTimes="jobTimes" :batchNo="batchNo" />
                <div class="devicetitle" v-if="isShow">
                <div>
                        <img src="/src/assets/images/task/sign.svg" alt="">
                    <p>
                        成果数据
                        <span>{{ total }}</span>
                        个
                    </p>
                </div>
                    <div class="rightBox" v-if="total">
                        <div class="downloadBtn" @click="htlsrwxq === 100 && downloadFun()">
                            <el-progress v-if="htlsrwxq !== 100" :percentage="htlsrwxq" :show-text="false" striped striped-flow :duration="1" />
@@ -159,6 +162,7 @@
import { droneEventList } from '../const/drc'
import { ElMessage,ElLoading } from 'element-plus'
import { useStore } from 'vuex';
import EventBus from '@/utils/eventBus';
const store = useStore();
const htlsrwxq = computed(() => store.state.common.downloadProgress?.htlsrwxq || 100)
const isShow = defineModel('show')
@@ -181,7 +185,7 @@
    { name: '任务类型', value: '', field: 'industry_type_str' },
    { name: '飞行事件', value: '', field: 'event_number' },
    { name: '所属机巢', value: '', field: 'device_names' },
    { name: '所属单位', value: '', field: 'dept_name' },
    { name: '所属部门', value: '', field: 'dept_name' },
    { name: '任务时间', value: '', field: 'cycle_time_value' },
    { name: '关联算法', value: '', field: 'ai_type_str' },
    { name: '任务描述', value: '', field: 'remark' },
@@ -347,7 +351,9 @@
function cancelDownload() {
    cancelDownloadApi({ type:'htlsrwxq' }).then(res =>{
        ElMessage.success('取消成功')
    })
    }).catch(e =>{
    EventBus.emit('useGlobalWS-messageHandler', {biz_code: 'DOWNLOAD_PROGRESS',data:{status: 'CANCELLED',type:'htlsrwxq'}})
  })
}
onMounted(() => {
    getDetails()
@@ -384,14 +390,18 @@
        .machineTableDetailsTitle {
            margin-bottom: 10px;
            background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
            // background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
            border-bottom: 2px solid #e4e7ed;
            background-size: 100% 100%;
            img{
            width: 15px;
            height: 15px;}
            span {
                display: inline-block;
                margin-left: 30px;
                margin-left: 10px;
                font-size: 16px;
                color: #0282ff;
                // color: #0282ff;
                color: #303133;
                line-height: 20px;
                text-align: left;
                margin-bottom: 8px;
@@ -400,12 +410,13 @@
        .devicetitle {
            margin-bottom: 16px;
            background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
            // background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
            border-bottom: 2px solid #e4e7ed;
            background-size: 100% 100%;
            display: flex;
            justify-content: space-between;
            align-content: center;
.rightBox{
            .rightBox{
                display: flex;
                align-items: center;
                padding-right: 10px;
@@ -451,9 +462,12 @@
                }
            }
            img{
            width: 15px;
            height: 15px;}
            p {
                display: inline-block;
                margin-left: 30px;
                margin-left: 10px;
                font-size: 16px;
                color: #363636;
                line-height: 20px;
src/views/job/components/JobRelatedEvents.vue
@@ -1,6 +1,7 @@
<template>
    <div class="JobRelatedEvents">
        <div class="machineTableDetailsTitle">
            <img src="/src/assets/images/task/sign.svg" alt="">
        <p>
            关联事件
            <span>{{ total }}</span>
@@ -194,11 +195,15 @@
.JobRelatedEvents {
    .machineTableDetailsTitle {
    margin-bottom: 16px;
    background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
    // background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
        border-bottom: 2px solid #e4e7ed;
    background-size: 100% 100%;
    img{
            width: 15px;
            height: 15px;}
    p {
        display: inline-block;
        margin-left: 30px;
        margin-left: 10px;
        font-size: 16px;
        color: #363636;
        line-height: 20px;
src/views/job/components/SearchBox.vue
@@ -14,7 +14,8 @@
            check-strictly
            node-key="id"
            :props="treeProps"
            @node-click="handleNodeClick"
            clearable
            @change="handleNodeClick"
          />
        </el-form-item>
        <el-form-item label="所属机巢:">
@@ -61,7 +62,7 @@
        <div class="more" v-if="isExpand" @click="toggleExpand">收起</div>
        <div class="more" v-else @click="toggleExpand">更多</div>
        <div class="search-btn" :style="{ bottom: isExpand ? '5px' : '-3px' }">
          <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
          <el-button icon="el-icon-refresh" @click="handleReset">清空</el-button>
        </div>
@@ -89,7 +90,6 @@
            collapse-tags
            collapse-tags-tooltip
            clearable
            @node-click="handleNodeClick"
            @check="handleCheck"
            @clear="handleClear"
          />
src/views/job/components/TaskIntermediateContent/TaskIntermediateContent.vue
@@ -17,7 +17,7 @@
            </el-tooltip-copy>
          </template>
        </el-table-column>
        <el-table-column prop="name" label="任务编号" width="160">
        <el-table-column prop="name" label="任务名称" width="160">
          <template #default="scope">
            <el-tooltip-copy :content="scope.row.name" :showCopyText="true">
              {{scope.row.name}}
@@ -119,7 +119,7 @@
import CancelTaskDialog from '../CancelTaskDialog.vue'
import { useStore } from 'vuex'
import { cloneDeep } from 'lodash'
import { inject, onBeforeUnmount, watch } from 'vue';
import { inject, onBeforeUnmount } from 'vue';
import ElTooltipCopy from '@/components/ElTooltipCopy.vue';
const store = useStore()
const singleUavHome = computed(() => store.state.home.singleUavHome)
@@ -271,7 +271,6 @@
  getJobList()
  changeKey.value++
})
onBeforeUnmount(() => {
  clearInterval(polling)
src/views/monitor/log/api.vue
@@ -1,5 +1,5 @@
<template>
  <basic-container>
  <basic-container >
    <avue-crud :option="option" :table-loading="loading" :data="data" ref="crud" v-model="form"
      :permission="permissionList" :before-open="beforeOpen" v-model:page="page" @search-change="searchChange"
      @search-reset="searchReset" @current-change="currentChange" @size-change="sizeChange"
@@ -205,4 +205,10 @@
}
</script>
<style scoped lang="scss"></style>
<style lang="scss">
.avue-crud__dialog__header .el-dialog__title {
  font-size: 18px !important;
}
</style>
src/views/monitor/log/flightLog.vue
@@ -4,44 +4,44 @@
    <div class="ztzf-search-mange">
      <el-form :model="params" inline>
        <div class="search-contain">
          <div>
            <el-form-item label="任务名称:">
              <el-input v-model="params.jobName" placeholder="请输入任务名称" clearable />
            </el-form-item>
            <el-form-item label="任务编号:">
              <el-input v-model="params.jobInfoNum" placeholder="请输入任务编号" clearable />
            </el-form-item>
            <el-form-item label="日期:">
              <el-date-picker
                v-model="rangTime"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                clearable
                @change="changeselect"
              />
            </el-form-item>
          </div>
          <div class="btns">
            <el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
            <el-button @click="cancelSearch" :icon="Delete">清空</el-button>
          </div>
          <!--          <div>-->
          <el-form-item label="任务名称:">
            <el-input v-model="params.jobName" placeholder="请输入任务名称" clearable />
          </el-form-item>
          <el-form-item label="任务编号:">
            <el-input v-model="params.jobInfoNum" placeholder="请输入任务编号" clearable />
          </el-form-item>
          <el-form-item label="日期:">
            <el-date-picker
              v-model="rangTime"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              clearable
              @change="changeselect"
            />
          </el-form-item>
          <!--          </div>-->
          <!--          <div class="btns">-->
          <el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
          <el-button @click="cancelSearch" :icon="Delete">清空</el-button>
          <!--          </div>-->
        </div>
      </el-form>
    </div>
    <div class="mange-table">
<!--      <el-tabs v-model="tabType" class="demo-tabs" @tab-click="handleTabClick">-->
<!--        <el-tab-pane label="全部" name="全部"></el-tab-pane>-->
<!--        <el-tab-pane label="我的收藏" name="收藏"></el-tab-pane>-->
<!--        -->
<!--      </el-tabs>-->
      <!--      <el-tabs v-model="tabType" class="demo-tabs" @tab-click="handleTabClick">-->
      <!--        <el-tab-pane label="全部" name="全部"></el-tab-pane>-->
      <!--        <el-tab-pane label="我的收藏" name="收藏"></el-tab-pane>-->
      <!--        -->
      <!--      </el-tabs>-->
      <el-table border :data="tableList" class="custom-header">
        <el-table-column label="序号" type="index" width="60"></el-table-column>
        <el-table-column prop="job_name" label="任务名称" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="job_info_num" label="任务编号" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="title" label="飞行类型" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="device_name" label="无人机" align="center"></el-table-column>
<!--        <el-table-column prop="title" label="飞行类型" align="center" show-overflow-tooltip></el-table-column>-->
        <el-table-column prop="nickname" label="机巢名称" align="center"></el-table-column>
        <el-table-column prop="start_time" label="开始时间" align="center">
          <template #default="scope">
            {{ timeFormatConvert(scope.row.start_time) }}
@@ -52,25 +52,27 @@
            {{ timeFormatConvert(scope.row.end_time) }}
          </template>
        </el-table-column>
<!--        <el-table-column prop="end_time" label="标签" align="center">-->
<!--          <template #default="scope">-->
<!--            <el-select v-model="scope.row.label_id" @change="handleUpdateLabel(scope.row)" clearable>-->
<!--              <el-option-->
<!--                v-for="item in tagList"-->
<!--                :key="item.id"-->
<!--                :label="item.label_name"-->
<!--                :value="item.id"-->
<!--              ></el-option>-->
<!--            </el-select>-->
<!--          </template>-->
<!--        </el-table-column>-->
        <el-table-column prop="create_name" label="创建人" align="center"></el-table-column>
        <!--        <el-table-column prop="end_time" label="标签" align="center">-->
        <!--          <template #default="scope">-->
        <!--            <el-select v-model="scope.row.label_id" @change="handleUpdateLabel(scope.row)" clearable>-->
        <!--              <el-option-->
        <!--                v-for="item in tagList"-->
        <!--                :key="item.id"-->
        <!--                :label="item.label_name"-->
        <!--                :value="item.id"-->
        <!--              ></el-option>-->
        <!--            </el-select>-->
        <!--          </template>-->
        <!--        </el-table-column>-->
        <el-table-column label="操作" width="300" align="center">
          <template #default="scope">
            <el-button icon="el-icon-view" type="text" @click="handleDetail(scope.row)">查看</el-button>
            <el-button icon="el-icon-view" type="text" @click="handleLineTrajectory(scope.row)">轨迹</el-button>
            <el-button icon="el-icon-delete" type="text" @click="handleDelete(scope.row)">删除</el-button>
<!--            <el-button type="text" @click="handleStar(scope.row)">-->
<!--              <el-icon><Star /></el-icon>-->
<!--              {{ scope.row.is_favorite ? '取消收藏':'收藏' }}</el-button>-->
            <!--            <el-button type="text" @click="handleStar(scope.row)">-->
            <!--              <el-icon><Star /></el-icon>-->
            <!--              {{ scope.row.is_favorite ? '取消收藏':'收藏' }}</el-button>-->
            <el-button type="text" @click="handleExport(scope.row)"><el-icon><Download /></el-icon>导出</el-button>
          </template>
        </el-table-column>
@@ -84,33 +86,50 @@
                     @size-change="handleSizeChange" @current-change="handleCurrentChange" />
    </div>
  </div>
  <el-dialog class="ztzf-dialog" append-to-body v-model="isShowView" title="查看"
             :width="pxToRem(1000)" :close-on-click-modal="false" :destroy-on-close="true">
    <!-- <div class="content"> -->
  <el-dialog class="ztzf-dialog-mange" append-to-body v-model="isShowView" title="查看" :width="pxToRem(1200)" :close-on-click-modal="false" :destroy-on-close="true">
    <el-table border :data="tableDataDetails" height="466">
      <el-table-column label="序号" type="index" width="60"></el-table-column>
      <el-table-column prop="flight_type" label="飞行类型" align="center" show-overflow-tooltip></el-table-column>
      <el-table-column prop="latitude" label="经度" align="center"></el-table-column>
      <el-table-column prop="longitude" label="纬度" align="center"></el-table-column>
      <el-table-column prop="height" label="高度" align="center"></el-table-column>
      <el-table-column prop="elevation" label="海拔高度" align="center"></el-table-column>
      <el-table-column prop="create_time" label="飞行时间" align="center" show-overflow-tooltip></el-table-column>
      <el-table-column prop="longitude" label="经度" align="center"></el-table-column>
      <el-table-column prop="latitude" label="纬度" align="center"></el-table-column>
      <el-table-column prop="height" label="绝对高度" align="center"></el-table-column>
      <el-table-column prop="elevation" label="实时真高" align="center"></el-table-column>
    </el-table>
    <div class="pagination" style="display: flex;justify-content: end;margin-top: 10px;">
      <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background
                     :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="detailParams.current"
                     v-model:page-size="detailParams.size" layout="total, sizes, prev, pager, next, jumper" :total="detailTotal"
                     @size-change="handleSizeChangeDetails" @current-change="handleCurrentChangeDetails" />
      <!-- </div> -->
    </div>
    <template #footer>
      <div class="pagination dialog-footer" style="display: flex;justify-content: end;margin-top: 10px;">
        <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background
                       :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="detailParams.current"
                       v-model:page-size="detailParams.size" layout="total, sizes, prev, pager, next, jumper" :total="detailTotal"
                       @size-change="handleSizeChangeDetails" @current-change="handleCurrentChangeDetails" />
      </div>
    </template>
  </el-dialog>
  <el-dialog class="ztzf-dialog-mange" append-to-body v-model="isShowFlyMapView" title="查看" :width="pxToRem(1000)" :close-on-click-modal="false" :destroy-on-close="true">
    <div id="flyMap" class="ztzf-cesium"></div>
  </el-dialog>
</template>
<script setup>
import { getHistoryTrack, cancelStar, addStar, updateDroneFlight, droneFlightLogInfoPage } from '@/api/logs';
import { getHistoryTrack, cancelStar, addStar, updateDroneFlight, deleteDroneFlight, droneFlightLogInfoPage } from '@/api/logs';
// import { flightLogPage } from '@/api/airspace/airspace';
import { downloadXls } from '@/utils/util';
import { exportBlob } from '@/api/common'
import * as Cesium from 'cesium';
import { PublicCesium } from '@/utils/cesium/publicCesium';
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
import { Delete, Search } from '@element-plus/icons-vue';
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
import { flyVisual } from '@/utils/cesium/mapUtil'
import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
import endPointImg from '@/assets/images/EndPointicon.png'
import { nextTick } from 'vue';
let publicCesiumInstance = null;
let viewer = null;
const viewInstance = shallowRef(null);
const homeViewer = shallowRef(null);
let previewDataSource = null
const total = ref(0)
let rangTime = ref([])
@@ -128,6 +147,8 @@
let isShowView = ref(false)
let isShowFlyMapView = ref(false)
let tabType = ref('全部')
function timeFormatConvert(time) {
@@ -142,8 +163,8 @@
    startTime: '',
    endTime: '',
    isFavorite: tabType.value === '收藏' ? true : false,
    page: '1',
    page_size: '10',
    page: 1,
    page_size: 10,
    jobName: '',
    jobInfoNum: '',
  }
@@ -181,12 +202,119 @@
function handleDetail(row) {
  isShowView.value = true
  detailParams.value.current = 1
  detailParams.value.size = 10
  detailParams.value.flightId = row.id
  detailTotal.value = 0
  droneFlightLogInfoPage(detailParams.value).then(res => {
    tableDataDetails.value = res.data.data.records
    detailTotal.value = res.data.data.total
  })
}
// 地图
const initMap = () => {
  if (!document.getElementById('flyMap')) {
    return;
  }
  publicCesiumInstance = new PublicCesium({
    dom: 'flyMap',
    flatMode: false,
    terrain: true,
    layerMode: 4,
    contour: false,
  });
  homeViewer.value = publicCesiumInstance.getViewer();
  viewer = publicCesiumInstance.getViewer();
  viewInstance.value = publicCesiumInstance;
  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewInstance.value.switchContour(true);
};
// 预览轨迹
let arrowLineMaterialProperty = new ArrowLineMaterialProperty({
  color: new Cesium.Color(128 / 255, 215 / 255, 255 / 255, 1),
  directionColor: new Cesium.Color(1, 1, 1, 1),
  outlineColor: new Cesium.Color(1, 1, 1, 1),
  outlineWidth: 0,
  speed: 5,
})
async function handleLineTrajectory(row) {
  isShowFlyMapView.value = true;
  // 确保地图容器已渲染
  await nextTick();
  // 确保地图初始化完成
  // if (!viewer) {
  //   initMap();
  // }
  initMap();
  detailParams.value.size = 9999
  detailParams.value.current = 1
  detailParams.value.flightId = row.id;
  const res = await droneFlightLogInfoPage(detailParams.value);
  tableDataDetails.value = res.data.data.records;
  // 清除现有数据源(如果有)
  if (previewDataSource) {
    viewer.dataSources.remove(previewDataSource);
  }
  // 创建新数据源
  previewDataSource = new Cesium.CustomDataSource('previewDataSource');
  await viewer.dataSources.add(previewDataSource);
  // 确保数据有效
  const validPositions = tableDataDetails.value
    .filter(i => i.longitude && i.latitude && i.height)
    .map(i => Cesium.Cartesian3.fromDegrees(
      Number(i.longitude),
      Number(i.latitude),
      Number(i.height)
    ));
  if (validPositions.length > 0) {
    previewDataSource.entities.add({
      polyline: {
        width: 4,
        positions: validPositions,
        material: arrowLineMaterialProperty,
        clampToGround: false,
      },
    });
    // 起点
    // previewDataSource.entities.add({
    //   position: validPositions[0],
    //   billboard: {
    //     image: rwqfdImg,
    //     width: 50,
    //     height: 50,
    //   },
    // })
    // 终点
    // previewDataSource.entities.add({
    //   position: validPositions[validPositions.length - 1],
    //   billboard: {
    //     image: new Cesium.ConstantProperty(endPointImg),
    //     width: 30,
    //     height: 30,
    //     verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐
    //   },
    // })
    flyVisual({
      positionsData: tableDataDetails.value.map(i => [
        Number(i.longitude),
        Number(i.latitude),
        Number(i.height)
      ]),
      viewer,
      multiple: 4.6,
      pitch: -60
    });
  } else {
    console.warn('No valid positions data');
  }
}
// 分页
function handleSizeChangeDetails(val) {
@@ -251,7 +379,7 @@
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    updateDroneFlight({ is_deleted: 1, id: row.id }).then(res => {
    deleteDroneFlight({ id: row.id }).then(res => {
      ElMessage.success('删除成功')
      getList()
    })
@@ -390,4 +518,8 @@
    }
  }
}
#flyMap {
  height: 500px;
  width: 100%;
}
</style>
src/views/resource/components/spotDetails.vue
@@ -133,6 +133,8 @@
import * as Cesium from 'cesium';
import { PublicCesium } from '@/utils/cesium/publicCesium';
import { ref, watch, onBeforeUnmount, onMounted } from 'vue';
// 标记地图是否初始化完成
const isMapReady = ref(false);
const uploadPatchDialog = defineModel('show');
const props = defineProps(['title', 'detailid', 'detailList', 'spotTypeOption', 'regionalData']);
const polygonTableEle = ref(null);
@@ -266,9 +268,8 @@
// 地图
const initMap = () => {
  if (!document.getElementById('spotMap')) {
    return;
  }
  if (!document.getElementById('spotMap') || isMapReady.value) return;
  publicCesiumInstance = new PublicCesium({
    dom: 'spotMap',
    flatMode: false,
@@ -276,12 +277,33 @@
    layerMode: 4,
    contour: false,
  });
  homeViewer.value = publicCesiumInstance.getViewer();
  viewer = publicCesiumInstance.getViewer();
  viewInstance.value = publicCesiumInstance;
  viewInstance.value = publicCesiumInstance;
  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewInstance.value.switchContour(true);
  // 确保 readyPromise 存在
  if (viewer.readyPromise) {
    viewer.readyPromise.then(() => {
      isMapReady.value = true;
      getTableList();
    }).catch((error) => {
      console.error('地图加载失败:', error);
      ElMessage.error('地图加载失败,请刷新重试');
    });
  } else {
    // 如果没有 readyPromise
    setTimeout(() => {
      isMapReady.value = true;
      getTableList();
    }, 1000);
  }
};
// 仅弹框初始化时执行的定位逻辑
const initMapLocation = () => {
  if (tbJwdList.length === 0 || !homeViewer.value) return;
@@ -303,6 +325,7 @@
};
// 初始化所有图斑
const entitiesAddSpot = () => {
if (!isMapReady.value || !viewer) return;
  viewer?.entities.removeAll();
  tbJwdList = []; // 重置经纬度列表
  
@@ -594,20 +617,21 @@
watch(uploadPatchDialog, newVal => {
  if (newVal) {
    isInit.value = true; 
    isMapReady.value = false;
    setTimeout(() => {
      initMap();      
      getTableList();
      getspotManagementTableApi();
      getspotManagementTableApi();
    }, 0);
  } else {
 tableData.value = [];
    tableData.value = [];
    isEditing.value = false;
    handleUpDateDrawState(false);
    destroyMap();
    isInit.value = false; 
    clearSelect();
    isMapReady.value = false;
  }
  refreshonload();
});
@@ -722,8 +746,8 @@
  z-index: 99;
  width: 277px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.6);
  // backdrop-filter: blur(5px);
  background: rgba(0, 0, 0, 0.8);
  border-radius: 8px 8px 8px 8px;
  padding: 6px 10px 0 10px;
  display: flex;
src/views/resource/patchTypeManagement.vue
@@ -21,7 +21,7 @@
      @on-load="onLoad"
    >
      <template #search-menu="{ row, size }">
        <el-button icon="el-icon-back" @click="goPatchManagement"> 返回 </el-button>
        <el-button icon="el-icon-back" @click="goPatchManagement" type="primary"> 返回 </el-button>
      </template>
      <template #status="{ row }">
        <el-tag>{{ row.statusName }}</el-tag>
src/views/resource/wayline.vue
@@ -45,7 +45,7 @@
        searchMenuSpan: 6,
        border: true,
        index: true,
        selection: true,
        // selection: true,
        dialogClickModal: false,
        menu: false, // 禁用默认操作列
src/views/system/dept.vue
@@ -40,10 +40,12 @@
import { getLazyTree } from '@/api/base/region'
import { mapGetters } from 'vuex'
import website from '@/config/website'
import { getList } from '@/api/device/device';
export default {
  data () {
    return {
      treeResolveMap: new Map(),
      form: {},
      selectionList: [],
      query: {},
@@ -73,33 +75,33 @@
        column: [
          {
            label: '机构名称',
            label: '部门名称',
            prop: 'deptName',
            search: true,
            labelWidth: 120,
            rules: [
              {
                required: true,
                message: '请输入机构名称',
                message: '请输入部门名称',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '机构全称',
            label: '部门全称',
            prop: 'fullName',
            search: true,
            labelWidth: 120,
            rules: [
              {
                required: true,
                message: '请输入机构全称',
                message: '请输入部门全称',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '上级机构',
            label: '上级部门',
            prop: 'parentId',
            dicData: [],
            type: 'tree',
@@ -113,13 +115,13 @@
            rules: [
              {
                required: false,
                message: '请选择上级机构',
                message: '请选择上级部门',
                trigger: 'click',
              },
            ],
          },
          {
            label: '机构类型',
            label: '部门类型',
            type: 'select',
            dicUrl: '/blade-system/dict/dictionary?code=org_category',
            props: {
@@ -134,13 +136,13 @@
            rules: [
              {
                required: true,
                message: '请输入机构类型',
                message: '请输入部门类型',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '机构性质',
            label: '部门性质',
            type: 'select',
            dicUrl: '/blade-system/dict/dictionary?code=org_nature',
            props: {
@@ -155,7 +157,7 @@
            rules: [
              {
                required: true,
                message: '请输入机构性质',
                message: '请输入部门性质',
                trigger: 'blur',
              },
            ],
@@ -379,6 +381,14 @@
            type: 'success',
            message: '操作成功!',
          })
          this.parentId = ''
          const resolve = this.treeResolveMap.get(row.parentId)
          if (resolve) {
            // 重新加载子节点数据
            getChildLazyTree({ parentId: row.parentId }).then(res => {
              resolve(res.data.data)
            })
          }
          this.onLoad(this.page)
          done(row)
        },
@@ -394,7 +404,7 @@
        loading()
        return
      }
      console.log('--- Start rowUpdate ---')
      // console.log('--- Start rowUpdate ---')
      // 提交时只使用县级代码
      const submitData = {
@@ -402,27 +412,33 @@
        areaCode: row.areaCode.split(',').pop(), // 取最后一个代码(县级)
      }
      console.log('Row data before submit:', row)
      console.log('编辑', row)
      update(submitData)
        .then(
          res => {
            console.log('Update response:', res.data)
            const resolve = this.treeResolveMap.get(row.parentId)
            if (resolve) {
              // 重新加载子节点数据
              getChildLazyTree({ parentId: row.parentId }).then(res => {
                resolve(res.data.data)
              })
            }
            this.onLoad(this.page)
            this.$message({
              type: 'success',
              message: '操作成功!',
            })
            this.onLoad(this.page)
            done(row)
          },
          error => {
            console.log('Update error:', error)
            // console.log('Update error:', error)
            this.loading = false
            loading()
          }
        )
        .catch(error => {
          console.log('Update promise rejected:', error)
          // console.log('Update promise rejected:', error)
          this.loading = false
        })
    },
@@ -436,11 +452,18 @@
          return remove(row.id)
        })
        .then(() => {
          const resolve = this.treeResolveMap.get(row.parentId)
          if (resolve) {
            // 重新加载子节点数据
            getChildLazyTree({ parentId: row.parentId }).then(res => {
              resolve(res.data.data)
            })
          }
          this.onLoad(this.page)
          this.$message({
            type: 'success',
            message: '操作成功!',
          })
          this.onLoad(this.page)
          done(row)
        })
    },
@@ -542,11 +565,11 @@
    },
    onLoad (page, params = {}) {
      this.loading = true
      console.log('onLoad triggered with page:', page, 'params:', params)
      console.log('Current parentId:', this.parentId, 'query:', this.query)
      // console.log('onLoad triggered with page:', page, 'params:', params)
      // console.log('Current parentId:', this.parentId, 'query:', this.query)
      getLazyList(this.parentId, Object.assign(params, this.query))
        .then(res => {
          console.log('onLoad response:', res.data)
          // console.log('onLoad response:', res.data)
          // 处理 areaCode,确保是单一字符串
          const data = (res.data.data || []).map(item => {
            const fullAreaCode = this.getFullAreaCode(item.areaCode)
@@ -561,16 +584,17 @@
          this.data = data
          this.loading = false
          this.selectionClear()
          console.log('Table data after onLoad:', this.data)
          // console.log('Table data after onLoad:', this.data)
        })
        .catch(error => {
          console.log('onLoad error:', error)
          // console.log('onLoad error:', error)
          this.loading = false
          this.data = this.data // 保留当前数据
          console.log('Table data after onLoad error:', this.data)
          // console.log('Table data after onLoad error:', this.data)
        })
    },
    treeLoad (tree, treeNode, resolve) {
      this.treeResolveMap.set(tree.id, resolve)
      getChildLazyTree({ parentId: tree.id }).then(res => {
        resolve(res.data.data)
      })
src/views/system/helpCenter.vue
@@ -2,7 +2,8 @@
  <basic-container>
    <div class="helpContainer">
      <el-table
        class="custom-table"
        border
        class="custom-header"
        :data="helpData"
        style="width: 100%"
        :row-class-name="tableRowClassName"
@@ -16,22 +17,37 @@
        <el-table-column prop="levelTwoType" label="二级类别" />
        <el-table-column prop="uploadUser" label="上传者" />
        <el-table-column prop="createTime" label="上传时间" />
        <el-table-column label="操作" width="150" align="center">
          <template #default="scope">
            <span class="look" @click="clickDetail(scope.row)" v-if="permission.helpCenterLook"
              >查看</span
            >
            <el-upload
              style="display: inline-block"
              :show-file-list="false"
              :before-upload="file => onUploadFileBefore(file, scope.row)"
              :limit="1"
              accept=".pdf"
            >
              <span class="uploads" v-if="permission.helpCenterUpload">上传</span>
            </el-upload>
          </template>
        </el-table-column>
     <el-table-column label="操作" width="200" align="center">
  <template #default="scope">
    <div class="actionBar" >
      <el-button
        class="look"
        icon="el-icon-view"
        type="text"
        @click="clickDetail(scope.row)"
        v-if="permission.helpCenterLook"
      >
        查看
      </el-button>
      <el-upload
        style="display: inline-block"
        :show-file-list="false"
        :before-upload="file => onUploadFileBefore(file, scope.row)"
        :limit="1"
        accept=".pdf"
      >
        <el-button
          class="uploads"
          icon="el-icon-upload"
          type="text"
          v-if="permission.helpCenterUpload"
        >
          上传
        </el-button>
      </el-upload>
    </div>
  </template>
</el-table-column>
      </el-table>
    </div>
  </basic-container>
@@ -110,12 +126,12 @@
</script>
<style lang="scss">
.helpContainer {
  .el-table .success-row {
    --el-table-tr-bg-color: #fff;
  }
  .el-table .warning-row {
    --el-table-tr-bg-color: #f3f6ff;
  }
  // .el-table .success-row {
  //   --el-table-tr-bg-color: #fff;
  // }
  // .el-table .warning-row {
  //   --el-table-tr-bg-color: #f3f6ff;
  // }
}
</style>
<style scoped lang="scss">
@@ -145,18 +161,30 @@
.helpContainer {
  height: 100%;
  .look {
    font-family: Source Han Sans CN, Source Han Sans CN;
    color: #1c5cff;
    // font-family: Source Han Sans CN, Source Han Sans CN;
    // color: #1c5cff;
    cursor: pointer;
    margin-right: 15px;
    font-size: 14px;
    // font-size: 14px;
  }
  .uploads {
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 400;
    font-size: 14px;
    color: #19876d;
    // font-family: Source Han Sans CN, Source Han Sans CN;
    // font-weight: 400;
    // font-size: 14px;
    // color: #19876d;
    cursor: pointer;
  }
  .actionBar {
  display: flex;
  justify-content: center;
   align-items: center;
    gap: 8px;
  }
  :deep(.custom-header th.el-table__cell) {
  color: rgba(0, 0, 0, 0.85);
  background: #fafafa;
}
}
</style>
src/views/system/menu.vue
@@ -114,6 +114,7 @@
            type: 'icon',
            slot: true,
            iconList: iconList,
            value: 'el-icon-menu',
            rules: [
              {
                required: true,
src/views/system/sysConfig.vue
@@ -72,7 +72,7 @@
            ],
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'deptName',
            addDisplay: false,
            editDisplay: false,
@@ -80,13 +80,13 @@
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'deptId',
            hide: true,
            type: 'tree',
@@ -99,7 +99,7 @@
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],
src/views/system/user.vue
@@ -515,6 +515,7 @@
            column: [
              {
                label: '到期时间',
                labelWidth: 110,
                prop: 'expireTime',
                type: 'datetime',
                format: 'YYYY-MM-DD HH:mm:ss',
@@ -522,12 +523,14 @@
              },
              {
                label: '次数限制',
                labelWidth: 110,
                prop: 'maxLoginNum',
                type: 'input',
              },
              {
                label: '飞行开始时间',
                labelWidth: 110,
                prop: 'flightStartTime',
                type: 'time',
                format: 'HH:mm',
@@ -542,6 +545,7 @@
              },
              {
                label: '飞行结束时间',
                labelWidth: 110,
                prop: 'flightEndTime',
                type: 'time',
                format: 'HH:mm',
src/views/system/userinfo.vue
@@ -52,7 +52,7 @@
            <!--                        <el-form-item label="昵称:">
                                                    <el-input class="ztzf-input" v-model="userInfo.name" />
                                                </el-form-item>-->
            <el-form-item label="所属单位:">
            <el-form-item label="所属部门:">
              <el-input class="ztzf-input" v-model="userInfo.deptName" disabled />
            </el-form-item>
            <el-form-item label="手机号:">
src/views/tickets/orderLog-copy1.vue
@@ -23,7 +23,7 @@
              </div>
              <div class="search-bar-box-item">
                <el-select placeholder="请选择所属单位" v-model="filters.create_dept" clearable>
                <el-select placeholder="请选择所属部门" v-model="filters.create_dept" clearable>
                  <el-option v-for="dept in departments" :key="dept.value" :label="dept.label" :value="dept.value" />
                </el-select>
              </div>
@@ -587,7 +587,7 @@
            showOverflowTooltip: true,
          },
          {
            label: '所属单位', prop: 'dept_name', width: 100, ellipsis: true,
            label: '所属部门', prop: 'dept_name', width: 100, ellipsis: true,
            showOverflowTooltip: true,
          },
          {
src/views/tickets/orderLog.vue
@@ -138,7 +138,7 @@
              <div class="search-bar-box-item search-btn">
                <el-button type="primary" icon="el-icon-search" @click="handleSearch"
                  >搜索</el-button
                >搜索</el-button
                >
                <el-button icon="el-icon-refresh" @click="handleReset">清空</el-button>
              </div>
@@ -178,10 +178,10 @@
                type="primary"
                icon="el-icon-plus"
                @click="handleAdd"
                >新建工单</el-button
              >新建工单</el-button
              >
              <el-button type="success" plain icon="el-icon-download" @click="exportData"
                >导出</el-button
              >导出</el-button
              >
            </template>
@@ -193,7 +193,7 @@
                    type="text"
                    icon="el-icon-view"
                    @click="handleCheckDetail(row)"
                    >审核</el-button
                  >审核</el-button
                  >
                </template>
                <!-- v-if="
@@ -207,42 +207,42 @@
                    icon="el-icon-warning"
                    v-if="hasRecallPaddingBtnPermission()"
                    @click="orderLogRecall(row.id)"
                    >撤回</el-button
                  >撤回</el-button
                  >
                  <!-- <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button> -->
                </template>
                <!--已驳回-->
                <template v-if="row.status == 2">
                  <el-button type="text" icon="el-icon-warning" @click="rejectDetail(row.id)"
                    >驳回原因</el-button
                  >驳回原因</el-button
                  >
                  <el-button
                    v-if="userInfo.user_id == row.create_user"
                    type="text"
                    icon="el-icon-view"
                    @click="handleViewDetail(row)"
                    >编辑</el-button
                  >编辑</el-button
                  >
                  <el-button v-else type="text" icon="el-icon-view" @click="handleViewDetail(row)"
                    >详情</el-button
                  >详情</el-button
                  >
                </template>
                <!-- 已通过 -->
                <template v-if="row.status == 3">
                  <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)"
                    >详情</el-button
                  >详情</el-button
                  >
                </template>
                <!--草稿-->
                <template v-if="row.status == 0">
                  <el-button type="text" icon="el-icon-edit" @click="handleViewDetail(row)"
                    >编辑</el-button
                  >编辑</el-button
                  >
                  <el-button type="text" icon="el-icon-position" @click="userPublishPush(row.id)"
                    >发布</el-button
                  >发布</el-button
                  >
                  <el-button type="text" icon="el-icon-delete" @click="deleteOrderLog(row.id)"
                    >删除</el-button
                  >删除</el-button
                  >
                </template>
              </div>
@@ -281,7 +281,7 @@
              ></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
          <el-col :span="6">
            <el-form-item label="关联航线" prop="file_id">
              <el-select
                v-model="form.file_id"
@@ -298,15 +298,15 @@
              </el-select>
            </el-form-item>
          </el-col>
<!--          <el-col :span="6">-->
<!--            <el-form-item label="安全返航真高" prop="rth_altitude">-->
<!--              <el-input-number-->
<!--                v-model="form.rth_altitude"-->
<!--                :min="30"-->
<!--                :max="300"-->
<!--              ></el-input-number>-->
<!--            </el-form-item>-->
<!--          </el-col>-->
          <el-col :span="6">
            <el-form-item label="安全返航真高" prop="rth_altitude">
              <el-input-number
                v-model="form.rth_altitude"
                :min="50"
                :max="300"
              ></el-input-number>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
@@ -394,13 +394,13 @@
          </el-col>
        </el-row>
<!--        <el-row>-->
<!--          <div class="add-box-btns">-->
<!--            <el-button type="danger" @click="submitForm(1)">发起</el-button>-->
<!--            <el-button type="primary" @click="submitForm(0)">存草稿</el-button>-->
<!--            <el-button @click="dialogVisible = false">取消</el-button>-->
<!--          </div>-->
<!--        </el-row>-->
        <!--        <el-row>-->
        <!--          <div class="add-box-btns">-->
        <!--            <el-button type="danger" @click="submitForm(1)">发起</el-button>-->
        <!--            <el-button type="primary" @click="submitForm(0)">存草稿</el-button>-->
        <!--            <el-button @click="dialogVisible = false">取消</el-button>-->
        <!--          </div>-->
        <!--        </el-row>-->
      </el-form>
      <template #footer>
        <div class="dialog-footer">
@@ -558,7 +558,8 @@
          <el-col :span="3">
            <el-time-picker
              style="width: 100px"
            class="timeStyle"
        :style="{width:pxToRem(140)}"
              v-model="form.deal_time"
              prop="deal_time"
              value-format="HH:mm"
@@ -624,7 +625,7 @@
          >驳回</el-button
          >
        </div>
        </template>
      </template>
    </el-dialog>
    <!-- 工单详情 -->
@@ -800,39 +801,40 @@
      </el-form>
      <template #footer>
      <div class="dialog-footer">
        <el-button
          type="danger"
          v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)"
          @click="submitForm(1)"
          icon="el-icon-position"
        >发布</el-button
        >
        <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user"
                        @click="submitForm(0)">保存</el-button> -->
        <div class="dialog-footer">
          <el-button
            type="danger"
            v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)"
            @click="submitForm(1)"
            icon="el-icon-position"
          >发布</el-button
          >
          <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user"
                          @click="submitForm(0)">保存</el-button> -->
        <el-button
          type="primary"
          v-if="form.status == 1 && hasPaddingBtnPermission()"
          @click="orderLogPass(form.id)"
          icon="el-icon-check"
        >通过</el-button
        >
        <el-button
          type="danger"
          v-if="form.status == 1 && hasRejectionBtnPermission()"
          @click="orderLogReject(form.id)"
          icon="el-icon-close"
        >驳回</el-button
        >
        <el-button @click="detailVisibleCopy = false" icon="el-icon-circle-close">取消</el-button>
      </div>
        </template>
          <el-button
            type="primary"
            v-if="form.status == 1 && hasPaddingBtnPermission()"
            @click="orderLogPass(form.id)"
            icon="el-icon-check"
          >通过</el-button
          >
          <el-button
            type="danger"
            v-if="form.status == 1 && hasRejectionBtnPermission()"
            @click="orderLogReject(form.id)"
            icon="el-icon-close"
          >驳回</el-button
          >
          <el-button @click="detailVisibleCopy = false" icon="el-icon-circle-close">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </basic-container>
</template>
<script>
import { pxToRem, pxToRemNum } from '@/utils/rem'
import { calculateDefaultRange } from '@/utils/util';
import {
  getList,
@@ -861,9 +863,13 @@
import weekday from 'dayjs/plugin/weekday';
import elTooltipCopy from '@/components/ElTooltipCopy.vue';
import { CircleClose, Promotion, Select } from '@element-plus/icons-vue';
import { useStore } from 'vuex';
import _ from 'lodash'
// const store = useStore()
dayjs.extend(weekday);
dayjs.locale('zh-cn');
// const lastHeight = computed(() => store.state.common.lastHeight)
export default {
  components: { elTooltipCopy },
@@ -871,7 +877,7 @@
  data() {
    return {
      activeTab: 'all',
      getlastHeight: 0,
      tabs: [
        { label: '全部工单', name: 'all', value: null, count: 0 },
        { label: '待审核', name: 'WAIT_AUDIT', value: 1, count: 0 },
@@ -913,7 +919,7 @@
        indexLabel: '序号',
        indexFixed: true,
        align: 'center',
        align: 'left',
        border: true,
        stripe: false,
        searchShow: true,
@@ -1095,6 +1101,10 @@
      return CircleClose
    },
    ...mapGetters(['userInfo', 'permission']),
    lastHeight() {
      const height = this.$store.state.common.lastHeight;
      return Number(height) || 0; // 确保是数字类型
    },
    filteredTabs() {
      // rejection_and_draft 权限控制“已驳回”和“草稿”tab
      // console.log(this.permission, '权限信息')
@@ -1269,43 +1279,53 @@
              return this.$message.warning('任务时间不能小于当前时间');
            }
          }
          const maxItem = this.device_sns.reduce((max, item) => {
            return item.drone_height > max.drone_height ? item : max;
          });
          console.log(maxItem, '高度')
          let result = _.round((maxItem.drone_height + this.form.rth_altitude), 2)
          const submitData = {
            ...this.form,
            status: status,
            ai_types: this.form.ai_types?.length ? this.form.ai_types : [],
          };
          // 判断该值this.form.date_range[0] 周几 和rep_fre_type 是不是相等
          // if (this.form.deal_time) {
          //    const weekday = dayjs(this.form.date_range[0]).format('dddd');
          //    console.log('444', weekday)
          //   //  form.rep_fre_type
          //   const now = new Date()
          //   const today = now.toDateString()
          //   const selectedDate = new Date(this.form.date_range[0]).toDateString()
          if (this.lastHeight > result) {
            this.$confirm(`安全返航高度${result}米低于航线返航点高度${this.lastHeight}米为确保返航路径安全,建议您进行调整后再发布`, '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(async () => {
              const submitData = {
                ...this.form,
                status: status,
                ai_types: this.form.ai_types?.length ? this.form.ai_types : [],
              };
              await saveUpdateOrderLog(submitData);
              let id = this.form.id;
              if (id) {
                this.$message.success('工单发布成功');
              } else {
                this.$message.success('工单创建成功');
              }
              this.dialogVisible = false;
              this.detailVisible = false;
              (this.device_sns = []), (this.wayLineList = []), this.fetchTableData();
            }).catch(() => {
          //   if (today === selectedDate) {
          //     const [hours, minutes] = this.form.deal_time.split(':')
          //     const selectedTime = new Date()
          //     selectedTime.setHours(parseInt(hours), parseInt(minutes))
          //     if (selectedTime < now) {
          //       return this.$message.warning('任务时间不能小于当前时间')
          //     }
          //   }
          // }
          await saveUpdateOrderLog(submitData);
          let id = this.form.id;
          if (id) {
            this.$message.success('工单发布成功');
            });
          } else {
            this.$message.success('工单创建成功');
            const submitData = {
              ...this.form,
              status: status,
              ai_types: this.form.ai_types?.length ? this.form.ai_types : [],
            };
            await saveUpdateOrderLog(submitData);
            let id = this.form.id;
            if (id) {
              this.$message.success('工单发布成功');
            } else {
              this.$message.success('工单创建成功');
            }
            this.dialogVisible = false;
            this.detailVisible = false;
            (this.device_sns = []), (this.wayLineList = []), this.fetchTableData();
          }
          this.dialogVisible = false;
          this.detailVisible = false;
          (this.device_sns = []), (this.wayLineList = []), this.fetchTableData();
        }
      });
    },
@@ -1411,6 +1431,7 @@
    handleAdd() {
      this.form = {};
      this.form.rth_altitude = 120;
      this.dialogVisible = true;
      this.$nextTick(() => {
@@ -1615,7 +1636,6 @@
      this.initMapLine({}, async polygon => {
        const currentLine = that.wayLineList.find(item => item.wayline_id === waylineId);
        //按照航线来
        const params = {
          type: ['2', '4', '5'].includes(currentLine.wayline_type) ? 2 : 0,
@@ -1677,8 +1697,11 @@
      });
    },
  },
  watch: {
    // lastHeight(newVal, oldVal) {
    //   console.log('lastHeight', newVal, oldVal);
    //   this.getlastHeight = newVal;
    // },
    tableData: {
      handler() {
        // this.updateTabCounts()
@@ -1690,6 +1713,7 @@
</script>
<style lang="scss" scoped>
:deep(.el-input-number) {
  width: 200px;
}
src/views/tickets/ticket.vue
@@ -20,7 +20,7 @@
            />
            <!-- <el-select
              v-model="filters.department"
              placeholder="请选择所属单位"
              placeholder="请选择所属部门"
              class="filter-item"
              clearable
            >
@@ -115,7 +115,6 @@
              collapse-tags-tooltip
              clearable
              @check="handleCheck"
              @node-click="handleSFNodeClick"
              @clear="handleClear"
            />
            <el-select
@@ -277,10 +276,10 @@
          <el-row :gutter="16">
            <el-col :span="12">
              <el-form-item label="所属部门" prop="department">
              <el-form-item label="处理部门" prop="department">
                <el-select
                  v-model="form.department"
                  placeholder="请选择所属部门"
                  placeholder="请选择处理部门"
                  @change="handleDepartmentChange"
                  class="full-width"
                >
@@ -297,7 +296,7 @@
              <el-form-item label="处理人员" prop="handler">
                <el-select
                  v-model="form.handler"
                  placeholder="请先选择所属部门"
                  placeholder="请先选择处理人员"
                  :disabled="!form.department"
                  class="full-width"
                >
@@ -332,7 +331,7 @@
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="选择位置" prop="location">
              <el-form-item label="事件位置" prop="location">
                <div class="location-wrapper">
                  <avue-input-map
                    v-model="form.location"
@@ -365,7 +364,7 @@
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="附件图片" prop="photos" required class="upload-wrapper">
              <el-form-item label="事件图片" prop="photos" required class="upload-wrapper">
                <el-upload
                  v-if="createoredit === 1"
                  ref="upload"
@@ -644,7 +643,7 @@
                      :src="getThumbUrl(currentDetail.mediaUrl)"
                      :preview-src-list="[getPreviewUrl(currentDetail.mediaUrl)]"
                      fit="contain"
                      style="pxToRemNum(width: 700px); pxToRemNum(height: 520px); cursor: pointer"
                      style=" cursor: pointer"
                    >
                      <template #placeholder>
                        <div class="image-placeholder">
@@ -857,13 +856,13 @@
      <div class="review-container">
        <div class="review-image-wrapper">
          <!-- 修改左右箭头的显示条件 -->
          <div
          <el-button
            v-if="selections.length > 1 && currentReviewImage"
            class="arrow-button left"
            @click="handlePrevImage"
            icon="el-icon-arrow-left"
          >
            <i class="el-icon-arrow-left"></i>
          </div>
          </el-button>
          <div class="review-image-container">
            <!-- <el-image v-if="currentReviewImage" :src="getThumbUrl(currentReviewImage)" fit="fill"
@@ -888,13 +887,13 @@
          </div>
          <!-- 修改右箭头的显示条件 -->
          <div
          <el-button
            v-if="selections.length > 1 && currentReviewImage"
            class="arrow-button right"
            @click="handleNextImage"
            icon="el-icon-arrow-right"
          >
            <i class="el-icon-arrow-right"></i>
          </div>
          </el-button>
        </div>
        <!-- 修改分页器的显示条件 -->
@@ -1049,8 +1048,8 @@
          // { label: "序号", prop: "id", width: 70 },
          { label: '工单编号', prop: 'orderNumber', width: 170 },
          { label: '工单名称', prop: 'orderName', width: 150, overHidden: true, tooltip: true },
          { label: '所属单位', prop: 'department', overHidden: true, tooltip: true },
          { label: '发起时间', prop: 'startTime', width: 160 },
          { label: '所属部门', prop: 'department', overHidden: true, tooltip: true },
          { label: '发起时间', prop: 'startTime', width: 160, overHidden: true },
          { label: '关联算法', prop: 'aiType', overHidden: true, tooltip: true },
          {
            label: '工单类型',
@@ -1068,8 +1067,8 @@
            width: 152,
            overHidden: true,
          },
          { label: '创建人', prop: 'creator', width: 70 },
          { label: '处理人', prop: 'handler', width: 70 },
          { label: '创建人', prop: 'creator', width: 120, overHidden: true, },
          { label: '处理人', prop: 'handler', width: 120, overHidden: true, },
          {
            slot: true,
            hide: envName === 'jiangwu' ? true : false,
@@ -1284,7 +1283,7 @@
          editable: false,
        },
        {
          label: '任务发起人',
          label: '工单创建人',
          value: this.currentDetail.creator,
          editable: false,
        },
@@ -1337,7 +1336,7 @@
          type: 'input',
        },
        { label: '关键任务', value: this.currentDetail.keyData, editable: false },
        { label: '任务发起人', value: this.currentDetail.creator, 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 },
        {
@@ -1370,7 +1369,7 @@
        },
        { label: '关联任务', value: this.currentDetail.job_name || '/' },
        { label: '任务发起人', value: this.currentDetail.creator },
        { label: '工单创建人', value: this.currentDetail.creator },
        { label: '当前状态', value: this.mapStatus(this.currentDetail.status) },
        { label: '事件地址', value: this.currentDetail.address || this.currentDetail.latAndLon }, // 包含经纬度信息
        {
@@ -1524,7 +1523,7 @@
        });
      } else if (column.no === 4) {
        navigator.clipboard.writeText(row.department).then(() => {
          this.$message.success('复制所属单位成功');
          this.$message.success('复制所属部门成功');
        });
      }
    },
@@ -1756,7 +1755,8 @@
          user_id: currentTab?.name === 'myTickets' ? this.userInfo.user_id : undefined,
          is_review: this.filters.isReview === '' ? undefined : this.filters.isReview, // 添加复核状态查询参数
        };
       source:1  ,//数据来源
       };
        const response = await getList(params);
        if (!response?.data?.data?.records) {
@@ -1804,6 +1804,8 @@
            job_name: item.job_name || '',
            job_create_time: item.job_create_time || '',
            isReview: item.is_review, // 添加复核状态字段映射
          };
        });
@@ -2213,9 +2215,10 @@
      };
      console.log('this.currentDetail', this.currentDetail);
      this.detailVisible = true;
      this.handleTypeChange(this.currentDetail.type);
      console.log('this.currentDetail.location', this.currentDetail.location);
      this.$nextTick(() => {
        if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) {
@@ -2291,7 +2294,7 @@
        const headers = [
          '工单编号',
          '工单名称',
          '所属单位',
          '所属部门',
          '发起时间',
          '关联算法',
          '工单内容',
@@ -2319,7 +2322,7 @@
      return {
        工单编号: item.orderNumber || item.event_num || '',
        工单名称: item.orderName || item.event_name || '',
        所属单位: item.department || item.dept_name || '',
        所属部门: item.department || item.dept_name || '',
        发起时间: item.startTime || item.create_time || '',
        关联算法: item.aiType || item.ai_types || '',
        工单内容: item.address || item.content || '',
@@ -2537,6 +2540,7 @@
      // console.log('权限检查:', this.permission)
      return this.permission && this.permission.tickets_review_btn === true;
    },
    async submitDispatch() {
      if (this.dispatchLoading) return;
      if (!this.currentDetail.orderName || !this.currentDetail.orderName.trim()) {
@@ -2561,7 +2565,22 @@
      }
      this.dispatchLoading = true;
      console.log('派发成功', this.currentDetail);
      const isValue = this.algorithms.some(item => item.value === this.currentDetail.aiType);
      let resultValue;
      if (isValue) {
        // 如果已经是value,直接使用
        resultValue = this.currentDetail.aiType;
      } else {
        // 否则查找对应的value
        const matched = this.algorithms.find(
          item => item.dict_value === this.currentDetail.aiType ||
                  item.label === this.currentDetail.aiType
        );
        resultValue = matched ? matched.value : null;
      }
// console.log('resultValue',resultValue);
      this.$refs.dispatchForm.validate(async valid => {
        if (valid) {
          try {
@@ -2575,7 +2594,7 @@
              content: this.currentDetail.content, // 使用 content 替代原来的 remark
              createDept: this.dispatchForm.department, // 派发部门 ID
              updateUser: this.dispatchForm.handler, // 处理人 ID
              aiType: this.currentDetail.aiType,
              aiType:resultValue,
            };
            console.log('派发', data);
@@ -3825,6 +3844,7 @@
    height: 44px;
    background: rgba(0, 0, 0, 0.3);
    border-radius: 50%;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
@@ -3843,10 +3863,12 @@
    &.left {
      left: 20px;
      color: #ffffff;
    }
    &.right {
      right: 20px;
      color: #ffffff;
    }
  }
src/views/wel/components/backlog.vue
@@ -15,7 +15,7 @@
        </div>
      </div>
      <div class="todo-items" v-if="todos.length > 0" v-loading="loading" element-loading-background="rgba(255, 255, 255, 0.8)">
      <div class="todo-items" v-if="todos.length > 0" v-loading="loading" element-loading-background="rgba(255, 255, 255, 0.5)">
        <div v-for="(item, index) in todos" :key="index" class="todo-item" :style="getStatusStyle(item.status)"
          @click="jumporder(item)">
          <div class="status-indicator"><img :src="getStatus(item.status)" alt=""></div>
@@ -60,7 +60,9 @@
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
const userInfo = computed(() => store.getters.userInfo)
const todos = ref([])
const loading = ref(false)
const router = useRouter()
const store = useStore()
const permission = computed(() => store.getters.permission)
@@ -87,9 +89,7 @@
  checked.value = item.name
  await getListMatter()
}
const userInfo = computed(() => store.getters.userInfo)
const todos = ref([])
const loading = ref(false)
// * 事件工单中2=待审核,0=待处理,3=处理中
// * 智飞工单中1: 待审核,2=已驳回,3=已通过
const statusMap = {
src/views/wel/components/proportionStatic.vue
@@ -61,6 +61,7 @@
  device_sn: '',
  end_date: undefined,
  start_date: undefined,
   source:1,//数据来源
});
const dateSelect = ref('CURRENT_YEAR');
const eventTypeList = ref([
src/views/workspace/index.vue
@@ -111,7 +111,7 @@
            ],
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'dept_name',
            addDisplay:false,
            editDisplay:false,
@@ -119,13 +119,13 @@
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '所属单位',
            label: '所属部门',
            prop: 'dept_id',
            hide: true,
            type: 'tree',
@@ -139,7 +139,7 @@
            rules: [
              {
                required: true,
                message: '请输入所属单位',
                message: '请输入所属部门',
                trigger: 'blur',
              },
            ],