forked from drone/command-center-dashboard

shuishen
2025-04-02 e14358f85a7d32a753225f253ff223d17cf36c25
style: 风格处理
112 files modified
24833 ■■■■ changed files
.prettierrc.json 23 ●●●● patch | view | raw | blame | history
package.json 107 ●●●● patch | view | raw | blame | history
src/api/base/region.js 84 ●●●● patch | view | raw | blame | history
src/api/common.js 16 ●●●● patch | view | raw | blame | history
src/api/desk/notice.js 98 ●●●● patch | view | raw | blame | history
src/api/flow/flow.js 196 ●●●● patch | view | raw | blame | history
src/api/home/aggregation.js 32 ●●●● patch | view | raw | blame | history
src/api/home/index.js 173 ●●●● patch | view | raw | blame | history
src/api/home/machineNest.js 85 ●●●● patch | view | raw | blame | history
src/api/job/jobinfo.js 124 ●●●● patch | view | raw | blame | history
src/api/job/jobserver.js 90 ●●●● patch | view | raw | blame | history
src/api/logs.js 104 ●●●● patch | view | raw | blame | history
src/api/report/report.js 38 ●●●● patch | view | raw | blame | history
src/api/resource/attach.js 78 ●●●● patch | view | raw | blame | history
src/api/resource/oss.js 94 ●●●● patch | view | raw | blame | history
src/api/resource/sms.js 114 ●●●● patch | view | raw | blame | history
src/api/system/client.js 78 ●●●● patch | view | raw | blame | history
src/api/system/dept.js 128 ●●●● patch | view | raw | blame | history
src/api/system/dict.js 142 ●●●● patch | view | raw | blame | history
src/api/system/dictbiz.js 142 ●●●● patch | view | raw | blame | history
src/api/system/menu.js 172 ●●●● patch | view | raw | blame | history
src/api/system/param.js 78 ●●●● patch | view | raw | blame | history
src/api/system/post.js 94 ●●●● patch | view | raw | blame | history
src/api/system/role.js 154 ●●●● patch | view | raw | blame | history
src/api/system/scope.js 154 ●●●● patch | view | raw | blame | history
src/api/system/tenant.js 196 ●●●● patch | view | raw | blame | history
src/api/system/tenantdatasource.js 78 ●●●● patch | view | raw | blame | history
src/api/system/tenantpackage.js 78 ●●●● patch | view | raw | blame | history
src/api/system/topmenu.js 122 ●●●● patch | view | raw | blame | history
src/api/system/user.js 240 ●●●● patch | view | raw | blame | history
src/api/tool/code.js 124 ●●●● patch | view | raw | blame | history
src/api/tool/codesetting.js 140 ●●●● patch | view | raw | blame | history
src/api/tool/datasource.js 78 ●●●● patch | view | raw | blame | history
src/api/tool/model.js 176 ●●●● patch | view | raw | blame | history
src/api/user.js 290 ●●●● patch | view | raw | blame | history
src/api/work/process.js 46 ●●●● patch | view | raw | blame | history
src/api/work/work.js 130 ●●●● patch | view | raw | blame | history
src/axios.js 390 ●●●● patch | view | raw | blame | history
src/components/basic-video/plugin.js 162 ●●●● patch | view | raw | blame | history
src/components/index.js 23 ●●●● patch | view | raw | blame | history
src/config/env.js 4 ●●●● patch | view | raw | blame | history
src/config/iconList.js 758 ●●●● patch | view | raw | blame | history
src/config/website.js 154 ●●●● patch | view | raw | blame | history
src/const/tool/model.js 662 ●●●● patch | view | raw | blame | history
src/debug.js 50 ●●●● patch | view | raw | blame | history
src/directive/drag.js 67 ●●●● patch | view | raw | blame | history
src/directive/selectLoad.js 18 ●●●● patch | view | raw | blame | history
src/error.js 46 ●●●● patch | view | raw | blame | history
src/lang/en.js 270 ●●●● patch | view | raw | blame | history
src/lang/index.js 46 ●●●● patch | view | raw | blame | history
src/lang/zh.js 270 ●●●● patch | view | raw | blame | history
src/main.js 14 ●●●● patch | view | raw | blame | history
src/mixins/crud.js 430 ●●●● patch | view | raw | blame | history
src/mixins/index.js 86 ●●●● patch | view | raw | blame | history
src/mockProdServer.js 12 ●●●● patch | view | raw | blame | history
src/option/job/jobinfo.js 1000 ●●●● patch | view | raw | blame | history
src/option/job/jobserver.js 154 ●●●● patch | view | raw | blame | history
src/option/system/dict.js 414 ●●●● patch | view | raw | blame | history
src/option/system/dictbiz.js 416 ●●●● patch | view | raw | blame | history
src/option/tool/code.js 1322 ●●●● patch | view | raw | blame | history
src/option/tool/codesetting.js 456 ●●●● patch | view | raw | blame | history
src/option/tool/formsetting.js 188 ●●●● patch | view | raw | blame | history
src/option/user/info.js 166 ●●●● patch | view | raw | blame | history
src/permission.js 110 ●●●● patch | view | raw | blame | history
src/router/avue-router.js 324 ●●●● patch | view | raw | blame | history
src/router/index.js 52 ●●●● patch | view | raw | blame | history
src/router/page/index.js 137 ●●●● patch | view | raw | blame | history
src/router/views/index.js 102 ●●●● patch | view | raw | blame | history
src/store/getters.js 74 ●●●● patch | view | raw | blame | history
src/store/index.js 38 ●●●● patch | view | raw | blame | history
src/store/modules/common.js 182 ●●●● patch | view | raw | blame | history
src/store/modules/dict.js 64 ●●●● patch | view | raw | blame | history
src/store/modules/home.js 181 ●●●● patch | view | raw | blame | history
src/store/modules/logs.js 92 ●●●● patch | view | raw | blame | history
src/store/modules/tags.js 72 ●●●● patch | view | raw | blame | history
src/store/modules/user.js 788 ●●●● patch | view | raw | blame | history
src/utils/auth.js 26 ●●●● patch | view | raw | blame | history
src/utils/cesium-tsa.js 1958 ●●●● patch | view | raw | blame | history
src/utils/cesium/AmapMercatorTilingScheme/CoordTransform.js 302 ●●●● patch | view | raw | blame | history
src/utils/cesium/AmapMercatorTilingScheme/index.js 66 ●●●● patch | view | raw | blame | history
src/utils/cesium/ImageTrailMaterial.js 144 ●●●● patch | view | raw | blame | history
src/utils/cesium/common.js 307 ●●●●● patch | view | raw | blame | history
src/utils/cesium/compressImage.js 74 ●●●● patch | view | raw | blame | history
src/utils/cesium/compressImage2.js 60 ●●●● patch | view | raw | blame | history
src/utils/cesium/frustum/CreateFrustum.js 486 ●●●● patch | view | raw | blame | history
src/utils/cesium/kmz.js 359 ●●●● patch | view | raw | blame | history
src/utils/cesium/mapUtil.js 537 ●●●● patch | view | raw | blame | history
src/utils/cesium/use-kmz-tsa.js 1316 ●●●● patch | view | raw | blame | history
src/utils/crypto.js 170 ●●●● patch | view | raw | blame | history
src/utils/date.js 82 ●●●● patch | view | raw | blame | history
src/utils/flow.js 10 ●●●● patch | view | raw | blame | history
src/utils/formatter.js 65 ●●●● patch | view | raw | blame | history
src/utils/func.js 556 ●●●● patch | view | raw | blame | history
src/utils/http/config.js 101 ●●●● patch | view | raw | blame | history
src/utils/http/enums.js 26 ●●●● patch | view | raw | blame | history
src/utils/module.js 60 ●●●● patch | view | raw | blame | history
src/utils/rem.js 7 ●●●●● patch | view | raw | blame | history
src/utils/sensitive.js 144 ●●●● patch | view | raw | blame | history
src/utils/sm2.js 14 ●●●● patch | view | raw | blame | history
src/utils/staticData/device.js 466 ●●●● patch | view | raw | blame | history
src/utils/staticData/enums.js 172 ●●●● patch | view | raw | blame | history
src/utils/store.js 158 ●●●● patch | view | raw | blame | history
src/utils/util.js 604 ●●●● patch | view | raw | blame | history
src/utils/validate.js 356 ●●●● patch | view | raw | blame | history
src/utils/websocket/connect-websocket.js 12 ●●●● patch | view | raw | blame | history
src/utils/websocket/drone-ws-control.js 249 ●●●●● patch | view | raw | blame | history
src/views/Home/Footer.vue 194 ●●●● patch | view | raw | blame | history
src/views/Home/components/HomeLeft/InspectionRaskDetails.vue 387 ●●●● patch | view | raw | blame | history
src/views/Home/useEventOperate/useEventOperate.js 400 ●●●● patch | view | raw | blame | history
src/views/Home/useUavHome/useUavHome.js 748 ●●●● patch | view | raw | blame | history
src/websocket/index.js 110 ●●●● patch | view | raw | blame | history
src/websocket/util/config.js 17 ●●●● patch | view | raw | blame | history
.prettierrc.json
@@ -1,9 +1,24 @@
{
  "printWidth": 120,
  "printWidth": 100,
  "tabWidth": 2,
  "semi": true,
  "semi": false,
  "singleAttributePerLine": false,
  "bracketSpacing": true,
  "singleQuote": true,
  "arrowParens": "avoid"
}
  "arrowParens": "avoid",
  "endOfLine": "crlf",
  "bracketSameLine": false,
  "proseWrap": "preserve",
  "useTabs": true,
  "trailingComma": "es5",
  "overrides": [
    {
      "files": "*.scss",
      "options": {
        "parser": "scss",
        "tabWidth": 4,
        "singleQuote": false
      }
    }
  ]
}
package.json
@@ -1,55 +1,56 @@
{
    "name": "saber",
    "version": "4.5.0",
    "scripts": {
        "dev": "vite --host",
        "prod": "vite --mode production",
        "build:dev": "vite build --mode development",
        "build:prod": "vite build --mode production",
        "serve": "vite preview --host"
    },
    "dependencies": {
        "@element-plus/icons-vue": "^2.3.1",
        "@saber/nf-design-base-elp": "^1.3.0",
        "@saber/nf-form-design-elp": "^1.4.1",
        "@saber/nf-form-elp": "^1.4.4",
        "@smallwei/avue": "^3.6.2",
        "animate.css": "^4.1.1",
        "avue-plugin-ueditor": "^1.0.4",
        "axios": "^1.8.3",
        "cesium": "^1.126.0",
        "codemirror": "^5.65.16",
        "crypto-js": "^4.1.1",
        "dayjs": "^1.10.6",
        "disable-devtool": "^0.3.8",
        "echarts": "^5.6.0",
        "element-plus": "^2.9.3",
        "highlight.js": "^11.9.0",
        "js-base64": "^3.7.4",
        "js-cookie": "^3.0.0",
        "js-md5": "^0.7.3",
        "lodash": "^4.17.21",
        "nprogress": "^0.2.0",
        "postcss-pxtorem": "^6.1.0",
        "reconnecting-websocket": "^4.4.0",
        "sm-crypto": "^0.3.13",
        "vue": "^3.5.13",
        "vue-i18n": "^9.1.9",
        "vue-router": "^4.3.2",
        "vue3-clipboard": "^1.0.0",
        "vuex": "^4.1.0",
        "@turf/turf": "^6.5.0"
    },
    "devDependencies": {
        "@vitejs/plugin-vue": "^5.0.4",
        "@vue/compiler-sfc": "^3.4.27",
        "prettier": "^2.8.7",
        "sass": "^1.85.1",
        "terser": "^5.31.1",
        "unplugin-auto-import": "^0.11.2",
        "vite": "^5.2.12",
        "vite-plugin-compression": "^0.5.1",
        "vite-plugin-svg-icons": "^2.0.1",
        "vite-plugin-vue-setup-extend": "^0.4.0"
    }
  "name": "saber",
  "version": "4.5.0",
  "scripts": {
    "dev": "vite --host",
    "prod": "vite --mode production",
    "build:dev": "vite build --mode development",
    "build:prod": "vite build --mode production",
    "serve": "vite preview --host",
    "format": "prettier --write \"src/**/*.+(js|ts|jsx|tsx)\""
  },
  "dependencies": {
    "@element-plus/icons-vue": "^2.3.1",
    "@saber/nf-design-base-elp": "^1.3.0",
    "@saber/nf-form-design-elp": "^1.4.1",
    "@saber/nf-form-elp": "^1.4.4",
    "@smallwei/avue": "^3.6.2",
    "animate.css": "^4.1.1",
    "avue-plugin-ueditor": "^1.0.4",
    "axios": "^1.8.3",
    "cesium": "^1.126.0",
    "codemirror": "^5.65.16",
    "crypto-js": "^4.1.1",
    "dayjs": "^1.10.6",
    "disable-devtool": "^0.3.8",
    "echarts": "^5.6.0",
    "element-plus": "^2.9.3",
    "highlight.js": "^11.9.0",
    "js-base64": "^3.7.4",
    "js-cookie": "^3.0.0",
    "js-md5": "^0.7.3",
    "lodash": "^4.17.21",
    "nprogress": "^0.2.0",
    "postcss-pxtorem": "^6.1.0",
    "reconnecting-websocket": "^4.4.0",
    "sm-crypto": "^0.3.13",
    "vue": "^3.5.13",
    "vue-i18n": "^9.1.9",
    "vue-router": "^4.3.2",
    "vue3-clipboard": "^1.0.0",
    "vuex": "^4.1.0",
    "@turf/turf": "^6.5.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.4",
    "@vue/compiler-sfc": "^3.4.27",
    "prettier": "^2.8.7",
    "sass": "^1.85.1",
    "terser": "^5.31.1",
    "unplugin-auto-import": "^0.11.2",
    "vite": "^5.2.12",
    "vite-plugin-compression": "^0.5.1",
    "vite-plugin-svg-icons": "^2.0.1",
    "vite-plugin-vue-setup-extend": "^0.4.0"
  }
}
src/api/base/region.js
@@ -1,52 +1,52 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/region/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/region/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getLazyTree = (parentCode, params) => {
  return request({
    url: '/blade-system/region/lazy-tree',
    method: 'get',
    params: {
      ...params,
      parentCode,
    },
  });
};
    return request({
        url: '/blade-system/region/lazy-tree',
        method: 'get',
        params: {
            ...params,
            parentCode,
        },
    })
}
export const getDetail = code => {
  return request({
    url: '/blade-system/region/detail',
    method: 'get',
    params: {
      code,
    },
  });
};
    return request({
        url: '/blade-system/region/detail',
        method: 'get',
        params: {
            code,
        },
    })
}
export const remove = id => {
  return request({
    url: '/blade-system/region/remove',
    method: 'post',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/region/remove',
        method: 'post',
        params: {
            id,
        },
    })
}
export const submit = row => {
  return request({
    url: '/blade-system/region/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/region/submit',
        method: 'post',
        data: row,
    })
}
src/api/common.js
@@ -1,4 +1,4 @@
import request from '@/axios';
import request from '@/axios'
/**
 * 文件流返回
@@ -6,10 +6,10 @@
 * @param params 接口参数
 */
export const exportBlob = (url, params) => {
  return request({
    url: url,
    params: params,
    method: 'get',
    responseType: 'blob',
  });
};
    return request({
        url: url,
        params: params,
        method: 'get',
        responseType: 'blob',
    })
}
src/api/desk/notice.js
@@ -1,59 +1,59 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-desk/notice/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
    cryptoToken: false,
    cryptoData: false,
  });
};
    return request({
        url: '/blade-desk/notice/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
        cryptoToken: false,
        cryptoData: false,
    })
}
export const remove = ids => {
  return request({
    url: '/blade-desk/notice/remove',
    method: 'post',
    params: {
      ids,
    },
    cryptoToken: false,
    cryptoData: false,
  });
};
    return request({
        url: '/blade-desk/notice/remove',
        method: 'post',
        params: {
            ids,
        },
        cryptoToken: false,
        cryptoData: false,
    })
}
export const add = row => {
  return request({
    url: '/blade-desk/notice/submit',
    method: 'post',
    data: row,
    cryptoToken: false,
    cryptoData: false,
  });
};
    return request({
        url: '/blade-desk/notice/submit',
        method: 'post',
        data: row,
        cryptoToken: false,
        cryptoData: false,
    })
}
export const update = row => {
  return request({
    url: '/blade-desk/notice/submit',
    method: 'post',
    data: row,
    cryptoToken: false,
    cryptoData: false,
  });
};
    return request({
        url: '/blade-desk/notice/submit',
        method: 'post',
        data: row,
        cryptoToken: false,
        cryptoData: false,
    })
}
export const getNotice = id => {
  return request({
    url: '/blade-desk/notice/detail',
    method: 'get',
    params: {
      id,
    },
    cryptoToken: false,
    cryptoData: false,
  });
};
    return request({
        url: '/blade-desk/notice/detail',
        method: 'get',
        params: {
            id,
        },
        cryptoToken: false,
        cryptoData: false,
    })
}
src/api/flow/flow.js
@@ -1,122 +1,122 @@
import request from '@/axios';
import request from '@/axios'
export const modelList = (current, size, params) => {
  return request({
    url: '/blade-flow/model/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/model/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const managerList = (current, size, params) => {
  return request({
    url: '/blade-flow/manager/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/manager/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const followList = (current, size, params) => {
  return request({
    url: '/blade-flow/follow/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/follow/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const removeModel = ids => {
  return request({
    url: '/blade-flow/model/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-flow/model/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const deployModel = params => {
  return request({
    url: '/blade-flow/model/deploy',
    method: 'post',
    params,
  });
};
    return request({
        url: '/blade-flow/model/deploy',
        method: 'post',
        params,
    })
}
export const changeState = params => {
  return request({
    url: '/blade-flow/manager/change-state',
    method: 'post',
    params,
  });
};
    return request({
        url: '/blade-flow/manager/change-state',
        method: 'post',
        params,
    })
}
export const deployUpload = (category, tenantIds, files) => {
  const formData = new FormData();
  formData.append('category', category);
  formData.append('tenantIds', tenantIds);
  files.forEach(file => {
    formData.append('files', file);
  });
  return request({
    headers: {
      'Content-Type': 'multipart/form-data',
    },
    url: '/blade-flow/manager/deploy-upload',
    method: 'post',
    data: formData,
  });
};
    const formData = new FormData()
    formData.append('category', category)
    formData.append('tenantIds', tenantIds)
    files.forEach(file => {
        formData.append('files', file)
    })
    return request({
        headers: {
            'Content-Type': 'multipart/form-data',
        },
        url: '/blade-flow/manager/deploy-upload',
        method: 'post',
        data: formData,
    })
}
export const deleteDeployment = deploymentIds => {
  return request({
    url: '/blade-flow/manager/delete-deployment',
    method: 'post',
    params: {
      deploymentIds,
    },
  });
};
    return request({
        url: '/blade-flow/manager/delete-deployment',
        method: 'post',
        params: {
            deploymentIds,
        },
    })
}
export const deleteProcessInstance = params => {
  return request({
    url: '/blade-flow/follow/delete-process-instance',
    method: 'post',
    params,
  });
};
    return request({
        url: '/blade-flow/follow/delete-process-instance',
        method: 'post',
        params,
    })
}
export const submitModel = data => {
  return request({
    url: '/blade-flow/model/submit',
    method: 'post',
    data,
  });
};
    return request({
        url: '/blade-flow/model/submit',
        method: 'post',
        data,
    })
}
export const detail = params => {
  return request({
    url: '/blade-flow/model/detail',
    method: 'get',
    params,
  });
};
    return request({
        url: '/blade-flow/model/detail',
        method: 'get',
        params,
    })
}
export const modelView = params => {
  return request({
    url: '/blade-flow/process/model-view',
    method: 'get',
    params,
  });
};
    return request({
        url: '/blade-flow/process/model-view',
        method: 'get',
        params,
    })
}
src/api/home/aggregation.js
@@ -1,19 +1,17 @@
import request from '@/axios';
import request from '@/axios'
export const getDeviceRegionCount = params => {
    return request({
        url: '/drone-device-core/manage/api/v1/devices/getDeviceRegionCount',
        method: 'get',
        params,
    })
}
export const getDeviceRegionCount = (params) => {
  return request({
    url: '/drone-device-core/manage/api/v1/devices/getDeviceRegionCount',
    method: 'get',
    params
  });
};
export const getDeviceRegion = (params) => {
  return request({
    url: '/drone-device-core/manage/api/v1/devices/getDeviceRegion',
    method: 'get',
    params
  });
};
export const getDeviceRegion = params => {
    return request({
        url: '/drone-device-core/manage/api/v1/devices/getDeviceRegion',
        method: 'get',
        params,
    })
}
src/api/home/index.js
@@ -1,110 +1,109 @@
import request from '@/axios';
import request from '@/axios'
// 巡检总任务数量
export const getTotalJobNum = (params) => {
  return request({
    url: '/drone-device-core/wayline/waylineJobInfo/totalJobNum',
    method: 'get',
    params
  });
};
export const getTotalJobNum = params => {
    return request({
        url: '/drone-device-core/wayline/waylineJobInfo/totalJobNum',
        method: 'get',
        params,
    })
}
// 巡检任务item数量
export const getJobStatistics = (data) => {
  return request({
    url: '/drone-device-core/wayline/waylineJobInfo/jobStatistics',
    method: 'post',
    data
  });
};
export const getJobStatistics = data => {
    return request({
        url: '/drone-device-core/wayline/waylineJobInfo/jobStatistics',
        method: 'post',
        data,
    })
}
// 巡检任务柱状图数据
export const getJobNumBar = (data) => {
  return request({
    url: '/drone-device-core/wayline/waylineJobInfo/jobNumBar',
    method: 'post',
    data
  });
};
export const getJobNumBar = data => {
    return request({
        url: '/drone-device-core/wayline/waylineJobInfo/jobNumBar',
        method: 'post',
        data,
    })
}
// 事件概况总数
export const getJobEventTotal = () => {
  return request({
    url: '/drone-device-core/jobEvent/total',
    method: 'get',
  });
};
    return request({
        url: '/drone-device-core/jobEvent/total',
        method: 'get',
    })
}
// 事件概况分类数
export const getJobEventByStatus = (data) => {
  return request({
    url: '/drone-device-core/jobEvent/eventByStatus',
    method: 'post',
    data
  });
};
export const getJobEventBrokerLine = (data) => {
  return request({
    url: '/drone-device-core/jobEvent/eventBrokerLine',
    method: 'post',
    data
  });
};
export const getJobEventByStatus = data => {
    return request({
        url: '/drone-device-core/jobEvent/eventByStatus',
        method: 'post',
        data,
    })
}
export const getJobEventBrokerLine = data => {
    return request({
        url: '/drone-device-core/jobEvent/eventBrokerLine',
        method: 'post',
        data,
    })
}
// 任务成果
export const getMediaFileCountBy = () => {
  return request({
    url: '/blade-resource/media/api/v1/workspaces/files/getMediaFileCountBy',
    method: 'get',
  });
};
    return request({
        url: '/blade-resource/media/api/v1/workspaces/files/getMediaFileCountBy',
        method: 'get',
    })
}
// 降本增效
export const optimizeCostEfficiency = () => {
  return request({
    url: '/drone-device-core/manage/api/v1/devices/optimizeCostEfficiency',
    method: 'get',
  });
};
    return request({
        url: '/drone-device-core/manage/api/v1/devices/optimizeCostEfficiency',
        method: 'get',
    })
}
// 历史巡检任务列表
export const getBeforeJob = (data) => {
  return request({
    url: '/drone-device-core/wayline/waylineJobInfo/beforeJob',
    method: 'post',
    data
  });
};
export const getBeforeJob = data => {
    return request({
        url: '/drone-device-core/wayline/waylineJobInfo/beforeJob',
        method: 'post',
        data,
    })
}
// 当前巡检任务列表
export const getTodayJob = (data) => {
  return request({
    url: '/drone-device-core/wayline/waylineJobInfo/todayJob',
    method: 'post',
    data
  });
};
export const getTodayJob = data => {
    return request({
        url: '/drone-device-core/wayline/waylineJobInfo/todayJob',
        method: 'post',
        data,
    })
}
// 巡检任务详情 柱状图
export const jobNumBar = (data) => {
  return request({
    url: '/drone-device-core/wayline/waylineJobInfo/jobEventBar',
    method: 'post',
    data
  });
};
export const jobNumBar = data => {
    return request({
        url: '/drone-device-core/wayline/waylineJobInfo/jobEventBar',
        method: 'post',
        data,
    })
}
// 巡检任务详情 饼图
export const eventNumPie = (data) => {
  return request({
    url: '/drone-device-core/jobEvent/eventNumPie',
    method: 'post',
    data
  });
};
export const eventNumPie = data => {
    return request({
        url: '/drone-device-core/jobEvent/eventNumPie',
        method: 'post',
        data,
    })
}
// 获取区域
export const getRegion = (code) => {
  return request({
    url: '/blade-system/region/select',
    method: 'get',
    params:{code}
  });
};
export const getRegion = code => {
    return request({
        url: '/blade-system/region/select',
        method: 'get',
        params: { code },
    })
}
src/api/home/machineNest.js
@@ -1,49 +1,48 @@
import request from '@/axios';
import request from '@/axios'
// 机巢统计
export const getDeviceInfoNum = (params) => {
  return request({
    url: '/drone-device-core/manage/api/v1/devices/getDeviceInfoNum',
    method: 'get',
    params,
  });
};
export const getDeviceInfoNum = params => {
    return request({
        url: '/drone-device-core/manage/api/v1/devices/getDeviceInfoNum',
        method: 'get',
        params,
    })
}
// 机巢列表
export const selectDevicePage = ({ nickname,is_execute, ...params}) => {
  return request({
    url: `/drone-device-core/manage/api/v1/devices/selectDevicePage?type=${params.type}&current=${params.current}&size=${params.size}`,
    method: 'post',
    data: {
      nickname,
      is_execute,
    },
  });
};
export const selectDevicePage = ({ nickname, is_execute, ...params }) => {
    return request({
        url: `/drone-device-core/manage/api/v1/devices/selectDevicePage?type=${params.type}&current=${params.current}&size=${params.size}`,
        method: 'post',
        data: {
            nickname,
            is_execute,
        },
    })
}
// 机巢数据
export const getFlightStatistics = (dockSn) => {
  return request({
    url: `/drone-device-core/manage/api/v1/devices/getFlightStatistics?dockSn=${dockSn}`,
    method: 'get',
    params: {},
  });
};
export const getFlightStatistics = dockSn => {
    return request({
        url: `/drone-device-core/manage/api/v1/devices/getFlightStatistics?dockSn=${dockSn}`,
        method: 'get',
        params: {},
    })
}
// 机巢直播/无人机直播 均可使用
export const liveStart = (deviceSn) => {
  return request({
    url: `/drone-device-core/manage/api/v1/live/streams/liveStart?deviceSn=${deviceSn}`,
    method: 'post',
    data: {},
    headers: {
      'areaCode': '',
    },
  });
};
export const liveStart = deviceSn => {
    return request({
        url: `/drone-device-core/manage/api/v1/live/streams/liveStart?deviceSn=${deviceSn}`,
        method: 'post',
        data: {},
        headers: {
            areaCode: '',
        },
    })
}
// 单个机巢获取机巢详情
export const getDeviceDetail = (deviceSn) => {
  return request({
    url: `/drone-device-core/manage/api/v1/devices/getDeviceDetail?deviceSn=${deviceSn}`,
    method: 'get',
    params: {},
  });
};
export const getDeviceDetail = deviceSn => {
    return request({
        url: `/drone-device-core/manage/api/v1/devices/getDeviceDetail?deviceSn=${deviceSn}`,
        method: 'get',
        params: {},
    })
}
src/api/job/jobinfo.js
@@ -1,78 +1,78 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-job/job-info/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-job/job-info/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-job/job-info/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-job/job-info/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-job/job-info/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-job/job-info/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-job/job-info/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-job/job-info/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-job/job-info/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-job/job-info/submit',
        method: 'post',
        data: row,
    })
}
export const change = row => {
  return request({
    url: '/blade-job/job-info/change',
    method: 'post',
    params: {
      id: row.id,
      enable: row.enable,
    },
  });
};
    return request({
        url: '/blade-job/job-info/change',
        method: 'post',
        params: {
            id: row.id,
            enable: row.enable,
        },
    })
}
export const run = row => {
  return request({
    url: '/blade-job/job-info/run',
    method: 'post',
    params: {
      id: row.id,
    },
  });
};
    return request({
        url: '/blade-job/job-info/run',
        method: 'post',
        params: {
            id: row.id,
        },
    })
}
export const sync = row => {
  return request({
    url: '/blade-job/job-info/sync',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-job/job-info/sync',
        method: 'post',
        data: row,
    })
}
src/api/job/jobserver.js
@@ -1,57 +1,57 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-job/job-server/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-job/job-server/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-job/job-server/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-job/job-server/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-job/job-server/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-job/job-server/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-job/job-server/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-job/job-server/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-job/job-server/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-job/job-server/submit',
        method: 'post',
        data: row,
    })
}
export const sync = row => {
  return request({
    url: '/blade-job/job-server/sync',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-job/job-server/sync',
        method: 'post',
        data: row,
    })
}
src/api/logs.js
@@ -1,62 +1,62 @@
import request from '@/axios';
import request from '@/axios'
export const getUsualList = (current, size) => {
  return request({
    url: '/blade-log/usual/list',
    method: 'get',
    params: {
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-log/usual/list',
        method: 'get',
        params: {
            current,
            size,
        },
    })
}
export const getApiList = (current, size) => {
  return request({
    url: '/blade-log/api/list',
    method: 'get',
    params: {
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-log/api/list',
        method: 'get',
        params: {
            current,
            size,
        },
    })
}
export const getErrorList = (current, size) => {
  return request({
    url: '/blade-log/error/list',
    method: 'get',
    params: {
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-log/error/list',
        method: 'get',
        params: {
            current,
            size,
        },
    })
}
export const getUsualLogs = id => {
  return request({
    url: '/blade-log/usual/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-log/usual/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getApiLogs = id => {
  return request({
    url: '/blade-log/api/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-log/api/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getErrorLogs = id => {
  return request({
    url: '/blade-log/error/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-log/error/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
src/api/report/report.js
@@ -1,22 +1,22 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-report/report/rest/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-report/report/rest/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-report/report/rest/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-report/report/rest/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
src/api/resource/attach.js
@@ -1,49 +1,49 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-resource/attach/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-resource/attach/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-resource/attach/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-resource/attach/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-resource/attach/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-resource/attach/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-resource/attach/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-resource/attach/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-resource/attach/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-resource/attach/submit',
        method: 'post',
        data: row,
    })
}
src/api/resource/oss.js
@@ -1,59 +1,59 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-resource/oss/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-resource/oss/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-resource/oss/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-resource/oss/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-resource/oss/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-resource/oss/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-resource/oss/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-resource/oss/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-resource/oss/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-resource/oss/submit',
        method: 'post',
        data: row,
    })
}
export const enable = id => {
  return request({
    url: '/blade-resource/oss/enable',
    method: 'post',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-resource/oss/enable',
        method: 'post',
        params: {
            id,
        },
    })
}
src/api/resource/sms.js
@@ -1,71 +1,71 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-resource/sms/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-resource/sms/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-resource/sms/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-resource/sms/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-resource/sms/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-resource/sms/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-resource/sms/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-resource/sms/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-resource/sms/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-resource/sms/submit',
        method: 'post',
        data: row,
    })
}
export const enable = id => {
  return request({
    url: '/blade-resource/sms/enable',
    method: 'post',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-resource/sms/enable',
        method: 'post',
        params: {
            id,
        },
    })
}
export const send = (code, phones, params) => {
  return request({
    url: '/blade-resource/sms/endpoint/send-message',
    method: 'post',
    params: {
      code,
      phones,
      params,
    },
  });
};
    return request({
        url: '/blade-resource/sms/endpoint/send-message',
        method: 'post',
        params: {
            code,
            phones,
            params,
        },
    })
}
src/api/system/client.js
@@ -1,49 +1,49 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/client/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/client/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-system/client/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/client/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/client/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/client/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/client/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/client/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/client/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/client/submit',
        method: 'post',
        data: row,
    })
}
src/api/system/dept.js
@@ -1,80 +1,80 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/dept/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/dept/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getLazyList = (parentId, params) => {
  return request({
    url: '/blade-system/dept/lazy-list',
    method: 'get',
    params: {
      ...params,
      parentId,
    },
  });
};
    return request({
        url: '/blade-system/dept/lazy-list',
        method: 'get',
        params: {
            ...params,
            parentId,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/dept/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/dept/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/dept/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/dept/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/dept/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/dept/submit',
        method: 'post',
        data: row,
    })
}
export const getDept = id => {
  return request({
    url: '/blade-system/dept/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/dept/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getDeptTree = tenantId => {
  return request({
    url: '/blade-system/dept/tree',
    method: 'get',
    params: {
      tenantId,
    },
  });
};
    return request({
        url: '/blade-system/dept/tree',
        method: 'get',
        params: {
            tenantId,
        },
    })
}
export const getDeptLazyTree = parentId => {
  return request({
    url: '/blade-system/dept/lazy-tree',
    method: 'get',
    params: {
      parentId,
    },
  });
};
    return request({
        url: '/blade-system/dept/lazy-tree',
        method: 'get',
        params: {
            parentId,
        },
    })
}
src/api/system/dict.js
@@ -1,88 +1,88 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/dict/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/dict/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getParentList = (current, size, params) => {
  return request({
    url: '/blade-system/dict/parent-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/dict/parent-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getChildList = (current, size, parentId, params) => {
  return request({
    url: '/blade-system/dict/child-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
      parentId: parentId,
    },
  });
};
    return request({
        url: '/blade-system/dict/child-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
            parentId: parentId,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/dict/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/dict/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/dict/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/dict/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/dict/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/dict/submit',
        method: 'post',
        data: row,
    })
}
export const getDict = id => {
  return request({
    url: '/blade-system/dict/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/dict/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getDictTree = () => {
  return request({
    url: '/blade-system/dict/tree?code=DICT',
    method: 'get',
  });
};
    return request({
        url: '/blade-system/dict/tree?code=DICT',
        method: 'get',
    })
}
export const getDictionary = params => {
  return request({
    url: '/blade-system/dict/dictionary',
    method: 'get',
    params,
  });
};
    return request({
        url: '/blade-system/dict/dictionary',
        method: 'get',
        params,
    })
}
src/api/system/dictbiz.js
@@ -1,88 +1,88 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/dict-biz/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/dict-biz/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getParentList = (current, size, params) => {
  return request({
    url: '/blade-system/dict-biz/parent-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/dict-biz/parent-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getChildList = (current, size, parentId, params) => {
  return request({
    url: '/blade-system/dict-biz/child-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
      parentId: parentId,
    },
  });
};
    return request({
        url: '/blade-system/dict-biz/child-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
            parentId: parentId,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/dict-biz/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/dict-biz/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/dict-biz/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/dict-biz/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/dict-biz/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/dict-biz/submit',
        method: 'post',
        data: row,
    })
}
export const getDict = id => {
  return request({
    url: '/blade-system/dict-biz/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/dict-biz/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getDictTree = () => {
  return request({
    url: '/blade-system/dict-biz/tree?code=DICT',
    method: 'get',
  });
};
    return request({
        url: '/blade-system/dict-biz/tree?code=DICT',
        method: 'get',
    })
}
export const getDictionary = params => {
  return request({
    url: '/blade-system/dict-biz/dictionary',
    method: 'get',
    params,
  });
};
    return request({
        url: '/blade-system/dict-biz/dictionary',
        method: 'get',
        params,
    })
}
src/api/system/menu.js
@@ -1,108 +1,108 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/menu/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/menu/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getLazyList = (parentId, params) => {
  return request({
    url: '/blade-system/menu/lazy-list',
    method: 'get',
    params: {
      ...params,
      parentId,
    },
  });
};
    return request({
        url: '/blade-system/menu/lazy-list',
        method: 'get',
        params: {
            ...params,
            parentId,
        },
    })
}
export const getLazyMenuList = (parentId, params) => {
  return request({
    url: '/blade-system/menu/lazy-menu-list',
    method: 'get',
    params: {
      ...params,
      parentId,
    },
  });
};
    return request({
        url: '/blade-system/menu/lazy-menu-list',
        method: 'get',
        params: {
            ...params,
            parentId,
        },
    })
}
export const getMenuList = (current, size, params) => {
  return request({
    url: '/blade-system/menu/menu-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/menu/menu-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getMenuTree = tenantId => {
  return request({
    url: '/blade-system/menu/tree',
    method: 'get',
    params: {
      tenantId,
    },
  });
};
    return request({
        url: '/blade-system/menu/tree',
        method: 'get',
        params: {
            tenantId,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/menu/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/menu/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/menu/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/menu/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/menu/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/menu/submit',
        method: 'post',
        data: row,
    })
}
export const getMenu = id => {
  return request({
    url: '/blade-system/menu/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/menu/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getTopMenu = () =>
  request({
    url: '/blade-system/menu/top-menu',
    method: 'get',
  });
    request({
        url: '/blade-system/menu/top-menu',
        method: 'get',
    })
export const getRoutes = topMenuId =>
  request({
    url: '/blade-system/menu/routes',
    method: 'get',
    params: {
      topMenuId,
    },
  });
    request({
        url: '/blade-system/menu/routes',
        method: 'get',
        params: {
            topMenuId,
        },
    })
src/api/system/param.js
@@ -1,49 +1,49 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/param/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/param/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-system/param/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/param/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/param/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/param/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/param/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/param/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/param/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/param/submit',
        method: 'post',
        data: row,
    })
}
src/api/system/post.js
@@ -1,59 +1,59 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/post/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/post/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getPostList = tenantId => {
  return request({
    url: '/blade-system/post/select',
    method: 'get',
    params: {
      tenantId,
    },
  });
};
    return request({
        url: '/blade-system/post/select',
        method: 'get',
        params: {
            tenantId,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-system/post/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/post/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/post/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/post/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/post/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/post/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/post/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/post/submit',
        method: 'post',
        data: row,
    })
}
src/api/system/role.js
@@ -1,96 +1,96 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/role/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/role/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const grantTree = () => {
  return request({
    url: '/blade-system/menu/grant-tree',
    method: 'get',
  });
};
    return request({
        url: '/blade-system/menu/grant-tree',
        method: 'get',
    })
}
export const grant = (roleIds, menuIds, dataScopeIds, apiScopeIds) => {
  return request({
    url: '/blade-system/role/grant',
    method: 'post',
    data: {
      roleIds,
      menuIds,
      dataScopeIds,
      apiScopeIds,
    },
  });
};
    return request({
        url: '/blade-system/role/grant',
        method: 'post',
        data: {
            roleIds,
            menuIds,
            dataScopeIds,
            apiScopeIds,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/role/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/role/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/role/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/role/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/role/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/role/submit',
        method: 'post',
        data: row,
    })
}
export const getRole = roleIds => {
  return request({
    url: '/blade-system/menu/role-tree-keys',
    method: 'get',
    params: {
      roleIds,
    },
  });
};
    return request({
        url: '/blade-system/menu/role-tree-keys',
        method: 'get',
        params: {
            roleIds,
        },
    })
}
export const getRoleTree = tenantId => {
  return request({
    url: '/blade-system/role/tree',
    method: 'get',
    params: {
      tenantId,
    },
  });
};
    return request({
        url: '/blade-system/role/tree',
        method: 'get',
        params: {
            tenantId,
        },
    })
}
export const getRoleTreeById = roleId => {
  return request({
    url: '/blade-system/role/tree-by-id',
    method: 'get',
    params: {
      roleId,
    },
  });
};
    return request({
        url: '/blade-system/role/tree-by-id',
        method: 'get',
        params: {
            roleId,
        },
    })
}
export const getRoleAlias = () => {
  return request({
    url: '/blade-system/role/alias',
    method: 'get',
    params: {},
  });
};
    return request({
        url: '/blade-system/role/alias',
        method: 'get',
        params: {},
    })
}
src/api/system/scope.js
@@ -1,97 +1,97 @@
import request from '@/axios';
import request from '@/axios'
export const getListDataScope = (current, size, params) => {
  return request({
    url: '/blade-system/data-scope/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/data-scope/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const removeDataScope = ids => {
  return request({
    url: '/blade-system/data-scope/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/data-scope/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const addDataScope = row => {
  return request({
    url: '/blade-system/data-scope/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/data-scope/submit',
        method: 'post',
        data: row,
    })
}
export const updateDataScope = row => {
  return request({
    url: '/blade-system/data-scope/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/data-scope/submit',
        method: 'post',
        data: row,
    })
}
export const getMenuDataScope = id => {
  return request({
    url: '/blade-system/data-scope/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/data-scope/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getListApiScope = (current, size, params) => {
  return request({
    url: '/blade-system/api-scope/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/api-scope/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const removeApiScope = ids => {
  return request({
    url: '/blade-system/api-scope/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/api-scope/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const addApiScope = row => {
  return request({
    url: '/blade-system/api-scope/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/api-scope/submit',
        method: 'post',
        data: row,
    })
}
export const updateApiScope = row => {
  return request({
    url: '/blade-system/api-scope/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/api-scope/submit',
        method: 'post',
        data: row,
    })
}
export const getMenuApiScope = id => {
  return request({
    url: '/blade-system/api-scope/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/api-scope/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
src/api/system/tenant.js
@@ -1,122 +1,122 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/tenant/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/tenant/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-system/tenant/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/tenant/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/tenant/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/tenant/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/tenant/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/tenant/submit',
        method: 'post',
        data: row,
    })
}
export const setting = (ids, form) => {
  return request({
    url: '/blade-system/tenant/setting',
    method: 'post',
    params: {
      ...form,
      ids,
    },
  });
};
    return request({
        url: '/blade-system/tenant/setting',
        method: 'post',
        params: {
            ...form,
            ids,
        },
    })
}
export const datasource = (tenantId, datasourceId) => {
  return request({
    url: '/blade-system/tenant/datasource',
    method: 'post',
    params: {
      tenantId,
      datasourceId,
    },
  });
};
    return request({
        url: '/blade-system/tenant/datasource',
        method: 'post',
        params: {
            tenantId,
            datasourceId,
        },
    })
}
export const info = domain => {
  return request({
    url: '/blade-system/tenant/info',
    method: 'get',
    params: {
      domain,
    },
  });
};
    return request({
        url: '/blade-system/tenant/info',
        method: 'get',
        params: {
            domain,
        },
    })
}
export const packageInfo = tenantId => {
  return request({
    url: '/blade-system/tenant/package-detail',
    method: 'get',
    params: {
      tenantId,
    },
  });
};
    return request({
        url: '/blade-system/tenant/package-detail',
        method: 'get',
        params: {
            tenantId,
        },
    })
}
export const packageSetting = (tenantId, packageId) => {
  return request({
    url: '/blade-system/tenant/package-setting',
    method: 'post',
    params: {
      tenantId,
      packageId,
    },
  });
};
    return request({
        url: '/blade-system/tenant/package-setting',
        method: 'post',
        params: {
            tenantId,
            packageId,
        },
    })
}
export const recycle = ids => {
  return request({
    url: '/blade-system/tenant/recycle',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/tenant/recycle',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const pass = ids => {
  return request({
    url: '/blade-system/tenant/pass',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/tenant/pass',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/tenant/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/tenant/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
src/api/system/tenantdatasource.js
@@ -1,49 +1,49 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/tenant-datasource/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/tenant-datasource/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-system/tenant-datasource/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/tenant-datasource/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/tenant-datasource/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/tenant-datasource/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/tenant-datasource/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/tenant-datasource/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/tenant-datasource/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/tenant-datasource/submit',
        method: 'post',
        data: row,
    })
}
src/api/system/tenantpackage.js
@@ -1,49 +1,49 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/tenant-package/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/tenant-package/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-system/tenant-package/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/tenant-package/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/tenant-package/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/tenant-package/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/tenant-package/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/tenant-package/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/tenant-package/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/tenant-package/submit',
        method: 'post',
        data: row,
    })
}
src/api/system/topmenu.js
@@ -1,77 +1,77 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-system/topmenu/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-system/topmenu/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-system/topmenu/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/topmenu/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/topmenu/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/topmenu/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/topmenu/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/topmenu/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/topmenu/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/topmenu/submit',
        method: 'post',
        data: row,
    })
}
export const grantTree = () => {
  return request({
    url: '/blade-system/menu/grant-top-tree',
    method: 'get',
  });
};
    return request({
        url: '/blade-system/menu/grant-top-tree',
        method: 'get',
    })
}
export const getTopTree = topMenuIds => {
  return request({
    url: '/blade-system/menu/top-tree-keys',
    method: 'get',
    params: {
      topMenuIds,
    },
  });
};
    return request({
        url: '/blade-system/menu/top-tree-keys',
        method: 'get',
        params: {
            topMenuIds,
        },
    })
}
export const grant = (topMenuIds, menuIds) => {
  return request({
    url: '/blade-system/topmenu/grant',
    method: 'post',
    data: {
      topMenuIds,
      menuIds,
    },
  });
};
    return request({
        url: '/blade-system/topmenu/grant',
        method: 'post',
        data: {
            topMenuIds,
            menuIds,
        },
    })
}
src/api/system/user.js
@@ -1,150 +1,150 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params, deptId) => {
  return request({
    url: '/blade-system/user/page',
    method: 'get',
    params: {
      ...params,
      current,
      size,
      deptId,
    },
  });
};
    return request({
        url: '/blade-system/user/page',
        method: 'get',
        params: {
            ...params,
            current,
            size,
            deptId,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-system/user/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-system/user/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-system/user/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/user/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-system/user/update',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/user/update',
        method: 'post',
        data: row,
    })
}
export const updatePlatform = (userId, userType, userExt) => {
  return request({
    url: '/blade-system/user/update-platform',
    method: 'post',
    params: {
      userId,
      userType,
      userExt,
    },
  });
};
    return request({
        url: '/blade-system/user/update-platform',
        method: 'post',
        params: {
            userId,
            userType,
            userExt,
        },
    })
}
export const getUser = id => {
  return request({
    url: '/blade-system/user/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/user/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getUserPlatform = id => {
  return request({
    url: '/blade-system/user/platform-detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-system/user/platform-detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const getUserInfo = () => {
  return request({
    url: '/blade-system/user/info',
    method: 'get',
  });
};
    return request({
        url: '/blade-system/user/info',
        method: 'get',
    })
}
export const resetPassword = userIds => {
  return request({
    url: '/blade-system/user/reset-password',
    method: 'post',
    params: {
      userIds,
    },
  });
};
    return request({
        url: '/blade-system/user/reset-password',
        method: 'post',
        params: {
            userIds,
        },
    })
}
export const updatePassword = (oldPassword, newPassword, newPassword1) => {
  return request({
    url: '/blade-system/user/update-password',
    method: 'post',
    params: {
      oldPassword,
      newPassword,
      newPassword1,
    },
  });
};
    return request({
        url: '/blade-system/user/update-password',
        method: 'post',
        params: {
            oldPassword,
            newPassword,
            newPassword1,
        },
    })
}
export const updateInfo = row => {
  return request({
    url: '/blade-system/user/update-info',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-system/user/update-info',
        method: 'post',
        data: row,
    })
}
export const grant = (userIds, roleIds) => {
  return request({
    url: '/blade-system/user/grant',
    method: 'post',
    params: {
      userIds,
      roleIds,
    },
  });
};
    return request({
        url: '/blade-system/user/grant',
        method: 'post',
        params: {
            userIds,
            roleIds,
        },
    })
}
export const unlock = userIds => {
  return request({
    url: '/blade-system/user/unlock',
    method: 'post',
    params: {
      userIds,
    },
  });
};
    return request({
        url: '/blade-system/user/unlock',
        method: 'post',
        params: {
            userIds,
        },
    })
}
export const auditPass = userIds => {
  return request({
    url: '/blade-system/user/audit-pass',
    method: 'post',
    params: {
      userIds,
    },
  });
};
    return request({
        url: '/blade-system/user/audit-pass',
        method: 'post',
        params: {
            userIds,
        },
    })
}
export const auditRefuse = userIds => {
  return request({
    url: '/blade-system/user/audit-refuse',
    method: 'post',
    params: {
      userIds,
    },
  });
};
    return request({
        url: '/blade-system/user/audit-refuse',
        method: 'post',
        params: {
            userIds,
        },
    })
}
src/api/tool/code.js
@@ -1,78 +1,78 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-develop/code/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-develop/code/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const build = ids => {
  return request({
    url: '/blade-develop/code/gen-code',
    method: 'post',
    params: {
      ids,
      system: 'saber',
    },
  });
};
    return request({
        url: '/blade-develop/code/gen-code',
        method: 'post',
        params: {
            ids,
            system: 'saber',
        },
    })
}
export const buildFast = form => {
  return request({
    url: '/blade-develop/code/gen-code-fast',
    method: 'post',
    data: form,
  });
};
    return request({
        url: '/blade-develop/code/gen-code-fast',
        method: 'post',
        data: form,
    })
}
export const remove = ids => {
  return request({
    url: '/blade-develop/code/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-develop/code/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-develop/code/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/code/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-develop/code/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/code/submit',
        method: 'post',
        data: row,
    })
}
export const copy = id => {
  return request({
    url: '/blade-develop/code/copy',
    method: 'post',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-develop/code/copy',
        method: 'post',
        params: {
            id,
        },
    })
}
export const getCode = id => {
  return request({
    url: '/blade-develop/code/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-develop/code/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
src/api/tool/codesetting.js
@@ -1,88 +1,88 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-develop/code-setting/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-develop/code-setting/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-develop/code-setting/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-develop/code-setting/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-develop/code-setting/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-develop/code-setting/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-develop/code-setting/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/code-setting/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-develop/code-setting/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/code-setting/submit',
        method: 'post',
        data: row,
    })
}
export const enable = id => {
  return request({
    url: '/blade-develop/code-setting/enable',
    method: 'post',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-develop/code-setting/enable',
        method: 'post',
        params: {
            id,
        },
    })
}
export const getEnableDetail = () => {
  return request({
    url: '/blade-develop/code-setting/enable-detail',
    method: 'get',
    params: {},
  });
};
    return request({
        url: '/blade-develop/code-setting/enable-detail',
        method: 'get',
        params: {},
    })
}
export const getTableForm = tableName => {
  return request({
    url: '/blade-develop/code-setting/table-form',
    method: 'get',
    params: {
      tableName,
    },
  });
};
    return request({
        url: '/blade-develop/code-setting/table-form',
        method: 'get',
        params: {
            tableName,
        },
    })
}
export const getTablePrototype = (tableName, datasourceId) => {
  return request({
    url: '/blade-develop/code-setting/table-prototype',
    method: 'get',
    params: {
      tableName,
      datasourceId,
    },
  });
};
    return request({
        url: '/blade-develop/code-setting/table-prototype',
        method: 'get',
        params: {
            tableName,
            datasourceId,
        },
    })
}
src/api/tool/datasource.js
@@ -1,49 +1,49 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-develop/datasource/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-develop/datasource/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-develop/datasource/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-develop/datasource/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-develop/datasource/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-develop/datasource/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-develop/datasource/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/datasource/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-develop/datasource/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/datasource/submit',
        method: 'post',
        data: row,
    })
}
src/api/tool/model.js
@@ -1,110 +1,110 @@
import request from '@/axios';
import request from '@/axios'
export const getList = (current, size, params) => {
  return request({
    url: '/blade-develop/model/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-develop/model/list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const getDetail = id => {
  return request({
    url: '/blade-develop/model/detail',
    method: 'get',
    params: {
      id,
    },
  });
};
    return request({
        url: '/blade-develop/model/detail',
        method: 'get',
        params: {
            id,
        },
    })
}
export const remove = ids => {
  return request({
    url: '/blade-develop/model/remove',
    method: 'post',
    params: {
      ids,
    },
  });
};
    return request({
        url: '/blade-develop/model/remove',
        method: 'post',
        params: {
            ids,
        },
    })
}
export const add = row => {
  return request({
    url: '/blade-develop/model/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/model/submit',
        method: 'post',
        data: row,
    })
}
export const update = row => {
  return request({
    url: '/blade-develop/model/submit',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/model/submit',
        method: 'post',
        data: row,
    })
}
export const getTableList = datasourceId => {
  return request({
    url: '/blade-develop/model/table-list',
    method: 'get',
    params: {
      datasourceId,
    },
  });
};
    return request({
        url: '/blade-develop/model/table-list',
        method: 'get',
        params: {
            datasourceId,
        },
    })
}
export const getTableInfo = (modelId, datasourceId) => {
  return request({
    url: '/blade-develop/model/table-info',
    method: 'get',
    params: {
      modelId,
      datasourceId,
    },
  });
};
    return request({
        url: '/blade-develop/model/table-info',
        method: 'get',
        params: {
            modelId,
            datasourceId,
        },
    })
}
export const getTableInfoByName = (tableName, datasourceId) => {
  return request({
    url: '/blade-develop/model/table-info',
    method: 'get',
    params: {
      tableName,
      datasourceId,
    },
  });
};
    return request({
        url: '/blade-develop/model/table-info',
        method: 'get',
        params: {
            tableName,
            datasourceId,
        },
    })
}
export const getModelPrototype = (modelId, datasourceId) => {
  return request({
    url: '/blade-develop/model/model-prototype',
    method: 'get',
    params: {
      modelId,
      datasourceId,
    },
  });
};
    return request({
        url: '/blade-develop/model/model-prototype',
        method: 'get',
        params: {
            modelId,
            datasourceId,
        },
    })
}
export const submitModelPrototype = row => {
  return request({
    url: '/blade-develop/model-prototype/submit-list',
    method: 'post',
    data: row,
  });
};
    return request({
        url: '/blade-develop/model-prototype/submit-list',
        method: 'post',
        data: row,
    })
}
export const prototypeDetail = modelId => {
  return request({
    url: '/blade-develop/model-prototype/select',
    method: 'get',
    params: {
      modelId,
    },
  });
};
    return request({
        url: '/blade-develop/model-prototype/select',
        method: 'get',
        params: {
            modelId,
        },
    })
}
src/api/user.js
@@ -1,174 +1,174 @@
import request from '@/axios';
import request from '@/axios'
import website from '@/config/website';
import func from '@/utils/func';
import website from '@/config/website'
import func from '@/utils/func'
export const loginByUsername = (tenantId, deptId, roleId, username, password, type, key, code) =>
  request({
    url: '/blade-auth/oauth/token',
    method: 'post',
    headers: {
      'Tenant-Id': tenantId,
      'Dept-Id': website.switchMode ? deptId : '',
      'Role-Id': website.switchMode ? roleId : '',
      'Captcha-Key': key,
      'Captcha-Code': code,
    },
    params: {
      tenantId,
      username,
      password,
      grant_type: 'password',
      scope: 'all',
      type,
    },
  });
    request({
        url: '/blade-auth/oauth/token',
        method: 'post',
        headers: {
            'Tenant-Id': tenantId,
            'Dept-Id': website.switchMode ? deptId : '',
            'Role-Id': website.switchMode ? roleId : '',
            'Captcha-Key': key,
            'Captcha-Code': code,
        },
        params: {
            tenantId,
            username,
            password,
            grant_type: 'password',
            scope: 'all',
            type,
        },
    })
export const loginBySocial = (tenantId, source, code, state) =>
  request({
    url: '/blade-auth/oauth/token',
    method: 'post',
    headers: {
      'Tenant-Id': tenantId,
    },
    params: {
      tenantId,
      source,
      code,
      state,
      grant_type: 'social',
      scope: 'all',
    },
  });
    request({
        url: '/blade-auth/oauth/token',
        method: 'post',
        headers: {
            'Tenant-Id': tenantId,
        },
        params: {
            tenantId,
            source,
            code,
            state,
            grant_type: 'social',
            scope: 'all',
        },
    })
export const loginBySso = (state, code) =>
  request({
    url: '/blade-auth/oauth/token',
    method: 'post',
    headers: {
      'Tenant-Id': state,
    },
    params: {
      tenantId: state,
      code,
      grant_type: 'authorization_code',
      scope: 'all',
      redirect_uri: website.oauth2.redirectUri,
    },
  });
    request({
        url: '/blade-auth/oauth/token',
        method: 'post',
        headers: {
            'Tenant-Id': state,
        },
        params: {
            tenantId: state,
            code,
            grant_type: 'authorization_code',
            scope: 'all',
            redirect_uri: website.oauth2.redirectUri,
        },
    })
export const loginByPhone = (tenantId, phone, id, value) =>
  request({
    url: '/blade-auth/oauth/token',
    method: 'post',
    headers: {
      'Tenant-Id': tenantId,
    },
    params: {
      tenantId,
      phone,
      id,
      value,
      grant_type: 'sms_code',
      scope: 'all',
    },
  });
    request({
        url: '/blade-auth/oauth/token',
        method: 'post',
        headers: {
            'Tenant-Id': tenantId,
        },
        params: {
            tenantId,
            phone,
            id,
            value,
            grant_type: 'sms_code',
            scope: 'all',
        },
    })
export const refreshToken = (refresh_token, tenantId, deptId, roleId) =>
  request({
    url: '/blade-auth/oauth/token',
    method: 'post',
    headers: {
      'Tenant-Id': tenantId,
      'Dept-Id': func.toStr(deptId),
      'Role-Id': func.toStr(roleId),
    },
    params: {
      tenantId,
      refresh_token,
      grant_type: 'refresh_token',
      scope: 'all',
    },
  });
    request({
        url: '/blade-auth/oauth/token',
        method: 'post',
        headers: {
            'Tenant-Id': tenantId,
            'Dept-Id': func.toStr(deptId),
            'Role-Id': func.toStr(roleId),
        },
        params: {
            tenantId,
            refresh_token,
            grant_type: 'refresh_token',
            scope: 'all',
        },
    })
export const registerUser = (tenantId, name, account, password, phone, email) =>
  request({
    url: '/blade-auth/oauth/token',
    method: 'post',
    headers: {
      'Tenant-Id': tenantId,
    },
    params: {
      name,
      username: account,
      account,
      password,
      phone,
      email,
      grant_type: 'register',
      scope: 'all',
    },
  });
    request({
        url: '/blade-auth/oauth/token',
        method: 'post',
        headers: {
            'Tenant-Id': tenantId,
        },
        params: {
            name,
            username: account,
            account,
            password,
            phone,
            email,
            grant_type: 'register',
            scope: 'all',
        },
    })
export const registerGuest = (form, oauthId) =>
  request({
    url: '/blade-system/user/register-guest',
    method: 'post',
    params: {
      tenantId: form.tenantId,
      name: form.name,
      account: form.account,
      password: form.password,
      oauthId,
    },
  });
    request({
        url: '/blade-system/user/register-guest',
        method: 'post',
        params: {
            tenantId: form.tenantId,
            name: form.name,
            account: form.account,
            password: form.password,
            oauthId,
        },
    })
export const getButtons = () =>
  request({
    url: '/blade-system/menu/buttons',
    method: 'get',
  });
    request({
        url: '/blade-system/menu/buttons',
        method: 'get',
    })
export const getCaptcha = () =>
  request({
    url: '/blade-auth/oauth/captcha',
    method: 'get',
    authorization: false,
  });
    request({
        url: '/blade-auth/oauth/captcha',
        method: 'get',
        authorization: false,
    })
export const logout = () =>
  request({
    url: '/blade-auth/oauth/logout',
    method: 'get',
    authorization: false,
  });
    request({
        url: '/blade-auth/oauth/logout',
        method: 'get',
        authorization: false,
    })
export const getUserInfo = () =>
  request({
    url: '/blade-auth/oauth/user-info',
    method: 'get',
  });
    request({
        url: '/blade-auth/oauth/user-info',
        method: 'get',
    })
export const sendLogs = list =>
  request({
    url: '/blade-auth/oauth/logout',
    method: 'post',
    data: list,
  });
    request({
        url: '/blade-auth/oauth/logout',
        method: 'post',
        data: list,
    })
export const clearCache = () =>
  request({
    url: '/blade-auth/oauth/clear-cache',
    method: 'get',
    authorization: false,
  });
    request({
        url: '/blade-auth/oauth/clear-cache',
        method: 'get',
        authorization: false,
    })
export const sendSms = (tenantId, phone) =>
  request({
    url: '/blade-auth/oauth/sms/send-validate',
    method: 'post',
    params: {
      tenantId,
      phone,
    },
  });
    request({
        url: '/blade-auth/oauth/sms/send-validate',
        method: 'post',
        params: {
            tenantId,
            phone,
        },
    })
src/api/work/process.js
@@ -1,33 +1,33 @@
import request from '@/axios';
import request from '@/axios'
// =====================参数===========================
export const historyFlowList = processInstanceId => {
  return request({
    url: '/blade-flow/process/history-flow-list',
    method: 'get',
    params: {
      processInstanceId,
    },
  });
};
    return request({
        url: '/blade-flow/process/history-flow-list',
        method: 'get',
        params: {
            processInstanceId,
        },
    })
}
// =====================请假流程===========================
export const leaveProcess = data => {
  return request({
    url: '/blade-desk/process/leave/start-process',
    method: 'post',
    data,
  });
};
    return request({
        url: '/blade-desk/process/leave/start-process',
        method: 'post',
        data,
    })
}
export const leaveDetail = businessId => {
  return request({
    url: '/blade-desk/process/leave/detail',
    method: 'get',
    params: {
      businessId,
    },
  });
};
    return request({
        url: '/blade-desk/process/leave/detail',
        method: 'get',
        params: {
            businessId,
        },
    })
}
src/api/work/work.js
@@ -1,79 +1,79 @@
import request from '@/axios';
import request from '@/axios'
export const startList = (current, size, params) => {
  return request({
    url: '/blade-flow/work/start-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/work/start-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const claimList = (current, size, params) => {
  return request({
    url: '/blade-flow/work/claim-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/work/claim-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const todoList = (current, size, params) => {
  return request({
    url: '/blade-flow/work/todo-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/work/todo-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const sendList = (current, size, params) => {
  return request({
    url: '/blade-flow/work/send-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/work/send-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const doneList = (current, size, params) => {
  return request({
    url: '/blade-flow/work/done-list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    },
  });
};
    return request({
        url: '/blade-flow/work/done-list',
        method: 'get',
        params: {
            ...params,
            current,
            size,
        },
    })
}
export const claimTask = taskId => {
  return request({
    url: '/blade-flow/work/claim-task',
    method: 'post',
    params: {
      taskId,
    },
  });
};
    return request({
        url: '/blade-flow/work/claim-task',
        method: 'post',
        params: {
            taskId,
        },
    })
}
export const completeTask = data => {
  return request({
    url: '/blade-flow/work/complete-task',
    method: 'post',
    data,
  });
};
    return request({
        url: '/blade-flow/work/complete-task',
        method: 'post',
        data,
    })
}
src/axios.js
@@ -5,222 +5,222 @@
 * isSerialize是否开启form表单提交
 * isToken是否需要token
 */
import axios from 'axios';
import store from '@/store/';
import router from '@/router/';
import { serialize } from '@/utils/util';
import { getToken, removeToken, removeRefreshToken } from '@/utils/auth';
import { isURL, validatenull } from '@/utils/validate';
import { ElMessage } from 'element-plus';
import website from '@/config/website';
import NProgress from 'nprogress'; // progress bar
import 'nprogress/nprogress.css'; // progress bar style
import { Base64 } from 'js-base64';
import { baseUrl } from '@/config/env';
import crypto from '@/utils/crypto';
import axios from 'axios'
import store from '@/store/'
import router from '@/router/'
import { serialize } from '@/utils/util'
import { getToken, removeToken, removeRefreshToken } from '@/utils/auth'
import { isURL, validatenull } from '@/utils/validate'
import { ElMessage } from 'element-plus'
import website from '@/config/website'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { Base64 } from 'js-base64'
import { baseUrl } from '@/config/env'
import crypto from '@/utils/crypto'
// 全局未授权错误提示状态,只提示一次
let isErrorShown = false;
let isErrorShown = false
// 全局锁机制相关变量
let isRefreshing = false; // 标记当前是否正在刷新token
let refreshTokenPromise = null; // 刷新token的Promise,避免重复请求
let isRefreshing = false // 标记当前是否正在刷新token
let refreshTokenPromise = null // 刷新token的Promise,避免重复请求
axios.defaults.timeout = 10000;
axios.defaults.timeout = 10000
//返回其他状态码
axios.defaults.validateStatus = function (status) {
  return status >= 200 && status <= 500; // 默认的
};
    return status >= 200 && status <= 500 // 默认的
}
//跨域请求,允许保存cookie
axios.defaults.withCredentials = true;
axios.defaults.withCredentials = true
// NProgress Configuration
NProgress.configure({
  showSpinner: false,
});
    showSpinner: false,
})
//http request拦截
axios.interceptors.request.use(
  config => {
    // start progress bar
    NProgress.start();
    // 初始化错误提示状态
    isErrorShown = false;
    //地址为已经配置状态则不添加前缀
    if (!isURL(config.url) && !config.url.startsWith(baseUrl)) {
      config.url = baseUrl + config.url;
    }
    config.headers['areaCode'] = store.state.user.selectedAreaCode;
    //安全请求header
    config.headers['Blade-Requested-With'] = 'BladeHttpRequest';
    //headers判断是否需要
    const authorization = config.authorization === false;
    if (!authorization) {
      config.headers['Authorization'] = `Basic ${Base64.encode(
        `${website.clientId}:${website.clientSecret}`
      )}`;
    }
    // 根据后端要求,post的data为空的话传{}
    if (config.method === 'post') {
      config.data = config.data || {};
    }
    //headers判断请求是否携带token
    const meta = config.meta || {};
    const isToken = meta.isToken === false;
    //headers传递token是否加密
    const cryptoToken = config.cryptoToken === true;
    //判断传递数据是否加密
    const cryptoData = config.cryptoData === true;
    const token = getToken();
    if (token && !isToken) {
      config.headers[website.tokenHeader] = cryptoToken
        ? 'crypto ' + crypto.encryptAES(token, crypto.cryptoKey)
        : 'bearer ' + token;
    }
    // 开启报文加密
    // if (cryptoData) {
    //   if (config.params) {
    //     const data = crypto.encryptAES(JSON.stringify(config.params), crypto.aesKey);
    //     config.params = { data };
    //   }
    //   if (config.data) {
    //     config.text = true;
    //     config.data = crypto.encryptAES(JSON.stringify(config.data), crypto.aesKey);
    //   }
    // }
    //headers中配置text请求
    if (config.text === true) {
      config.headers['Content-Type'] = 'text/plain';
    }
    //headers中配置serialize为true开启序列化
    if (config.method === 'post' && meta.isSerialize === true) {
      config.data = serialize(config.data);
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);
    config => {
        // start progress bar
        NProgress.start()
        // 初始化错误提示状态
        isErrorShown = false
        //地址为已经配置状态则不添加前缀
        if (!isURL(config.url) && !config.url.startsWith(baseUrl)) {
            config.url = baseUrl + config.url
        }
        config.headers['areaCode'] = store.state.user.selectedAreaCode
        //安全请求header
        config.headers['Blade-Requested-With'] = 'BladeHttpRequest'
        //headers判断是否需要
        const authorization = config.authorization === false
        if (!authorization) {
            config.headers['Authorization'] = `Basic ${Base64.encode(
                `${website.clientId}:${website.clientSecret}`
            )}`
        }
        // 根据后端要求,post的data为空的话传{}
        if (config.method === 'post') {
            config.data = config.data || {}
        }
        //headers判断请求是否携带token
        const meta = config.meta || {}
        const isToken = meta.isToken === false
        //headers传递token是否加密
        const cryptoToken = config.cryptoToken === true
        //判断传递数据是否加密
        const cryptoData = config.cryptoData === true
        const token = getToken()
        if (token && !isToken) {
            config.headers[website.tokenHeader] = cryptoToken
                ? 'crypto ' + crypto.encryptAES(token, crypto.cryptoKey)
                : 'bearer ' + token
        }
        // 开启报文加密
        // if (cryptoData) {
        //   if (config.params) {
        //     const data = crypto.encryptAES(JSON.stringify(config.params), crypto.aesKey);
        //     config.params = { data };
        //   }
        //   if (config.data) {
        //     config.text = true;
        //     config.data = crypto.encryptAES(JSON.stringify(config.data), crypto.aesKey);
        //   }
        // }
        //headers中配置text请求
        if (config.text === true) {
            config.headers['Content-Type'] = 'text/plain'
        }
        //headers中配置serialize为true开启序列化
        if (config.method === 'post' && meta.isSerialize === true) {
            config.data = serialize(config.data)
        }
        return config
    },
    error => {
        return Promise.reject(error)
    }
)
//http response拦截
axios.interceptors.response.use(
  res => {
    NProgress.done();
    //获取配置信息
    const config = res.config;
    const cryptoData = config.cryptoData === true;
    //解析加密报文
    if (cryptoData) {
      res.data = JSON.parse(crypto.decryptAES(res.data, crypto.aesKey));
    }
    //获取状态信息
    const status = res.data.error_code || res.data.code || res.status;
    const statusWhiteList = website.statusWhiteList || [];
    const message = res.data.msg || res.data.error_description || '系统错误';
    //如果在白名单里则自行catch逻辑处理
    if (statusWhiteList.includes(status)) return Promise.reject(res);
    res => {
        NProgress.done()
        //获取配置信息
        const config = res.config
        const cryptoData = config.cryptoData === true
        //解析加密报文
        if (cryptoData) {
            res.data = JSON.parse(crypto.decryptAES(res.data, crypto.aesKey))
        }
        //获取状态信息
        const status = res.data.error_code || res.data.code || res.status
        const statusWhiteList = website.statusWhiteList || []
        const message = res.data.msg || res.data.error_description || '系统错误'
        //如果在白名单里则自行catch逻辑处理
        if (statusWhiteList.includes(status)) return Promise.reject(res)
    // 如果是401并且没有重试过,尝试刷新token
    if (status === 401 && !config._retry) {
      config._retry = true;
        // 如果是401并且没有重试过,尝试刷新token
        if (status === 401 && !config._retry) {
            config._retry = true
      // 如果当前已经在刷新token,等待刷新完成
      if (isRefreshing) {
        return refreshTokenPromise.then(() => {
          const meta = config.meta || {};
          const isToken = meta.isToken === false;
          const cryptoToken = config.cryptoToken === true;
          const token = getToken();
          if (token && !isToken) {
            config.headers[website.tokenHeader] = cryptoToken
              ? 'crypto ' + crypto.encryptAES(token, crypto.cryptoKey)
              : 'bearer ' + token;
          }
          return axios(config);
        });
      }
            // 如果当前已经在刷新token,等待刷新完成
            if (isRefreshing) {
                return refreshTokenPromise.then(() => {
                    const meta = config.meta || {}
                    const isToken = meta.isToken === false
                    const cryptoToken = config.cryptoToken === true
                    const token = getToken()
                    if (token && !isToken) {
                        config.headers[website.tokenHeader] = cryptoToken
                            ? 'crypto ' + crypto.encryptAES(token, crypto.cryptoKey)
                            : 'bearer ' + token
                    }
                    return axios(config)
                })
            }
      // 开始刷新token
      isRefreshing = true;
            // 开始刷新token
            isRefreshing = true
      // 调用RefreshToken action来刷新token
      refreshTokenPromise = store
        .dispatch('RefreshToken')
        .then(() => {
          isRefreshing = false; // 重置刷新标志
          const meta = config.meta || {};
          const isToken = meta.isToken === false;
          const cryptoToken = config.cryptoToken === true;
          // 获取刷新后的token
          const token = getToken();
          if (token && !isToken) {
            config.headers[website.tokenHeader] = cryptoToken
              ? 'crypto ' + crypto.encryptAES(token, crypto.cryptoKey)
              : 'bearer ' + token;
          }
          return axios(config);
        })
        .catch(() => {
          isRefreshing = false; // 重置刷新标志
          // 首次报错时提示
          if (!isErrorShown) {
            isErrorShown = true;
            ElMessage({
              message: '用户令牌不可用,请重新登录',
              type: 'error',
            });
          }
          // 清除token信息
          removeToken();
          removeRefreshToken();
          // 重定向到登录页
          store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }));
          return Promise.reject(new Error(message));
        });
            // 调用RefreshToken action来刷新token
            refreshTokenPromise = store
                .dispatch('RefreshToken')
                .then(() => {
                    isRefreshing = false // 重置刷新标志
                    const meta = config.meta || {}
                    const isToken = meta.isToken === false
                    const cryptoToken = config.cryptoToken === true
                    // 获取刷新后的token
                    const token = getToken()
                    if (token && !isToken) {
                        config.headers[website.tokenHeader] = cryptoToken
                            ? 'crypto ' + crypto.encryptAES(token, crypto.cryptoKey)
                            : 'bearer ' + token
                    }
                    return axios(config)
                })
                .catch(() => {
                    isRefreshing = false // 重置刷新标志
                    // 首次报错时提示
                    if (!isErrorShown) {
                        isErrorShown = true
                        ElMessage({
                            message: '用户令牌不可用,请重新登录',
                            type: 'error',
                        })
                    }
                    // 清除token信息
                    removeToken()
                    removeRefreshToken()
                    // 重定向到登录页
                    store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }))
                    return Promise.reject(new Error(message))
                })
      return refreshTokenPromise;
    }
            return refreshTokenPromise
        }
    // 如果是401并且已经重试过,直接跳转到登录页面
    if (status === 401 && config._retry) {
      if (!isErrorShown) {
        isErrorShown = true;
        ElMessage({
          message: '用户令牌不可用,请重新登录',
          type: 'error',
        });
      }
      removeToken();
      removeRefreshToken();
      store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }));
      return Promise.reject(new Error(message));
    }
        // 如果是401并且已经重试过,直接跳转到登录页面
        if (status === 401 && config._retry) {
            if (!isErrorShown) {
                isErrorShown = true
                ElMessage({
                    message: '用户令牌不可用,请重新登录',
                    type: 'error',
                })
            }
            removeToken()
            removeRefreshToken()
            store.dispatch('FedLogOut').then(() => router.push({ path: '/login' }))
            return Promise.reject(new Error(message))
        }
    // 如果请求为oauth2错误码则首次报错时提示
    if (status > 2000 && !validatenull(res.data.error_description)) {
      if (!isErrorShown) {
        isErrorShown = true;
        ElMessage({
          message: message,
          type: 'error',
        });
      }
      return Promise.reject(new Error(message));
    }
        // 如果请求为oauth2错误码则首次报错时提示
        if (status > 2000 && !validatenull(res.data.error_description)) {
            if (!isErrorShown) {
                isErrorShown = true
                ElMessage({
                    message: message,
                    type: 'error',
                })
            }
            return Promise.reject(new Error(message))
        }
    // 如果请求为非200则默认统一处理
    if (status !== 200) {
      ElMessage({
        message: message,
        type: 'error',
      });
      return Promise.reject(new Error(message));
    }
    return res;
  },
  error => {
    NProgress.done();
    return Promise.reject(new Error(error));
  }
);
        // 如果请求为非200则默认统一处理
        if (status !== 200) {
            ElMessage({
                message: message,
                type: 'error',
            })
            return Promise.reject(new Error(message))
        }
        return res
    },
    error => {
        NProgress.done()
        return Promise.reject(new Error(error))
    }
)
export default axios;
export default axios
src/components/basic-video/plugin.js
@@ -1,88 +1,88 @@
export default class RecordVideo {
  /**
   * 构造函数
   *
   * @param  {Object}   videoObj 视频对象
   */
  constructor(videoObj) {
    this.video = videoObj;
    this.mediaRecorder = null;
    this.chunks = [];
  }
    /**
     * 构造函数
     *
     * @param  {Object}   videoObj 视频对象
     */
    constructor(videoObj) {
        this.video = videoObj
        this.mediaRecorder = null
        this.chunks = []
    }
  /**
   * 初始化
   *
   * @return {Object} promise
   */
  init() {
    // 返回Promise对象
    // resolve 正常处理
    // reject 处理异常情况
    return new Promise((resovle, reject) => {
      navigator.mediaDevices
        .getUserMedia({
          audio: true,
          video: true,
          // video: {
          //     width: this.videoWidth,
          //     height: this.videoHeight
          // }
        })
        // 返回一个媒体内容的流
        .then(stream => {
          // 检测是否支持 srcObject,该属性在新的浏览器支持
          if ('srcObject' in this.video) {
            this.video.srcObject = stream;
          } else {
            // 兼容旧的浏览器
            this.video.src = window.URL.createObjectURL(stream);
          }
    /**
     * 初始化
     *
     * @return {Object} promise
     */
    init() {
        // 返回Promise对象
        // resolve 正常处理
        // reject 处理异常情况
        return new Promise((resovle, reject) => {
            navigator.mediaDevices
                .getUserMedia({
                    audio: true,
                    video: true,
                    // video: {
                    //     width: this.videoWidth,
                    //     height: this.videoHeight
                    // }
                })
                // 返回一个媒体内容的流
                .then(stream => {
                    // 检测是否支持 srcObject,该属性在新的浏览器支持
                    if ('srcObject' in this.video) {
                        this.video.srcObject = stream
                    } else {
                        // 兼容旧的浏览器
                        this.video.src = window.URL.createObjectURL(stream)
                    }
          // 当视频的元数据已经加载时触发
          this.video.addEventListener('loadmetadata', () => {
            this.video.play();
          });
          this.mediaRecorder = new MediaRecorder(stream);
          this.mediaRecorder.addEventListener('dataavailable', e => {
            this.chunks.push(e.data);
          });
          resovle();
        })
        // 异常抓取,包括用于禁用麦克风、摄像头
        .catch(error => {
          reject(error);
        });
    });
  }
                    // 当视频的元数据已经加载时触发
                    this.video.addEventListener('loadmetadata', () => {
                        this.video.play()
                    })
                    this.mediaRecorder = new MediaRecorder(stream)
                    this.mediaRecorder.addEventListener('dataavailable', e => {
                        this.chunks.push(e.data)
                    })
                    resovle()
                })
                // 异常抓取,包括用于禁用麦克风、摄像头
                .catch(error => {
                    reject(error)
                })
        })
    }
  /**
   * 视频开始录制
   */
  startRecord() {
    if (this.mediaRecorder.state === 'inactive') {
      this.mediaRecorder.start();
    }
  }
    /**
     * 视频开始录制
     */
    startRecord() {
        if (this.mediaRecorder.state === 'inactive') {
            this.mediaRecorder.start()
        }
    }
  /**
   * 视频结束录制
   */
  stopRecord() {
    if (this.mediaRecorder.state === 'recording') {
      this.mediaRecorder.stop();
    }
  }
    /**
     * 视频结束录制
     */
    stopRecord() {
        if (this.mediaRecorder.state === 'recording') {
            this.mediaRecorder.stop()
        }
    }
  /**
   * 检测当前浏览器对否支持
   *
   * @return {boolean} 当前浏览器是否支持
   */
  isSupport() {
    const flag = navigator.mediaDevices && navigator.mediaDevices.getUserMedia;
    if (flag) {
      return true;
    }
  }
    /**
     * 检测当前浏览器对否支持
     *
     * @return {boolean} 当前浏览器是否支持
     */
    isSupport() {
        const flag = navigator.mediaDevices && navigator.mediaDevices.getUserMedia
        if (flag) {
            return true
        }
    }
}
src/components/index.js
@@ -1,16 +1,15 @@
import { defineAsyncComponent } from 'vue'
export default {
    install (app) {
        // 匹配当前目录下所有.vue文件(包括子目录)
        const components = import.meta.glob('./global/*.vue', { eager: true })
    install(app) {
        // 匹配当前目录下所有.vue文件(包括子目录)
        const components = import.meta.glob('./global/*.vue', { eager: true })
        for (const [path, module] of Object.entries(components)) {
            // 提取组件名(去除路径和扩展名)
            const name = path.split('/').pop()?.replace('.vue', '') || ''
            // 注册组件
            app.component(name, (module).default)
        }
    }
}
        for (const [path, module] of Object.entries(components)) {
            // 提取组件名(去除路径和扩展名)
            const name = path.split('/').pop()?.replace('.vue', '') || ''
            // 注册组件
            app.component(name, module.default)
        }
    },
}
src/config/env.js
@@ -1,2 +1,2 @@
let baseUrl = import.meta.env.VITE_APP_API;
export { baseUrl };
let baseUrl = import.meta.env.VITE_APP_API
export { baseUrl }
src/config/iconList.js
@@ -1,380 +1,380 @@
export default [
  {
    label: '通用图标',
    list: [
      'iconfont iconicon_roundadd',
      'iconfont iconicon_compile',
      'iconfont iconicon_glass',
      'iconfont iconicon_roundclose',
      'iconfont iconicon_roundreduce',
      'iconfont iconicon_delete',
      'iconfont iconicon_shakehands',
      'iconfont iconicon_task_done',
      'iconfont iconicon_voipphone',
      'iconfont iconicon_safety',
      'iconfont iconicon_work',
      'iconfont iconicon_study',
      'iconfont iconicon_task',
      'iconfont iconicon_subordinate',
      'iconfont iconicon_star',
      'iconfont iconicon_setting',
      'iconfont iconicon_sms',
      'iconfont iconicon_share',
      'iconfont iconicon_secret',
      'iconfont iconicon_scan_namecard',
      'iconfont iconicon_principal',
      'iconfont iconicon_group',
      'iconfont iconicon_send',
      'iconfont iconicon_scan',
      'iconfont iconicon_search',
      'iconfont iconicon_refresh',
      'iconfont iconicon_savememo',
      'iconfont iconicon_QRcode',
      'iconfont iconicon_im_keyboard',
      'iconfont iconicon_redpacket',
      'iconfont iconicon_photo',
      'iconfont iconicon_qq',
      'iconfont iconicon_wechat',
      'iconfont iconicon_phone',
      'iconfont iconicon_namecard',
      'iconfont iconicon_notice',
      'iconfont iconicon_next_arrow',
      'iconfont iconicon_left',
      'iconfont iconicon_more',
      'iconfont iconicon_details',
      'iconfont iconicon_message',
      'iconfont iconicon_mobilephone',
      'iconfont iconicon_im_voice',
      'iconfont iconicon_GPS',
      'iconfont iconicon_ding',
      'iconfont iconicon_exchange',
      'iconfont iconicon_cspace',
      'iconfont iconicon_doc',
      'iconfont iconicon_dispose',
      'iconfont iconicon_discovery',
      'iconfont iconicon_community_line',
      'iconfont iconicon_cloud_history',
      'iconfont iconicon_coinpurse_line',
      'iconfont iconicon_airplay',
      'iconfont iconicon_at',
      'iconfont iconicon_addressbook',
      'iconfont iconicon_boss',
      'iconfont iconicon_addperson',
      'iconfont iconicon_affiliations_li',
      'iconfont iconicon_addmessage',
      'iconfont iconicon_addresslist',
      'iconfont iconicon_add',
      'iconfont icongithub',
      'iconfont icongitee2',
    ],
  },
  {
    label: '系统图标',
    list: [
      'iconfont icon-zhongyingwen',
      'iconfont icon-caidan',
      'iconfont icon-rizhi1',
      'iconfont icon-zhuti',
      'iconfont icon-suoping',
      'iconfont icon-bug',
      'iconfont icon-qq1',
      'iconfont icon-weixin1',
      'iconfont icon-shouji',
      'iconfont icon-mima',
      'iconfont icon-yonghu',
      'iconfont icon-yanzhengma',
      'iconfont icon-canshu',
      'iconfont icon-dongtai',
      'iconfont icon-iconset0265',
      'iconfont icon-shujuzhanshi2',
      'iconfont icon-tuichuquanping',
      'iconfont icon-rizhi',
      'iconfont icon-cuowutishitubiao',
      'iconfont icon-debug',
      'iconfont icon-iconset0216',
      'iconfont icon-quanxian',
      'iconfont icon-quanxian',
      'iconfont icon-shuaxin',
      'iconfont icon-bofangqi-suoping',
      'iconfont icon-quanping',
      'iconfont icon-navicon',
      'iconfont icon-biaodan',
      'iconfont icon-liuliangyunpingtaitubiao08',
      'iconfont icon-caidanguanli',
      'iconfont icon-cuowu',
      'iconfont icon-wxbgongju',
      'iconfont icon-tuichu',
      'iconfont icon-daohanglanmoshi02',
      'iconfont icon-changyonglogo27',
      'iconfont icon-biaoge',
      'iconfont icon-baidu1',
      'iconfont icon-tubiao',
      'iconfont icon-souhu',
      'iconfont icon-msnui-360',
      'iconfont icon-iframe',
      'iconfont icon-huanyingye',
    ],
  },
  {
    label: '业务图标',
    list: [
      'iconfont icon-zidingyi',
      'iconfont icon-xiajiantou',
      'iconfont icon-shangjiantou',
      'iconfont icon-icon_loading',
      'iconfont icon-biaodanzujian-shurukuang',
      'iconfont icon-biaodanzujian-biaoge',
      'iconfont icon-biaodanzujian-xialakuang',
      'iconfont icon-tubiao-bingtu',
      'iconfont icon-biaodanzujian-anniu',
      'iconfont icon-gongyezujian-yibiaopan',
      'iconfont icon-tubiao-qiapian',
      'iconfont icon-gongyezujian-zhishideng',
      'iconfont icon-tubiao-zhexiantu',
      'iconfont icon-xingzhuang-juxing',
      'iconfont icon-xingzhuang-jianxing',
      'iconfont icon-gongyezujian-kaiguan',
      'iconfont icon-tubiao-zhuzhuangtu',
      'iconfont icon-xingzhuang-tupian',
      'iconfont icon-xingzhuang-wenzi',
      'iconfont icon-xingzhuang-tuoyuanxing',
      'iconfont icon-xingzhuang-sanjiaoxing',
      'iconfont icon-xingzhuang-xingxing',
      'iconfont icon-guize',
      'iconfont icon-shebeiguanli',
      'iconfont icon-gongnengdingyi1',
      'iconfont icon-jishufuwu1',
      'iconfont icon-yunyingzhongxin',
      'iconfont icon-yunyingguanli',
      'iconfont icon-zuzhixiaxia',
      'iconfont icon-zuzhizhankai',
      'iconfont icon-zuzhiqunzu',
      'iconfont icon-dakai',
      'iconfont icon-yingwen',
      'iconfont icon-zhongwen',
      'iconfont icon-miwen',
      'iconfont icon-xianhao',
      'iconfont icon-kongxinduigou',
      'iconfont icon-huixingzhen',
      'iconfont icon-duigou',
      'iconfont icon-xiayibu',
      'iconfont icon-shangyibu',
      'iconfont icon-kongjianxuanzhong',
      'iconfont icon-kongjianweixuan',
      'iconfont icon-kongjianyixuan',
      'iconfont icon--diangan',
      'iconfont icon-rongxuejirongjiechi',
      'iconfont icon-lubiantingchechang',
      'iconfont icon--lumingpai',
      'iconfont icon-jietouzuoyi',
      'iconfont icon--zhongdaweixian',
      'iconfont icon--jiaotongbiaozhipai',
      'iconfont icon-gongcezhishipai',
      'iconfont icon-fangkuai',
      'iconfont icon-fangkuai-',
      'iconfont icon-shuaxin',
      'iconfont icon-baocun',
      'iconfont icon-fabu',
      'iconfont icon-xiayibu1',
      'iconfont icon-shangyibu1',
      'iconfont icon-xiangxiazhanhang',
      'iconfont icon-xiangshangzhanhang',
      'iconfont icon-tupianjiazaishibai',
      'iconfont icon-fuwudiqiu',
      'iconfont icon-suoxiao',
      'iconfont icon-fangda',
      'iconfont icon-huanyuanhuabu',
      'iconfont icon-quanping',
      'iconfont icon-biaodanzujian-biaoge1',
      'iconfont icon-APIshuchu',
      'iconfont icon-APIjieru',
      'iconfont icon-wenjianjia',
      'iconfont icon-DOC',
      'iconfont icon-BMP',
      'iconfont icon-GIF',
      'iconfont icon-JPG',
      'iconfont icon-PNG',
      'iconfont icon-weizhigeshi',
      'iconfont icon-gengduo',
      'iconfont icon-yunduanxiazai',
      'iconfont icon-yunduanshangchuan',
      'iconfont icon-dian',
      'iconfont icon-mian',
      'iconfont icon-xian',
      'iconfont icon-shebeizhuangtai',
      'iconfont icon-fenzuguanli',
      'iconfont icon-kuaisubianpai',
      'iconfont icon-APPkaifa',
      'iconfont icon-wentijieda',
      'iconfont icon-kefu',
      'iconfont icon-ruanjiankaifabao',
      'iconfont icon-sousuobianxiao',
      'iconfont icon-sousuofangda',
      'iconfont icon-dingwei',
      'iconfont icon-wumoxing',
      'iconfont icon-gaojing',
      'iconfont icon-renwujincheng',
      'iconfont icon-xiaoxitongzhi',
      'iconfont icon-youhui',
      'iconfont icon-gaojing1',
      'iconfont icon-zhihangfankui',
      'iconfont icon-gongdanqueren',
      'iconfont icon-guangbo',
      'iconfont icon-gongdan',
      'iconfont icon-xiaoxi',
      'iconfont icon-xinhao',
      'iconfont icon-lanya',
      'iconfont icon-Wi-Fi',
      'iconfont icon-chaxun',
      'iconfont icon-dianbiao',
      'iconfont icon-anquan',
      'iconfont icon-daibanshixiang',
      'iconfont icon-bingxiang',
      'iconfont icon-fanshe',
      'iconfont icon-fengche',
      'iconfont icon-guandao',
      'iconfont icon-guize1',
      'iconfont icon-guizeyinqing',
      'iconfont icon-huowudui',
      'iconfont icon-jianceqi',
      'iconfont icon-jinggai',
      'iconfont icon-liujisuan',
      'iconfont icon-hanshu',
      'iconfont icon-lianjieliu',
      'iconfont icon-ludeng',
      'iconfont icon-shexiangji',
      'iconfont icon-rentijiance',
      'iconfont icon-moshubang',
      'iconfont icon-shujuwajue',
      'iconfont icon-wangguan',
      'iconfont icon-shenjing',
      'iconfont icon-chucun',
      'iconfont icon-wuguan',
      'iconfont icon-yunduanshuaxin',
      'iconfont icon-yunhang',
      'iconfont icon-luyouqi',
      'iconfont icon-bug',
      'iconfont icon-get',
      'iconfont icon-PIR',
      'iconfont icon-zhexiantu',
      'iconfont icon-shuibiao',
      'iconfont icon-js',
      'iconfont icon-zihangche',
      'iconfont icon-liebiao',
      'iconfont icon-qichedingwei',
      'iconfont icon-dici',
      'iconfont icon-mysql',
      'iconfont icon-qiche',
      'iconfont icon-shenjing1',
      'iconfont icon-chengshi',
      'iconfont icon-tixingshixin',
      'iconfont icon-menci',
      'iconfont icon-chazuo',
      'iconfont icon-ranqijianceqi',
      'iconfont icon-kaiguan',
      'iconfont icon-chatou',
      'iconfont icon-xiyiji',
      'iconfont icon-yijiankaiguan',
      'iconfont icon-yanwubaojingqi',
      'iconfont icon-wuxiandianbo',
      'iconfont icon-fuzhi',
      'iconfont icon-shanchu',
      'iconfont icon-bianjisekuai',
      'iconfont icon-ishipinshixiao',
      'iconfont icon-iframetianjia',
      'iconfont icon-tupiantianjia',
      'iconfont icon-liebiaomoshi_kuai',
      'iconfont icon-qiapianmoshi_kuai',
      'iconfont icon-fenlan',
      'iconfont icon-fengexian',
      'iconfont icon-dianzan',
      'iconfont icon-charulianjie',
      'iconfont icon-charutupian',
      'iconfont icon-quxiaolianjie',
      'iconfont icon-wuxupailie',
      'iconfont icon-juzhongduiqi',
      'iconfont icon-yinyong',
      'iconfont icon-youxupailie',
      'iconfont icon-youduiqi',
      'iconfont icon-zitidaima',
      'iconfont icon-xiaolian',
      'iconfont icon-zitijiacu',
      'iconfont icon-zitishanchuxian',
      'iconfont icon-zitishangbiao',
      'iconfont icon-zitibiaoti',
      'iconfont icon-zitixiahuaxian',
      'iconfont icon-zitixieti',
      'iconfont icon-zitiyanse',
      'iconfont icon-zuoduiqi',
      'iconfont icon-zitiyulan',
      'iconfont icon-zitixiabiao',
      'iconfont icon-zuoyouduiqi',
      'iconfont icon-tianxie',
      'iconfont icon-huowudui1',
      'iconfont icon-yingjian',
      'iconfont icon-shebeikaifa',
      'iconfont icon-dianzan_kuai',
      'iconfont icon-zhihuan',
      'iconfont icon-tuoguan',
      'iconfont icon-duigoux',
      'iconfont icon-guanbi1',
      'iconfont icon-aixin_shixin',
      'iconfont icon-ranqixieloubaojingqi',
      'iconfont icon-dianbiao_shiti',
      'iconfont icon-aixin',
      'iconfont icon-shuibiao_shiti',
      'iconfont icon-zhinengxiaofangshuan',
      'iconfont icon-ranqibiao_shiti',
      'iconfont icon-shexiangtou_shiti',
      'iconfont icon-shexiangtou_guanbi',
      'iconfont icon-shexiangtou',
      'iconfont icon-shengyin_shiti',
      'iconfont icon-shengyinkai',
      'iconfont icon-shoucang_shixin',
      'iconfont icon-shoucang',
      'iconfont icon-shengyinwu',
      'iconfont icon-shengyinjingyin',
      'iconfont icon-zhunbeiliangchan',
      'iconfont icon-shebeikaifa1',
      'iconfont icon-kongxinwenhao',
      'iconfont icon-cuowukongxin',
      'iconfont icon-fangkuai1',
      'iconfont icon-fangkuai2',
      'iconfont icon-kongjianxuanzhong1',
      'iconfont icon-kongxinduigou1',
      'iconfont icon-xinxikongxin',
      'iconfont icon-kongjian',
      'iconfont icon-gaojingkongxin',
      'iconfont icon-duigou_kuai',
      'iconfont icon-cuocha_kuai',
      'iconfont icon-jia_sekuai',
      'iconfont icon-jian_sekuai',
      'iconfont icon-tiaoshi',
      'iconfont icon-fenxiangfangshi',
      'iconfont icon-changjingguanli',
      'iconfont icon-bianji',
      'iconfont icon-guanlianshebei',
      'iconfont icon-guanfangbanben',
      'iconfont icon-gongnengdingyi',
      'iconfont icon-jichuguanli',
      'iconfont icon-jishufuwu',
      'iconfont icon-hezuohuobanmiyueguanli',
      'iconfont icon-ceshishenqing',
      'iconfont icon-jiedianguanli',
      'iconfont icon-jinggao',
      'iconfont icon-peiwangyindao',
      'iconfont icon-renjijiaohu',
      'iconfont icon-shiyongwendang',
      'iconfont icon-quanxianshenpi',
      'iconfont icon-yishouquan',
      'iconfont icon-tianshenpi',
      'iconfont icon-shujukanban',
      'iconfont icon-yingyongguanli',
      'iconfont icon-yibiaopan',
      'iconfont icon-zhanghaoquanxianguanli',
      'iconfont icon-yuanquyunwei',
      'iconfont icon-jizhanguanli',
      'iconfont icon-guanbi',
    ],
  },
];
    {
        label: '通用图标',
        list: [
            'iconfont iconicon_roundadd',
            'iconfont iconicon_compile',
            'iconfont iconicon_glass',
            'iconfont iconicon_roundclose',
            'iconfont iconicon_roundreduce',
            'iconfont iconicon_delete',
            'iconfont iconicon_shakehands',
            'iconfont iconicon_task_done',
            'iconfont iconicon_voipphone',
            'iconfont iconicon_safety',
            'iconfont iconicon_work',
            'iconfont iconicon_study',
            'iconfont iconicon_task',
            'iconfont iconicon_subordinate',
            'iconfont iconicon_star',
            'iconfont iconicon_setting',
            'iconfont iconicon_sms',
            'iconfont iconicon_share',
            'iconfont iconicon_secret',
            'iconfont iconicon_scan_namecard',
            'iconfont iconicon_principal',
            'iconfont iconicon_group',
            'iconfont iconicon_send',
            'iconfont iconicon_scan',
            'iconfont iconicon_search',
            'iconfont iconicon_refresh',
            'iconfont iconicon_savememo',
            'iconfont iconicon_QRcode',
            'iconfont iconicon_im_keyboard',
            'iconfont iconicon_redpacket',
            'iconfont iconicon_photo',
            'iconfont iconicon_qq',
            'iconfont iconicon_wechat',
            'iconfont iconicon_phone',
            'iconfont iconicon_namecard',
            'iconfont iconicon_notice',
            'iconfont iconicon_next_arrow',
            'iconfont iconicon_left',
            'iconfont iconicon_more',
            'iconfont iconicon_details',
            'iconfont iconicon_message',
            'iconfont iconicon_mobilephone',
            'iconfont iconicon_im_voice',
            'iconfont iconicon_GPS',
            'iconfont iconicon_ding',
            'iconfont iconicon_exchange',
            'iconfont iconicon_cspace',
            'iconfont iconicon_doc',
            'iconfont iconicon_dispose',
            'iconfont iconicon_discovery',
            'iconfont iconicon_community_line',
            'iconfont iconicon_cloud_history',
            'iconfont iconicon_coinpurse_line',
            'iconfont iconicon_airplay',
            'iconfont iconicon_at',
            'iconfont iconicon_addressbook',
            'iconfont iconicon_boss',
            'iconfont iconicon_addperson',
            'iconfont iconicon_affiliations_li',
            'iconfont iconicon_addmessage',
            'iconfont iconicon_addresslist',
            'iconfont iconicon_add',
            'iconfont icongithub',
            'iconfont icongitee2',
        ],
    },
    {
        label: '系统图标',
        list: [
            'iconfont icon-zhongyingwen',
            'iconfont icon-caidan',
            'iconfont icon-rizhi1',
            'iconfont icon-zhuti',
            'iconfont icon-suoping',
            'iconfont icon-bug',
            'iconfont icon-qq1',
            'iconfont icon-weixin1',
            'iconfont icon-shouji',
            'iconfont icon-mima',
            'iconfont icon-yonghu',
            'iconfont icon-yanzhengma',
            'iconfont icon-canshu',
            'iconfont icon-dongtai',
            'iconfont icon-iconset0265',
            'iconfont icon-shujuzhanshi2',
            'iconfont icon-tuichuquanping',
            'iconfont icon-rizhi',
            'iconfont icon-cuowutishitubiao',
            'iconfont icon-debug',
            'iconfont icon-iconset0216',
            'iconfont icon-quanxian',
            'iconfont icon-quanxian',
            'iconfont icon-shuaxin',
            'iconfont icon-bofangqi-suoping',
            'iconfont icon-quanping',
            'iconfont icon-navicon',
            'iconfont icon-biaodan',
            'iconfont icon-liuliangyunpingtaitubiao08',
            'iconfont icon-caidanguanli',
            'iconfont icon-cuowu',
            'iconfont icon-wxbgongju',
            'iconfont icon-tuichu',
            'iconfont icon-daohanglanmoshi02',
            'iconfont icon-changyonglogo27',
            'iconfont icon-biaoge',
            'iconfont icon-baidu1',
            'iconfont icon-tubiao',
            'iconfont icon-souhu',
            'iconfont icon-msnui-360',
            'iconfont icon-iframe',
            'iconfont icon-huanyingye',
        ],
    },
    {
        label: '业务图标',
        list: [
            'iconfont icon-zidingyi',
            'iconfont icon-xiajiantou',
            'iconfont icon-shangjiantou',
            'iconfont icon-icon_loading',
            'iconfont icon-biaodanzujian-shurukuang',
            'iconfont icon-biaodanzujian-biaoge',
            'iconfont icon-biaodanzujian-xialakuang',
            'iconfont icon-tubiao-bingtu',
            'iconfont icon-biaodanzujian-anniu',
            'iconfont icon-gongyezujian-yibiaopan',
            'iconfont icon-tubiao-qiapian',
            'iconfont icon-gongyezujian-zhishideng',
            'iconfont icon-tubiao-zhexiantu',
            'iconfont icon-xingzhuang-juxing',
            'iconfont icon-xingzhuang-jianxing',
            'iconfont icon-gongyezujian-kaiguan',
            'iconfont icon-tubiao-zhuzhuangtu',
            'iconfont icon-xingzhuang-tupian',
            'iconfont icon-xingzhuang-wenzi',
            'iconfont icon-xingzhuang-tuoyuanxing',
            'iconfont icon-xingzhuang-sanjiaoxing',
            'iconfont icon-xingzhuang-xingxing',
            'iconfont icon-guize',
            'iconfont icon-shebeiguanli',
            'iconfont icon-gongnengdingyi1',
            'iconfont icon-jishufuwu1',
            'iconfont icon-yunyingzhongxin',
            'iconfont icon-yunyingguanli',
            'iconfont icon-zuzhixiaxia',
            'iconfont icon-zuzhizhankai',
            'iconfont icon-zuzhiqunzu',
            'iconfont icon-dakai',
            'iconfont icon-yingwen',
            'iconfont icon-zhongwen',
            'iconfont icon-miwen',
            'iconfont icon-xianhao',
            'iconfont icon-kongxinduigou',
            'iconfont icon-huixingzhen',
            'iconfont icon-duigou',
            'iconfont icon-xiayibu',
            'iconfont icon-shangyibu',
            'iconfont icon-kongjianxuanzhong',
            'iconfont icon-kongjianweixuan',
            'iconfont icon-kongjianyixuan',
            'iconfont icon--diangan',
            'iconfont icon-rongxuejirongjiechi',
            'iconfont icon-lubiantingchechang',
            'iconfont icon--lumingpai',
            'iconfont icon-jietouzuoyi',
            'iconfont icon--zhongdaweixian',
            'iconfont icon--jiaotongbiaozhipai',
            'iconfont icon-gongcezhishipai',
            'iconfont icon-fangkuai',
            'iconfont icon-fangkuai-',
            'iconfont icon-shuaxin',
            'iconfont icon-baocun',
            'iconfont icon-fabu',
            'iconfont icon-xiayibu1',
            'iconfont icon-shangyibu1',
            'iconfont icon-xiangxiazhanhang',
            'iconfont icon-xiangshangzhanhang',
            'iconfont icon-tupianjiazaishibai',
            'iconfont icon-fuwudiqiu',
            'iconfont icon-suoxiao',
            'iconfont icon-fangda',
            'iconfont icon-huanyuanhuabu',
            'iconfont icon-quanping',
            'iconfont icon-biaodanzujian-biaoge1',
            'iconfont icon-APIshuchu',
            'iconfont icon-APIjieru',
            'iconfont icon-wenjianjia',
            'iconfont icon-DOC',
            'iconfont icon-BMP',
            'iconfont icon-GIF',
            'iconfont icon-JPG',
            'iconfont icon-PNG',
            'iconfont icon-weizhigeshi',
            'iconfont icon-gengduo',
            'iconfont icon-yunduanxiazai',
            'iconfont icon-yunduanshangchuan',
            'iconfont icon-dian',
            'iconfont icon-mian',
            'iconfont icon-xian',
            'iconfont icon-shebeizhuangtai',
            'iconfont icon-fenzuguanli',
            'iconfont icon-kuaisubianpai',
            'iconfont icon-APPkaifa',
            'iconfont icon-wentijieda',
            'iconfont icon-kefu',
            'iconfont icon-ruanjiankaifabao',
            'iconfont icon-sousuobianxiao',
            'iconfont icon-sousuofangda',
            'iconfont icon-dingwei',
            'iconfont icon-wumoxing',
            'iconfont icon-gaojing',
            'iconfont icon-renwujincheng',
            'iconfont icon-xiaoxitongzhi',
            'iconfont icon-youhui',
            'iconfont icon-gaojing1',
            'iconfont icon-zhihangfankui',
            'iconfont icon-gongdanqueren',
            'iconfont icon-guangbo',
            'iconfont icon-gongdan',
            'iconfont icon-xiaoxi',
            'iconfont icon-xinhao',
            'iconfont icon-lanya',
            'iconfont icon-Wi-Fi',
            'iconfont icon-chaxun',
            'iconfont icon-dianbiao',
            'iconfont icon-anquan',
            'iconfont icon-daibanshixiang',
            'iconfont icon-bingxiang',
            'iconfont icon-fanshe',
            'iconfont icon-fengche',
            'iconfont icon-guandao',
            'iconfont icon-guize1',
            'iconfont icon-guizeyinqing',
            'iconfont icon-huowudui',
            'iconfont icon-jianceqi',
            'iconfont icon-jinggai',
            'iconfont icon-liujisuan',
            'iconfont icon-hanshu',
            'iconfont icon-lianjieliu',
            'iconfont icon-ludeng',
            'iconfont icon-shexiangji',
            'iconfont icon-rentijiance',
            'iconfont icon-moshubang',
            'iconfont icon-shujuwajue',
            'iconfont icon-wangguan',
            'iconfont icon-shenjing',
            'iconfont icon-chucun',
            'iconfont icon-wuguan',
            'iconfont icon-yunduanshuaxin',
            'iconfont icon-yunhang',
            'iconfont icon-luyouqi',
            'iconfont icon-bug',
            'iconfont icon-get',
            'iconfont icon-PIR',
            'iconfont icon-zhexiantu',
            'iconfont icon-shuibiao',
            'iconfont icon-js',
            'iconfont icon-zihangche',
            'iconfont icon-liebiao',
            'iconfont icon-qichedingwei',
            'iconfont icon-dici',
            'iconfont icon-mysql',
            'iconfont icon-qiche',
            'iconfont icon-shenjing1',
            'iconfont icon-chengshi',
            'iconfont icon-tixingshixin',
            'iconfont icon-menci',
            'iconfont icon-chazuo',
            'iconfont icon-ranqijianceqi',
            'iconfont icon-kaiguan',
            'iconfont icon-chatou',
            'iconfont icon-xiyiji',
            'iconfont icon-yijiankaiguan',
            'iconfont icon-yanwubaojingqi',
            'iconfont icon-wuxiandianbo',
            'iconfont icon-fuzhi',
            'iconfont icon-shanchu',
            'iconfont icon-bianjisekuai',
            'iconfont icon-ishipinshixiao',
            'iconfont icon-iframetianjia',
            'iconfont icon-tupiantianjia',
            'iconfont icon-liebiaomoshi_kuai',
            'iconfont icon-qiapianmoshi_kuai',
            'iconfont icon-fenlan',
            'iconfont icon-fengexian',
            'iconfont icon-dianzan',
            'iconfont icon-charulianjie',
            'iconfont icon-charutupian',
            'iconfont icon-quxiaolianjie',
            'iconfont icon-wuxupailie',
            'iconfont icon-juzhongduiqi',
            'iconfont icon-yinyong',
            'iconfont icon-youxupailie',
            'iconfont icon-youduiqi',
            'iconfont icon-zitidaima',
            'iconfont icon-xiaolian',
            'iconfont icon-zitijiacu',
            'iconfont icon-zitishanchuxian',
            'iconfont icon-zitishangbiao',
            'iconfont icon-zitibiaoti',
            'iconfont icon-zitixiahuaxian',
            'iconfont icon-zitixieti',
            'iconfont icon-zitiyanse',
            'iconfont icon-zuoduiqi',
            'iconfont icon-zitiyulan',
            'iconfont icon-zitixiabiao',
            'iconfont icon-zuoyouduiqi',
            'iconfont icon-tianxie',
            'iconfont icon-huowudui1',
            'iconfont icon-yingjian',
            'iconfont icon-shebeikaifa',
            'iconfont icon-dianzan_kuai',
            'iconfont icon-zhihuan',
            'iconfont icon-tuoguan',
            'iconfont icon-duigoux',
            'iconfont icon-guanbi1',
            'iconfont icon-aixin_shixin',
            'iconfont icon-ranqixieloubaojingqi',
            'iconfont icon-dianbiao_shiti',
            'iconfont icon-aixin',
            'iconfont icon-shuibiao_shiti',
            'iconfont icon-zhinengxiaofangshuan',
            'iconfont icon-ranqibiao_shiti',
            'iconfont icon-shexiangtou_shiti',
            'iconfont icon-shexiangtou_guanbi',
            'iconfont icon-shexiangtou',
            'iconfont icon-shengyin_shiti',
            'iconfont icon-shengyinkai',
            'iconfont icon-shoucang_shixin',
            'iconfont icon-shoucang',
            'iconfont icon-shengyinwu',
            'iconfont icon-shengyinjingyin',
            'iconfont icon-zhunbeiliangchan',
            'iconfont icon-shebeikaifa1',
            'iconfont icon-kongxinwenhao',
            'iconfont icon-cuowukongxin',
            'iconfont icon-fangkuai1',
            'iconfont icon-fangkuai2',
            'iconfont icon-kongjianxuanzhong1',
            'iconfont icon-kongxinduigou1',
            'iconfont icon-xinxikongxin',
            'iconfont icon-kongjian',
            'iconfont icon-gaojingkongxin',
            'iconfont icon-duigou_kuai',
            'iconfont icon-cuocha_kuai',
            'iconfont icon-jia_sekuai',
            'iconfont icon-jian_sekuai',
            'iconfont icon-tiaoshi',
            'iconfont icon-fenxiangfangshi',
            'iconfont icon-changjingguanli',
            'iconfont icon-bianji',
            'iconfont icon-guanlianshebei',
            'iconfont icon-guanfangbanben',
            'iconfont icon-gongnengdingyi',
            'iconfont icon-jichuguanli',
            'iconfont icon-jishufuwu',
            'iconfont icon-hezuohuobanmiyueguanli',
            'iconfont icon-ceshishenqing',
            'iconfont icon-jiedianguanli',
            'iconfont icon-jinggao',
            'iconfont icon-peiwangyindao',
            'iconfont icon-renjijiaohu',
            'iconfont icon-shiyongwendang',
            'iconfont icon-quanxianshenpi',
            'iconfont icon-yishouquan',
            'iconfont icon-tianshenpi',
            'iconfont icon-shujukanban',
            'iconfont icon-yingyongguanli',
            'iconfont icon-yibiaopan',
            'iconfont icon-zhanghaoquanxianguanli',
            'iconfont icon-yuanquyunwei',
            'iconfont icon-jizhanguanli',
            'iconfont icon-guanbi',
        ],
    },
]
src/config/website.js
@@ -2,80 +2,80 @@
 * 全局配置文件
 */
export default {
  title: '',
  logo: 'S',
  key: 'saber', //配置主键,目前用于存储
  indexTitle: 'BladeX 微服务平台',
  clientId: 'drone', // 客户端id
  clientSecret: 'drone_secret', // 客户端密钥
  tenantMode: false, // 是否开启租户模式
  tenantId: '000000', // 管理组租户编号
  captchaMode: false, // 是否开启验证码模式
  switchMode: false, // 是否开启登录切换角色部门
  lockPage: '/lock',
  tokenTime: 3000,
  tokenHeader: 'Blade-Auth',
  //HTTP状态码白名单
  statusWhiteList: [],
  //配置首页不可关闭
  setting: {
    sidebar: 'vertical',
    tag: true,
    debug: true,
    collapse: true,
    search: true,
    color: true,
    lock: true,
    screenshot: true,
    fullscreen: true,
    theme: true,
    menu: true,
  },
  //首页配置
  fistPage: {
    name: '首页',
    path: '/wel/index',
  },
  //配置菜单的属性
  menu: {
    iconDefault: 'icon-caidan',
    label: 'name',
    path: 'path',
    icon: 'source',
    children: 'children',
    query: 'query',
    href: 'path',
    meta: 'meta',
  },
  //水印配置
  watermark: {
    mode: false,
    text: 'BladeX',
  },
  //oauth2配置
  oauth2: {
    // 是否开启注册功能
    registerMode: true,
    // 使用后端工程 @org.springblade.test.Sm2KeyGenerator 获取
    publicKey: '请配置国密sm2公钥',
    // 第三方系统授权地址
    authUrl: 'http://localhost/blade-auth/oauth/render',
    // 单点登录系统认证
    ssoMode: false, // 是否开启单点登录功能
    ssoBaseUrl: 'http://localhost:8100', // 单点登录系统地址(cloud端口为8100,boot端口为80)
    ssoAuthUrl: '/oauth/authorize?client_id=saber3&response_type=code&redirect_uri=', // 单点登录授权地址
    ssoLogoutUrl: '/oauth/authorize/logout?redirect_uri=', // 单点登录退出地址
    redirectUri: 'http://localhost:2888/login', // 单点登录回调地址(Saber服务的登录界面地址)
  },
  //设计器配置
  design: {
    // 流程设计器类型(true->nutflow,false->flowable)
    designMode: true,
    // 流程设计器地址(flowable模式)
    designUrl: 'http://localhost:9999',
    // 报表设计器地址(cloud端口为8108,boot端口为80)
    reportUrl: 'http://localhost:8108/ureport',
    // 规则设计引擎地址
    edgeUrl: 'http://localhost:1880',
  },
};
    title: '',
    logo: 'S',
    key: 'saber', //配置主键,目前用于存储
    indexTitle: 'BladeX 微服务平台',
    clientId: 'drone', // 客户端id
    clientSecret: 'drone_secret', // 客户端密钥
    tenantMode: false, // 是否开启租户模式
    tenantId: '000000', // 管理组租户编号
    captchaMode: false, // 是否开启验证码模式
    switchMode: false, // 是否开启登录切换角色部门
    lockPage: '/lock',
    tokenTime: 3000,
    tokenHeader: 'Blade-Auth',
    //HTTP状态码白名单
    statusWhiteList: [],
    //配置首页不可关闭
    setting: {
        sidebar: 'vertical',
        tag: true,
        debug: true,
        collapse: true,
        search: true,
        color: true,
        lock: true,
        screenshot: true,
        fullscreen: true,
        theme: true,
        menu: true,
    },
    //首页配置
    fistPage: {
        name: '首页',
        path: '/wel/index',
    },
    //配置菜单的属性
    menu: {
        iconDefault: 'icon-caidan',
        label: 'name',
        path: 'path',
        icon: 'source',
        children: 'children',
        query: 'query',
        href: 'path',
        meta: 'meta',
    },
    //水印配置
    watermark: {
        mode: false,
        text: 'BladeX',
    },
    //oauth2配置
    oauth2: {
        // 是否开启注册功能
        registerMode: true,
        // 使用后端工程 @org.springblade.test.Sm2KeyGenerator 获取
        publicKey: '请配置国密sm2公钥',
        // 第三方系统授权地址
        authUrl: 'http://localhost/blade-auth/oauth/render',
        // 单点登录系统认证
        ssoMode: false, // 是否开启单点登录功能
        ssoBaseUrl: 'http://localhost:8100', // 单点登录系统地址(cloud端口为8100,boot端口为80)
        ssoAuthUrl: '/oauth/authorize?client_id=saber3&response_type=code&redirect_uri=', // 单点登录授权地址
        ssoLogoutUrl: '/oauth/authorize/logout?redirect_uri=', // 单点登录退出地址
        redirectUri: 'http://localhost:2888/login', // 单点登录回调地址(Saber服务的登录界面地址)
    },
    //设计器配置
    design: {
        // 流程设计器类型(true->nutflow,false->flowable)
        designMode: true,
        // 流程设计器地址(flowable模式)
        designUrl: 'http://localhost:9999',
        // 报表设计器地址(cloud端口为8108,boot端口为80)
        reportUrl: 'http://localhost:8108/ureport',
        // 规则设计引擎地址
        edgeUrl: 'http://localhost:1880',
    },
}
src/const/tool/model.js
@@ -1,344 +1,344 @@
export const switchDic = [
  {
    label: '',
    value: 0,
  },
  {
    label: '',
    value: 1,
  },
];
    {
        label: '',
        value: 0,
    },
    {
        label: '',
        value: 1,
    },
]
export const entityDic = [
  {
    label: 'String',
    value: 'java.lang.String',
  },
  {
    label: 'Integer',
    value: 'java.lang.Integer',
  },
  {
    label: 'Long',
    value: 'java.lang.Long',
  },
  {
    label: 'Double',
    value: 'java.lang.Double',
  },
  {
    label: 'BigDecimal',
    value: 'java.math.BigDecimal',
  },
  {
    label: 'Boolean',
    value: 'java.lang.Boolean',
  },
  {
    label: 'Date',
    value: 'java.util.Date',
  },
];
    {
        label: 'String',
        value: 'java.lang.String',
    },
    {
        label: 'Integer',
        value: 'java.lang.Integer',
    },
    {
        label: 'Long',
        value: 'java.lang.Long',
    },
    {
        label: 'Double',
        value: 'java.lang.Double',
    },
    {
        label: 'BigDecimal',
        value: 'java.math.BigDecimal',
    },
    {
        label: 'Boolean',
        value: 'java.lang.Boolean',
    },
    {
        label: 'Date',
        value: 'java.util.Date',
    },
]
export const componentDic = [
  {
    label: '单行文本',
    value: 'input',
  },
  {
    label: '多行文本',
    value: 'textarea',
  },
  {
    label: '富文本',
    value: 'editor',
  },
  {
    label: '下拉选项',
    value: 'select',
  },
  {
    label: '树形下拉选项',
    value: 'tree',
  },
  {
    label: '单选框',
    value: 'radio',
  },
  {
    label: '多选框',
    value: 'checkbox',
  },
  {
    label: '开关框',
    value: 'switch',
  },
  {
    label: '日期框',
    value: 'date',
  },
];
    {
        label: '单行文本',
        value: 'input',
    },
    {
        label: '多行文本',
        value: 'textarea',
    },
    {
        label: '富文本',
        value: 'editor',
    },
    {
        label: '下拉选项',
        value: 'select',
    },
    {
        label: '树形下拉选项',
        value: 'tree',
    },
    {
        label: '单选框',
        value: 'radio',
    },
    {
        label: '多选框',
        value: 'checkbox',
    },
    {
        label: '开关框',
        value: 'switch',
    },
    {
        label: '日期框',
        value: 'date',
    },
]
export const queryDic = [
  {
    label: '等于',
    value: 'equal',
  },
  {
    label: '不等于',
    value: 'notequal',
  },
  {
    label: '大于',
    value: 'gt',
  },
  {
    label: '大于等于',
    value: 'ge',
  },
  {
    label: '小于',
    value: 'lt',
  },
  {
    label: '小于等于',
    value: 'le',
  },
  {
    label: '区间',
    value: 'between',
  },
  {
    label: '模糊',
    value: 'like',
  },
  {
    label: '左模糊',
    value: 'likeleft',
  },
  {
    label: '右模糊',
    value: 'likeright',
  },
];
    {
        label: '等于',
        value: 'equal',
    },
    {
        label: '不等于',
        value: 'notequal',
    },
    {
        label: '大于',
        value: 'gt',
    },
    {
        label: '大于等于',
        value: 'ge',
    },
    {
        label: '小于',
        value: 'lt',
    },
    {
        label: '小于等于',
        value: 'le',
    },
    {
        label: '区间',
        value: 'between',
    },
    {
        label: '模糊',
        value: 'like',
    },
    {
        label: '左模糊',
        value: 'likeleft',
    },
    {
        label: '右模糊',
        value: 'likeright',
    },
]
export const templateDic = [
  {
    label: '单表',
    value: 'crud',
  },
  {
    label: '主子表',
    value: 'sub',
  },
  {
    label: '树表',
    value: 'tree',
  },
];
    {
        label: '单表',
        value: 'crud',
    },
    {
        label: '主子表',
        value: 'sub',
    },
    {
        label: '树表',
        value: 'tree',
    },
]
export const option = {
  height: 'auto',
  searchShow: true,
  searchMenuSpan: 6,
  tip: false,
  border: true,
  index: true,
  viewBtn: true,
  grid: true,
  selection: true,
  menuWidth: 250,
  column: [
    {
      label: '数据源',
      prop: 'datasourceId',
      search: true,
      span: 24,
      type: 'select',
      dicUrl: '/blade-develop/datasource/select',
      props: {
        label: 'name',
        value: 'id',
      },
      rules: [
        {
          required: true,
          message: '请选择数据源',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '物理表名',
      prop: 'modelTable',
      type: 'tree',
      slot: true,
      filterable: true,
      dicData: [],
      props: {
        label: 'comment',
        value: 'name',
      },
      rules: [
        {
          required: true,
          message: '请输入数据库表名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '模型类名',
      prop: 'modelClass',
      addDisabled: true,
      editDisabled: true,
      rules: [
        {
          required: true,
          message: '请输入模型类名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '模型名称',
      prop: 'modelName',
      search: true,
      rules: [
        {
          required: true,
          message: '请输入模型名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '模型编号',
      prop: 'modelCode',
      search: true,
      rules: [
        {
          required: true,
          message: '请输入模型编号',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '模型备注',
      prop: 'modelRemark',
      hide: true,
      span: 24,
    },
  ],
};
    height: 'auto',
    searchShow: true,
    searchMenuSpan: 6,
    tip: false,
    border: true,
    index: true,
    viewBtn: true,
    grid: true,
    selection: true,
    menuWidth: 250,
    column: [
        {
            label: '数据源',
            prop: 'datasourceId',
            search: true,
            span: 24,
            type: 'select',
            dicUrl: '/blade-develop/datasource/select',
            props: {
                label: 'name',
                value: 'id',
            },
            rules: [
                {
                    required: true,
                    message: '请选择数据源',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '物理表名',
            prop: 'modelTable',
            type: 'tree',
            slot: true,
            filterable: true,
            dicData: [],
            props: {
                label: 'comment',
                value: 'name',
            },
            rules: [
                {
                    required: true,
                    message: '请输入数据库表名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '模型类名',
            prop: 'modelClass',
            addDisabled: true,
            editDisabled: true,
            rules: [
                {
                    required: true,
                    message: '请输入模型类名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '模型名称',
            prop: 'modelName',
            search: true,
            rules: [
                {
                    required: true,
                    message: '请输入模型名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '模型编号',
            prop: 'modelCode',
            search: true,
            rules: [
                {
                    required: true,
                    message: '请输入模型编号',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '模型备注',
            prop: 'modelRemark',
            hide: true,
            span: 24,
        },
    ],
}
export const optionModel = {
  border: true,
  index: true,
  addBtn: false,
  editBtn: false,
  addRowBtn: false,
  cellBtn: false,
  cancelBtn: false,
  tip: false,
  menu: false,
  selection: true,
  column: [
    {
      label: '物理列名',
      prop: 'jdbcName',
    },
    {
      label: '物理类型',
      prop: 'jdbcType',
    },
    {
      label: '实体列名',
      prop: 'propertyName',
      cell: true,
    },
    {
      label: '实体类型',
      prop: 'propertyEntity',
      type: 'select',
      dicData: entityDic,
      cell: true,
    },
    {
      label: '字段说明',
      prop: 'jdbcComment',
      cell: true,
    },
    {
      label: '列表显示',
      prop: 'isList',
      type: 'switch',
      dicData: switchDic,
      align: 'center',
      width: 60,
      cell: true,
    },
    {
      label: '表单显示',
      prop: 'isForm',
      type: 'switch',
      dicData: switchDic,
      align: 'center',
      width: 60,
      cell: true,
    },
    {
      label: '独占一行',
      prop: 'isRow',
      type: 'switch',
      dicData: switchDic,
      align: 'center',
      width: 60,
      cell: true,
    },
    {
      label: '必填',
      prop: 'isRequired',
      type: 'switch',
      dicData: switchDic,
      align: 'center',
      width: 60,
      cell: true,
    },
    {
      label: '组件类型',
      prop: 'componentType',
      type: 'select',
      dicData: componentDic,
      cell: true,
    },
    {
      label: '字典编码',
      prop: 'dictCode',
      type: 'select',
      dicUrl: '/blade-system/dict/select',
      props: {
        label: 'dictValue',
        value: 'code',
      },
      cell: true,
    },
    {
      label: '查询配置',
      prop: 'isQuery',
      type: 'switch',
      dicData: switchDic,
      align: 'center',
      width: 60,
      cell: true,
    },
    {
      label: '查询类型',
      prop: 'queryType',
      type: 'select',
      dicData: queryDic,
      cell: true,
    },
  ],
};
    border: true,
    index: true,
    addBtn: false,
    editBtn: false,
    addRowBtn: false,
    cellBtn: false,
    cancelBtn: false,
    tip: false,
    menu: false,
    selection: true,
    column: [
        {
            label: '物理列名',
            prop: 'jdbcName',
        },
        {
            label: '物理类型',
            prop: 'jdbcType',
        },
        {
            label: '实体列名',
            prop: 'propertyName',
            cell: true,
        },
        {
            label: '实体类型',
            prop: 'propertyEntity',
            type: 'select',
            dicData: entityDic,
            cell: true,
        },
        {
            label: '字段说明',
            prop: 'jdbcComment',
            cell: true,
        },
        {
            label: '列表显示',
            prop: 'isList',
            type: 'switch',
            dicData: switchDic,
            align: 'center',
            width: 60,
            cell: true,
        },
        {
            label: '表单显示',
            prop: 'isForm',
            type: 'switch',
            dicData: switchDic,
            align: 'center',
            width: 60,
            cell: true,
        },
        {
            label: '独占一行',
            prop: 'isRow',
            type: 'switch',
            dicData: switchDic,
            align: 'center',
            width: 60,
            cell: true,
        },
        {
            label: '必填',
            prop: 'isRequired',
            type: 'switch',
            dicData: switchDic,
            align: 'center',
            width: 60,
            cell: true,
        },
        {
            label: '组件类型',
            prop: 'componentType',
            type: 'select',
            dicData: componentDic,
            cell: true,
        },
        {
            label: '字典编码',
            prop: 'dictCode',
            type: 'select',
            dicUrl: '/blade-system/dict/select',
            props: {
                label: 'dictValue',
                value: 'code',
            },
            cell: true,
        },
        {
            label: '查询配置',
            prop: 'isQuery',
            type: 'switch',
            dicData: switchDic,
            align: 'center',
            width: 60,
            cell: true,
        },
        {
            label: '查询类型',
            prop: 'queryType',
            type: 'select',
            dicData: queryDic,
            cell: true,
        },
    ],
}
src/debug.js
@@ -1,5 +1,5 @@
import DisableDevtool from 'disable-devtool';
import { ElMessageBox } from 'element-plus';
import DisableDevtool from 'disable-devtool'
import { ElMessageBox } from 'element-plus'
/**
 * 安全警告的HTML模板, 使用Tailwind CSS样式
@@ -17,34 +17,34 @@
      如您频繁此类操作,系统将记录上报。
    </p>
  </div>
</div>`;
</div>`
/**
 * Element Plus 消息框配置选项
 */
const ALERT_OPTIONS = {
  type: 'error',
  showClose: false,
  center: true,
  closeOnClickModal: false,
  closeOnPressEscape: false,
  dangerouslyUseHTMLString: true,
};
    type: 'error',
    showClose: false,
    center: true,
    closeOnClickModal: false,
    closeOnPressEscape: false,
    dangerouslyUseHTMLString: true,
}
export default () => {
  if (import.meta.env.VITE_APP_DEBUG_SWITCH === 'false') return;
    if (import.meta.env.VITE_APP_DEBUG_SWITCH === 'false') return
  const debugKey = import.meta.env.VITE_APP_DEBUG_KEY;
  let flag = false;
  DisableDevtool({
    md5: DisableDevtool.md5(debugKey),
    disableMenu: false,
    ondevtoolopen: (type, next) => {
      if (!flag) ElMessageBox.alert(SECURITY_WARNING_TEMPLATE, '安全警告', ALERT_OPTIONS);
      flag = true;
      setTimeout(() => {
        next();
      }, 5000);
    },
  });
};
    const debugKey = import.meta.env.VITE_APP_DEBUG_KEY
    let flag = false
    DisableDevtool({
        md5: DisableDevtool.md5(debugKey),
        disableMenu: false,
        ondevtoolopen: (type, next) => {
            if (!flag) ElMessageBox.alert(SECURITY_WARNING_TEMPLATE, '安全警告', ALERT_OPTIONS)
            flag = true
            setTimeout(() => {
                next()
            }, 5000)
        },
    })
}
src/directive/drag.js
@@ -1,42 +1,41 @@
const drag = {
  mounted(el, binding) {
    mounted(el, binding) {
        const dragBox = document.querySelector('#' + binding.arg)
        //鼠标点击距离box盒子left的距离
        let spotToBoxLeft = 0
        let spotToBoxTop = 0
    const dragBox = document.querySelector('#' + binding.arg)
    //鼠标点击距离box盒子left的距离
    let spotToBoxLeft = 0
    let spotToBoxTop = 0
        const mouseupFun = e => {
            window.removeEventListener('mousemove', mousemoveFun)
            window.removeEventListener('mouseup', mouseupFun)
        }
    const mouseupFun = (e) => {
      window.removeEventListener('mousemove', mousemoveFun)
      window.removeEventListener('mouseup', mouseupFun)
    }
        const mousemoveFun = evt => {
            console.log(66666)
            //获取body宽高,获取拖动盒子的宽高
            const { offsetWidth: bodyWidth, offsetHeight: bodyHeight } = document.body
            const { offsetWidth: boxWidth, offsetHeight: boxHeight } = dragBox
            //max取最大值,min取最小值
            const left = Math.max(evt.clientX - spotToBoxLeft, 0)
            const top = Math.max(evt.clientY - spotToBoxTop, 0)
            dragBox.style.left = Math.min(left, bodyWidth - boxWidth) + 'px'
            dragBox.style.top = Math.min(top, bodyHeight - boxHeight) + 'px'
        }
    const mousemoveFun = (evt) => {
      console.log(66666);
      //获取body宽高,获取拖动盒子的宽高
      const {offsetWidth: bodyWidth, offsetHeight: bodyHeight} = document.body
      const {offsetWidth: boxWidth, offsetHeight: boxHeight} = dragBox
      //max取最大值,min取最小值
      const left = Math.max(evt.clientX - spotToBoxLeft, 0)
      const top = Math.max(evt.clientY - spotToBoxTop, 0)
      dragBox.style.left = Math.min(left, bodyWidth - boxWidth) + 'px'
      dragBox.style.top = Math.min(top, bodyHeight - boxHeight) + 'px'
    }
        el.__mousedownFun = evt => {
            //鼠标坐标减去 box盒子相对于父盒子body 的距离
            spotToBoxLeft = evt.clientX - dragBox.offsetLeft
            spotToBoxTop = evt.clientY - dragBox.offsetTop
            window.addEventListener('mousemove', mousemoveFun)
            window.addEventListener('mouseup', mouseupFun)
        }
        el.addEventListener('mousedown', el.__mousedownFun)
    },
    el.__mousedownFun = (evt) => {
      //鼠标坐标减去 box盒子相对于父盒子body 的距离
      spotToBoxLeft = evt.clientX - dragBox.offsetLeft
      spotToBoxTop = evt.clientY - dragBox.offsetTop
      window.addEventListener('mousemove', mousemoveFun)
      window.addEventListener('mouseup', mouseupFun)
    }
    el.addEventListener('mousedown', el.__mousedownFun);
  },
  // 绑定元素的父组件卸载前调用
  beforeUnmount(el, binding,) {
    el.removeEventListener('mousedown', el.__mousedownFun)
  },
    // 绑定元素的父组件卸载前调用
    beforeUnmount(el, binding) {
        el.removeEventListener('mousedown', el.__mousedownFun)
    },
}
export default drag
src/directive/selectLoad.js
@@ -1,13 +1,13 @@
const selectLoad = {
  mounted(el, binding){
    const dom = document.querySelector('.' + binding.arg)
    const wrap = dom.querySelector('.el-scrollbar__wrap')
    wrap.addEventListener('scroll', function () {
      if (this.scrollHeight - this.scrollTop < this.clientHeight + 1) {
        binding.value()
      }
    })
  }
    mounted(el, binding) {
        const dom = document.querySelector('.' + binding.arg)
        const wrap = dom.querySelector('.el-scrollbar__wrap')
        wrap.addEventListener('scroll', function () {
            if (this.scrollHeight - this.scrollTop < this.clientHeight + 1) {
                binding.value()
            }
        })
    },
}
export default selectLoad
src/error.js
@@ -1,25 +1,25 @@
import store from './store';
import store from './store'
export default {
  install: app => {
    app.config.errorHandler = (err, vm, info) => {
      store.commit('ADD_LOGS', {
        type: 'error',
        message: err.message,
        stack: err.stack,
        info,
      });
      if (process.env.NODE_ENV === 'development') {
        console.group('>>>>>> 错误信息 >>>>>>');
        console.log(info);
        console.groupEnd();
        console.group('>>>>>> Vue 实例 >>>>>>');
        console.log(vm);
        console.groupEnd();
        console.group('>>>>>> Error >>>>>>');
        console.log(err);
        console.groupEnd();
      }
    };
  },
};
    install: app => {
        app.config.errorHandler = (err, vm, info) => {
            store.commit('ADD_LOGS', {
                type: 'error',
                message: err.message,
                stack: err.stack,
                info,
            })
            if (process.env.NODE_ENV === 'development') {
                console.group('>>>>>> 错误信息 >>>>>>')
                console.log(info)
                console.groupEnd()
                console.group('>>>>>> Vue 实例 >>>>>>')
                console.log(vm)
                console.groupEnd()
                console.group('>>>>>> Error >>>>>>')
                console.log(err)
                console.groupEnd()
            }
        }
    },
}
src/lang/en.js
@@ -1,136 +1,136 @@
export default {
  title: 'BladeX Admin',
  logoutTip: 'Exit the system, do you want to continue?',
  submitText: 'submit',
  cancelText: 'cancel',
  search: 'Please input search content',
  menuTip: 'none menu list',
  common: {
    condition: 'condition',
    display: 'display',
    hide: 'hide',
  },
  tip: {
    select: 'Please select',
    input: 'Please input',
  },
  upload: {
    upload: 'upload',
    tip: 'Drag files here,/',
  },
  date: {
    start: 'Start date',
    end: 'End date',
    t: 'today',
    y: 'yesterday',
    n: 'nearly 7',
    a: 'whole',
  },
  form: {
    printBtn: 'print',
    mockBtn: 'mock',
    submitBtn: 'submit',
    emptyBtn: 'empty',
  },
  crud: {
    filter: {
      addBtn: 'add',
      clearBtn: 'clear',
      resetBtn: 'reset',
      cancelBtn: 'cancel',
      submitBtn: 'submit',
    },
    column: {
      name: 'name',
      hide: 'hide',
      fixed: 'fixed',
      filters: 'filters',
      sortable: 'sortable',
      index: 'index',
      width: 'width',
    },
    tipStartTitle: 'Currently selected',
    tipEndTitle: 'items',
    editTitle: 'edit',
    copyTitle: 'copy',
    addTitle: 'add',
    viewTitle: 'view',
    filterTitle: 'filter',
    showTitle: 'showTitle',
    menu: 'menu',
    addBtn: 'add',
    show: 'show',
    hide: 'hide',
    open: 'open',
    shrink: 'shrink',
    printBtn: 'print',
    excelBtn: 'excel',
    updateBtn: 'update',
    cancelBtn: 'cancel',
    searchBtn: 'search',
    emptyBtn: 'empty',
    menuBtn: 'menu',
    saveBtn: 'save',
    viewBtn: 'view',
    editBtn: 'edit',
    copyBtn: 'copy',
    delBtn: 'delete',
  },
  login: {
    title: 'Login ',
    info: 'BladeX Development Platform',
    tenantId: 'Please input tenantId',
    name: 'Please input name',
    username: 'Please input account',
    email: 'Please input email',
    password: 'Please input password',
    password1: 'Please input confirm password',
    wechat: 'Wechat',
    qq: 'QQ',
    github: 'github',
    gitee: 'gitee',
    phone: 'Please input a phone',
    code: 'Please input a code',
    submit: 'Login',
    register: 'Register',
    back: 'Back',
    userLogin: 'userLogin',
    phoneLogin: 'phoneLogin',
    thirdLogin: 'thirdLogin',
    ssoLogin: 'ssoLogin',
    msgText: 'send code',
    msgSuccess: 'reissued',
  },
  navbar: {
    info: 'info',
    logOut: 'logout',
    userinfo: 'userinfo',
    roleName: 'role name',
    deptName: 'dept name',
    currentDeptName: 'current role name',
    currentRoleName: 'current dept name',
    switchRoleTo: 'switch role to',
    switchRole: 'switch role',
    switchDeptTo: 'switch dept to',
    switchDept: 'switch dept',
    switchTip: 'whether to switch identities',
    switchSuccess: 'switch success',
    dashboard: 'dashboard',
    lock: 'lock',
    bug: 'none bug',
    bugs: 'bug',
    screenfullF: 'exit screenfull',
    screenfull: 'screenfull',
    language: 'language',
    notice: 'notice',
    theme: 'theme',
    color: 'color',
  },
  tagsView: {
    search: 'Search',
    menu: 'menu',
    clearCache: 'Clear Cache',
    closeOthers: 'Close Others',
    closeAll: 'Close All',
  },
};
    title: 'BladeX Admin',
    logoutTip: 'Exit the system, do you want to continue?',
    submitText: 'submit',
    cancelText: 'cancel',
    search: 'Please input search content',
    menuTip: 'none menu list',
    common: {
        condition: 'condition',
        display: 'display',
        hide: 'hide',
    },
    tip: {
        select: 'Please select',
        input: 'Please input',
    },
    upload: {
        upload: 'upload',
        tip: 'Drag files here,/',
    },
    date: {
        start: 'Start date',
        end: 'End date',
        t: 'today',
        y: 'yesterday',
        n: 'nearly 7',
        a: 'whole',
    },
    form: {
        printBtn: 'print',
        mockBtn: 'mock',
        submitBtn: 'submit',
        emptyBtn: 'empty',
    },
    crud: {
        filter: {
            addBtn: 'add',
            clearBtn: 'clear',
            resetBtn: 'reset',
            cancelBtn: 'cancel',
            submitBtn: 'submit',
        },
        column: {
            name: 'name',
            hide: 'hide',
            fixed: 'fixed',
            filters: 'filters',
            sortable: 'sortable',
            index: 'index',
            width: 'width',
        },
        tipStartTitle: 'Currently selected',
        tipEndTitle: 'items',
        editTitle: 'edit',
        copyTitle: 'copy',
        addTitle: 'add',
        viewTitle: 'view',
        filterTitle: 'filter',
        showTitle: 'showTitle',
        menu: 'menu',
        addBtn: 'add',
        show: 'show',
        hide: 'hide',
        open: 'open',
        shrink: 'shrink',
        printBtn: 'print',
        excelBtn: 'excel',
        updateBtn: 'update',
        cancelBtn: 'cancel',
        searchBtn: 'search',
        emptyBtn: 'empty',
        menuBtn: 'menu',
        saveBtn: 'save',
        viewBtn: 'view',
        editBtn: 'edit',
        copyBtn: 'copy',
        delBtn: 'delete',
    },
    login: {
        title: 'Login ',
        info: 'BladeX Development Platform',
        tenantId: 'Please input tenantId',
        name: 'Please input name',
        username: 'Please input account',
        email: 'Please input email',
        password: 'Please input password',
        password1: 'Please input confirm password',
        wechat: 'Wechat',
        qq: 'QQ',
        github: 'github',
        gitee: 'gitee',
        phone: 'Please input a phone',
        code: 'Please input a code',
        submit: 'Login',
        register: 'Register',
        back: 'Back',
        userLogin: 'userLogin',
        phoneLogin: 'phoneLogin',
        thirdLogin: 'thirdLogin',
        ssoLogin: 'ssoLogin',
        msgText: 'send code',
        msgSuccess: 'reissued',
    },
    navbar: {
        info: 'info',
        logOut: 'logout',
        userinfo: 'userinfo',
        roleName: 'role name',
        deptName: 'dept name',
        currentDeptName: 'current role name',
        currentRoleName: 'current dept name',
        switchRoleTo: 'switch role to',
        switchRole: 'switch role',
        switchDeptTo: 'switch dept to',
        switchDept: 'switch dept',
        switchTip: 'whether to switch identities',
        switchSuccess: 'switch success',
        dashboard: 'dashboard',
        lock: 'lock',
        bug: 'none bug',
        bugs: 'bug',
        screenfullF: 'exit screenfull',
        screenfull: 'screenfull',
        language: 'language',
        notice: 'notice',
        theme: 'theme',
        color: 'color',
    },
    tagsView: {
        search: 'Search',
        menu: 'menu',
        clearCache: 'Clear Cache',
        closeOthers: 'Close Others',
        closeAll: 'Close All',
    },
}
src/lang/index.js
@@ -1,26 +1,26 @@
import { createI18n } from 'vue-i18n';
import Store from '@/store';
import elementEnLocale from 'element-plus/es/locale/lang/en';
import elementZhLocale from 'element-plus/es/locale/lang/zh-cn';
import enLocale from './en';
import zhLocale from './zh';
import AvueEnLocale from '@smallwei/avue/lib/locale/lang/en';
import AvueZhLocale from '@smallwei/avue/lib/locale/lang/zh';
import { createI18n } from 'vue-i18n'
import Store from '@/store'
import elementEnLocale from 'element-plus/es/locale/lang/en'
import elementZhLocale from 'element-plus/es/locale/lang/zh-cn'
import enLocale from './en'
import zhLocale from './zh'
import AvueEnLocale from '@smallwei/avue/lib/locale/lang/en'
import AvueZhLocale from '@smallwei/avue/lib/locale/lang/zh'
export const messages = {
  en: {
    ...enLocale,
    ...AvueEnLocale,
    ...elementEnLocale,
  },
  'zh-cn': {
    ...zhLocale,
    ...AvueZhLocale,
    ...elementZhLocale,
  },
};
export const language = Store.getters.language;
    en: {
        ...enLocale,
        ...AvueEnLocale,
        ...elementEnLocale,
    },
    'zh-cn': {
        ...zhLocale,
        ...AvueZhLocale,
        ...elementZhLocale,
    },
}
export const language = Store.getters.language
export default createI18n({
  locale: language,
  messages,
});
    locale: language,
    messages,
})
src/lang/zh.js
@@ -1,136 +1,136 @@
export default {
  title: '指挥调度平台',
  confirmTip: '提示',
  logoutTip: '退出系统, 是否继续?',
  submitText: '确定',
  cancelText: '取消',
  search: '请输入搜索内容',
  menuTip: '没有发现菜单',
  common: {
    condition: '条件',
    display: '显示',
    hide: '隐藏',
  },
  tip: {
    select: '请选择',
    input: '请输入',
  },
  upload: {
    upload: '点击上传',
    tip: '将文件拖到此处,或',
  },
  date: {
    start: '开始日期',
    end: '结束日期',
    t: '今日',
    y: '昨日',
    n: '近7天',
    a: '全部',
  },
  form: {
    printBtn: '打 印',
    mockBtn: '模 拟',
    submitBtn: '提 交',
    emptyBtn: '清 空',
  },
  crud: {
    filter: {
      addBtn: '新增条件',
      clearBtn: '清空数据',
      resetBtn: '清空条件',
      cancelBtn: '取 消',
      submitBtn: '确 定',
    },
    column: {
      name: '列名',
      hide: '隐藏',
      fixed: '冻结',
      filters: '过滤',
      sortable: '排序',
      index: '顺序',
      width: '宽度',
    },
    tipStartTitle: '当前表格已选择',
    tipEndTitle: '项',
    editTitle: '编 辑',
    copyTitle: '复 制',
    addTitle: '新 增',
    viewTitle: '查 看',
    filterTitle: '过滤条件',
    showTitle: '列显隐',
    menu: '操作',
    addBtn: '新 增',
    show: '显 示',
    hide: '隐 藏',
    open: '展 开',
    shrink: '收 缩',
    printBtn: '打 印',
    excelBtn: '导 出',
    updateBtn: '修 改',
    cancelBtn: '取 消',
    searchBtn: '搜 索',
    emptyBtn: '清 空',
    menuBtn: '功 能',
    saveBtn: '保 存',
    viewBtn: '查 看',
    editBtn: '编 辑',
    copyBtn: '复 制',
    delBtn: '删 除',
  },
  login: {
    title: '登录 ',
    info: 'BladeX 微服务平台',
    tenantId: '请输入租户ID',
    name: '请输入姓名',
    username: '请输入账号',
    email: '请输入邮箱',
    password: '请输入密码',
    password1: '请输入确认密码',
    wechat: '微信',
    qq: 'QQ',
    github: 'github',
    gitee: '码云',
    phone: '请输入手机号',
    code: '请输入验证码',
    submit: '登录',
    register: '注册',
    back: '返回',
    userLogin: '账号密码登录',
    phoneLogin: '手机号登录',
    thirdLogin: '第三方登录',
    ssoLogin: '单点登录',
    msgText: '发送验证码',
    msgSuccess: '秒后重发',
  },
  navbar: {
    logOut: '退出登录',
    userinfo: '个人信息',
    roleName: '所属角色',
    deptName: '所属部门',
    currentDeptName: '当前部门',
    currentRoleName: '当前角色',
    switchRoleTo: '角色切换至',
    switchRole: '角色切换',
    switchDeptTo: '部门切换至',
    switchDept: '部门切换',
    switchTip: '是否进行身份切换',
    switchSuccess: '切换成功',
    dashboard: '首页',
    lock: '锁屏',
    bug: '没有错误日志',
    bugs: '条错误日志',
    screenfullF: '退出全屏',
    screenfull: '全屏',
    language: '中英文',
    notice: '消息通知',
    theme: '主题',
    color: '换色',
  },
  tagsView: {
    search: '搜索',
    menu: '更多',
    clearCache: '清除缓存',
    closeOthers: '关闭其它',
    closeAll: '关闭所有',
  },
};
    title: '指挥调度平台',
    confirmTip: '提示',
    logoutTip: '退出系统, 是否继续?',
    submitText: '确定',
    cancelText: '取消',
    search: '请输入搜索内容',
    menuTip: '没有发现菜单',
    common: {
        condition: '条件',
        display: '显示',
        hide: '隐藏',
    },
    tip: {
        select: '请选择',
        input: '请输入',
    },
    upload: {
        upload: '点击上传',
        tip: '将文件拖到此处,或',
    },
    date: {
        start: '开始日期',
        end: '结束日期',
        t: '今日',
        y: '昨日',
        n: '近7天',
        a: '全部',
    },
    form: {
        printBtn: '打 印',
        mockBtn: '模 拟',
        submitBtn: '提 交',
        emptyBtn: '清 空',
    },
    crud: {
        filter: {
            addBtn: '新增条件',
            clearBtn: '清空数据',
            resetBtn: '清空条件',
            cancelBtn: '取 消',
            submitBtn: '确 定',
        },
        column: {
            name: '列名',
            hide: '隐藏',
            fixed: '冻结',
            filters: '过滤',
            sortable: '排序',
            index: '顺序',
            width: '宽度',
        },
        tipStartTitle: '当前表格已选择',
        tipEndTitle: '项',
        editTitle: '编 辑',
        copyTitle: '复 制',
        addTitle: '新 增',
        viewTitle: '查 看',
        filterTitle: '过滤条件',
        showTitle: '列显隐',
        menu: '操作',
        addBtn: '新 增',
        show: '显 示',
        hide: '隐 藏',
        open: '展 开',
        shrink: '收 缩',
        printBtn: '打 印',
        excelBtn: '导 出',
        updateBtn: '修 改',
        cancelBtn: '取 消',
        searchBtn: '搜 索',
        emptyBtn: '清 空',
        menuBtn: '功 能',
        saveBtn: '保 存',
        viewBtn: '查 看',
        editBtn: '编 辑',
        copyBtn: '复 制',
        delBtn: '删 除',
    },
    login: {
        title: '登录 ',
        info: 'BladeX 微服务平台',
        tenantId: '请输入租户ID',
        name: '请输入姓名',
        username: '请输入账号',
        email: '请输入邮箱',
        password: '请输入密码',
        password1: '请输入确认密码',
        wechat: '微信',
        qq: 'QQ',
        github: 'github',
        gitee: '码云',
        phone: '请输入手机号',
        code: '请输入验证码',
        submit: '登录',
        register: '注册',
        back: '返回',
        userLogin: '账号密码登录',
        phoneLogin: '手机号登录',
        thirdLogin: '第三方登录',
        ssoLogin: '单点登录',
        msgText: '发送验证码',
        msgSuccess: '秒后重发',
    },
    navbar: {
        logOut: '退出登录',
        userinfo: '个人信息',
        roleName: '所属角色',
        deptName: '所属部门',
        currentDeptName: '当前部门',
        currentRoleName: '当前角色',
        switchRoleTo: '角色切换至',
        switchRole: '角色切换',
        switchDeptTo: '部门切换至',
        switchDept: '部门切换',
        switchTip: '是否进行身份切换',
        switchSuccess: '切换成功',
        dashboard: '首页',
        lock: '锁屏',
        bug: '没有错误日志',
        bugs: '条错误日志',
        screenfullF: '退出全屏',
        screenfull: '全屏',
        language: '中英文',
        notice: '消息通知',
        theme: '主题',
        color: '换色',
    },
    tagsView: {
        search: '搜索',
        menu: '更多',
        clearCache: '清除缓存',
        closeOthers: '关闭其它',
        closeAll: '关闭所有',
    },
}
src/main.js
@@ -46,7 +46,7 @@
window.axios = axios
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
    app.component(key, component)
}
app.component('basicContainer', basicContainer)
app.component('basicBlock', basicBlock)
@@ -71,17 +71,17 @@
app.use(store)
app.use(router)
app.use(ElementPlus, {
    locale: messages[language],
    locale: messages[language],
})
app.use(Avue, {
    axios,
    calcHeight: 10,
    locale: messages[language],
    axios,
    calcHeight: 10,
    locale: messages[language],
})
app.use(avueUeditor, { axios })
app.use(VueClipboard, {
    autoSetContainer: true,
    appendToBody: true, // 这可以帮助解决一些更复杂的使用场景下的问题
    autoSetContainer: true,
    appendToBody: true, // 这可以帮助解决一些更复杂的使用场景下的问题
})
app.use(globalComponents)
app.mount('#app')
src/mixins/crud.js
@@ -1,217 +1,217 @@
import { mapGetters } from 'vuex';
import { mapGetters } from 'vuex'
export default (app, option = {}) => {
  let optionObj = import.meta.glob(`../option/**/**`)[`../option/${option.name}.js`];
  let apiObj = import.meta.glob(`../api/**/**`)[`../api/${option.name}.js`];
  let mixins = {
    data() {
      return {
        data: [],
        form: {},
        params: {},
        option: {},
        api: {},
        loading: false,
        page: {},
      };
    },
    created() {
      optionObj().then(mode => (this.option = mode.default));
      apiObj().then(mode => {
        this.api = mode;
        this.getList();
      });
    },
    computed: {
      ...mapGetters(['userInfo', 'permission', 'roles']),
      ids() {
        const ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele[this.rowKey]);
        });
        return ids.join(',');
      },
      bindVal() {
        return {
          ref: 'crud',
          option: this.option,
          data: this.data,
          tableLoading: this.loading,
        };
      },
      onEvent() {
        return {
          'size-change': this.sizeChange,
          'current-change': this.currentChange,
          'row-save': this.rowSave,
          'row-update': this.rowUpdate,
          'row-del': this.rowDel,
          'refresh-change': this.refreshChange,
          'search-reset': this.searchChange,
          'search-change': this.searchChange,
        };
      },
      rowKey() {
        return option.rowKey || 'id';
      },
    },
    methods: {
      getList() {
        const callback = () => {
          this.loading = true;
          this.data = [];
          this.api[option.list || 'getList'](
            this.page.currentPage,
            this.page.pageSize,
            this.params
          ).then(res => {
            this.loading = false;
            let data;
            if (option.res) {
              data = option.res(res.data);
            } else {
              data = res.data.data;
            }
            this.page.total = data[option.total || 'total'];
            const result = data[option.data || 'records'];
            this.data = result;
            if (this.listAfter) {
              this.listAfter(data);
            }
          });
        };
        if (this.listBefore) {
          this.listBefore();
        }
        callback();
      },
      rowSave(row, done, loading) {
        const callback = () => {
          delete this.form.params;
          this.api[option.add || 'add'](this.form)
            .then(data => {
              this.getList();
              if (this.addAfter) {
                this.addAfter(data);
              } else {
                this.$message.success('新增成功');
              }
              done();
            })
            .catch(() => {
              loading();
            });
        };
        if (this.addBefore) {
          this.addBefore();
        }
        callback();
      },
      rowUpdate(row, index, done, loading) {
        const callback = () => {
          delete this.form.params;
          this.api[option.update || 'update'](this.form)
            .then(data => {
              this.getList();
              if (this.updateAfter) {
                this.updateAfter(data);
              } else {
                this.$message.success('更新成功');
              }
              done();
            })
            .catch(() => {
              loading();
            });
        };
        if (this.updateBefore) {
          this.updateBefore();
        }
        callback();
      },
      rowDel(row, index) {
        const callback = () => {
          this.api[option.del || 'del'](row[this.rowKey], row).then(data => {
            this.getList();
            if (this.delAfter) {
              this.delAfter(data, row, index);
            } else {
              this.$message.success('删除成功');
            }
          });
        };
        if (this.delBefore) {
          this.delBefore();
          callback();
        } else {
          this.$confirm('确定将选择数据删除?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          }).then(() => {
            callback();
          });
        }
      },
      handleDelete() {
        if (this.selectionList.length === 0) {
          this.$message.warning('请选择至少一条数据');
          return;
        }
        this.$confirm('确定将选择数据删除?', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }).then(() => {
          this.api[option.del || 'remove'](this.ids).then(data => {
            this.getList();
            if (this.delMultiAfter) {
              this.delMultiAfter(data, this.ids);
            } else {
              this.$message.success('删除成功');
            }
          });
        });
      },
      searchChange(params, done) {
        if (done) done();
        this.params = params;
        this.page.currentPage = 1;
        this.getList();
      },
      dateChange(date) {
        if (date) {
          this.params.createTime_dategt = date[0];
          this.params.createTime_datelt = date[1];
        } else {
          delete this.params.createTime_dategt;
          delete this.params.createTime_datelt;
        }
        this.page.currentPage = 1;
        this.getList();
      },
      selectionChange(list) {
        this.selectionList = list;
      },
      selectionClear() {
        this.selectionList = [];
        this.$refs.crud.toggleSelection();
      },
      refreshChange() {
        this.getList();
      },
      sizeChange(val) {
        this.page.currentPage = 1;
        this.page.pageSize = val;
        this.getList();
      },
      currentChange(val) {
        this.page.currentPage = val;
        this.getList();
      },
    },
  };
  app.mixins = app.mixins || [];
  app.mixins.push(mixins);
  return app;
};
    let optionObj = import.meta.glob(`../option/**/**`)[`../option/${option.name}.js`]
    let apiObj = import.meta.glob(`../api/**/**`)[`../api/${option.name}.js`]
    let mixins = {
        data() {
            return {
                data: [],
                form: {},
                params: {},
                option: {},
                api: {},
                loading: false,
                page: {},
            }
        },
        created() {
            optionObj().then(mode => (this.option = mode.default))
            apiObj().then(mode => {
                this.api = mode
                this.getList()
            })
        },
        computed: {
            ...mapGetters(['userInfo', 'permission', 'roles']),
            ids() {
                const ids = []
                this.selectionList.forEach(ele => {
                    ids.push(ele[this.rowKey])
                })
                return ids.join(',')
            },
            bindVal() {
                return {
                    ref: 'crud',
                    option: this.option,
                    data: this.data,
                    tableLoading: this.loading,
                }
            },
            onEvent() {
                return {
                    'size-change': this.sizeChange,
                    'current-change': this.currentChange,
                    'row-save': this.rowSave,
                    'row-update': this.rowUpdate,
                    'row-del': this.rowDel,
                    'refresh-change': this.refreshChange,
                    'search-reset': this.searchChange,
                    'search-change': this.searchChange,
                }
            },
            rowKey() {
                return option.rowKey || 'id'
            },
        },
        methods: {
            getList() {
                const callback = () => {
                    this.loading = true
                    this.data = []
                    this.api[option.list || 'getList'](
                        this.page.currentPage,
                        this.page.pageSize,
                        this.params
                    ).then(res => {
                        this.loading = false
                        let data
                        if (option.res) {
                            data = option.res(res.data)
                        } else {
                            data = res.data.data
                        }
                        this.page.total = data[option.total || 'total']
                        const result = data[option.data || 'records']
                        this.data = result
                        if (this.listAfter) {
                            this.listAfter(data)
                        }
                    })
                }
                if (this.listBefore) {
                    this.listBefore()
                }
                callback()
            },
            rowSave(row, done, loading) {
                const callback = () => {
                    delete this.form.params
                    this.api[option.add || 'add'](this.form)
                        .then(data => {
                            this.getList()
                            if (this.addAfter) {
                                this.addAfter(data)
                            } else {
                                this.$message.success('新增成功')
                            }
                            done()
                        })
                        .catch(() => {
                            loading()
                        })
                }
                if (this.addBefore) {
                    this.addBefore()
                }
                callback()
            },
            rowUpdate(row, index, done, loading) {
                const callback = () => {
                    delete this.form.params
                    this.api[option.update || 'update'](this.form)
                        .then(data => {
                            this.getList()
                            if (this.updateAfter) {
                                this.updateAfter(data)
                            } else {
                                this.$message.success('更新成功')
                            }
                            done()
                        })
                        .catch(() => {
                            loading()
                        })
                }
                if (this.updateBefore) {
                    this.updateBefore()
                }
                callback()
            },
            rowDel(row, index) {
                const callback = () => {
                    this.api[option.del || 'del'](row[this.rowKey], row).then(data => {
                        this.getList()
                        if (this.delAfter) {
                            this.delAfter(data, row, index)
                        } else {
                            this.$message.success('删除成功')
                        }
                    })
                }
                if (this.delBefore) {
                    this.delBefore()
                    callback()
                } else {
                    this.$confirm('确定将选择数据删除?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                    }).then(() => {
                        callback()
                    })
                }
            },
            handleDelete() {
                if (this.selectionList.length === 0) {
                    this.$message.warning('请选择至少一条数据')
                    return
                }
                this.$confirm('确定将选择数据删除?', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning',
                }).then(() => {
                    this.api[option.del || 'remove'](this.ids).then(data => {
                        this.getList()
                        if (this.delMultiAfter) {
                            this.delMultiAfter(data, this.ids)
                        } else {
                            this.$message.success('删除成功')
                        }
                    })
                })
            },
            searchChange(params, done) {
                if (done) done()
                this.params = params
                this.page.currentPage = 1
                this.getList()
            },
            dateChange(date) {
                if (date) {
                    this.params.createTime_dategt = date[0]
                    this.params.createTime_datelt = date[1]
                } else {
                    delete this.params.createTime_dategt
                    delete this.params.createTime_datelt
                }
                this.page.currentPage = 1
                this.getList()
            },
            selectionChange(list) {
                this.selectionList = list
            },
            selectionClear() {
                this.selectionList = []
                this.$refs.crud.toggleSelection()
            },
            refreshChange() {
                this.getList()
            },
            sizeChange(val) {
                this.page.currentPage = 1
                this.page.pageSize = val
                this.getList()
            },
            currentChange(val) {
                this.page.currentPage = val
                this.getList()
            },
        },
    }
    app.mixins = app.mixins || []
    app.mixins.push(mixins)
    return app
}
src/mixins/index.js
@@ -1,45 +1,45 @@
import { validatenull } from '@/utils/validate';
import { getStore } from '@/utils/store.js';
import { validatenull } from '@/utils/validate'
import { getStore } from '@/utils/store.js'
export default {
  data() {
    return {
      //刷新token锁
      refreshLock: false,
      //刷新token的时间
      refreshTime: '',
    };
  },
  created() {
    //实时检测刷新token
    //this.refreshToken();
  },
  methods: {
    //实时检测刷新token
    refreshToken() {
      this.refreshTime = setInterval(() => {
        const token =
          getStore({
            name: 'token',
            debug: true,
          }) || {};
        let date1 = this.$dayjs(token.datetime);
        let date2 = this.$dayjs();
        const date = date2.diff(date1, 'seconds');
        if (validatenull(date)) return;
        if (date >= this.website.tokenTime && !this.refreshLock) {
          this.refreshLock = true;
          this.$store
            .dispatch('RefreshToken')
            .then(() => {
              this.refreshLock = false;
            })
            .catch(err => {
              console.log(err);
              this.refreshLock = false;
            });
        }
      }, 1000);
    },
  },
};
    data() {
        return {
            //刷新token锁
            refreshLock: false,
            //刷新token的时间
            refreshTime: '',
        }
    },
    created() {
        //实时检测刷新token
        //this.refreshToken();
    },
    methods: {
        //实时检测刷新token
        refreshToken() {
            this.refreshTime = setInterval(() => {
                const token =
                    getStore({
                        name: 'token',
                        debug: true,
                    }) || {}
                let date1 = this.$dayjs(token.datetime)
                let date2 = this.$dayjs()
                const date = date2.diff(date1, 'seconds')
                if (validatenull(date)) return
                if (date >= this.website.tokenTime && !this.refreshLock) {
                    this.refreshLock = true
                    this.$store
                        .dispatch('RefreshToken')
                        .then(() => {
                            this.refreshLock = false
                        })
                        .catch(err => {
                            console.log(err)
                            this.refreshLock = false
                        })
                }
            }, 1000)
        },
    },
}
src/mockProdServer.js
@@ -1,9 +1,9 @@
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
import menuModule from '../mock/menu';
import userModule from '../mock/user';
import crudModule from '../mock/crud';
import menuModule from '../mock/menu'
import userModule from '../mock/user'
import crudModule from '../mock/crud'
export const setupProdMockServer = () => {
  createProdMockServer([...menuModule, ...userModule, ...crudModule]);
};
    createProdMockServer([...menuModule, ...userModule, ...crudModule])
}
src/option/job/jobinfo.js
@@ -1,515 +1,515 @@
export const timeExpressionTypeDic = [
  {
    label: 'API',
    value: 1,
  },
  {
    label: 'CRON',
    value: 2,
  },
  {
    label: '固定频率(毫秒)',
    value: 3,
  },
  {
    label: '固定延迟(毫秒)',
    value: 4,
  },
  {
    label: '工作流',
    value: 5,
  },
];
    {
        label: 'API',
        value: 1,
    },
    {
        label: 'CRON',
        value: 2,
    },
    {
        label: '固定频率(毫秒)',
        value: 3,
    },
    {
        label: '固定延迟(毫秒)',
        value: 4,
    },
    {
        label: '工作流',
        value: 5,
    },
]
export const executeTypeDic = [
  {
    label: '单机执行',
    value: 1,
  },
  {
    label: '广播执行',
    value: 2,
  },
  {
    label: 'MapReduce',
    value: 3,
  },
];
    {
        label: '单机执行',
        value: 1,
    },
    {
        label: '广播执行',
        value: 2,
    },
    {
        label: 'MapReduce',
        value: 3,
    },
]
export const processorTypeDic = [
  {
    label: '内建处理器',
    value: 1,
  },
  {
    label: '外部处理器(动态加载)',
    value: 4,
  },
];
    {
        label: '内建处理器',
        value: 1,
    },
    {
        label: '外部处理器(动态加载)',
        value: 4,
    },
]
export const dispatchStrategyDic = [
  {
    label: 'HEALTH_FIRST',
    value: 1,
  },
  {
    label: 'RANDOM',
    value: 2,
  },
];
    {
        label: 'HEALTH_FIRST',
        value: 1,
    },
    {
        label: 'RANDOM',
        value: 2,
    },
]
export const enableDic = [
  {
    label: '暂停',
    value: 0,
  },
  {
    label: '启用',
    value: 1,
  },
];
    {
        label: '暂停',
        value: 0,
    },
    {
        label: '启用',
        value: 1,
    },
]
export const logTypeDic = [
  {
    label: 'ONLINE',
    value: 1,
  },
  {
    label: 'LOCAL',
    value: 2,
  },
  {
    label: 'STDOUT',
    value: 3,
  },
  {
    label: 'LOCAL_AND_ONLINE',
    value: 4,
  },
  {
    label: 'NULL',
    value: 999,
  },
];
    {
        label: 'ONLINE',
        value: 1,
    },
    {
        label: 'LOCAL',
        value: 2,
    },
    {
        label: 'STDOUT',
        value: 3,
    },
    {
        label: 'LOCAL_AND_ONLINE',
        value: 4,
    },
    {
        label: 'NULL',
        value: 999,
    },
]
export const logLevelDic = [
  {
    label: 'DEBUG',
    value: 1,
  },
  {
    label: 'INFO',
    value: 2,
  },
  {
    label: 'WARN',
    value: 3,
  },
  {
    label: 'ERROR',
    value: 4,
  },
  {
    label: 'OFF',
    value: 99,
  },
];
    {
        label: 'DEBUG',
        value: 1,
    },
    {
        label: 'INFO',
        value: 2,
    },
    {
        label: 'WARN',
        value: 3,
    },
    {
        label: 'ERROR',
        value: 4,
    },
    {
        label: 'OFF',
        value: 99,
    },
]
export default {
  height: 'auto',
  calcHeight: 30,
  tip: false,
  searchShow: true,
  searchMenuSpan: 6,
  border: true,
  index: true,
  viewBtn: true,
  selection: true,
  grid: true,
  labelWidth: 180,
  menuWidth: 350,
  dialogWidth: 1200,
  dialogClickModal: false,
  tabs: true,
  column: [
    {
      label: '任务应用',
      prop: 'jobServerId',
      type: 'select',
      dicUrl: '/blade-job/job-server/select',
      props: {
        label: 'jobAppName',
        value: 'id',
      },
      search: true,
      display: false,
    },
    {
      label: '任务ID',
      prop: 'jobId',
      type: 'input',
      search: true,
      width: 80,
      display: false,
    },
    {
      label: '任务名称',
      prop: 'jobName',
      type: 'input',
      search: true,
      width: 200,
      display: false,
    },
    {
      label: '定时信息',
      labelTip: '时间表达式类型',
      prop: 'timeExpressionType',
      type: 'select',
      dicData: timeExpressionTypeDic,
      rules: [
        {
          required: true,
          message: '请选择定时信息',
          trigger: 'blur',
        },
      ],
      width: 120,
      display: false,
    },
    {
      label: '执行类型',
      labelTip: '枚举值',
      prop: 'executeType',
      type: 'select',
      dicData: executeTypeDic,
      rules: [
        {
          required: true,
          message: '请选择执行器类型',
          trigger: 'blur',
        },
      ],
      width: 110,
      display: false,
    },
    {
      label: '处理器类型',
      labelTip: '枚举值',
      prop: 'processorType',
      type: 'select',
      dicData: processorTypeDic,
      rules: [
        {
          required: true,
          message: '请选择处理器类型',
          trigger: 'blur',
        },
      ],
      width: 180,
      display: false,
    },
    {
      label: '任务状态',
      labelTip: '未启用的任务不会被调度',
      prop: 'enable',
      type: 'switch',
      dicData: enableDic,
      slot: true,
      width: 100,
      display: false,
    },
  ],
  group: [
    {
      label: '基础配置',
      prop: 'modelSetting',
      icon: 'el-icon-tickets',
      column: [
        {
          label: '任务应用',
          prop: 'jobServerId',
          type: 'select',
          dicUrl: '/blade-job/job-server/select',
          props: {
            label: 'jobAppName',
            value: 'id',
          },
          editDisabled: true,
          rules: [
            {
              required: true,
              message: '请选择任务应用',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '任务状态',
          labelTip: '未启用的任务不会被调度',
          prop: 'enable',
          type: 'switch',
          value: 1,
          rules: [
            {
              required: true,
              message: '请选择是否开启',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '任务名称',
          prop: 'jobName',
          type: 'input',
          rules: [
            {
              required: true,
              message: '请输入任务名称',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '生命周期',
          labelTip: '预留,用于指定定时调度任务的生效时间范围)',
          prop: 'lifecycle',
          type: 'datetimerange',
          format: 'YYYY-MM-DD HH:mm:ss',
          valueFormat: 'YYYY-MM-DD HH:mm:ss',
          startPlaceholder: '任务开始时间',
          endPlaceholder: '任务结束时间',
        },
        {
          label: '定时类型',
          labelTip: '时间表达式类型',
          prop: 'timeExpressionType',
          type: 'select',
          dicData: timeExpressionTypeDic,
          value: 2,
          rules: [
            {
              required: true,
              message: '请选择定时信息',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '时间表达式',
          labelTip: '填写类型由 定时类型 决定,比如 CRON 需要填写 CRON 表达式',
          prop: 'timeExpression',
          type: 'input',
        },
        {
          label: '执行类型',
          labelTip: '枚举值',
          prop: 'executeType',
          type: 'select',
          dicData: executeTypeDic,
          value: 1,
          rules: [
            {
              required: true,
              message: '请选择执行器类型',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '运行时配置',
          labelTip: '目前支持随机(RANDOM)和健康度优先(HEALTH_FIRST)',
          prop: 'dispatchStrategy',
          type: 'select',
          dicData: dispatchStrategyDic,
          value: 1,
          rules: [
            {
              required: true,
              message: '请选择运行时配置',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '处理器类型',
          labelTip: '枚举值',
          prop: 'processorType',
          type: 'select',
          dicData: processorTypeDic,
          value: 1,
          rules: [
            {
              required: true,
              message: '请选择处理器类型',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '处理器参数',
          labelTip:
            '如Java处理器需要填写全限定类名,如:org.springblade.demo.MapReduceProcessorDemo',
          prop: 'processorInfo',
          type: 'input',
          rules: [
            {
              required: true,
              message: '请输入处理器参数',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '任务参数',
          labelTip: '方法入参 TaskContext 对象的 json 字段',
          prop: 'jobParams',
          type: 'input',
          span: 24,
        },
        {
          label: '任务描述',
          prop: 'jobDescription',
          type: 'textarea',
          minRows: 3,
          span: 24,
        },
      ],
    },
    {
      label: '高级配置',
      prop: 'templateSetting',
      icon: 'el-icon-copy-document',
      column: [
        {
          label: '最大实例数',
          labelTip:
            '该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例)',
          prop: 'maxInstanceNum',
          type: 'number',
          value: 0,
        },
        {
          label: '单机线程并发数',
          labelTip: '该实例执行过程中每个 Worker 使用的线程数量',
          prop: 'concurrency',
          type: 'number',
          value: 5,
        },
        {
          label: '任务实例运行时间限制',
          labelTip: '0 代表无任何限制,超时会被打断并判定为执行失败',
          prop: 'instanceTimeLimit',
          type: 'number',
          value: 0,
        },
        {
          label: '任务实例重试次数',
          labelTip: '任务实例重试次数,整个任务失败时重试,代价大,不推荐使用',
          prop: 'instanceRetryNum',
          type: 'number',
          value: 0,
        },
        {
          label: '任务作业重试次数',
          labelTip: 'Task 重试次数,每个子 Task 失败后单独重试,代价小,推荐使用',
          prop: 'taskRetryNum',
          type: 'number',
          value: 0,
        },
        {
          label: '最低CPU核心',
          labelTip:
            '最小可用 CPU 核心数,CPU 可用核心数小于该值的 Worker 将不会执行该任务,0 代表无任何限制',
          prop: 'minCpuCores',
          type: 'number',
          value: 0,
        },
        {
          label: '最低内存(GB)',
          labelTip: '可用内存小于该值的Worker 将不会执行该任务,0 代表无任何限制',
          prop: 'minMemorySpace',
          type: 'number',
          value: 0,
        },
        {
          label: '最低磁盘空间(GB)',
          labelTip: '可用磁盘空间小于该值的Worker 将不会执行该任务,0 代表无任何限制',
          prop: 'minDiskSpace',
          type: 'number',
          value: 0,
        },
        {
          label: '执行机器地址',
          labelTip: '设置该参数后只有列表中的机器允许执行该任务,空代表不指定机器',
          prop: 'designatedWorkers',
          type: 'input',
        },
        {
          label: '最大执行机器数量',
          labelTip: '限定调动执行的机器数量,0代表无限制',
          prop: 'maxWorkerCount',
          type: 'number',
          value: 0,
        },
      ],
    },
    {
      label: '其他配置',
      prop: 'codingSetting',
      icon: 'el-icon-printer',
      column: [
        {
          label: '报警人员ID列表',
          labelTip: '接收报警的用户ID列表',
          prop: 'notifyUserIds',
          type: 'input',
        },
        {
          label: '错误阈值',
          labelTip: '错误阈值,0代表不限制',
          prop: 'alertThreshold',
          type: 'number',
          value: 0,
        },
        {
          label: '统计窗口(s)',
          labelTip: '统计的窗口长度(s),0代表不限制',
          prop: 'statisticWindowLen',
          type: 'number',
          value: 0,
        },
        {
          label: '沉默窗口(s)',
          labelTip: '沉默时间窗口(s),0代表不限制',
          prop: 'silenceWindowLen',
          type: 'number',
          value: 0,
        },
        {
          label: '日志配置',
          labelTip: '日志配置',
          prop: 'logType',
          type: 'select',
          value: 1,
          dicData: logTypeDic,
        },
        {
          label: '日志级别',
          labelTip: '日志级别',
          prop: 'logLevel',
          type: 'select',
          value: 2,
          dicData: logLevelDic,
        },
        {
          label: '扩展字段',
          labelTip: '供开发者使用,用于功能扩展,powerjob 自身不会使用该字段',
          prop: 'extra',
          type: 'textarea',
          minRows: 3,
          span: 24,
        },
      ],
    },
  ],
};
    height: 'auto',
    calcHeight: 30,
    tip: false,
    searchShow: true,
    searchMenuSpan: 6,
    border: true,
    index: true,
    viewBtn: true,
    selection: true,
    grid: true,
    labelWidth: 180,
    menuWidth: 350,
    dialogWidth: 1200,
    dialogClickModal: false,
    tabs: true,
    column: [
        {
            label: '任务应用',
            prop: 'jobServerId',
            type: 'select',
            dicUrl: '/blade-job/job-server/select',
            props: {
                label: 'jobAppName',
                value: 'id',
            },
            search: true,
            display: false,
        },
        {
            label: '任务ID',
            prop: 'jobId',
            type: 'input',
            search: true,
            width: 80,
            display: false,
        },
        {
            label: '任务名称',
            prop: 'jobName',
            type: 'input',
            search: true,
            width: 200,
            display: false,
        },
        {
            label: '定时信息',
            labelTip: '时间表达式类型',
            prop: 'timeExpressionType',
            type: 'select',
            dicData: timeExpressionTypeDic,
            rules: [
                {
                    required: true,
                    message: '请选择定时信息',
                    trigger: 'blur',
                },
            ],
            width: 120,
            display: false,
        },
        {
            label: '执行类型',
            labelTip: '枚举值',
            prop: 'executeType',
            type: 'select',
            dicData: executeTypeDic,
            rules: [
                {
                    required: true,
                    message: '请选择执行器类型',
                    trigger: 'blur',
                },
            ],
            width: 110,
            display: false,
        },
        {
            label: '处理器类型',
            labelTip: '枚举值',
            prop: 'processorType',
            type: 'select',
            dicData: processorTypeDic,
            rules: [
                {
                    required: true,
                    message: '请选择处理器类型',
                    trigger: 'blur',
                },
            ],
            width: 180,
            display: false,
        },
        {
            label: '任务状态',
            labelTip: '未启用的任务不会被调度',
            prop: 'enable',
            type: 'switch',
            dicData: enableDic,
            slot: true,
            width: 100,
            display: false,
        },
    ],
    group: [
        {
            label: '基础配置',
            prop: 'modelSetting',
            icon: 'el-icon-tickets',
            column: [
                {
                    label: '任务应用',
                    prop: 'jobServerId',
                    type: 'select',
                    dicUrl: '/blade-job/job-server/select',
                    props: {
                        label: 'jobAppName',
                        value: 'id',
                    },
                    editDisabled: true,
                    rules: [
                        {
                            required: true,
                            message: '请选择任务应用',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '任务状态',
                    labelTip: '未启用的任务不会被调度',
                    prop: 'enable',
                    type: 'switch',
                    value: 1,
                    rules: [
                        {
                            required: true,
                            message: '请选择是否开启',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '任务名称',
                    prop: 'jobName',
                    type: 'input',
                    rules: [
                        {
                            required: true,
                            message: '请输入任务名称',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '生命周期',
                    labelTip: '预留,用于指定定时调度任务的生效时间范围)',
                    prop: 'lifecycle',
                    type: 'datetimerange',
                    format: 'YYYY-MM-DD HH:mm:ss',
                    valueFormat: 'YYYY-MM-DD HH:mm:ss',
                    startPlaceholder: '任务开始时间',
                    endPlaceholder: '任务结束时间',
                },
                {
                    label: '定时类型',
                    labelTip: '时间表达式类型',
                    prop: 'timeExpressionType',
                    type: 'select',
                    dicData: timeExpressionTypeDic,
                    value: 2,
                    rules: [
                        {
                            required: true,
                            message: '请选择定时信息',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '时间表达式',
                    labelTip: '填写类型由 定时类型 决定,比如 CRON 需要填写 CRON 表达式',
                    prop: 'timeExpression',
                    type: 'input',
                },
                {
                    label: '执行类型',
                    labelTip: '枚举值',
                    prop: 'executeType',
                    type: 'select',
                    dicData: executeTypeDic,
                    value: 1,
                    rules: [
                        {
                            required: true,
                            message: '请选择执行器类型',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '运行时配置',
                    labelTip: '目前支持随机(RANDOM)和健康度优先(HEALTH_FIRST)',
                    prop: 'dispatchStrategy',
                    type: 'select',
                    dicData: dispatchStrategyDic,
                    value: 1,
                    rules: [
                        {
                            required: true,
                            message: '请选择运行时配置',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '处理器类型',
                    labelTip: '枚举值',
                    prop: 'processorType',
                    type: 'select',
                    dicData: processorTypeDic,
                    value: 1,
                    rules: [
                        {
                            required: true,
                            message: '请选择处理器类型',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '处理器参数',
                    labelTip:
                        '如Java处理器需要填写全限定类名,如:org.springblade.demo.MapReduceProcessorDemo',
                    prop: 'processorInfo',
                    type: 'input',
                    rules: [
                        {
                            required: true,
                            message: '请输入处理器参数',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '任务参数',
                    labelTip: '方法入参 TaskContext 对象的 json 字段',
                    prop: 'jobParams',
                    type: 'input',
                    span: 24,
                },
                {
                    label: '任务描述',
                    prop: 'jobDescription',
                    type: 'textarea',
                    minRows: 3,
                    span: 24,
                },
            ],
        },
        {
            label: '高级配置',
            prop: 'templateSetting',
            icon: 'el-icon-copy-document',
            column: [
                {
                    label: '最大实例数',
                    labelTip:
                        '该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例)',
                    prop: 'maxInstanceNum',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '单机线程并发数',
                    labelTip: '该实例执行过程中每个 Worker 使用的线程数量',
                    prop: 'concurrency',
                    type: 'number',
                    value: 5,
                },
                {
                    label: '任务实例运行时间限制',
                    labelTip: '0 代表无任何限制,超时会被打断并判定为执行失败',
                    prop: 'instanceTimeLimit',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '任务实例重试次数',
                    labelTip: '任务实例重试次数,整个任务失败时重试,代价大,不推荐使用',
                    prop: 'instanceRetryNum',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '任务作业重试次数',
                    labelTip: 'Task 重试次数,每个子 Task 失败后单独重试,代价小,推荐使用',
                    prop: 'taskRetryNum',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '最低CPU核心',
                    labelTip:
                        '最小可用 CPU 核心数,CPU 可用核心数小于该值的 Worker 将不会执行该任务,0 代表无任何限制',
                    prop: 'minCpuCores',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '最低内存(GB)',
                    labelTip: '可用内存小于该值的Worker 将不会执行该任务,0 代表无任何限制',
                    prop: 'minMemorySpace',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '最低磁盘空间(GB)',
                    labelTip: '可用磁盘空间小于该值的Worker 将不会执行该任务,0 代表无任何限制',
                    prop: 'minDiskSpace',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '执行机器地址',
                    labelTip: '设置该参数后只有列表中的机器允许执行该任务,空代表不指定机器',
                    prop: 'designatedWorkers',
                    type: 'input',
                },
                {
                    label: '最大执行机器数量',
                    labelTip: '限定调动执行的机器数量,0代表无限制',
                    prop: 'maxWorkerCount',
                    type: 'number',
                    value: 0,
                },
            ],
        },
        {
            label: '其他配置',
            prop: 'codingSetting',
            icon: 'el-icon-printer',
            column: [
                {
                    label: '报警人员ID列表',
                    labelTip: '接收报警的用户ID列表',
                    prop: 'notifyUserIds',
                    type: 'input',
                },
                {
                    label: '错误阈值',
                    labelTip: '错误阈值,0代表不限制',
                    prop: 'alertThreshold',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '统计窗口(s)',
                    labelTip: '统计的窗口长度(s),0代表不限制',
                    prop: 'statisticWindowLen',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '沉默窗口(s)',
                    labelTip: '沉默时间窗口(s),0代表不限制',
                    prop: 'silenceWindowLen',
                    type: 'number',
                    value: 0,
                },
                {
                    label: '日志配置',
                    labelTip: '日志配置',
                    prop: 'logType',
                    type: 'select',
                    value: 1,
                    dicData: logTypeDic,
                },
                {
                    label: '日志级别',
                    labelTip: '日志级别',
                    prop: 'logLevel',
                    type: 'select',
                    value: 2,
                    dicData: logLevelDic,
                },
                {
                    label: '扩展字段',
                    labelTip: '供开发者使用,用于功能扩展,powerjob 自身不会使用该字段',
                    prop: 'extra',
                    type: 'textarea',
                    minRows: 3,
                    span: 24,
                },
            ],
        },
    ],
}
src/option/job/jobserver.js
@@ -1,78 +1,78 @@
export default {
  height: 'auto',
  calcHeight: 30,
  tip: false,
  searchShow: true,
  searchMenuSpan: 6,
  border: true,
  index: true,
  viewBtn: true,
  selection: true,
  grid: true,
  labelWidth: 100,
  menuWidth: 350,
  dialogClickModal: false,
  column: [
    {
      label: '服务名称',
      prop: 'jobServerName',
      type: 'input',
      span: 24,
      search: true,
      rules: [
        {
          required: true,
          message: '请输入服务名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '服务器地址',
      prop: 'jobServerUrl',
      type: 'input',
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入服务器地址',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '应用名称',
      prop: 'jobAppName',
      type: 'input',
      span: 24,
      search: true,
      rules: [
        {
          required: true,
          message: '请输入应用名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '应用密码',
      prop: 'jobAppPassword',
      type: 'input',
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入应用密码',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '任务备注',
      prop: 'jobRemark',
      type: 'textarea',
      minRows: 3,
      span: 24,
    },
  ],
};
    height: 'auto',
    calcHeight: 30,
    tip: false,
    searchShow: true,
    searchMenuSpan: 6,
    border: true,
    index: true,
    viewBtn: true,
    selection: true,
    grid: true,
    labelWidth: 100,
    menuWidth: 350,
    dialogClickModal: false,
    column: [
        {
            label: '服务名称',
            prop: 'jobServerName',
            type: 'input',
            span: 24,
            search: true,
            rules: [
                {
                    required: true,
                    message: '请输入服务名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '服务器地址',
            prop: 'jobServerUrl',
            type: 'input',
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入服务器地址',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '应用名称',
            prop: 'jobAppName',
            type: 'input',
            span: 24,
            search: true,
            rules: [
                {
                    required: true,
                    message: '请输入应用名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '应用密码',
            prop: 'jobAppPassword',
            type: 'input',
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入应用密码',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '任务备注',
            prop: 'jobRemark',
            type: 'textarea',
            minRows: 3,
            span: 24,
        },
    ],
}
src/option/system/dict.js
@@ -1,210 +1,210 @@
export const optionParent = {
  height: 'auto',
  calcHeight: 32,
  tip: false,
  searchShow: true,
  searchMenuSpan: 10,
  border: true,
  index: true,
  selection: true,
  viewBtn: true,
  menuWidth: 250,
  dialogWidth: 880,
  dialogClickModal: false,
  column: [
    {
      label: '字典编号',
      prop: 'code',
      search: true,
      slot: true,
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入字典编号',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典名称',
      prop: 'dictValue',
      search: true,
      align: 'center',
      rules: [
        {
          required: true,
          message: '请输入字典名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典排序',
      prop: 'sort',
      type: 'number',
      align: 'right',
      width: 100,
      rules: [
        {
          required: true,
          message: '请输入字典排序',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '封存',
      prop: 'isSealed',
      type: 'switch',
      align: 'center',
      width: 100,
      dicData: [
        {
          label: '否',
          value: 0,
        },
        {
          label: '是',
          value: 1,
        },
      ],
      value: 0,
      slot: true,
      rules: [
        {
          required: true,
          message: '请选择封存',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典备注',
      prop: 'remark',
      hide: true,
    },
  ],
};
    height: 'auto',
    calcHeight: 32,
    tip: false,
    searchShow: true,
    searchMenuSpan: 10,
    border: true,
    index: true,
    selection: true,
    viewBtn: true,
    menuWidth: 250,
    dialogWidth: 880,
    dialogClickModal: false,
    column: [
        {
            label: '字典编号',
            prop: 'code',
            search: true,
            slot: true,
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入字典编号',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典名称',
            prop: 'dictValue',
            search: true,
            align: 'center',
            rules: [
                {
                    required: true,
                    message: '请输入字典名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典排序',
            prop: 'sort',
            type: 'number',
            align: 'right',
            width: 100,
            rules: [
                {
                    required: true,
                    message: '请输入字典排序',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '封存',
            prop: 'isSealed',
            type: 'switch',
            align: 'center',
            width: 100,
            dicData: [
                {
                    label: '否',
                    value: 0,
                },
                {
                    label: '是',
                    value: 1,
                },
            ],
            value: 0,
            slot: true,
            rules: [
                {
                    required: true,
                    message: '请选择封存',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典备注',
            prop: 'remark',
            hide: true,
        },
    ],
}
export const optionChild = {
  height: 'auto',
  calcHeight: 95,
  tip: false,
  searchShow: true,
  searchMenuSpan: 10,
  tree: true,
  border: true,
  index: true,
  selection: true,
  viewBtn: true,
  menuWidth: 300,
  dialogWidth: 880,
  dialogClickModal: false,
  column: [
    {
      label: '字典编号',
      prop: 'code',
      addDisabled: true,
      editDisabled: true,
      search: true,
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入字典编号',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典名称',
      prop: 'dictValue',
      search: true,
      align: 'center',
      rules: [
        {
          required: true,
          message: '请输入字典名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '上级字典',
      prop: 'parentId',
      type: 'tree',
      dicData: [],
      hide: true,
      props: {
        label: 'title',
      },
      addDisabled: true,
      editDisabled: true,
      rules: [
        {
          required: false,
          message: '请选择上级字典',
          trigger: 'click',
        },
      ],
    },
    {
      label: '字典键值',
      prop: 'dictKey',
      width: 85,
      rules: [
        {
          required: true,
          message: '请输入字典键值',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典排序',
      prop: 'sort',
      type: 'number',
      align: 'right',
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入字典排序',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '封存',
      prop: 'isSealed',
      type: 'switch',
      align: 'center',
      width: 80,
      dicData: [
        {
          label: '否',
          value: 0,
        },
        {
          label: '是',
          value: 1,
        },
      ],
      value: 0,
      slot: true,
      rules: [
        {
          required: true,
          message: '请选择封存',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典备注',
      prop: 'remark',
      hide: true,
    },
  ],
};
    height: 'auto',
    calcHeight: 95,
    tip: false,
    searchShow: true,
    searchMenuSpan: 10,
    tree: true,
    border: true,
    index: true,
    selection: true,
    viewBtn: true,
    menuWidth: 300,
    dialogWidth: 880,
    dialogClickModal: false,
    column: [
        {
            label: '字典编号',
            prop: 'code',
            addDisabled: true,
            editDisabled: true,
            search: true,
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入字典编号',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典名称',
            prop: 'dictValue',
            search: true,
            align: 'center',
            rules: [
                {
                    required: true,
                    message: '请输入字典名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '上级字典',
            prop: 'parentId',
            type: 'tree',
            dicData: [],
            hide: true,
            props: {
                label: 'title',
            },
            addDisabled: true,
            editDisabled: true,
            rules: [
                {
                    required: false,
                    message: '请选择上级字典',
                    trigger: 'click',
                },
            ],
        },
        {
            label: '字典键值',
            prop: 'dictKey',
            width: 85,
            rules: [
                {
                    required: true,
                    message: '请输入字典键值',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典排序',
            prop: 'sort',
            type: 'number',
            align: 'right',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入字典排序',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '封存',
            prop: 'isSealed',
            type: 'switch',
            align: 'center',
            width: 80,
            dicData: [
                {
                    label: '否',
                    value: 0,
                },
                {
                    label: '是',
                    value: 1,
                },
            ],
            value: 0,
            slot: true,
            rules: [
                {
                    required: true,
                    message: '请选择封存',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典备注',
            prop: 'remark',
            hide: true,
        },
    ],
}
src/option/system/dictbiz.js
@@ -1,211 +1,211 @@
export const optionParent = {
  height: 'auto',
  calcHeight: 32,
  tip: false,
  searchShow: true,
  searchMenuSpan: 10,
  border: true,
  index: true,
  selection: true,
  viewBtn: true,
  menuWidth: 250,
  dialogWidth: 880,
  dialogClickModal: false,
  column: [
    {
      label: '字典编号',
      prop: 'code',
      search: true,
      slot: true,
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入字典编号',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典名称',
      prop: 'dictValue',
      search: true,
      align: 'center',
      rules: [
        {
          required: true,
          message: '请输入字典名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典排序',
      prop: 'sort',
      type: 'number',
      align: 'right',
      width: 100,
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入字典排序',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '封存',
      prop: 'isSealed',
      type: 'switch',
      align: 'center',
      width: 100,
      dicData: [
        {
          label: '否',
          value: 0,
        },
        {
          label: '是',
          value: 1,
        },
      ],
      value: 0,
      slot: true,
      rules: [
        {
          required: true,
          message: '请选择封存',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典备注',
      prop: 'remark',
      hide: true,
    },
  ],
};
    height: 'auto',
    calcHeight: 32,
    tip: false,
    searchShow: true,
    searchMenuSpan: 10,
    border: true,
    index: true,
    selection: true,
    viewBtn: true,
    menuWidth: 250,
    dialogWidth: 880,
    dialogClickModal: false,
    column: [
        {
            label: '字典编号',
            prop: 'code',
            search: true,
            slot: true,
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入字典编号',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典名称',
            prop: 'dictValue',
            search: true,
            align: 'center',
            rules: [
                {
                    required: true,
                    message: '请输入字典名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典排序',
            prop: 'sort',
            type: 'number',
            align: 'right',
            width: 100,
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入字典排序',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '封存',
            prop: 'isSealed',
            type: 'switch',
            align: 'center',
            width: 100,
            dicData: [
                {
                    label: '否',
                    value: 0,
                },
                {
                    label: '是',
                    value: 1,
                },
            ],
            value: 0,
            slot: true,
            rules: [
                {
                    required: true,
                    message: '请选择封存',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典备注',
            prop: 'remark',
            hide: true,
        },
    ],
}
export const optionChild = {
  height: 'auto',
  calcHeight: 95,
  tip: false,
  searchShow: true,
  searchMenuSpan: 10,
  tree: true,
  border: true,
  index: true,
  selection: true,
  viewBtn: true,
  menuWidth: 300,
  dialogWidth: 880,
  dialogClickModal: false,
  column: [
    {
      label: '字典编号',
      prop: 'code',
      addDisabled: true,
      editDisabled: true,
      search: true,
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入字典编号',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典名称',
      prop: 'dictValue',
      search: true,
      align: 'center',
      rules: [
        {
          required: true,
          message: '请输入字典名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '上级字典',
      prop: 'parentId',
      type: 'tree',
      dicData: [],
      hide: true,
      props: {
        label: 'title',
      },
      addDisabled: true,
      editDisabled: true,
      rules: [
        {
          required: false,
          message: '请选择上级字典',
          trigger: 'click',
        },
      ],
    },
    {
      label: '字典键值',
      prop: 'dictKey',
      width: 85,
      rules: [
        {
          required: true,
          message: '请输入字典键值',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典排序',
      prop: 'sort',
      type: 'number',
      align: 'right',
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入字典排序',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '封存',
      prop: 'isSealed',
      type: 'switch',
      align: 'center',
      width: 80,
      dicData: [
        {
          label: '否',
          value: 0,
        },
        {
          label: '是',
          value: 1,
        },
      ],
      value: 0,
      slot: true,
      rules: [
        {
          required: true,
          message: '请选择封存',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '字典备注',
      prop: 'remark',
      hide: true,
    },
  ],
};
    height: 'auto',
    calcHeight: 95,
    tip: false,
    searchShow: true,
    searchMenuSpan: 10,
    tree: true,
    border: true,
    index: true,
    selection: true,
    viewBtn: true,
    menuWidth: 300,
    dialogWidth: 880,
    dialogClickModal: false,
    column: [
        {
            label: '字典编号',
            prop: 'code',
            addDisabled: true,
            editDisabled: true,
            search: true,
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入字典编号',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典名称',
            prop: 'dictValue',
            search: true,
            align: 'center',
            rules: [
                {
                    required: true,
                    message: '请输入字典名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '上级字典',
            prop: 'parentId',
            type: 'tree',
            dicData: [],
            hide: true,
            props: {
                label: 'title',
            },
            addDisabled: true,
            editDisabled: true,
            rules: [
                {
                    required: false,
                    message: '请选择上级字典',
                    trigger: 'click',
                },
            ],
        },
        {
            label: '字典键值',
            prop: 'dictKey',
            width: 85,
            rules: [
                {
                    required: true,
                    message: '请输入字典键值',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典排序',
            prop: 'sort',
            type: 'number',
            align: 'right',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入字典排序',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '封存',
            prop: 'isSealed',
            type: 'switch',
            align: 'center',
            width: 80,
            dicData: [
                {
                    label: '否',
                    value: 0,
                },
                {
                    label: '是',
                    value: 1,
                },
            ],
            value: 0,
            slot: true,
            rules: [
                {
                    required: true,
                    message: '请选择封存',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '字典备注',
            prop: 'remark',
            hide: true,
        },
    ],
}
src/option/tool/code.js
@@ -1,665 +1,665 @@
import { templateDic } from '@/const/tool/model';
import { templateDic } from '@/const/tool/model'
export const codeOption = {
  height: 'auto',
  calcHeight: 32,
  dialogWidth: 900,
  tip: false,
  searchShow: true,
  searchMenuSpan: 6,
  border: true,
  index: true,
  selection: true,
  labelWidth: 120,
  menuWidth: 350,
  viewBtn: true,
  dialogClickModal: false,
  tabs: true,
  column: [
    {
      label: '模块名',
      prop: 'codeName',
      search: true,
      display: false,
    },
    {
      label: '模版类型',
      prop: 'templateType',
      type: 'select',
      dicData: templateDic,
      display: false,
    },
    {
      label: '表名',
      prop: 'tableName',
      search: true,
      display: false,
    },
    {
      label: '服务名',
      prop: 'serviceName',
      search: true,
      display: false,
    },
    {
      label: '包名',
      prop: 'packageName',
      display: false,
    },
  ],
  group: [
    {
      label: '模型配置',
      prop: 'modelSetting',
      icon: 'el-icon-tickets',
      column: [
        {
          label: '上级菜单',
          prop: 'menuId',
          type: 'tree',
          dicData: [],
          span: 24,
          hide: true,
          addDisabled: false,
          props: {
            label: 'title',
          },
          rules: [
            {
              required: true,
              message: '请选择上级菜单',
              trigger: 'click',
            },
          ],
        },
        {
          label: '数据模型',
          prop: 'modelId',
          search: true,
          span: 24,
          type: 'select',
          dicUrl: '/blade-develop/model/select',
          props: {
            label: 'modelName',
            value: 'id',
          },
          rules: [
            {
              required: true,
              message: '请选择数据模型',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '模块名',
          prop: 'codeName',
          search: true,
          rules: [
            {
              required: true,
              message: '请输入模块名',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '表名',
          prop: 'tableName',
          rules: [
            {
              required: true,
              message: '请输入表名',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '表前缀',
          prop: 'tablePrefix',
          hide: true,
          rules: [
            {
              required: true,
              message: '请输入表前缀',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '主键名',
          prop: 'pkName',
          hide: true,
          rules: [
            {
              required: true,
              message: '请输入主键名',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '服务名',
          prop: 'serviceName',
          search: true,
          rules: [
            {
              required: true,
              message: '请输入服务名',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '包名',
          prop: 'packageName',
          overHidden: true,
          rules: [
            {
              required: true,
              message: '请输入包名',
              trigger: 'blur',
            },
          ],
        },
      ],
    },
    {
      label: '模版配置',
      prop: 'templateSetting',
      icon: 'el-icon-copy-document',
      column: [
        {
          label: '模版类型',
          prop: 'templateType',
          type: 'select',
          dicData: templateDic,
          value: 'crud',
          rules: [
            {
              required: true,
              message: '请选择模版类型',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '作者信息',
          prop: 'author',
          value: 'BladeX',
          rules: [
            {
              required: true,
              message: '请输入作者',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '子表模型',
          prop: 'subModelId',
          type: 'select',
          dicUrl: '/blade-develop/model/select',
          props: {
            label: 'modelName',
            value: 'id',
          },
          display: false,
          hide: true,
        },
        {
          label: '子表外键',
          prop: 'subFkId',
          display: false,
          hide: true,
        },
        {
          label: '树主键字段',
          prop: 'treeId',
          type: 'select',
          dicData: [],
          props: {
            label: 'jdbcComment',
            value: 'jdbcName',
          },
          display: false,
          hide: true,
        },
        {
          label: '树父主键字段',
          prop: 'treePid',
          type: 'select',
          dicData: [],
          props: {
            label: 'jdbcComment',
            value: 'jdbcName',
          },
          display: false,
          hide: true,
        },
        {
          label: '树名称字段',
          prop: 'treeName',
          type: 'select',
          dicData: [],
          props: {
            label: 'jdbcComment',
            value: 'jdbcName',
          },
          display: false,
          hide: true,
        },
      ],
    },
    {
      label: '生成配置',
      prop: 'codingSetting',
      icon: 'el-icon-printer',
      column: [
        {
          label: '基础业务',
          labelTip: '配置是否使用BladeX封装的BaseService解锁更多功能',
          prop: 'baseMode',
          type: 'radio',
          dicUrl: '/blade-system/dict/dictionary?code=yes_no',
          props: {
            label: 'dictValue',
            value: 'dictKey',
          },
          value: 2,
          dataType: 'number',
          hide: true,
          rules: [
            {
              required: true,
              message: '请选择基础业务',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '包装器',
          labelTip: '配置是否使用Wrapper包装器来拓展Controller返回列表的字段',
          prop: 'wrapMode',
          type: 'radio',
          dicUrl: '/blade-system/dict/dictionary?code=yes_no',
          props: {
            label: 'dictValue',
            value: 'dictKey',
          },
          value: 2,
          dataType: 'number',
          hide: true,
          rules: [
            {
              required: true,
              message: '请选择包装器',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '远程调用',
          labelTip: '配置是否使用Feign远程调用',
          prop: 'feignMode',
          type: 'radio',
          dicUrl: '/blade-system/dict/dictionary?code=yes_no',
          props: {
            label: 'dictValue',
            value: 'dictKey',
          },
          value: 1,
          dataType: 'number',
          hide: true,
          rules: [
            {
              required: true,
              message: '请选择基础业务',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '代码风格',
          labelTip: '选择不同底层实现的代码模版',
          prop: 'codeStyle',
          type: 'radio',
          dicData: [
            {
              label: 'saber3',
              value: 'saber3',
            },
            {
              label: 'element-plus',
              value: 'element-plus',
            },
          ],
          value: 'saber3',
          hide: true,
          rules: [
            {
              required: true,
              message: '请选择代码风格',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '后端生成路径',
          prop: 'apiPath',
          span: 24,
          hide: true,
          rules: [
            {
              required: true,
              message: '请输入后端生成路径',
              trigger: 'blur',
            },
          ],
        },
        {
          label: '前端生成路径',
          prop: 'webPath',
          span: 24,
          hide: true,
          rules: [
            {
              required: true,
              message: '请输入前端生成路径',
              trigger: 'blur',
            },
          ],
        },
      ],
    },
  ],
};
    height: 'auto',
    calcHeight: 32,
    dialogWidth: 900,
    tip: false,
    searchShow: true,
    searchMenuSpan: 6,
    border: true,
    index: true,
    selection: true,
    labelWidth: 120,
    menuWidth: 350,
    viewBtn: true,
    dialogClickModal: false,
    tabs: true,
    column: [
        {
            label: '模块名',
            prop: 'codeName',
            search: true,
            display: false,
        },
        {
            label: '模版类型',
            prop: 'templateType',
            type: 'select',
            dicData: templateDic,
            display: false,
        },
        {
            label: '表名',
            prop: 'tableName',
            search: true,
            display: false,
        },
        {
            label: '服务名',
            prop: 'serviceName',
            search: true,
            display: false,
        },
        {
            label: '包名',
            prop: 'packageName',
            display: false,
        },
    ],
    group: [
        {
            label: '模型配置',
            prop: 'modelSetting',
            icon: 'el-icon-tickets',
            column: [
                {
                    label: '上级菜单',
                    prop: 'menuId',
                    type: 'tree',
                    dicData: [],
                    span: 24,
                    hide: true,
                    addDisabled: false,
                    props: {
                        label: 'title',
                    },
                    rules: [
                        {
                            required: true,
                            message: '请选择上级菜单',
                            trigger: 'click',
                        },
                    ],
                },
                {
                    label: '数据模型',
                    prop: 'modelId',
                    search: true,
                    span: 24,
                    type: 'select',
                    dicUrl: '/blade-develop/model/select',
                    props: {
                        label: 'modelName',
                        value: 'id',
                    },
                    rules: [
                        {
                            required: true,
                            message: '请选择数据模型',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '模块名',
                    prop: 'codeName',
                    search: true,
                    rules: [
                        {
                            required: true,
                            message: '请输入模块名',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '表名',
                    prop: 'tableName',
                    rules: [
                        {
                            required: true,
                            message: '请输入表名',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '表前缀',
                    prop: 'tablePrefix',
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请输入表前缀',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '主键名',
                    prop: 'pkName',
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请输入主键名',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '服务名',
                    prop: 'serviceName',
                    search: true,
                    rules: [
                        {
                            required: true,
                            message: '请输入服务名',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '包名',
                    prop: 'packageName',
                    overHidden: true,
                    rules: [
                        {
                            required: true,
                            message: '请输入包名',
                            trigger: 'blur',
                        },
                    ],
                },
            ],
        },
        {
            label: '模版配置',
            prop: 'templateSetting',
            icon: 'el-icon-copy-document',
            column: [
                {
                    label: '模版类型',
                    prop: 'templateType',
                    type: 'select',
                    dicData: templateDic,
                    value: 'crud',
                    rules: [
                        {
                            required: true,
                            message: '请选择模版类型',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '作者信息',
                    prop: 'author',
                    value: 'BladeX',
                    rules: [
                        {
                            required: true,
                            message: '请输入作者',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '子表模型',
                    prop: 'subModelId',
                    type: 'select',
                    dicUrl: '/blade-develop/model/select',
                    props: {
                        label: 'modelName',
                        value: 'id',
                    },
                    display: false,
                    hide: true,
                },
                {
                    label: '子表外键',
                    prop: 'subFkId',
                    display: false,
                    hide: true,
                },
                {
                    label: '树主键字段',
                    prop: 'treeId',
                    type: 'select',
                    dicData: [],
                    props: {
                        label: 'jdbcComment',
                        value: 'jdbcName',
                    },
                    display: false,
                    hide: true,
                },
                {
                    label: '树父主键字段',
                    prop: 'treePid',
                    type: 'select',
                    dicData: [],
                    props: {
                        label: 'jdbcComment',
                        value: 'jdbcName',
                    },
                    display: false,
                    hide: true,
                },
                {
                    label: '树名称字段',
                    prop: 'treeName',
                    type: 'select',
                    dicData: [],
                    props: {
                        label: 'jdbcComment',
                        value: 'jdbcName',
                    },
                    display: false,
                    hide: true,
                },
            ],
        },
        {
            label: '生成配置',
            prop: 'codingSetting',
            icon: 'el-icon-printer',
            column: [
                {
                    label: '基础业务',
                    labelTip: '配置是否使用BladeX封装的BaseService解锁更多功能',
                    prop: 'baseMode',
                    type: 'radio',
                    dicUrl: '/blade-system/dict/dictionary?code=yes_no',
                    props: {
                        label: 'dictValue',
                        value: 'dictKey',
                    },
                    value: 2,
                    dataType: 'number',
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请选择基础业务',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '包装器',
                    labelTip: '配置是否使用Wrapper包装器来拓展Controller返回列表的字段',
                    prop: 'wrapMode',
                    type: 'radio',
                    dicUrl: '/blade-system/dict/dictionary?code=yes_no',
                    props: {
                        label: 'dictValue',
                        value: 'dictKey',
                    },
                    value: 2,
                    dataType: 'number',
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请选择包装器',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '远程调用',
                    labelTip: '配置是否使用Feign远程调用',
                    prop: 'feignMode',
                    type: 'radio',
                    dicUrl: '/blade-system/dict/dictionary?code=yes_no',
                    props: {
                        label: 'dictValue',
                        value: 'dictKey',
                    },
                    value: 1,
                    dataType: 'number',
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请选择基础业务',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '代码风格',
                    labelTip: '选择不同底层实现的代码模版',
                    prop: 'codeStyle',
                    type: 'radio',
                    dicData: [
                        {
                            label: 'saber3',
                            value: 'saber3',
                        },
                        {
                            label: 'element-plus',
                            value: 'element-plus',
                        },
                    ],
                    value: 'saber3',
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请选择代码风格',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '后端生成路径',
                    prop: 'apiPath',
                    span: 24,
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请输入后端生成路径',
                            trigger: 'blur',
                        },
                    ],
                },
                {
                    label: '前端生成路径',
                    prop: 'webPath',
                    span: 24,
                    hide: true,
                    rules: [
                        {
                            required: true,
                            message: '请输入前端生成路径',
                            trigger: 'blur',
                        },
                    ],
                },
            ],
        },
    ],
}
export const genOption = {
  labelWidth: 120,
  column: [
    {
      label: '上级菜单',
      prop: 'menuId',
      type: 'tree',
      dicData: [],
      span: 24,
      hide: true,
      addDisabled: false,
      props: {
        label: 'title',
      },
      rules: [
        {
          required: true,
          message: '请选择上级菜单',
          trigger: 'click',
        },
      ],
    },
    {
      label: '数据源',
      prop: 'datasourceId',
      search: true,
      span: 24,
      type: 'select',
      dicUrl: '/blade-develop/datasource/select',
      props: {
        label: 'name',
        value: 'id',
      },
      rules: [
        {
          required: true,
          message: '请选择数据源',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '物理表名',
      prop: 'modelTable',
      type: 'tree',
      slot: true,
      filterable: true,
      span: 24,
      display: true,
      dicData: [],
      props: {
        label: 'comment',
        value: 'name',
      },
      rules: [
        {
          required: true,
          message: '请输入数据库表名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '表单设计',
      prop: 'modelForm',
      type: 'select',
      props: {
        label: 'name',
        value: 'id',
      },
      dicData: [],
      filterable: true,
      display: false,
      span: 24,
    },
    {
      label: '模型类名',
      prop: 'modelClass',
      display: false,
      disabled: true,
      rules: [
        {
          required: true,
          message: '请输入模型类名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '模型编号',
      prop: 'modelCode',
      display: false,
      rules: [
        {
          required: true,
          message: '请输入模型编号',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '模块名',
      prop: 'codeName',
      display: false,
      rules: [
        {
          required: true,
          message: '请输入模块名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '表名',
      prop: 'tableName',
      display: false,
      rules: [
        {
          required: true,
          message: '请输入表名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '表前缀',
      prop: 'tablePrefix',
      display: false,
      rules: [
        {
          required: true,
          message: '请输入表前缀',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '主键名',
      prop: 'pkName',
      display: false,
      rules: [
        {
          required: true,
          message: '请输入主键名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '服务名',
      prop: 'serviceName',
      search: true,
      rules: [
        {
          required: true,
          message: '请输入服务名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '包名',
      prop: 'packageName',
      overHidden: true,
      rules: [
        {
          required: true,
          message: '请输入包名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '基础业务',
      labelTip: '配置是否使用BladeX封装的BaseService解锁更多功能',
      prop: 'baseMode',
      type: 'radio',
      dicUrl: '/blade-system/dict/dictionary?code=yes_no',
      props: {
        label: 'dictValue',
        value: 'dictKey',
      },
      value: 2,
      dataType: 'number',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择基础业务',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '包装器',
      labelTip: '配置是否使用Wrapper包装器来拓展Controller返回列表的字段',
      prop: 'wrapMode',
      type: 'radio',
      dicUrl: '/blade-system/dict/dictionary?code=yes_no',
      props: {
        label: 'dictValue',
        value: 'dictKey',
      },
      value: 2,
      dataType: 'number',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择包装器',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '远程调用',
      labelTip: '配置是否使用Feign远程调用',
      prop: 'feignMode',
      type: 'radio',
      dicUrl: '/blade-system/dict/dictionary?code=yes_no',
      props: {
        label: 'dictValue',
        value: 'dictKey',
      },
      value: 1,
      dataType: 'number',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择基础业务',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '代码风格',
      labelTip: '选择不同底层实现的代码模版',
      prop: 'codeStyle',
      type: 'radio',
      dicData: [
        {
          label: 'saber3',
          value: 'saber3',
        },
        {
          label: 'element-plus',
          value: 'element-plus',
        },
      ],
      value: 'saber3',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择代码风格',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '后端生成路径',
      prop: 'apiPath',
      span: 24,
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入后端生成路径',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '前端生成路径',
      prop: 'webPath',
      span: 24,
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入前端生成路径',
          trigger: 'blur',
        },
      ],
    },
  ],
};
    labelWidth: 120,
    column: [
        {
            label: '上级菜单',
            prop: 'menuId',
            type: 'tree',
            dicData: [],
            span: 24,
            hide: true,
            addDisabled: false,
            props: {
                label: 'title',
            },
            rules: [
                {
                    required: true,
                    message: '请选择上级菜单',
                    trigger: 'click',
                },
            ],
        },
        {
            label: '数据源',
            prop: 'datasourceId',
            search: true,
            span: 24,
            type: 'select',
            dicUrl: '/blade-develop/datasource/select',
            props: {
                label: 'name',
                value: 'id',
            },
            rules: [
                {
                    required: true,
                    message: '请选择数据源',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '物理表名',
            prop: 'modelTable',
            type: 'tree',
            slot: true,
            filterable: true,
            span: 24,
            display: true,
            dicData: [],
            props: {
                label: 'comment',
                value: 'name',
            },
            rules: [
                {
                    required: true,
                    message: '请输入数据库表名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '表单设计',
            prop: 'modelForm',
            type: 'select',
            props: {
                label: 'name',
                value: 'id',
            },
            dicData: [],
            filterable: true,
            display: false,
            span: 24,
        },
        {
            label: '模型类名',
            prop: 'modelClass',
            display: false,
            disabled: true,
            rules: [
                {
                    required: true,
                    message: '请输入模型类名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '模型编号',
            prop: 'modelCode',
            display: false,
            rules: [
                {
                    required: true,
                    message: '请输入模型编号',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '模块名',
            prop: 'codeName',
            display: false,
            rules: [
                {
                    required: true,
                    message: '请输入模块名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '表名',
            prop: 'tableName',
            display: false,
            rules: [
                {
                    required: true,
                    message: '请输入表名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '表前缀',
            prop: 'tablePrefix',
            display: false,
            rules: [
                {
                    required: true,
                    message: '请输入表前缀',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '主键名',
            prop: 'pkName',
            display: false,
            rules: [
                {
                    required: true,
                    message: '请输入主键名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '服务名',
            prop: 'serviceName',
            search: true,
            rules: [
                {
                    required: true,
                    message: '请输入服务名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '包名',
            prop: 'packageName',
            overHidden: true,
            rules: [
                {
                    required: true,
                    message: '请输入包名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '基础业务',
            labelTip: '配置是否使用BladeX封装的BaseService解锁更多功能',
            prop: 'baseMode',
            type: 'radio',
            dicUrl: '/blade-system/dict/dictionary?code=yes_no',
            props: {
                label: 'dictValue',
                value: 'dictKey',
            },
            value: 2,
            dataType: 'number',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择基础业务',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '包装器',
            labelTip: '配置是否使用Wrapper包装器来拓展Controller返回列表的字段',
            prop: 'wrapMode',
            type: 'radio',
            dicUrl: '/blade-system/dict/dictionary?code=yes_no',
            props: {
                label: 'dictValue',
                value: 'dictKey',
            },
            value: 2,
            dataType: 'number',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择包装器',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '远程调用',
            labelTip: '配置是否使用Feign远程调用',
            prop: 'feignMode',
            type: 'radio',
            dicUrl: '/blade-system/dict/dictionary?code=yes_no',
            props: {
                label: 'dictValue',
                value: 'dictKey',
            },
            value: 1,
            dataType: 'number',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择基础业务',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '代码风格',
            labelTip: '选择不同底层实现的代码模版',
            prop: 'codeStyle',
            type: 'radio',
            dicData: [
                {
                    label: 'saber3',
                    value: 'saber3',
                },
                {
                    label: 'element-plus',
                    value: 'element-plus',
                },
            ],
            value: 'saber3',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择代码风格',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '后端生成路径',
            prop: 'apiPath',
            span: 24,
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入后端生成路径',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '前端生成路径',
            prop: 'webPath',
            span: 24,
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入前端生成路径',
                    trigger: 'blur',
                },
            ],
        },
    ],
}
src/option/tool/codesetting.js
@@ -1,229 +1,229 @@
export default {
  height: 'auto',
  calcHeight: 50,
  tip: false,
  searchShow: true,
  searchMenuSpan: 6,
  border: true,
  index: true,
  viewBtn: true,
  grid: true,
  selection: true,
  labelWidth: 120,
  searchLabelWidth: 100,
  menuWidth: 320,
  dialogClickModal: false,
  column: [
    {
      label: '配置名称',
      labelTip: '用于定义本配置的代表名称,实际不参与代码生成',
      prop: 'name',
      gridRow: true,
      search: true,
      rules: [
        {
          required: true,
          message: '请输入配置名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '配置编号',
      labelTip: '用于定义本配置的代表编号,实际不参与代码生成',
      prop: 'code',
      gridRow: true,
      search: true,
      rules: [
        {
          required: true,
          message: '请输入配置编号',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '上级菜单',
      prop: 'menuId',
      type: 'tree',
      dicData: [],
      span: 24,
      hide: true,
      addDisabled: false,
      props: {
        label: 'title',
      },
      rules: [
        {
          required: true,
          message: '请选择上级菜单',
          trigger: 'click',
        },
      ],
    },
    {
      label: '是否启用',
      prop: 'status',
      span: 24,
      width: 85,
      align: 'center',
      slot: true,
      gridRow: true,
      addDisplay: false,
      editDisplay: false,
      viewDisplay: false,
    },
    {
      label: '配置参数',
      prop: 'settings',
      display: false,
      gridRow: true,
      overHidden: true,
      rules: [
        {
          required: true,
          message: '请输入服务名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '服务名',
      prop: 'serviceName',
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入服务名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '包名',
      prop: 'packageName',
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入包名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '基础业务',
      labelTip: '配置是否使用BladeX封装的BaseService解锁更多功能',
      prop: 'baseMode',
      type: 'radio',
      dicUrl: '/blade-system/dict/dictionary?code=yes_no',
      props: {
        label: 'dictValue',
        value: 'dictKey',
      },
      value: 2,
      dataType: 'number',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择基础业务',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '包装器',
      labelTip: '配置是否使用Wrapper包装器来拓展Controller返回列表的字段',
      prop: 'wrapMode',
      type: 'radio',
      dicUrl: '/blade-system/dict/dictionary?code=yes_no',
      props: {
        label: 'dictValue',
        value: 'dictKey',
      },
      value: 2,
      dataType: 'number',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择包装器',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '远程调用',
      labelTip: '配置是否使用Feign远程调用',
      prop: 'feignMode',
      type: 'radio',
      dicUrl: '/blade-system/dict/dictionary?code=yes_no',
      props: {
        label: 'dictValue',
        value: 'dictKey',
      },
      value: 1,
      dataType: 'number',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择基础业务',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '代码风格',
      labelTip: '选择不同底层实现的代码模版',
      prop: 'codeStyle',
      type: 'radio',
      dicData: [
        {
          label: 'saber3',
          value: 'saber3',
        },
        {
          label: 'element-plus',
          value: 'element-plus',
        },
      ],
      value: 'saber3',
      hide: true,
      rules: [
        {
          required: true,
          message: '请选择代码风格',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '后端生成路径',
      prop: 'apiPath',
      span: 24,
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入后端生成路径',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '前端生成路径',
      prop: 'webPath',
      span: 24,
      hide: true,
      rules: [
        {
          required: true,
          message: '请输入前端生成路径',
          trigger: 'blur',
        },
      ],
    },
  ],
};
    height: 'auto',
    calcHeight: 50,
    tip: false,
    searchShow: true,
    searchMenuSpan: 6,
    border: true,
    index: true,
    viewBtn: true,
    grid: true,
    selection: true,
    labelWidth: 120,
    searchLabelWidth: 100,
    menuWidth: 320,
    dialogClickModal: false,
    column: [
        {
            label: '配置名称',
            labelTip: '用于定义本配置的代表名称,实际不参与代码生成',
            prop: 'name',
            gridRow: true,
            search: true,
            rules: [
                {
                    required: true,
                    message: '请输入配置名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '配置编号',
            labelTip: '用于定义本配置的代表编号,实际不参与代码生成',
            prop: 'code',
            gridRow: true,
            search: true,
            rules: [
                {
                    required: true,
                    message: '请输入配置编号',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '上级菜单',
            prop: 'menuId',
            type: 'tree',
            dicData: [],
            span: 24,
            hide: true,
            addDisabled: false,
            props: {
                label: 'title',
            },
            rules: [
                {
                    required: true,
                    message: '请选择上级菜单',
                    trigger: 'click',
                },
            ],
        },
        {
            label: '是否启用',
            prop: 'status',
            span: 24,
            width: 85,
            align: 'center',
            slot: true,
            gridRow: true,
            addDisplay: false,
            editDisplay: false,
            viewDisplay: false,
        },
        {
            label: '配置参数',
            prop: 'settings',
            display: false,
            gridRow: true,
            overHidden: true,
            rules: [
                {
                    required: true,
                    message: '请输入服务名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '服务名',
            prop: 'serviceName',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入服务名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '包名',
            prop: 'packageName',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入包名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '基础业务',
            labelTip: '配置是否使用BladeX封装的BaseService解锁更多功能',
            prop: 'baseMode',
            type: 'radio',
            dicUrl: '/blade-system/dict/dictionary?code=yes_no',
            props: {
                label: 'dictValue',
                value: 'dictKey',
            },
            value: 2,
            dataType: 'number',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择基础业务',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '包装器',
            labelTip: '配置是否使用Wrapper包装器来拓展Controller返回列表的字段',
            prop: 'wrapMode',
            type: 'radio',
            dicUrl: '/blade-system/dict/dictionary?code=yes_no',
            props: {
                label: 'dictValue',
                value: 'dictKey',
            },
            value: 2,
            dataType: 'number',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择包装器',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '远程调用',
            labelTip: '配置是否使用Feign远程调用',
            prop: 'feignMode',
            type: 'radio',
            dicUrl: '/blade-system/dict/dictionary?code=yes_no',
            props: {
                label: 'dictValue',
                value: 'dictKey',
            },
            value: 1,
            dataType: 'number',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择基础业务',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '代码风格',
            labelTip: '选择不同底层实现的代码模版',
            prop: 'codeStyle',
            type: 'radio',
            dicData: [
                {
                    label: 'saber3',
                    value: 'saber3',
                },
                {
                    label: 'element-plus',
                    value: 'element-plus',
                },
            ],
            value: 'saber3',
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请选择代码风格',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '后端生成路径',
            prop: 'apiPath',
            span: 24,
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入后端生成路径',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '前端生成路径',
            prop: 'webPath',
            span: 24,
            hide: true,
            rules: [
                {
                    required: true,
                    message: '请输入前端生成路径',
                    trigger: 'blur',
                },
            ],
        },
    ],
}
src/option/tool/formsetting.js
@@ -1,95 +1,95 @@
export default {
  height: 'auto',
  calcHeight: 50,
  tip: false,
  searchShow: true,
  searchMenuSpan: 6,
  border: true,
  index: true,
  viewBtn: true,
  grid: true,
  selection: true,
  labelWidth: 120,
  searchLabelWidth: 100,
  menuWidth: 320,
  dialogWidth: 500,
  dialogClickModal: false,
  column: [
    {
      label: '数据源',
      labelTip: '数据源管理配置的数据源列表',
      prop: 'datasourceId',
      hide: true,
      editDisplay: false,
      viewDisplay: false,
      span: 24,
      type: 'select',
      dicUrl: '/blade-develop/datasource/select',
      props: {
        label: 'name',
        value: 'id',
      },
      rules: [
        {
          required: true,
          message: '请选择数据源',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '物理表名',
      labelTip: '从数据源列表选择的物理表名',
      filterable: true,
      prop: 'modelTable',
      type: 'tree',
      span: 24,
      hide: true,
      editDisplay: false,
      viewDisplay: false,
      dicData: [],
      props: {
        label: 'comment',
        value: 'name',
      },
      rules: [
        {
          required: true,
          message: '请输入数据库表名',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '表单名称',
      labelTip: '用于定义本配置的代表名称,默认为数据库表说明',
      prop: 'name',
      gridRow: true,
      search: true,
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入表单名称',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '关联表名',
      labelTip: '用于定义本配置的代表编号,默认为数据库表名,在代码快速生成时会关联匹配',
      prop: 'code',
      gridRow: true,
      search: true,
      disabled: true,
      span: 24,
      rules: [
        {
          required: true,
          message: '请输入表单编号',
          trigger: 'blur',
        },
      ],
    },
  ],
};
    height: 'auto',
    calcHeight: 50,
    tip: false,
    searchShow: true,
    searchMenuSpan: 6,
    border: true,
    index: true,
    viewBtn: true,
    grid: true,
    selection: true,
    labelWidth: 120,
    searchLabelWidth: 100,
    menuWidth: 320,
    dialogWidth: 500,
    dialogClickModal: false,
    column: [
        {
            label: '数据源',
            labelTip: '数据源管理配置的数据源列表',
            prop: 'datasourceId',
            hide: true,
            editDisplay: false,
            viewDisplay: false,
            span: 24,
            type: 'select',
            dicUrl: '/blade-develop/datasource/select',
            props: {
                label: 'name',
                value: 'id',
            },
            rules: [
                {
                    required: true,
                    message: '请选择数据源',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '物理表名',
            labelTip: '从数据源列表选择的物理表名',
            filterable: true,
            prop: 'modelTable',
            type: 'tree',
            span: 24,
            hide: true,
            editDisplay: false,
            viewDisplay: false,
            dicData: [],
            props: {
                label: 'comment',
                value: 'name',
            },
            rules: [
                {
                    required: true,
                    message: '请输入数据库表名',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '表单名称',
            labelTip: '用于定义本配置的代表名称,默认为数据库表说明',
            prop: 'name',
            gridRow: true,
            search: true,
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入表单名称',
                    trigger: 'blur',
                },
            ],
        },
        {
            label: '关联表名',
            labelTip: '用于定义本配置的代表编号,默认为数据库表名,在代码快速生成时会关联匹配',
            prop: 'code',
            gridRow: true,
            search: true,
            disabled: true,
            span: 24,
            rules: [
                {
                    required: true,
                    message: '请输入表单编号',
                    trigger: 'blur',
                },
            ],
        },
    ],
}
src/option/user/info.js
@@ -1,84 +1,84 @@
export default {
  tabs: true,
  tabsActive: 1,
  group: [
    {
      label: '个人信息',
      prop: 'info',
      column: [
        {
          label: '头像',
          type: 'upload',
          listType: 'picture-img',
          propsHttp: {
            res: 'data',
            url: 'link',
          },
          action: '/blade-resource/oss/endpoint/put-file',
          tip: '只能上传jpg/png用户头像,且不超过500kb',
          span: 12,
          row: true,
          prop: 'avatar',
        },
        {
          prefixIcon: 'el-icon-bell',
          label: '姓名',
          span: 12,
          row: true,
          prop: 'realName',
        },
        {
          prefixIcon: 'el-icon-user',
          label: '用户名',
          span: 12,
          row: true,
          prop: 'name',
        },
        {
          prefixIcon: 'el-icon-iphone',
          label: '手机号',
          span: 12,
          row: true,
          prop: 'phone',
        },
        {
          prefixIcon: 'el-icon-message',
          label: '邮箱',
          prop: 'email',
          span: 12,
          row: true,
        },
      ],
    },
    {
      label: '修改密码',
      prop: 'password',
      column: [
        {
          prefixIcon: 'el-icon-lock',
          label: '原密码',
          span: 12,
          row: true,
          type: 'password',
          prop: 'oldPassword',
        },
        {
          prefixIcon: 'el-icon-lock',
          label: '新密码',
          span: 12,
          row: true,
          type: 'password',
          prop: 'newPassword',
        },
        {
          prefixIcon: 'el-icon-lock',
          label: '确认密码',
          span: 12,
          row: true,
          type: 'password',
          prop: 'newPassword1',
        },
      ],
    },
  ],
};
    tabs: true,
    tabsActive: 1,
    group: [
        {
            label: '个人信息',
            prop: 'info',
            column: [
                {
                    label: '头像',
                    type: 'upload',
                    listType: 'picture-img',
                    propsHttp: {
                        res: 'data',
                        url: 'link',
                    },
                    action: '/blade-resource/oss/endpoint/put-file',
                    tip: '只能上传jpg/png用户头像,且不超过500kb',
                    span: 12,
                    row: true,
                    prop: 'avatar',
                },
                {
                    prefixIcon: 'el-icon-bell',
                    label: '姓名',
                    span: 12,
                    row: true,
                    prop: 'realName',
                },
                {
                    prefixIcon: 'el-icon-user',
                    label: '用户名',
                    span: 12,
                    row: true,
                    prop: 'name',
                },
                {
                    prefixIcon: 'el-icon-iphone',
                    label: '手机号',
                    span: 12,
                    row: true,
                    prop: 'phone',
                },
                {
                    prefixIcon: 'el-icon-message',
                    label: '邮箱',
                    prop: 'email',
                    span: 12,
                    row: true,
                },
            ],
        },
        {
            label: '修改密码',
            prop: 'password',
            column: [
                {
                    prefixIcon: 'el-icon-lock',
                    label: '原密码',
                    span: 12,
                    row: true,
                    type: 'password',
                    prop: 'oldPassword',
                },
                {
                    prefixIcon: 'el-icon-lock',
                    label: '新密码',
                    span: 12,
                    row: true,
                    type: 'password',
                    prop: 'newPassword',
                },
                {
                    prefixIcon: 'el-icon-lock',
                    label: '确认密码',
                    span: 12,
                    row: true,
                    type: 'password',
                    prop: 'newPassword1',
                },
            ],
        },
    ],
}
src/permission.js
@@ -1,58 +1,58 @@
import router from './router/';
import store from './store';
import { getToken } from '@/utils/auth';
import NProgress from 'nprogress'; // progress bar
import 'nprogress/nprogress.css'; // progress bar style
NProgress.configure({ showSpinner: false });
const lockPage = '/lock'; //锁屏页
import router from './router/'
import store from './store'
import { getToken } from '@/utils/auth'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
NProgress.configure({ showSpinner: false })
const lockPage = '/lock' //锁屏页
router.beforeEach((to, from, next) => {
  const meta = to.meta || {};
  const isMenu = meta.menu === undefined ? to.query.menu : meta.menu;
  store.commit('SET_IS_MENU', isMenu === undefined);
  if (getToken()) {
    if (store.getters.isLock && to.path !== lockPage) {
      //如果系统激活锁屏,全部跳转到锁屏页
      next({ path: lockPage });
    } else if (to.path === '/login') {
      //如果登录成功访问登录页跳转到主页
      next({ path: '/' });
    } else {
      if (store.getters.token.length === 0) {
        store.dispatch('FedLogOut').then(() => {
          next({ path: '/login' });
        });
      } else {
        const meta = to.meta || {};
        const query = to.query || {};
        if (meta.target) {
          window.open(query.url.replace(/#/g, '&'));
          return;
        } else if (meta.isTab !== false) {
          store.commit('ADD_TAG', {
            name: query.name || to.name,
            path: to.path,
            fullPath: to.path,
            params: to.params,
            query: to.query,
            meta: meta,
          });
        }
        next();
      }
    }
  } else {
    //判断是否需要认证,没有登录访问去登录页
    if (meta.isAuth === false) {
      next();
    } else {
      next('/login');
    }
  }
});
    const meta = to.meta || {}
    const isMenu = meta.menu === undefined ? to.query.menu : meta.menu
    store.commit('SET_IS_MENU', isMenu === undefined)
    if (getToken()) {
        if (store.getters.isLock && to.path !== lockPage) {
            //如果系统激活锁屏,全部跳转到锁屏页
            next({ path: lockPage })
        } else if (to.path === '/login') {
            //如果登录成功访问登录页跳转到主页
            next({ path: '/' })
        } else {
            if (store.getters.token.length === 0) {
                store.dispatch('FedLogOut').then(() => {
                    next({ path: '/login' })
                })
            } else {
                const meta = to.meta || {}
                const query = to.query || {}
                if (meta.target) {
                    window.open(query.url.replace(/#/g, '&'))
                    return
                } else if (meta.isTab !== false) {
                    store.commit('ADD_TAG', {
                        name: query.name || to.name,
                        path: to.path,
                        fullPath: to.path,
                        params: to.params,
                        query: to.query,
                        meta: meta,
                    })
                }
                next()
            }
        }
    } else {
        //判断是否需要认证,没有登录访问去登录页
        if (meta.isAuth === false) {
            next()
        } else {
            next('/login')
        }
    }
})
router.afterEach(to => {
  NProgress.done();
  let title = router.$avueRouter.generateTitle(to, { label: 'name' });
  router.$avueRouter.setTitle(title);
  store.commit('SET_IS_SEARCH', false);
});
    NProgress.done()
    let title = router.$avueRouter.generateTitle(to, { label: 'name' })
    router.$avueRouter.setTitle(title)
    store.commit('SET_IS_SEARCH', false)
})
src/router/avue-router.js
@@ -1,171 +1,171 @@
import website from '@/config/website';
import website from '@/config/website'
const modules = import.meta.glob('../**/**/*.vue');
const modules = import.meta.glob('../**/**/*.vue')
function isURL(s) {
  return /^http[s]?:\/\/.*/.test(s);
    return /^http[s]?:\/\/.*/.test(s)
}
let RouterPlugin = function () {
  this.$router = null;
  this.$store = null;
};
    this.$router = null
    this.$store = null
}
RouterPlugin.install = function (option = {}) {
  this.$router = option.router;
  this.$store = option.store;
  let i18n = option.i18n.global;
  this.$router.$avueRouter = {
    safe: this,
    // 设置标题
    setTitle: title => {
      const defaultTitle = i18n.t('title');
      title = title ? `${title} | ${defaultTitle}` : defaultTitle;
      document.title = title;
    },
    closeTag: value => {
      let tag = value || this.$store.getters.tag;
      if (typeof value === 'string') {
        tag = this.$store.getters.tagList.find(ele => ele.fullPath === value);
      }
      this.$store.commit('DEL_TAG', tag);
    },
    generateTitle: (item, props = {}) => {
      let query = item[props.query || 'query'] || {};
      let title = query.name || item[props.label || 'label'];
      let meta = item[props.meta || 'meta'] || {};
      let key = meta.i18n;
      if (key) {
        const hasKey = i18n.te('route.' + key);
        if (hasKey) return i18n.t('route.' + key);
      }
      return title ? title.split(',')[0] : title;
    },
    //动态路由
    formatRoutes: function (aMenu = [], first) {
      const aRouter = [];
      const propsDefault = website.menu;
    this.$router = option.router
    this.$store = option.store
    let i18n = option.i18n.global
    this.$router.$avueRouter = {
        safe: this,
        // 设置标题
        setTitle: title => {
            const defaultTitle = i18n.t('title')
            title = title ? `${title} | ${defaultTitle}` : defaultTitle
            document.title = title
        },
        closeTag: value => {
            let tag = value || this.$store.getters.tag
            if (typeof value === 'string') {
                tag = this.$store.getters.tagList.find(ele => ele.fullPath === value)
            }
            this.$store.commit('DEL_TAG', tag)
        },
        generateTitle: (item, props = {}) => {
            let query = item[props.query || 'query'] || {}
            let title = query.name || item[props.label || 'label']
            let meta = item[props.meta || 'meta'] || {}
            let key = meta.i18n
            if (key) {
                const hasKey = i18n.te('route.' + key)
                if (hasKey) return i18n.t('route.' + key)
            }
            return title ? title.split(',')[0] : title
        },
        //动态路由
        formatRoutes: function (aMenu = [], first) {
            const aRouter = []
            const propsDefault = website.menu
      if (aMenu && aMenu.length === 0) return;
      for (let i = 0; i < aMenu.length; i++) {
        const oMenu = aMenu[i];
        let path = oMenu[propsDefault.path],
          isComponent = true,
          component = oMenu.component,
          name = oMenu[propsDefault.label] + ',' + oMenu.id,
          icon = oMenu[propsDefault.icon],
          children = oMenu[propsDefault.children],
          query = oMenu[propsDefault.query],
          meta = oMenu[propsDefault.meta];
        if (option.keepAlive) {
          meta.keepAlive = option.keepAlive;
        }
        const isChild = !!(children && children.length !== 0);
        const oRouter = {
          path: path,
          component: (() => {
            // 判断是否为首路由
            if (first) {
              return modules[
                option.store.getters.isMacOs || !website.setting.menu
                  ? '../page/index/layout.vue'
                  : '../page/index/index.vue'
              ];
              // 判断是否为多层路由
            } else if (isChild && !first) {
              return modules['../page/index/layout.vue'];
              // 判断是否为最终的页面视图
            } else {
              let result = modules[`../${component}.vue`];
              if (result) result().then(mod => (mod.default.name = path));
              else {
                isComponent = false;
              }
              return result;
            }
          })(),
          name,
          icon,
          meta,
          query,
          redirect: (() => {
            if (!isChild && first) return `${path}`;
            else return '';
          })(),
          // 处理是否为一级路由
          children: !isChild
            ? (() => {
                if (first) {
                  oMenu[propsDefault.path] = `${path}`;
                  let result = modules[`../${component}.vue`];
                  if (result) result().then(mod => (mod.default.name = path));
                  else {
                    isComponent = false;
                  }
                  return [
                    {
                      component: result,
                      icon: icon,
                      name: name,
                      meta: meta,
                      query: query,
                      path: '',
                    },
                  ];
                }
                return [];
              })()
            : (() => {
                return this.formatRoutes(children, false);
              })(),
        };
        if (!isURL(path) && isComponent) aRouter.push(oRouter);
      }
      if (first) {
        aRouter.forEach(ele => this.safe.$router.addRoute(ele));
      } else {
        return aRouter;
      }
    },
  };
};
            if (aMenu && aMenu.length === 0) return
            for (let i = 0; i < aMenu.length; i++) {
                const oMenu = aMenu[i]
                let path = oMenu[propsDefault.path],
                    isComponent = true,
                    component = oMenu.component,
                    name = oMenu[propsDefault.label] + ',' + oMenu.id,
                    icon = oMenu[propsDefault.icon],
                    children = oMenu[propsDefault.children],
                    query = oMenu[propsDefault.query],
                    meta = oMenu[propsDefault.meta]
                if (option.keepAlive) {
                    meta.keepAlive = option.keepAlive
                }
                const isChild = !!(children && children.length !== 0)
                const oRouter = {
                    path: path,
                    component: (() => {
                        // 判断是否为首路由
                        if (first) {
                            return modules[
                                option.store.getters.isMacOs || !website.setting.menu
                                    ? '../page/index/layout.vue'
                                    : '../page/index/index.vue'
                            ]
                            // 判断是否为多层路由
                        } else if (isChild && !first) {
                            return modules['../page/index/layout.vue']
                            // 判断是否为最终的页面视图
                        } else {
                            let result = modules[`../${component}.vue`]
                            if (result) result().then(mod => (mod.default.name = path))
                            else {
                                isComponent = false
                            }
                            return result
                        }
                    })(),
                    name,
                    icon,
                    meta,
                    query,
                    redirect: (() => {
                        if (!isChild && first) return `${path}`
                        else return ''
                    })(),
                    // 处理是否为一级路由
                    children: !isChild
                        ? (() => {
                                if (first) {
                                    oMenu[propsDefault.path] = `${path}`
                                    let result = modules[`../${component}.vue`]
                                    if (result) result().then(mod => (mod.default.name = path))
                                    else {
                                        isComponent = false
                                    }
                                    return [
                                        {
                                            component: result,
                                            icon: icon,
                                            name: name,
                                            meta: meta,
                                            query: query,
                                            path: '',
                                        },
                                    ]
                                }
                                return []
                          })()
                        : (() => {
                                return this.formatRoutes(children, false)
                          })(),
                }
                if (!isURL(path) && isComponent) aRouter.push(oRouter)
            }
            if (first) {
                aRouter.forEach(ele => this.safe.$router.addRoute(ele))
            } else {
                return aRouter
            }
        },
    }
}
export const formatPath = (ele, first) => {
  const propsDefault = website.menu;
  const icon = ele[propsDefault.icon];
  ele[propsDefault.icon] = !icon ? propsDefault.iconDefault : icon;
  ele.meta = {
    keepAlive: ele.isOpen === 2,
  };
  const iframeComponent = 'components/iframe/main';
  const iframeSrc = href => {
    return href.replace(/&/g, '#');
  };
  const isChild = !!(ele[propsDefault.children] && ele[propsDefault.children].length !== 0);
  if (!isChild && first) {
    ele.component = 'views' + ele[propsDefault.path];
    if (isURL(ele[propsDefault.href])) {
      let href = ele[propsDefault.href];
      ele.component = iframeComponent;
      ele[propsDefault.query] = {
        url: iframeSrc(href),
      };
    }
  } else {
    ele[propsDefault.children] &&
      ele[propsDefault.children].forEach(child => {
        child.component = 'views' + child[propsDefault.path];
        child.meta = {
          keepAlive: child.isOpen === 2,
        };
        if (isURL(child[propsDefault.href])) {
          let href = child[propsDefault.href];
          child[propsDefault.path] = ele[propsDefault.path] + '/' + child.code;
          child.component = iframeComponent;
          child[propsDefault.query] = {
            url: iframeSrc(href),
          };
        }
        formatPath(child);
      });
  }
};
export default RouterPlugin;
    const propsDefault = website.menu
    const icon = ele[propsDefault.icon]
    ele[propsDefault.icon] = !icon ? propsDefault.iconDefault : icon
    ele.meta = {
        keepAlive: ele.isOpen === 2,
    }
    const iframeComponent = 'components/iframe/main'
    const iframeSrc = href => {
        return href.replace(/&/g, '#')
    }
    const isChild = !!(ele[propsDefault.children] && ele[propsDefault.children].length !== 0)
    if (!isChild && first) {
        ele.component = 'views' + ele[propsDefault.path]
        if (isURL(ele[propsDefault.href])) {
            let href = ele[propsDefault.href]
            ele.component = iframeComponent
            ele[propsDefault.query] = {
                url: iframeSrc(href),
            }
        }
    } else {
        ele[propsDefault.children] &&
            ele[propsDefault.children].forEach(child => {
                child.component = 'views' + child[propsDefault.path]
                child.meta = {
                    keepAlive: child.isOpen === 2,
                }
                if (isURL(child[propsDefault.href])) {
                    let href = child[propsDefault.href]
                    child[propsDefault.path] = ele[propsDefault.path] + '/' + child.code
                    child.component = iframeComponent
                    child[propsDefault.query] = {
                        url: iframeSrc(href),
                    }
                }
                formatPath(child)
            })
    }
}
export default RouterPlugin
src/router/index.js
@@ -1,34 +1,34 @@
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router';
import PageRouter from './page/';
import ViewsRouter from './views/';
import AvueRouter from './avue-router';
import i18n from '@/lang';
import Store from '@/store/';
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import PageRouter from './page/'
import ViewsRouter from './views/'
import AvueRouter from './avue-router'
import i18n from '@/lang'
import Store from '@/store/'
//创建路由
const Router = createRouter({
  base: import.meta.env.VITE_APP_BASE,
  history: createWebHashHistory(import.meta.env.VITE_APP_BASE),
  routes: [...PageRouter, ...ViewsRouter],
});
    base: import.meta.env.VITE_APP_BASE,
    history: createWebHashHistory(import.meta.env.VITE_APP_BASE),
    routes: [...PageRouter, ...ViewsRouter],
})
AvueRouter.install({
  store: Store,
  router: Router,
  i18n: i18n,
});
    store: Store,
    router: Router,
    i18n: i18n,
})
Router.$avueRouter.formatRoutes(Store.getters.menuAll, true);
Router.$avueRouter.formatRoutes(Store.getters.menuAll, true)
export function resetRouter() {
  // 重置路由 比如用于身份验证失败,需要重新登录时 先清空当前的路有权限
  const newRouter = createRouter({
    history: createWebHashHistory(import.meta.env.VITE_APP_BASE),
  });
  Router.matcher = newRouter.matcher; // reset router
  AvueRouter.install(Vue, {
    router: Router,
    store: Store,
    i18n: i18n,
  });
    // 重置路由 比如用于身份验证失败,需要重新登录时 先清空当前的路有权限
    const newRouter = createRouter({
        history: createWebHashHistory(import.meta.env.VITE_APP_BASE),
    })
    Router.matcher = newRouter.matcher // reset router
    AvueRouter.install(Vue, {
        router: Router,
        store: Store,
        i18n: i18n,
    })
}
export default Router;
export default Router
src/router/page/index.js
@@ -1,72 +1,69 @@
import Store from '@/store/';
import Store from '@/store/'
export default [
  {
    path: '/login',
    name: '登录页',
    component: () =>
      import('@/page/login/index.vue'),
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/oauth/redirect/:source',
    name: '第三方登录',
    component: () =>
      import('@/page/login/index.vue'),
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/lock',
    name: '锁屏页',
    component: () =>
      import('@/page/lock/index.vue'),
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/404',
    component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/404.vue'),
    name: '404',
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/403',
    component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/403.vue'),
    name: '403',
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/500',
    component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/500.vue'),
    name: '500',
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false,
    },
  },
  {
    path: '/',
    name: '主页',
    redirect: '/index',
  },
];
    {
        path: '/login',
        name: '登录页',
        component: () => import('@/page/login/index.vue'),
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/oauth/redirect/:source',
        name: '第三方登录',
        component: () => import('@/page/login/index.vue'),
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/lock',
        name: '锁屏页',
        component: () => import('@/page/lock/index.vue'),
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/404',
        component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/404.vue'),
        name: '404',
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/403',
        component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/403.vue'),
        name: '403',
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/500',
        component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/500.vue'),
        name: '500',
        meta: {
            keepAlive: true,
            isTab: false,
            isAuth: false,
        },
    },
    {
        path: '/',
        name: '主页',
        redirect: '/index',
    },
]
src/router/views/index.js
@@ -1,51 +1,55 @@
import Index from '@/layout/index.vue';
import Store from '@/store/';
import Layout from '@/page/index/layout.vue';
import Index from '@/layout/index.vue'
import Store from '@/store/'
import Layout from '@/page/index/layout.vue'
export default [
  {
    path: '/',
    component: () => import('@/layout/index.vue'),
    redirect: '/index',
    children: [
      {
        path: 'index',
        name: '首页',
        meta: {
          i18n: 'dashboard',
        },
        component: () => import(/* webpackChunkName: "home" */ '@/views/Home/Home.vue'),
      },
      {
        path: 'signMachineNest',
        name: '单个机巢详情',
        meta: {
          i18n: 'dashboard',
          menu: false,
        },
        component: () => import(/* webpackChunkName: "TaskManage" */ '@/views/SignMachineNest/SignMachineNest.vue'),
      },
      {
        path: 'taskManage',
        name: '任务管理',
        meta: {
          i18n: 'dashboard',
          menu: false,
        },
        component: () => import(/* webpackChunkName: "TaskManage" */ '@/views/TaskManage/TaskManage.vue'),
      },
    ],
  },
  {
    path: '/info',
    component: () => import('@/layout/index.vue'),
    redirect: '/info/index',
    children: [
      {
        path: 'index',
        name: '个人信息',
        component: () => import('@/views/System/Userinfo.vue'),
      },
    ],
  },
];
    {
        path: '/',
        component: () => import('@/layout/index.vue'),
        redirect: '/index',
        children: [
            {
                path: 'index',
                name: '首页',
                meta: {
                    i18n: 'dashboard',
                },
                component: () => import(/* webpackChunkName: "home" */ '@/views/Home/Home.vue'),
            },
            {
                path: 'signMachineNest',
                name: '单个机巢详情',
                meta: {
                    i18n: 'dashboard',
                    menu: false,
                },
                component: () =>
                    import(
                        /* webpackChunkName: "TaskManage" */ '@/views/SignMachineNest/SignMachineNest.vue'
                    ),
            },
            {
                path: 'taskManage',
                name: '任务管理',
                meta: {
                    i18n: 'dashboard',
                    menu: false,
                },
                component: () =>
                    import(/* webpackChunkName: "TaskManage" */ '@/views/TaskManage/TaskManage.vue'),
            },
        ],
    },
    {
        path: '/info',
        component: () => import('@/layout/index.vue'),
        redirect: '/info/index',
        children: [
            {
                path: 'index',
                name: '个人信息',
                component: () => import('@/views/System/Userinfo.vue'),
            },
        ],
    },
]
src/store/getters.js
@@ -1,38 +1,38 @@
const getters = {
  tag: state => state.tags.tag,
  language: state => state.common.language,
  setting: state => state.common.setting,
  userInfo: state => state.user.userInfo,
  colorName: state => state.common.colorName,
  themeName: state => state.common.themeName,
  isMacOs: (state, getters) => getters.themeName === 'mac-os',
  isRefresh: state => state.common.isRefresh,
  isSearch: state => state.common.isSearch,
  isHorizontal: state => state.common.setting.sidebar === 'horizontal',
  isCollapse: state => state.common.isCollapse,
  isLock: state => state.common.isLock,
  isFullScren: state => state.common.isFullScren,
  isMenu: state => state.common.isMenu,
  lockPasswd: state => state.common.lockPasswd,
  tagList: state => state.tags.tagList,
  tagsKeep: (state, getters) => {
    return getters.tagList
      .filter(ele => {
        return (ele.meta || {}).keepAlive;
      })
      .map(ele => ele.fullPath);
  },
  tagWel: state => state.tags.tagWel,
  token: state => state.user.token,
  roles: state => state.user.roles,
  permission: state => state.user.permission,
  menuId: state => state.user.menuId,
  menu: state => state.user.menu,
  menuAll: state => state.user.menuAll,
  logsList: state => state.logs.logsList,
  logsLen: state => state.logs.logsList.length || 0,
  logsFlag: (state, getters) => getters.logsLen === 0,
  flowRoutes: state => state.dict.flowRoutes,
  singleUavHome: state => state.home.singleUavHome,
};
export default getters;
    tag: state => state.tags.tag,
    language: state => state.common.language,
    setting: state => state.common.setting,
    userInfo: state => state.user.userInfo,
    colorName: state => state.common.colorName,
    themeName: state => state.common.themeName,
    isMacOs: (state, getters) => getters.themeName === 'mac-os',
    isRefresh: state => state.common.isRefresh,
    isSearch: state => state.common.isSearch,
    isHorizontal: state => state.common.setting.sidebar === 'horizontal',
    isCollapse: state => state.common.isCollapse,
    isLock: state => state.common.isLock,
    isFullScren: state => state.common.isFullScren,
    isMenu: state => state.common.isMenu,
    lockPasswd: state => state.common.lockPasswd,
    tagList: state => state.tags.tagList,
    tagsKeep: (state, getters) => {
        return getters.tagList
            .filter(ele => {
                return (ele.meta || {}).keepAlive
            })
            .map(ele => ele.fullPath)
    },
    tagWel: state => state.tags.tagWel,
    token: state => state.user.token,
    roles: state => state.user.roles,
    permission: state => state.user.permission,
    menuId: state => state.user.menuId,
    menu: state => state.user.menu,
    menuAll: state => state.user.menuAll,
    logsList: state => state.logs.logsList,
    logsLen: state => state.logs.logsList.length || 0,
    logsFlag: (state, getters) => getters.logsLen === 0,
    flowRoutes: state => state.dict.flowRoutes,
    singleUavHome: state => state.home.singleUavHome,
}
export default getters
src/store/index.js
@@ -1,22 +1,22 @@
import { createStore } from 'vuex';
import user from './modules/user';
import common from './modules/common';
import tags from './modules/tags';
import logs from './modules/logs';
import dict from './modules/dict';
import getters from './getters';
import home from '@/store/modules/home';
import { createStore } from 'vuex'
import user from './modules/user'
import common from './modules/common'
import tags from './modules/tags'
import logs from './modules/logs'
import dict from './modules/dict'
import getters from './getters'
import home from '@/store/modules/home'
const store = createStore({
  modules: {
    user,
    common,
    logs,
    tags,
    dict,
    home,
  },
  getters,
});
    modules: {
        user,
        common,
        logs,
        tags,
        dict,
        home,
    },
    getters,
})
export default store;
export default store
src/store/modules/common.js
@@ -1,93 +1,93 @@
import { setStore, getStore, removeStore } from 'utils/store';
import website from '@/config/website';
import { setStore, getStore, removeStore } from 'utils/store'
import website from '@/config/website'
const common = {
  state: {
    language: getStore({ name: 'language' }) || 'zh-cn',
    isCollapse: false,
    isFullScren: false,
    isMenu: true,
    isSearch: false,
    isRefresh: true,
    isLock: getStore({ name: 'isLock' }),
    colorName: getStore({ name: 'colorName' }) || '#2C77F1',
    themeName: getStore({ name: 'themeName' }) || 'theme-go',
    lockPasswd: getStore({ name: 'lockPasswd' }) || '',
    website: website,
    setting: website.setting,
    // 地图设置
    mapSetting: {
      mode: 3, // 0为标准地图, 1为卫星地图
      roadLine: true,
      visual: '3D',
      isDark: false,
    },
  },
  mutations: {
    SET_LANGUAGE: (state, language) => {
      state.language = language;
      setStore({
        name: 'language',
        content: state.language,
      });
    },
    SET_COLLAPSE: state => {
      state.isCollapse = !state.isCollapse;
    },
    SET_IS_MENU: (state, menu) => {
      state.isMenu = menu;
    },
    SET_IS_REFRESH: (state, refresh) => {
      state.isRefresh = refresh;
    },
    SET_IS_SEARCH: (state, search) => {
      state.isSearch = search;
    },
    SET_FULLSCREN: state => {
      state.isFullScren = !state.isFullScren;
    },
    SET_LOCK: state => {
      state.isLock = true;
      setStore({
        name: 'isLock',
        content: state.isLock,
        type: 'session',
      });
    },
    SET_COLOR_NAME: (state, colorName) => {
      state.colorName = colorName;
      setStore({
        name: 'colorName',
        content: state.colorName,
      });
    },
    SET_THEME_NAME: (state, themeName) => {
      state.themeName = themeName;
      setStore({
        name: 'themeName',
        content: state.themeName,
      });
    },
    SET_LOCK_PASSWD: (state, lockPasswd) => {
      state.lockPasswd = lockPasswd;
      setStore({
        name: 'lockPasswd',
        content: state.lockPasswd,
        type: 'session',
      });
    },
    CLEAR_LOCK: state => {
      state.isLock = false;
      state.lockPasswd = '';
      removeStore({
        name: 'lockPasswd',
        type: 'session',
      });
      removeStore({
        name: 'isLock',
        type: 'session',
      });
    },
  },
};
export default common;
    state: {
        language: getStore({ name: 'language' }) || 'zh-cn',
        isCollapse: false,
        isFullScren: false,
        isMenu: true,
        isSearch: false,
        isRefresh: true,
        isLock: getStore({ name: 'isLock' }),
        colorName: getStore({ name: 'colorName' }) || '#2C77F1',
        themeName: getStore({ name: 'themeName' }) || 'theme-go',
        lockPasswd: getStore({ name: 'lockPasswd' }) || '',
        website: website,
        setting: website.setting,
        // 地图设置
        mapSetting: {
            mode: 3, // 0为标准地图, 1为卫星地图
            roadLine: true,
            visual: '3D',
            isDark: false,
        },
    },
    mutations: {
        SET_LANGUAGE: (state, language) => {
            state.language = language
            setStore({
                name: 'language',
                content: state.language,
            })
        },
        SET_COLLAPSE: state => {
            state.isCollapse = !state.isCollapse
        },
        SET_IS_MENU: (state, menu) => {
            state.isMenu = menu
        },
        SET_IS_REFRESH: (state, refresh) => {
            state.isRefresh = refresh
        },
        SET_IS_SEARCH: (state, search) => {
            state.isSearch = search
        },
        SET_FULLSCREN: state => {
            state.isFullScren = !state.isFullScren
        },
        SET_LOCK: state => {
            state.isLock = true
            setStore({
                name: 'isLock',
                content: state.isLock,
                type: 'session',
            })
        },
        SET_COLOR_NAME: (state, colorName) => {
            state.colorName = colorName
            setStore({
                name: 'colorName',
                content: state.colorName,
            })
        },
        SET_THEME_NAME: (state, themeName) => {
            state.themeName = themeName
            setStore({
                name: 'themeName',
                content: state.themeName,
            })
        },
        SET_LOCK_PASSWD: (state, lockPasswd) => {
            state.lockPasswd = lockPasswd
            setStore({
                name: 'lockPasswd',
                content: state.lockPasswd,
                type: 'session',
            })
        },
        CLEAR_LOCK: state => {
            state.isLock = false
            state.lockPasswd = ''
            removeStore({
                name: 'lockPasswd',
                type: 'session',
            })
            removeStore({
                name: 'isLock',
                type: 'session',
            })
        },
    },
}
export default common
src/store/modules/dict.js
@@ -1,36 +1,36 @@
import { getStore, setStore } from '@/utils/store';
import { getStore, setStore } from '@/utils/store'
import { getDictionary } from '@/api/system/dict';
import { getDictionary } from '@/api/system/dict'
const dict = {
  state: {
    flowRoutes: getStore({ name: 'flowRoutes' }) || {},
  },
  actions: {
    FlowRoutes({ commit }) {
      return new Promise((resolve, reject) => {
        getDictionary({ code: 'flow' })
          .then(res => {
            commit('SET_FLOW_ROUTES', res.data.data);
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
  },
  mutations: {
    SET_FLOW_ROUTES: (state, data) => {
      state.flowRoutes = data.map(item => {
        return {
          routeKey: `${item.code}_${item.dictKey}`,
          routeValue: item.remark,
        };
      });
      setStore({ name: 'flowRoutes', content: state.flowRoutes });
    },
  },
};
    state: {
        flowRoutes: getStore({ name: 'flowRoutes' }) || {},
    },
    actions: {
        FlowRoutes({ commit }) {
            return new Promise((resolve, reject) => {
                getDictionary({ code: 'flow' })
                    .then(res => {
                        commit('SET_FLOW_ROUTES', res.data.data)
                        resolve()
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        },
    },
    mutations: {
        SET_FLOW_ROUTES: (state, data) => {
            state.flowRoutes = data.map(item => {
                return {
                    routeKey: `${item.code}_${item.dictKey}`,
                    routeValue: item.remark,
                }
            })
            setStore({ name: 'flowRoutes', content: state.flowRoutes })
        },
    },
}
export default dict;
export default dict
src/store/modules/home.js
@@ -1,95 +1,94 @@
import { set } from "lodash";
import { set } from 'lodash'
import { EDeviceTypeName } from '@/utils/staticData/enums'
const home = {
  state: {
    singleUavHome: {},
    // 项目id
    selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'),
    wsMessage: {},
    deviceState: {
      gatewayInfo: {},
      deviceInfo: {},
      timestamp: '',
      dockInfo: {},
      currentSn: '',
      currentType: -1,
      drone_charge_state_new: {},
      psdk_widget_values: {},
      speakerAudioPlayStartProgress: {},
    },
    osdVisible: {
      // osd 显示设备相关信息
      sn: '',
      callsign: '',
      model: '',
      visible: false,
      gateway_sn: '',
      is_dock: false,
      payloads: null,
      device_domain: '',
      device_sub_type: '',
      device_type: '',
    },
  },
  actions: {},
  mutations: {
    setSingleUavHome: (state, data) => {
      state.singleUavHome = data;
    },
    setSelectedWorkSpaceId: (state, id) => {
      state.selectedWorkSpaceId = id
      window.localStorage.setItem('bs_workspace_id', id)
    },
    setOsdVisibleInfo: (state, info) => {
      console.log(info, '哒哒哒')
      state.osdVisible = Object.assign({}, info)
      window.localStorage.setItem('bs_osd', JSON.stringify(info))
    },
    setWsMessage: (state, data) => {
      state.wsMessage = data.host;
    },
    setDeviceInfo: (state, data) => {
      const info = data.data
      state.deviceState.timestamp = data.timestamp
      state.deviceState.deviceInfo[info.sn] = info.host
      state.deviceState.currentSn = info.sn
      state.deviceState.currentType = EDeviceTypeName.Aircraft
    },
    setGatewayInfo: (state, info) => {
      state.deviceState.gatewayInfo[info.sn] = info.host
      state.deviceState.currentSn = info.sn
      state.deviceState.currentType = EDeviceTypeName.Gateway
    },
    setDockOnfo: (state, info) => {
      if (Object.keys(info.host).length === 0) return
      if (!state.deviceState.dockInfo[info.sn]) {
        state.deviceState.dockInfo[info.sn] = {}
      }
      state.deviceState.currentSn = info.sn
      state.deviceState.currentType = EDeviceTypeName.Dock
      const dock = state.deviceState.dockInfo[info.sn]
      if (info.host.mode_code !== undefined) {
        dock.basic_osd = info.host
        state.deviceState.drone_charge_state_new =
          dock.basic_osd.drone_charge_state
        return
      }
      if (info.host.sdr) {
        dock.link_osd = info.host
        return
      }
      if (info.host.job_number !== undefined) {
        dock.work_osd = info.host
      }
    },
  },
  getters:{
    test(state) {
      return state.singleUavHome.id.toString() + '65'
    }
  }
};
    state: {
        singleUavHome: {},
        // 项目id
        selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'),
        wsMessage: {},
        deviceState: {
            gatewayInfo: {},
            deviceInfo: {},
            timestamp: '',
            dockInfo: {},
            currentSn: '',
            currentType: -1,
            drone_charge_state_new: {},
            psdk_widget_values: {},
            speakerAudioPlayStartProgress: {},
        },
        osdVisible: {
            // osd 显示设备相关信息
            sn: '',
            callsign: '',
            model: '',
            visible: false,
            gateway_sn: '',
            is_dock: false,
            payloads: null,
            device_domain: '',
            device_sub_type: '',
            device_type: '',
        },
    },
    actions: {},
    mutations: {
        setSingleUavHome: (state, data) => {
            state.singleUavHome = data
        },
        setSelectedWorkSpaceId: (state, id) => {
            state.selectedWorkSpaceId = id
            window.localStorage.setItem('bs_workspace_id', id)
        },
        setOsdVisibleInfo: (state, info) => {
            console.log(info, '哒哒哒')
            state.osdVisible = Object.assign({}, info)
            window.localStorage.setItem('bs_osd', JSON.stringify(info))
        },
        setWsMessage: (state, data) => {
            state.wsMessage = data.host
        },
        setDeviceInfo: (state, data) => {
            const info = data.data
            state.deviceState.timestamp = data.timestamp
            state.deviceState.deviceInfo[info.sn] = info.host
            state.deviceState.currentSn = info.sn
            state.deviceState.currentType = EDeviceTypeName.Aircraft
        },
        setGatewayInfo: (state, info) => {
            state.deviceState.gatewayInfo[info.sn] = info.host
            state.deviceState.currentSn = info.sn
            state.deviceState.currentType = EDeviceTypeName.Gateway
        },
        setDockOnfo: (state, info) => {
            if (Object.keys(info.host).length === 0) return
export default home;
            if (!state.deviceState.dockInfo[info.sn]) {
                state.deviceState.dockInfo[info.sn] = {}
            }
            state.deviceState.currentSn = info.sn
            state.deviceState.currentType = EDeviceTypeName.Dock
            const dock = state.deviceState.dockInfo[info.sn]
            if (info.host.mode_code !== undefined) {
                dock.basic_osd = info.host
                state.deviceState.drone_charge_state_new = dock.basic_osd.drone_charge_state
                return
            }
            if (info.host.sdr) {
                dock.link_osd = info.host
                return
            }
            if (info.host.job_number !== undefined) {
                dock.work_osd = info.host
            }
        },
    },
    getters: {
        test(state) {
            return state.singleUavHome.id.toString() + '65'
        },
    },
}
export default home
src/store/modules/logs.js
@@ -1,49 +1,49 @@
import { setStore, getStore } from 'utils/store';
import dayjs from 'dayjs';
import { sendLogs } from '@/api/user';
import { setStore, getStore } from 'utils/store'
import dayjs from 'dayjs'
import { sendLogs } from '@/api/user'
const logs = {
  state: {
    logsList: getStore({ name: 'logsList' }) || [],
  },
  actions: {
    //发送错误日志
    SendLogs({ state, commit }) {
      return new Promise((resolve, reject) => {
        sendLogs(state.logsList)
          .then(() => {
            commit('CLEAR_LOGS');
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
  },
  mutations: {
    ADD_LOGS: (state, { type, message, stack, info }) => {
      state.logsList.push(
        Object.assign(
          {
            url: window.location.href,
            time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
          },
          {
            type,
            message,
            stack,
            info: info.toString(),
          }
        )
      );
      setStore({ name: 'logsList', content: state.logsList });
    },
    CLEAR_LOGS: state => {
      state.logsList = [];
      setStore({ name: 'logsList', content: state.logsList });
    },
  },
};
    state: {
        logsList: getStore({ name: 'logsList' }) || [],
    },
    actions: {
        //发送错误日志
        SendLogs({ state, commit }) {
            return new Promise((resolve, reject) => {
                sendLogs(state.logsList)
                    .then(() => {
                        commit('CLEAR_LOGS')
                        resolve()
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        },
    },
    mutations: {
        ADD_LOGS: (state, { type, message, stack, info }) => {
            state.logsList.push(
                Object.assign(
                    {
                        url: window.location.href,
                        time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
                    },
                    {
                        type,
                        message,
                        stack,
                        info: info.toString(),
                    }
                )
            )
            setStore({ name: 'logsList', content: state.logsList })
        },
        CLEAR_LOGS: state => {
            state.logsList = []
            setStore({ name: 'logsList', content: state.logsList })
        },
    },
}
export default logs;
export default logs
src/store/modules/tags.js
@@ -1,38 +1,38 @@
import { setStore, getStore } from 'utils/store';
import website from '@/config/website';
import { setStore, getStore } from 'utils/store'
import website from '@/config/website'
const tagWel = website.fistPage;
const tagWel = website.fistPage
const navs = {
  state: {
    tagList: getStore({ name: 'tagList' }) || [],
    tag: getStore({ name: 'tag' }) || {},
    tagWel: tagWel,
  },
  mutations: {
    ADD_TAG: (state, action) => {
      if (typeof action.name == 'function') action.name = action.name(action.query);
      state.tag = action;
      setStore({ name: 'tag', content: state.tag });
      if (state.tagList.some(ele => ele.fullPath == action.fullPath)) return;
      state.tagList.push(action);
      setStore({ name: 'tagList', content: state.tagList });
    },
    DEL_TAG: (state, action) => {
      state.tagList = state.tagList.filter(item => {
        return item.fullPath !== action.fullPath;
      });
      setStore({ name: 'tagList', content: state.tagList });
    },
    DEL_ALL_TAG: (state, tagList = []) => {
      state.tagList = tagList;
      setStore({ name: 'tagList', content: state.tagList });
    },
    DEL_TAG_OTHER: state => {
      state.tagList = state.tagList.filter(item => {
        return [state.tag.fullPath, website.fistPage.path].includes(item.fullPath);
      });
      setStore({ name: 'tagList', content: state.tagList });
    },
  },
};
export default navs;
    state: {
        tagList: getStore({ name: 'tagList' }) || [],
        tag: getStore({ name: 'tag' }) || {},
        tagWel: tagWel,
    },
    mutations: {
        ADD_TAG: (state, action) => {
            if (typeof action.name == 'function') action.name = action.name(action.query)
            state.tag = action
            setStore({ name: 'tag', content: state.tag })
            if (state.tagList.some(ele => ele.fullPath == action.fullPath)) return
            state.tagList.push(action)
            setStore({ name: 'tagList', content: state.tagList })
        },
        DEL_TAG: (state, action) => {
            state.tagList = state.tagList.filter(item => {
                return item.fullPath !== action.fullPath
            })
            setStore({ name: 'tagList', content: state.tagList })
        },
        DEL_ALL_TAG: (state, tagList = []) => {
            state.tagList = tagList
            setStore({ name: 'tagList', content: state.tagList })
        },
        DEL_TAG_OTHER: state => {
            state.tagList = state.tagList.filter(item => {
                return [state.tag.fullPath, website.fistPage.path].includes(item.fullPath)
            })
            setStore({ name: 'tagList', content: state.tagList })
        },
    },
}
export default navs
src/store/modules/user.js
@@ -1,401 +1,401 @@
import { ELocalStorageKey } from '@/utils/http/enums';
import { ELocalStorageKey } from '@/utils/http/enums'
import {
  setToken,
  setRefreshToken,
  removeToken,
  removeRefreshToken,
  getRefreshToken,
} from '@/utils/auth';
import { setStore, getStore } from '@/utils/store';
import { validatenull } from '@/utils/validate';
import { deepClone } from '@/utils/util';
    setToken,
    setRefreshToken,
    removeToken,
    removeRefreshToken,
    getRefreshToken,
} from '@/utils/auth'
import { setStore, getStore } from '@/utils/store'
import { validatenull } from '@/utils/validate'
import { deepClone } from '@/utils/util'
import {
  loginByUsername,
  loginBySocial,
  loginBySso,
  loginByPhone,
  getUserInfo,
  logout,
  refreshToken,
  getButtons,
  registerUser,
} from '@/api/user';
import { getRoutes, getTopMenu } from '@/api/system/menu';
import { formatPath } from '@/router/avue-router';
import { ElMessage } from 'element-plus';
import { encrypt } from '@/utils/sm2';
import md5 from 'js-md5';
    loginByUsername,
    loginBySocial,
    loginBySso,
    loginByPhone,
    getUserInfo,
    logout,
    refreshToken,
    getButtons,
    registerUser,
} from '@/api/user'
import { getRoutes, getTopMenu } from '@/api/system/menu'
import { formatPath } from '@/router/avue-router'
import { ElMessage } from 'element-plus'
import { encrypt } from '@/utils/sm2'
import md5 from 'js-md5'
const userInfoData = getStore({ name: 'userInfo' }) || {}
const user = {
  state: {
    // 当前选中的请求头
    selectedAreaCode: userInfoData?.detail?.areaCode || '',
    tenantId: getStore({ name: 'tenantId' }) || '',
    userInfo: userInfoData,
    permission: getStore({ name: 'permission' }) || {},
    roles: [],
    menuId: {},
    menu: getStore({ name: 'menu' }) || [],
    menuAll: getStore({ name: 'menuAll' }) || [],
    token: getStore({ name: 'token' }) || '',
    refreshToken: getStore({ name: 'refreshToken' }) || '',
  },
  actions: {
    //根据用户名登录
    LoginByUsername({ commit }, userInfo = {}) {
      return new Promise((resolve, reject) => {
        loginByUsername(
          userInfo.tenantId,
          userInfo.deptId,
          userInfo.roleId,
          userInfo.username,
          md5(userInfo.password),
          userInfo.type,
          userInfo.key,
          userInfo.code
        )
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('SET_USER_INFO', data);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //根据第三方信息登录
    LoginBySocial({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state)
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_USER_INFO', data);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //根据单点信息登录
    LoginBySso({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        loginBySso(userInfo.state, userInfo.code)
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_USER_INFO', data);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //根据手机信息登录
    LoginByPhone({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        loginByPhone(
          userInfo.tenantId,
          encrypt(userInfo.phone),
          userInfo.codeId,
          userInfo.codeValue
        )
          .then(res => {
            const data = res.data;
            if (data.error_description) {
              ElMessage({
                message: data.error_description,
                type: 'error',
              });
            } else {
              commit('SET_TOKEN', data.access_token);
              commit('SET_REFRESH_TOKEN', data.refresh_token);
              commit('SET_USER_INFO', data);
              commit('SET_TENANT_ID', data.tenant_id);
              commit('DEL_ALL_TAG');
              commit('CLEAR_LOCK');
            }
            resolve();
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //用户注册
    RegisterUser({ commit }, userInfo = {}) {
      return new Promise((resolve, reject) => {
        registerUser(
          userInfo.tenantId,
          userInfo.name,
          userInfo.account,
          encrypt(userInfo.password),
          userInfo.phone,
          userInfo.email
        ).then(res => {
          const data = res.data;
          if (data.error_description) {
            ElMessage({
              message: data.error_description,
              type: 'error',
            });
            reject(data.error_description);
          } else {
            commit('SET_TOKEN', data.access_token);
            commit('SET_REFRESH_TOKEN', data.refresh_token);
            commit('SET_USER_INFO', data);
            commit('SET_TENANT_ID', data.tenant_id);
            commit('DEL_ALL_TAG');
            commit('CLEAR_LOCK');
          }
          resolve();
        });
      });
    },
    GetUserInfo({ commit }) {
      return new Promise((resolve, reject) => {
        getUserInfo()
          .then(res => {
            const data = res.data.data;
            commit('SET_ROLES', data.roles);
            resolve(data);
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    //刷新token
    RefreshToken({ state, commit }, userInfo) {
      return new Promise((resolve, reject) => {
        refreshToken(
          getRefreshToken(),
          state.tenantId,
          !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
          !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
        )
          .then(res => {
            const data = res.data;
            commit('SET_TOKEN', data.access_token);
            commit('SET_REFRESH_TOKEN', data.refresh_token);
            commit('SET_USER_INFO', data);
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    // 登出
    LogOut({ commit }) {
      return new Promise((resolve, reject) => {
        logout()
          .then(() => {
            commit('SET_TOKEN', '');
            commit('SET_MENU_ALL_NULL', []);
            commit('SET_MENU', []);
            commit('SET_ROLES', []);
            commit('DEL_ALL_TAG', []);
            commit('CLEAR_LOCK');
            removeToken();
            removeRefreshToken();
            removeToken();
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    //注销session
    FedLogOut({ commit }) {
      return new Promise(resolve => {
        commit('SET_TOKEN', '');
        commit('SET_MENU_ALL_NULL', []);
        commit('SET_MENU', []);
        commit('SET_ROLES', []);
        commit('DEL_ALL_TAG', []);
        commit('CLEAR_LOCK');
        removeToken();
        removeRefreshToken();
        removeToken();
        resolve();
      });
    },
    GetTopMenu() {
      return new Promise(resolve => {
        getTopMenu().then(res => {
          const data = res.data.data || [];
          resolve(data);
        });
      });
    },
    GetMenu({ commit, dispatch }, tenantId) {
      return new Promise(resolve => {
        getRoutes(tenantId).then(res => {
          const data = res.data.data;
          let menu = deepClone(data);
          menu.forEach(ele => formatPath(ele, true));
          commit('SET_MENU', menu);
          commit('SET_MENU_ALL', menu);
          dispatch('GetButtons');
          resolve(menu);
        });
      });
    },
    GetButtons({ commit }) {
      return new Promise(resolve => {
        getButtons().then(res => {
          const data = res.data.data;
          commit('SET_PERMISSION', data);
          resolve();
        });
      });
    },
  },
  mutations: {
    setSelectedAreaCode:(state, code) =>{
      state.selectedAreaCode = code
    },
    SET_TOKEN: (state, token) => {
      setToken(token);
      state.token = token;
      setStore({ name: 'token', content: state.token });
      console.log('顶顶顶111',token)
      window.localStorage.setItem(ELocalStorageKey.Token, token);
    },
    SET_REFRESH_TOKEN: (state, refreshToken) => {
      setRefreshToken(refreshToken);
      state.refreshToken = refreshToken;
      setStore({ name: 'refreshToken', content: state.refreshToken });
    },
    SET_MENU_ID(state, menuId) {
      state.menuId = menuId;
    },
    SET_TENANT_ID: (state, tenantId) => {
      state.tenantId = tenantId;
      setStore({ name: 'tenantId', content: state.tenantId });
    },
    SET_USER_INFO: (state, userInfo) => {
      if (validatenull(userInfo.user_id) && validatenull(userInfo.account)) {
        state.userInfo = { user_name: 'unauth', role_name: 'unauth', authority: 'unauth' };
      } else {
        if (validatenull(userInfo.avatar)) {
          userInfo.avatar = '/img/bg/img-logo.png';
        }
        if (!validatenull(userInfo.role_name)) {
          userInfo.roleName = userInfo.role_name;
          userInfo.authority = userInfo.role_name;
        }
        if (!validatenull(userInfo.user_id)) {
          userInfo.userId = userInfo.user_id;
        }
        if (!validatenull(userInfo.user_name)) {
          userInfo.userName = userInfo.user_name;
        }
        if (!validatenull(userInfo.tenant_id)) {
          userInfo.tenantId = userInfo.tenant_id;
        }
        if (!validatenull(userInfo.dept_id)) {
          userInfo.deptId = userInfo.dept_id;
        }
        if (!validatenull(userInfo.role_id)) {
          userInfo.roleId = userInfo.role_id;
        }
        if (!validatenull(userInfo.oauth_id)) {
          userInfo.oauthId = userInfo.oauth_id;
        }
        userInfo.selectedAreaCode = userInfo?.detail?.areaCode || '';
        state.userInfo = userInfo;
      }
      setStore({ name: 'userInfo', content: state.userInfo });
    },
    SET_MENU_ALL: (state, menuAll) => {
      let menu = state.menuAll;
      menuAll.forEach(ele => {
        let index = menu.findIndex(item => item.path === ele.path);
        if (index === -1) {
          menu.push(ele);
        } else {
          menu[index] = ele;
        }
      });
      state.menuAll = menu;
      setStore({ name: 'menuAll', content: state.menuAll });
    },
    SET_MENU_ALL_NULL: state => {
      state.menuAll = [];
      setStore({ name: 'menuAll', content: state.menuAll });
    },
    SET_MENU: (state, menu) => {
      state.menu = menu;
      setStore({ name: 'menu', content: state.menu });
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles;
    },
    SET_PERMISSION: (state, permission) => {
      let result = [];
    state: {
        // 当前选中的请求头
        selectedAreaCode: userInfoData?.detail?.areaCode || '',
        tenantId: getStore({ name: 'tenantId' }) || '',
        userInfo: userInfoData,
        permission: getStore({ name: 'permission' }) || {},
        roles: [],
        menuId: {},
        menu: getStore({ name: 'menu' }) || [],
        menuAll: getStore({ name: 'menuAll' }) || [],
        token: getStore({ name: 'token' }) || '',
        refreshToken: getStore({ name: 'refreshToken' }) || '',
    },
    actions: {
        //根据用户名登录
        LoginByUsername({ commit }, userInfo = {}) {
            return new Promise((resolve, reject) => {
                loginByUsername(
                    userInfo.tenantId,
                    userInfo.deptId,
                    userInfo.roleId,
                    userInfo.username,
                    md5(userInfo.password),
                    userInfo.type,
                    userInfo.key,
                    userInfo.code
                )
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('SET_USER_INFO', data)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //根据第三方信息登录
        LoginBySocial({ commit }, userInfo) {
            return new Promise((resolve, reject) => {
                loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state)
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_USER_INFO', data)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //根据单点信息登录
        LoginBySso({ commit }, userInfo) {
            return new Promise((resolve, reject) => {
                loginBySso(userInfo.state, userInfo.code)
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_USER_INFO', data)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //根据手机信息登录
        LoginByPhone({ commit }, userInfo) {
            return new Promise((resolve, reject) => {
                loginByPhone(
                    userInfo.tenantId,
                    encrypt(userInfo.phone),
                    userInfo.codeId,
                    userInfo.codeValue
                )
                    .then(res => {
                        const data = res.data
                        if (data.error_description) {
                            ElMessage({
                                message: data.error_description,
                                type: 'error',
                            })
                        } else {
                            commit('SET_TOKEN', data.access_token)
                            commit('SET_REFRESH_TOKEN', data.refresh_token)
                            commit('SET_USER_INFO', data)
                            commit('SET_TENANT_ID', data.tenant_id)
                            commit('DEL_ALL_TAG')
                            commit('CLEAR_LOCK')
                        }
                        resolve()
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //用户注册
        RegisterUser({ commit }, userInfo = {}) {
            return new Promise((resolve, reject) => {
                registerUser(
                    userInfo.tenantId,
                    userInfo.name,
                    userInfo.account,
                    encrypt(userInfo.password),
                    userInfo.phone,
                    userInfo.email
                ).then(res => {
                    const data = res.data
                    if (data.error_description) {
                        ElMessage({
                            message: data.error_description,
                            type: 'error',
                        })
                        reject(data.error_description)
                    } else {
                        commit('SET_TOKEN', data.access_token)
                        commit('SET_REFRESH_TOKEN', data.refresh_token)
                        commit('SET_USER_INFO', data)
                        commit('SET_TENANT_ID', data.tenant_id)
                        commit('DEL_ALL_TAG')
                        commit('CLEAR_LOCK')
                    }
                    resolve()
                })
            })
        },
        GetUserInfo({ commit }) {
            return new Promise((resolve, reject) => {
                getUserInfo()
                    .then(res => {
                        const data = res.data.data
                        commit('SET_ROLES', data.roles)
                        resolve(data)
                    })
                    .catch(err => {
                        reject(err)
                    })
            })
        },
        //刷新token
        RefreshToken({ state, commit }, userInfo) {
            return new Promise((resolve, reject) => {
                refreshToken(
                    getRefreshToken(),
                    state.tenantId,
                    !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
                    !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
                )
                    .then(res => {
                        const data = res.data
                        commit('SET_TOKEN', data.access_token)
                        commit('SET_REFRESH_TOKEN', data.refresh_token)
                        commit('SET_USER_INFO', data)
                        resolve()
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        },
        // 登出
        LogOut({ commit }) {
            return new Promise((resolve, reject) => {
                logout()
                    .then(() => {
                        commit('SET_TOKEN', '')
                        commit('SET_MENU_ALL_NULL', [])
                        commit('SET_MENU', [])
                        commit('SET_ROLES', [])
                        commit('DEL_ALL_TAG', [])
                        commit('CLEAR_LOCK')
                        removeToken()
                        removeRefreshToken()
                        removeToken()
                        resolve()
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        },
        //注销session
        FedLogOut({ commit }) {
            return new Promise(resolve => {
                commit('SET_TOKEN', '')
                commit('SET_MENU_ALL_NULL', [])
                commit('SET_MENU', [])
                commit('SET_ROLES', [])
                commit('DEL_ALL_TAG', [])
                commit('CLEAR_LOCK')
                removeToken()
                removeRefreshToken()
                removeToken()
                resolve()
            })
        },
        GetTopMenu() {
            return new Promise(resolve => {
                getTopMenu().then(res => {
                    const data = res.data.data || []
                    resolve(data)
                })
            })
        },
        GetMenu({ commit, dispatch }, tenantId) {
            return new Promise(resolve => {
                getRoutes(tenantId).then(res => {
                    const data = res.data.data
                    let menu = deepClone(data)
                    menu.forEach(ele => formatPath(ele, true))
                    commit('SET_MENU', menu)
                    commit('SET_MENU_ALL', menu)
                    dispatch('GetButtons')
                    resolve(menu)
                })
            })
        },
        GetButtons({ commit }) {
            return new Promise(resolve => {
                getButtons().then(res => {
                    const data = res.data.data
                    commit('SET_PERMISSION', data)
                    resolve()
                })
            })
        },
    },
    mutations: {
        setSelectedAreaCode: (state, code) => {
            state.selectedAreaCode = code
        },
        SET_TOKEN: (state, token) => {
            setToken(token)
            state.token = token
            setStore({ name: 'token', content: state.token })
            console.log('顶顶顶111', token)
            window.localStorage.setItem(ELocalStorageKey.Token, token)
        },
        SET_REFRESH_TOKEN: (state, refreshToken) => {
            setRefreshToken(refreshToken)
            state.refreshToken = refreshToken
            setStore({ name: 'refreshToken', content: state.refreshToken })
        },
        SET_MENU_ID(state, menuId) {
            state.menuId = menuId
        },
        SET_TENANT_ID: (state, tenantId) => {
            state.tenantId = tenantId
            setStore({ name: 'tenantId', content: state.tenantId })
        },
        SET_USER_INFO: (state, userInfo) => {
            if (validatenull(userInfo.user_id) && validatenull(userInfo.account)) {
                state.userInfo = { user_name: 'unauth', role_name: 'unauth', authority: 'unauth' }
            } else {
                if (validatenull(userInfo.avatar)) {
                    userInfo.avatar = '/img/bg/img-logo.png'
                }
                if (!validatenull(userInfo.role_name)) {
                    userInfo.roleName = userInfo.role_name
                    userInfo.authority = userInfo.role_name
                }
                if (!validatenull(userInfo.user_id)) {
                    userInfo.userId = userInfo.user_id
                }
                if (!validatenull(userInfo.user_name)) {
                    userInfo.userName = userInfo.user_name
                }
                if (!validatenull(userInfo.tenant_id)) {
                    userInfo.tenantId = userInfo.tenant_id
                }
                if (!validatenull(userInfo.dept_id)) {
                    userInfo.deptId = userInfo.dept_id
                }
                if (!validatenull(userInfo.role_id)) {
                    userInfo.roleId = userInfo.role_id
                }
                if (!validatenull(userInfo.oauth_id)) {
                    userInfo.oauthId = userInfo.oauth_id
                }
                userInfo.selectedAreaCode = userInfo?.detail?.areaCode || ''
                state.userInfo = userInfo
            }
            setStore({ name: 'userInfo', content: state.userInfo })
        },
        SET_MENU_ALL: (state, menuAll) => {
            let menu = state.menuAll
            menuAll.forEach(ele => {
                let index = menu.findIndex(item => item.path === ele.path)
                if (index === -1) {
                    menu.push(ele)
                } else {
                    menu[index] = ele
                }
            })
            state.menuAll = menu
            setStore({ name: 'menuAll', content: state.menuAll })
        },
        SET_MENU_ALL_NULL: state => {
            state.menuAll = []
            setStore({ name: 'menuAll', content: state.menuAll })
        },
        SET_MENU: (state, menu) => {
            state.menu = menu
            setStore({ name: 'menu', content: state.menu })
        },
        SET_ROLES: (state, roles) => {
            state.roles = roles
        },
        SET_PERMISSION: (state, permission) => {
            let result = []
      function getCode(list) {
        list.forEach(ele => {
          if (typeof ele === 'object') {
            const children = ele.children;
            const code = ele.code;
            if (children && children.length > 0) {
              getCode(children);
            } else {
              result.push(code);
            }
          }
        });
      }
            function getCode(list) {
                list.forEach(ele => {
                    if (typeof ele === 'object') {
                        const children = ele.children
                        const code = ele.code
                        if (children && children.length > 0) {
                            getCode(children)
                        } else {
                            result.push(code)
                        }
                    }
                })
            }
      getCode(permission);
      state.permission = {};
      result.forEach(ele => {
        state.permission[ele] = true;
      });
      setStore({ name: 'permission', content: state.permission, type: 'session' });
    },
  },
};
export default user;
            getCode(permission)
            state.permission = {}
            result.forEach(ele => {
                state.permission[ele] = true
            })
            setStore({ name: 'permission', content: state.permission, type: 'session' })
        },
    },
}
export default user
src/utils/auth.js
@@ -1,32 +1,32 @@
import Cookies from 'js-cookie';
import Cookies from 'js-cookie'
const TokenKey = 'saber3-access-token';
const RefreshTokenKey = 'saber3-refresh-token';
const SessionId = 'JSESSIONID';
const UserId = 'b-user-id';
const TokenKey = 'saber3-access-token'
const RefreshTokenKey = 'saber3-refresh-token'
const SessionId = 'JSESSIONID'
const UserId = 'b-user-id'
export function getToken() {
  return Cookies.get(TokenKey);
    return Cookies.get(TokenKey)
}
export function setToken(token) {
  return Cookies.set(TokenKey, token);
    return Cookies.set(TokenKey, token)
}
export function getRefreshToken() {
  return Cookies.get(RefreshTokenKey);
    return Cookies.get(RefreshTokenKey)
}
export function setRefreshToken(token) {
  return Cookies.set(RefreshTokenKey, token);
    return Cookies.set(RefreshTokenKey, token)
}
export function removeToken() {
  Cookies.remove(SessionId);
  Cookies.remove(UserId);
  return Cookies.remove(TokenKey);
    Cookies.remove(SessionId)
    Cookies.remove(UserId)
    return Cookies.remove(TokenKey)
}
export function removeRefreshToken() {
  return Cookies.remove(RefreshTokenKey);
    return Cookies.remove(RefreshTokenKey)
}
src/utils/cesium-tsa.js
@@ -1,1137 +1,1131 @@
import * as Cesium from 'cesium';
import AmapMercatorTilingScheme from './cesium/AmapMercatorTilingScheme/index';
import store from '@/store';
import { Terrain } from 'cesium';
import * as Cesium from 'cesium'
import AmapMercatorTilingScheme from './cesium/AmapMercatorTilingScheme/index'
import store from '@/store'
import { Terrain } from 'cesium'
// vite env
const { VITE_APP_BASE } = import.meta.env;
const { VITE_APP_BASE } = import.meta.env
window.CESIUM_BASE_URL = `${VITE_APP_BASE}cesiumPu`;
window.CESIUM_BASE_URL = `${VITE_APP_BASE}cesiumPu`
// 定义全局的viewer变量防止重复生成
let viewer = null;
let globalBaseMapLayers = [];
let viewer = null
let globalBaseMapLayers = []
window.globalCesium = Cesium;
window.$viewer = null;
window.globalCesium = Cesium
window.$viewer = null
let customEntityDataSources = {};
let customEntityDataSources = {}
let customMapLayer = {};
let customMapLayer = {}
let handlerEvents = {
  handler: null,
};
    handler: null,
}
export default function cesiumOperation() {
  const TDT_Token = 'c6eea7dad4fa1e2d1e32ec0e7c9735db';
  // 天地图地图
  const TDT_IMG_C =
    'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
    '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
    '&style=default&format=tiles&tk=' +
    TDT_Token;
  // 天地图注记
  const TDT_ZJ =
    'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
    '&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
    '&style=default&format=tiles&tk=' +
    TDT_Token;
  // 标准地图注记
  const TID_STAND =
    'https://{s}.tianditu.gov.cn/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0' +
    '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
    '&style=default&format=tiles&tk=' +
    TDT_Token;
  // 天地图图层变量
  const imageryProvider_tdt = new Cesium.WebMapTileServiceImageryProvider({
    url: TDT_IMG_C,
    layer: 'tdtImg_c',
    style: 'default',
    format: 'tiles',
    tileMatrixSetID: 'c',
    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
    tilingScheme: new Cesium.GeographicTilingScheme(),
    tileMatrixLabels: [
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      '10',
      '11',
      '12',
      '13',
      '14',
      '15',
      '16',
      '17',
      '18',
      '19',
    ],
    maximumLevel: 17,
  });
  // 标准地图图层变量
  const imageryProvider_stand = new Cesium.UrlTemplateImageryProvider({
    url: 'https://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
    // format: 'image/jpeg',
    // show: true,
    maximumLevel: 18,
    credit: 'stand_tc',
  });
  // 标准地图图层注解
  const imageryProvider_standZh = new Cesium.UrlTemplateImageryProvider({
    url: 'https://t{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
    maximumLevel: 18,
    credit: 'stand_zj',
  });
  // 天地图中文注记加载
  const annotation = new Cesium.WebMapTileServiceImageryProvider({
    url: TDT_ZJ,
    layer: 'tdtZwImg_c',
    style: 'default',
    format: 'tiles',
    tileMatrixSetID: 'c',
    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
    tilingScheme: new Cesium.GeographicTilingScheme(),
    tileMatrixLabels: [
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      '10',
      '11',
      '12',
      '13',
      '14',
      '15',
      '16',
      '17',
      '18',
      '19',
    ],
    maximumLevel: 50,
  });
    const TDT_Token = 'c6eea7dad4fa1e2d1e32ec0e7c9735db'
    // 天地图地图
    const TDT_IMG_C =
        'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
        '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
        '&style=default&format=tiles&tk=' +
        TDT_Token
    // 天地图注记
    const TDT_ZJ =
        'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
        '&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
        '&style=default&format=tiles&tk=' +
        TDT_Token
    // 标准地图注记
    const TID_STAND =
        'https://{s}.tianditu.gov.cn/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0' +
        '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
        '&style=default&format=tiles&tk=' +
        TDT_Token
    // 天地图图层变量
    const imageryProvider_tdt = new Cesium.WebMapTileServiceImageryProvider({
        url: TDT_IMG_C,
        layer: 'tdtImg_c',
        style: 'default',
        format: 'tiles',
        tileMatrixSetID: 'c',
        subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
        tilingScheme: new Cesium.GeographicTilingScheme(),
        tileMatrixLabels: [
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            '10',
            '11',
            '12',
            '13',
            '14',
            '15',
            '16',
            '17',
            '18',
            '19',
        ],
        maximumLevel: 17,
    })
    // 标准地图图层变量
    const imageryProvider_stand = new Cesium.UrlTemplateImageryProvider({
        url: 'https://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        // format: 'image/jpeg',
        // show: true,
        maximumLevel: 18,
        credit: 'stand_tc',
    })
    // 标准地图图层注解
    const imageryProvider_standZh = new Cesium.UrlTemplateImageryProvider({
        url: 'https://t{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        maximumLevel: 18,
        credit: 'stand_zj',
    })
    // 天地图中文注记加载
    const annotation = new Cesium.WebMapTileServiceImageryProvider({
        url: TDT_ZJ,
        layer: 'tdtZwImg_c',
        style: 'default',
        format: 'tiles',
        tileMatrixSetID: 'c',
        subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
        tilingScheme: new Cesium.GeographicTilingScheme(),
        tileMatrixLabels: [
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            '10',
            '11',
            '12',
            '13',
            '14',
            '15',
            '16',
            '17',
            '18',
            '19',
        ],
        maximumLevel: 50,
    })
  // 高德地图图层变量
  //高德矢量地图数据图层,自带注记
  const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
    url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
    layer: 'tdtVecBasicLayer',
    style: 'default',
    format: 'image/png',
    tileMatrixSetID: 'GoogleMapsCompatible',
    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
    maximumLevel: 18,
    tilingScheme: new AmapMercatorTilingScheme(),
    credit: 'amap_SL',
  });
    // 高德地图图层变量
    //高德矢量地图数据图层,自带注记
    const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
        url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
        layer: 'tdtVecBasicLayer',
        style: 'default',
        format: 'image/png',
        tileMatrixSetID: 'GoogleMapsCompatible',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        maximumLevel: 18,
        tilingScheme: new AmapMercatorTilingScheme(),
        credit: 'amap_SL',
    })
  //高德影像地图数据图层,自带注记
  const imageryProvider_ammap = new Cesium.UrlTemplateImageryProvider({
    url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
    layer: 'tdtVecBasicLayer',
    style: 'default',
    format: 'image/png',
    tileMatrixSetID: 'GoogleMapsCompatible',
    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
    maximumLevel: 18,
    tilingScheme: new AmapMercatorTilingScheme(),
    credit: 'amap_stand',
  });
  // 高德影像地图数据图层,注记
  const imageryProvider_ammapBz = new Cesium.UrlTemplateImageryProvider({
    url: 'https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8',
    tilingScheme: new AmapMercatorTilingScheme(),
    minimumLevel: 3,
  });
    //高德影像地图数据图层,自带注记
    const imageryProvider_ammap = new Cesium.UrlTemplateImageryProvider({
        url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
        layer: 'tdtVecBasicLayer',
        style: 'default',
        format: 'image/png',
        tileMatrixSetID: 'GoogleMapsCompatible',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        maximumLevel: 18,
        tilingScheme: new AmapMercatorTilingScheme(),
        credit: 'amap_stand',
    })
    // 高德影像地图数据图层,注记
    const imageryProvider_ammapBz = new Cesium.UrlTemplateImageryProvider({
        url: 'https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8',
        tilingScheme: new AmapMercatorTilingScheme(),
        minimumLevel: 3,
    })
  Cesium.Ion.defaultAccessToken =
    'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkMzg4MDk5YS05MWEzLTQ3NTYtOTYzNS04Yzk4MjU2MjI5N2YiLCJpZCI6MjE3OTM4LCJpYXQiOjE3MTY3NzIzOTR9.q1rzR7SRtIulQKTtJuv5HPUbp1av5E9RaOe-6voPDGc';
  const _init = async id => {
    const cesiumToken =
      'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYTZlNGNlYS01NTU1LTQ1MGEtYmNlZS0yNTE2NDk5YWM2MjEiLCJpZCI6MTc5Njk2LCJpYXQiOjE3MDA1NDcwMjV9.qcl4AH2731cfFd0-I1ZLUINPXqvglLkDFD-UGR2zU5M';
    Cesium.Ion.defaultAccessToken = cesiumToken;
    Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45;
    // 西南东北,默认显示中国
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55);
    viewer = new Cesium.Viewer(id, {
      terrain: Terrain.fromWorldTerrain(),
      infoBox: false, // 禁用沙箱,解决控制台报错
      animation: false, // 左下角的动画仪表盘
      baseLayerPicker: false, // 右上角的图层选择按钮
      geocoder: false, // 搜索框
      homeButton: false, // home按钮
      sceneModePicker: false, // 模式切换按钮
      timeline: false, // 底部的时间轴
      navigationHelpButton: false, // 右上角的帮助按钮,
      selectionIndicator: false, // 是否显示选择指示器
      baseLayer: false,
      fullscreenButton: false,
    });
    Cesium.Ion.defaultAccessToken =
        'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkMzg4MDk5YS05MWEzLTQ3NTYtOTYzNS04Yzk4MjU2MjI5N2YiLCJpZCI6MjE3OTM4LCJpYXQiOjE3MTY3NzIzOTR9.q1rzR7SRtIulQKTtJuv5HPUbp1av5E9RaOe-6voPDGc'
    const _init = async id => {
        const cesiumToken =
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYTZlNGNlYS01NTU1LTQ1MGEtYmNlZS0yNTE2NDk5YWM2MjEiLCJpZCI6MTc5Njk2LCJpYXQiOjE3MDA1NDcwMjV9.qcl4AH2731cfFd0-I1ZLUINPXqvglLkDFD-UGR2zU5M'
        Cesium.Ion.defaultAccessToken = cesiumToken
        Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
        // 西南东北,默认显示中国
        Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
        viewer = new Cesium.Viewer(id, {
            terrain: Terrain.fromWorldTerrain(),
            infoBox: false, // 禁用沙箱,解决控制台报错
            animation: false, // 左下角的动画仪表盘
            baseLayerPicker: false, // 右上角的图层选择按钮
            geocoder: false, // 搜索框
            homeButton: false, // home按钮
            sceneModePicker: false, // 模式切换按钮
            timeline: false, // 底部的时间轴
            navigationHelpButton: false, // 右上角的帮助按钮,
            selectionIndicator: false, // 是否显示选择指示器
            baseLayer: false,
            fullscreenButton: false,
        })
    // viewer.scene.globe.depthTestAgainstTerrain = true;
        // viewer.scene.globe.depthTestAgainstTerrain = true;
    viewer.imageryLayers.removeAll();
        viewer.imageryLayers.removeAll()
    globalBaseMapLayers = [];
        globalBaseMapLayers = []
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    ); // 禁用双击
    viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100;
    viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000;
    // viewer.scene.camera.setView({
    //   destination: Cesium.Cartesian3.fromDegrees(115.856725497,28.624514734, 8000)
    // });
    // // 添加地形数据
        viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
            Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
        ) // 禁用双击
        viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100
        viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
        // viewer.scene.camera.setView({
        //   destination: Cesium.Cartesian3.fromDegrees(115.856725497,28.624514734, 8000)
        // });
        // // 添加地形数据
    // viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
    //   url: 'https://data.marsgis.cn/terrain',
    // });
        // viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
        //   url: 'https://data.marsgis.cn/terrain',
        // });
    // viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
    //   url: Cesium.IonResource.fromAssetId(1),
    //   requestWaterMask: false,
    //   requestVertexNormals: true,
    // })
        // viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
        //   url: Cesium.IonResource.fromAssetId(1),
        //   requestWaterMask: false,
        //   requestVertexNormals: true,
        // })
    window.$viewer = viewer;
    loadLAYER();
  };
        window.$viewer = viewer
        loadLAYER()
    }
  const loadLAYER = () => {
    let mapLayers = [];
    const loadLAYER = () => {
        let mapLayers = []
    globalBaseMapLayers.length &&
      globalBaseMapLayers.forEach(item => {
        if (item.mapLayer) item.mapLayer.show = false;
      });
        globalBaseMapLayers.length &&
            globalBaseMapLayers.forEach(item => {
                if (item.mapLayer) item.mapLayer.show = false
            })
        // 高德影像地图数据图层
        if (store.state.common.mapSetting.mode === 3) {
            mapLayers.push(
                ...[
                    { key: 'imageryProvider_ammap', layer: imageryProvider_ammap },
                    { key: 'imageryProvider_ammapBz', layer: imageryProvider_ammapBz },
                ]
            )
        }
        // 高德地图矢量图层加载
        if (store.state.common.mapSetting.mode === 2) {
            mapLayers.push({
                key: 'imageryProvider_ammapSL',
                layer: imageryProvider_ammapSL,
            })
        }
    // 高德影像地图数据图层
    if (store.state.common.mapSetting.mode === 3) {
      mapLayers.push(
        ...[
          { key: 'imageryProvider_ammap', layer: imageryProvider_ammap },
          { key: 'imageryProvider_ammapBz', layer: imageryProvider_ammapBz },
        ]
      );
    }
    // 高德地图矢量图层加载
    if (store.state.common.mapSetting.mode === 2) {
      mapLayers.push({
        key: 'imageryProvider_ammapSL',
        layer: imageryProvider_ammapSL,
      });
    }
        // 标准地图加载
        if (store.state.common.mapSetting.mode === 0) {
            mapLayers.push(
                ...[
                    { key: 'imageryProvider_standZh', layer: imageryProvider_standZh },
                    { key: 'imageryProvider_stand', layer: imageryProvider_stand },
                ]
            )
        }
    // 标准地图加载
    if (store.state.common.mapSetting.mode === 0) {
      mapLayers.push(
        ...[
          { key: 'imageryProvider_standZh', layer: imageryProvider_standZh },
          { key: 'imageryProvider_stand', layer: imageryProvider_stand },
        ]
      );
    }
        // 路线图加载
        if (
            store.state.common.mapSetting.roadLine === true &&
            store.state.common.mapSetting.mode === 1
        ) {
            mapLayers.push({ key: 'annotation', layer: annotation })
        }
    // 路线图加载
    if (
      store.state.common.mapSetting.roadLine === true &&
      store.state.common.mapSetting.mode === 1
    ) {
      mapLayers.push({ key: 'annotation', layer: annotation });
    }
        // 天地图图层加载
        if (store.state.common.mapSetting.mode === 1) {
            mapLayers.push({
                key: 'imageryProvider_tdt',
                layer: imageryProvider_tdt,
            })
        }
    // 天地图图层加载
    if (store.state.common.mapSetting.mode === 1) {
      mapLayers.push({
        key: 'imageryProvider_tdt',
        layer: imageryProvider_tdt,
      });
    }
        // 创建一个Set来快速查找array2中的id
        let keyBaseMap = new Set(globalBaseMapLayers.map(item => item.key))
        let keyMapLayers = new Set(mapLayers.map(item => item.key))
    // 创建一个Set来快速查找array2中的id
    let keyBaseMap = new Set(globalBaseMapLayers.map(item => item.key));
    let keyMapLayers = new Set(mapLayers.map(item => item.key));
        let keyExistBaseMap = mapLayers.filter(item => !keyBaseMap.has(item.key))
    let keyExistBaseMap = mapLayers.filter(item => !keyBaseMap.has(item.key));
        let keyNoExistBaseMap = globalBaseMapLayers.filter(item => keyMapLayers.has(item.key))
    let keyNoExistBaseMap = globalBaseMapLayers.filter(item => keyMapLayers.has(item.key));
        keyExistBaseMap.length &&
            keyExistBaseMap.forEach(item => {
                let curLayer = {
                    key: item.key,
                    mapLayer: viewer?.imageryLayers.addImageryProvider(item.layer),
                }
    keyExistBaseMap.length &&
      keyExistBaseMap.forEach(item => {
        let curLayer = {
          key: item.key,
          mapLayer: viewer?.imageryLayers.addImageryProvider(item.layer),
        };
                if (curLayer.mapLayer) curLayer.mapLayer.show = true
        if (curLayer.mapLayer) curLayer.mapLayer.show = true;
                viewer?.imageryLayers.lowerToBottom(curLayer.mapLayer)
        viewer?.imageryLayers.lowerToBottom(curLayer.mapLayer);
                globalBaseMapLayers.push(curLayer)
            })
        globalBaseMapLayers.push(curLayer);
      });
        keyNoExistBaseMap.length &&
            keyNoExistBaseMap.forEach(item => {
                if (item.mapLayer) item.mapLayer.show = true
    keyNoExistBaseMap.length &&
      keyNoExistBaseMap.forEach(item => {
        if (item.mapLayer) item.mapLayer.show = true;
                viewer?.imageryLayers.lowerToBottom(item.mapLayer)
            })
        // 2D/3D切换
        switchModel(store.state.common.mapSetting.visual)
    }
        viewer?.imageryLayers.lowerToBottom(item.mapLayer);
      });
    // 2D/3D切换
    switchModel(store.state.common.mapSetting.visual);
  };
    const addCustomLayers = (layerName, options) => {
        if (options.type == 'arcgis') {
            var imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
                url: options.src,
                layer: options.title,
                style: 'default',
                format: 'image/png',
                tileMatrixSetID: 'default',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                tileMatrixLabels: [
                    '0',
                    '1',
                    '2',
                    '3',
                    '4',
                    '5',
                    '6',
                    '7',
                    '8',
                    '9',
                    '10',
                    '11',
                    '12',
                    '13',
                    '14',
                    '15',
                    '16',
                    '17',
                    '18',
                    '19',
                ],
            })
  const addCustomLayers = (layerName, options) => {
    if (options.type == 'arcgis') {
      var imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
        url: options.src,
        layer: options.title,
        style: 'default',
        format: 'image/png',
        tileMatrixSetID: 'default',
        tilingScheme: new Cesium.GeographicTilingScheme(),
        tileMatrixLabels: [
          '0',
          '1',
          '2',
          '3',
          '4',
          '5',
          '6',
          '7',
          '8',
          '9',
          '10',
          '11',
          '12',
          '13',
          '14',
          '15',
          '16',
          '17',
          '18',
          '19',
        ],
      });
            customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(imageryProvider)
      customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(imageryProvider);
            // const layerProvider = new Cesium.ArcGisMapServerImageryProvider({
            //   url: options.src,
            //   tilingScheme: new Cesium.GeographicTilingScheme()
            // })
            // customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(layerProvider)
        }
    }
      // const layerProvider = new Cesium.ArcGisMapServerImageryProvider({
      //   url: options.src,
      //   tilingScheme: new Cesium.GeographicTilingScheme()
      // })
      // customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(layerProvider)
    }
  };
    const removeCustomLayers = (layerName = '') => {
        if (layerName) {
            if (customMapLayer[layerName]) {
                viewer?.imageryLayers.remove(customMapLayer[layerName])
  const removeCustomLayers = (layerName = '') => {
    if (layerName) {
      if (customMapLayer[layerName]) {
        viewer?.imageryLayers.remove(customMapLayer[layerName]);
                delete customMapLayer[layerName]
            }
        } else {
            for (let k in customMapLayer) {
                viewer?.imageryLayers.remove(customMapLayer[k])
            }
        delete customMapLayer[layerName];
      }
    } else {
      for (let k in customMapLayer) {
        viewer?.imageryLayers.remove(customMapLayer[k]);
      }
            customMapLayer = {}
        }
    }
      customMapLayer = {};
    }
  };
    // 切换不同背景图层
    const patternMap = () => {
        const imageryLayers = viewer?.scene.imageryLayers
        // 切换为标准图层
        if (store.state.common.mapSetting.mode === 0) {
            const tdtImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtImg_c')
            const tdtZwImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtZwImg_c')
            viewer?.imageryLayers.remove(tdtImg_c)
            viewer?.imageryLayers.remove(tdtZwImg_c)
        } else {
            const tdtStand_c = imageryLayers?._layers.find(
                v => v.imageryProvider.credit?.html === 'stand_tc'
            )
            const tdtStand_zj = imageryLayers?._layers.find(
                v => v.imageryProvider.credit?.html === 'stand_zj'
            )
            viewer?.imageryLayers.remove(tdtStand_c)
            viewer?.imageryLayers.remove(tdtStand_zj)
        }
        loadLAYER()
    }
  // 切换不同背景图层
  const patternMap = () => {
    const imageryLayers = viewer?.scene.imageryLayers;
    // 切换为标准图层
    if (store.state.common.mapSetting.mode === 0) {
      const tdtImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtImg_c');
      const tdtZwImg_c = imageryLayers?._layers.find(
        v => v.imageryProvider._layer === 'tdtZwImg_c'
      );
      viewer?.imageryLayers.remove(tdtImg_c);
      viewer?.imageryLayers.remove(tdtZwImg_c);
    } else {
      const tdtStand_c = imageryLayers?._layers.find(
        v => v.imageryProvider.credit?.html === 'stand_tc'
      );
      const tdtStand_zj = imageryLayers?._layers.find(
        v => v.imageryProvider.credit?.html === 'stand_zj'
      );
      viewer?.imageryLayers.remove(tdtStand_c);
      viewer?.imageryLayers.remove(tdtStand_zj);
    }
    loadLAYER();
  };
    // 生成或删除路网图层
    const roadPattern = flag => {
        if (store.state.common.mapSetting.mode === 0) return
        const imageryLayers = viewer?.scene.imageryLayers
        const tdtZwImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtZwImg_c')
        if (!flag) {
            viewer?.imageryLayers.remove(tdtZwImg_c)
        } else {
            viewer?.imageryLayers.addImageryProvider(annotation)
        }
    }
  // 生成或删除路网图层
  const roadPattern = flag => {
    if (store.state.common.mapSetting.mode === 0) return;
    const imageryLayers = viewer?.scene.imageryLayers;
    const tdtZwImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtZwImg_c');
    if (!flag) {
      viewer?.imageryLayers.remove(tdtZwImg_c);
    } else {
      viewer?.imageryLayers.addImageryProvider(annotation);
    }
  };
    // 二维三维切换
    // 切换为二三维模式
    const switchModel = type => {
        switch (type) {
            case '2D':
                viewer?.scene.morphTo2D(0)
                // viewer?.scene.camera.setView({
                //   orientation: {
                //     pitch: Cesium.Math.toRadians(-60),
                //     heading: Cesium.Math.toRadians(0),
                //   },
                // });
                break
            case '3D':
                viewer?.scene.morphTo3D(0)
                // viewer?.scene.camera.setView({
                //   orientation: {
                //     pitch: Cesium.Math.toRadians(-90),
                //     heading: Cesium.Math.toRadians(0),
                //   },
                // });
                break
            default:
                break
        }
    }
  // 二维三维切换
  // 切换为二三维模式
  const switchModel = type => {
    switch (type) {
      case '2D':
        viewer?.scene.morphTo2D(0);
        // viewer?.scene.camera.setView({
        //   orientation: {
        //     pitch: Cesium.Math.toRadians(-60),
        //     heading: Cesium.Math.toRadians(0),
        //   },
        // });
        break;
      case '3D':
        viewer?.scene.morphTo3D(0);
        // viewer?.scene.camera.setView({
        //   orientation: {
        //     pitch: Cesium.Math.toRadians(-90),
        //     heading: Cesium.Math.toRadians(0),
        //   },
        // });
        break;
      default:
        break;
    }
  };
    /**
     * @description: 地图暗黑模式切换
     * @param {*} viewer 地图实例
     * @param {*} options 配置项
     * @return {*}
     */
    const darkMap = (viewer, isDark = false, options) => {
        const defaultOptions = {
            brightness: 1,
            contrast: 1,
            gamma: 1,
            hue: 0,
            saturation: 1,
        }
  /**
   * @description: 地图暗黑模式切换
   * @param {*} viewer 地图实例
   * @param {*} options 配置项
   * @return {*}
   */
  const darkMap = (viewer, isDark = false, options) => {
    const defaultOptions = {
      brightness: 1,
      contrast: 1,
      gamma: 1,
      hue: 0,
      saturation: 1,
    };
        !isDark && Object.assign(options, defaultOptions)
    !isDark && Object.assign(options, defaultOptions);
        const baseLayer = viewer.imageryLayers.get(0)
        baseLayer.brightness = options.brightness || 0
        baseLayer.contrast = options.contrast || 0
        baseLayer.gamma = options.gamma || 2
        baseLayer.hue = options.hue || 0
        baseLayer.saturation = options.saturation || 0
    const baseLayer = viewer.imageryLayers.get(0);
    baseLayer.brightness = options.brightness || 0;
    baseLayer.contrast = options.contrast || 0;
    baseLayer.gamma = options.gamma || 2;
    baseLayer.hue = options.hue || 0;
    baseLayer.saturation = options.saturation || 0;
    const baseFragShader = viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources;
    for (let i = 0; i < baseFragShader.length; i++) {
      const strS = 'color = czm_saturation(color, textureSaturation);\n#endif\n';
      let strT = 'color = czm_saturation(color, textureSaturation);\n#endif\n';
      if (options.invertColor) {
        strT += `
        const baseFragShader = viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources
        for (let i = 0; i < baseFragShader.length; i++) {
            const strS = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
            let strT = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
            if (options.invertColor) {
                strT += `
        color.r = 1.0 - color.r;
        color.g = 1.0 - color.g;
        color.b = 1.0 - color.b;
        `;
      }
      if (options.filterRGB.length > 0) {
        strT += `
        `
            }
            if (options.filterRGB.length > 0) {
                strT += `
        color.r = color.r * ${options.filterRGB[0]}.0/255.0;
        color.g = color.g * ${options.filterRGB[1]}.0/255.0;
        color.b = color.b * ${options.filterRGB[2]}.0/255.0;
        `;
      }
      if (!isDark) {
        //恢复默认
        baseFragShader[i] = baseFragShader[i].replace(strT, strS);
      } else {
        // 替换为暗黑模式
        baseFragShader[i] = baseFragShader[i].replace(strS, strT);
      }
    }
  };
        `
            }
            if (!isDark) {
                //恢复默认
                baseFragShader[i] = baseFragShader[i].replace(strT, strS)
            } else {
                // 替换为暗黑模式
                baseFragShader[i] = baseFragShader[i].replace(strS, strT)
            }
        }
    }
  const switchDarkModel = () => {
    const isDark = store.state.common.mapSetting.isDark;
    darkMap(viewer, isDark, {
      //反色
      invertColor: true,
      //滤色值  [176, 224, 230]
      filterRGB: [60, 145, 172],
    });
  };
    const switchDarkModel = () => {
        const isDark = store.state.common.mapSetting.isDark
        darkMap(viewer, isDark, {
            //反色
            invertColor: true,
            //滤色值  [176, 224, 230]
            filterRGB: [60, 145, 172],
        })
    }
  //移除DataSource中所有实体
  const removeAllDataSource = () => {
    viewer?.dataSources.removeAll();
  };
    //移除DataSource中所有实体
    const removeAllDataSource = () => {
        viewer?.dataSources.removeAll()
    }
  // 清除所有标记点
  const removeAllPoint = () => {
    if (viewer) {
      viewer?.entities?.removeAll();
      // viewer?.scene?.primitives?.removeAll();
    }
  };
    // 清除所有标记点
    const removeAllPoint = () => {
        if (viewer) {
            viewer?.entities?.removeAll()
            // viewer?.scene?.primitives?.removeAll();
        }
    }
  // 通过点ID删除
  const removeById = id => {
    viewer?.entities.removeById(id);
    const pointEntity = viewer?.entities.getById(id);
    if (pointEntity && pointEntity !== undefined) {
      viewer?.entities.remove(pointEntity);
    }
  };
    // 通过点ID删除
    const removeById = id => {
        viewer?.entities.removeById(id)
        const pointEntity = viewer?.entities.getById(id)
        if (pointEntity && pointEntity !== undefined) {
            viewer?.entities.remove(pointEntity)
        }
    }
  // 通过点ID获取实体
  const getEntityById = id => {
    const pointEntity = viewer?.entities.getById(id);
    return pointEntity;
  };
    // 通过点ID获取实体
    const getEntityById = id => {
        const pointEntity = viewer?.entities.getById(id)
        return pointEntity
    }
  // 添加标记点
  const addPoint = pointOption => {
    if (!pointOption.longitude && !pointOption.latitude) return;
    const position = Cesium.Cartesian3.fromDegrees(
      pointOption.longitude,
      pointOption.latitude,
      pointOption?.altitude || 0
    );
    viewer?.entities.add({
      position,
      billboard: pointOption.billboard,
      point: pointOption.point,
      label: pointOption.label,
      id: pointOption.id,
    });
  };
    // 添加标记点
    const addPoint = pointOption => {
        if (!pointOption.longitude && !pointOption.latitude) return
        const position = Cesium.Cartesian3.fromDegrees(
            pointOption.longitude,
            pointOption.latitude,
            pointOption?.altitude || 0
        )
        viewer?.entities.add({
            position,
            billboard: pointOption.billboard,
            point: pointOption.point,
            label: pointOption.label,
            id: pointOption.id,
        })
    }
  const addPolyline = pointOption => {
    return viewer?.entities.add({
      polyline: pointOption.polyline,
      id: pointOption.id,
    });
  };
    const addPolyline = pointOption => {
        return viewer?.entities.add({
            polyline: pointOption.polyline,
            id: pointOption.id,
        })
    }
  // 更新图片实体位置
  function updateEntityPosition(longitude, latitude, id, params) {
    const entity = getEntityById(id);
    const position = Cesium.Cartesian3.fromDegrees(longitude, latitude);
    const heading = Cesium.Math.toRadians(-params.heading);
    if (Cesium.defined(entity)) {
      entity.position = position;
      entity.billboard.rotation = heading;
    }
  }
    // 更新图片实体位置
    function updateEntityPosition(longitude, latitude, id, params) {
        const entity = getEntityById(id)
        const position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
        const heading = Cesium.Math.toRadians(-params.heading)
        if (Cesium.defined(entity)) {
            entity.position = position
            entity.billboard.rotation = heading
        }
    }
  // 飞行 flyto
  const flyTo = (pointOption, time = 4, height = 3000, orientation = {}) => {
    if (!pointOption.longitude && !pointOption.latitude) return;
    const destination = Cesium.Cartesian3.fromDegrees(
      pointOption.longitude,
      pointOption.latitude,
      height
    );
    const duration = time;
    viewer?.camera.flyTo({
      destination,
      duration,
      orientation,
    });
  };
    // 飞行 flyto
    const flyTo = (pointOption, time = 4, height = 3000, orientation = {}) => {
        if (!pointOption.longitude && !pointOption.latitude) return
        const destination = Cesium.Cartesian3.fromDegrees(
            pointOption.longitude,
            pointOption.latitude,
            height
        )
        const duration = time
        viewer?.camera.flyTo({
            destination,
            duration,
            orientation,
        })
    }
  // 鼠标点击事件
  const addLeftClickEvent = (sid, cb, eventKey = 'handler') => {
    if (handlerEvents.handler) removeLeftClickEvent();
    if (handlerEvents[eventKey]) removeLeftClickEvent(eventKey);
    // 鼠标点击事件
    const addLeftClickEvent = (sid, cb, eventKey = 'handler') => {
        if (handlerEvents.handler) removeLeftClickEvent()
        if (handlerEvents[eventKey]) removeLeftClickEvent(eventKey)
    handlerEvents[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas);
    handlerEvents[eventKey].setInputAction(function (click) {
      const pick = viewer?.scene.pick(click.position);
        handlerEvents[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
        handlerEvents[eventKey].setInputAction(function (click) {
            const pick = viewer?.scene.pick(click.position)
      if (pick && pick.primitive && pick.primitive?.customParams?.type == '3DTileset') {
        return cb(click, pick, viewer, handlerEvents[eventKey]);
      }
            if (pick && pick.primitive && pick.primitive?.customParams?.type == '3DTileset') {
                return cb(click, pick, viewer, handlerEvents[eventKey])
            }
      if (pick && pick.id && (pick.id._id === sid || pick.id._id.includes(sid))) {
        cb(click, pick, viewer, handlerEvents[eventKey]);
      }
            if (pick && pick.id && (pick.id._id === sid || pick.id._id.includes(sid))) {
                cb(click, pick, viewer, handlerEvents[eventKey])
            }
      if (sid === null) {
        cb(click, pick, viewer, handlerEvents[eventKey]);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  };
            if (sid === null) {
                cb(click, pick, viewer, handlerEvents[eventKey])
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    }
  // 移除鼠标点击事件
  const removeLeftClickEvent = (eventKey = 'handler') => {
    if (handlerEvents[eventKey] == null) return;
    handlerEvents[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    // 移除鼠标点击事件
    const removeLeftClickEvent = (eventKey = 'handler') => {
        if (handlerEvents[eventKey] == null) return
        handlerEvents[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    handlerEvents[eventKey] = null;
  };
        handlerEvents[eventKey] = null
    }
  // 鼠标左键按下事件
  let leftDownClickHandler = { handler: null };
  const addLeftDownClickEvent = (sid, cb, eventKey = 'handler') => {
    if (leftDownClickHandler.handler) removeLeftDownClickEvent();
    if (leftDownClickHandler[eventKey]) removeLeftDownClickEvent(eventKey);
    // 鼠标左键按下事件
    let leftDownClickHandler = { handler: null }
    const addLeftDownClickEvent = (sid, cb, eventKey = 'handler') => {
        if (leftDownClickHandler.handler) removeLeftDownClickEvent()
        if (leftDownClickHandler[eventKey]) removeLeftDownClickEvent(eventKey)
    leftDownClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas);
        leftDownClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
    leftDownClickHandler[eventKey].setInputAction(function (click) {
      const pick = viewer?.scene.pick(click.position);
      cb(click, pick, viewer);
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
  };
        leftDownClickHandler[eventKey].setInputAction(function (click) {
            const pick = viewer?.scene.pick(click.position)
            cb(click, pick, viewer)
        }, Cesium.ScreenSpaceEventType.LEFT_DOWN)
    }
  // 移除鼠标左键按下事件
  const removeLeftDownClickEvent = (eventKey = 'handler') => {
    if (leftDownClickHandler[eventKey] == null) return;
    leftDownClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
    // 移除鼠标左键按下事件
    const removeLeftDownClickEvent = (eventKey = 'handler') => {
        if (leftDownClickHandler[eventKey] == null) return
        leftDownClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN)
    leftDownClickHandler[eventKey] = null;
  };
        leftDownClickHandler[eventKey] = null
    }
  // 鼠标右击事件
  let leftUpClickHandler = { handler: null };
  const addLeftUpClickEvent = (sid, cb, eventKey = 'handler') => {
    if (leftUpClickHandler.handler) removeLeftUpClickEvent();
    if (leftUpClickHandler[eventKey]) removeLeftUpClickEvent(eventKey);
    // 鼠标右击事件
    let leftUpClickHandler = { handler: null }
    const addLeftUpClickEvent = (sid, cb, eventKey = 'handler') => {
        if (leftUpClickHandler.handler) removeLeftUpClickEvent()
        if (leftUpClickHandler[eventKey]) removeLeftUpClickEvent(eventKey)
    leftUpClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas);
        leftUpClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
    leftUpClickHandler[eventKey].setInputAction(function (click) {
      const pick = viewer?.scene.pick(click.position);
      cb(click, pick, viewer);
    }, Cesium.ScreenSpaceEventType.LEFT_UP);
  };
        leftUpClickHandler[eventKey].setInputAction(function (click) {
            const pick = viewer?.scene.pick(click.position)
            cb(click, pick, viewer)
        }, Cesium.ScreenSpaceEventType.LEFT_UP)
    }
  // 移除鼠标右键事件
  const removeLeftUpClickEvent = (eventKey = 'handler') => {
    if (leftUpClickHandler[eventKey] == null) return;
    leftUpClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
    // 移除鼠标右键事件
    const removeLeftUpClickEvent = (eventKey = 'handler') => {
        if (leftUpClickHandler[eventKey] == null) return
        leftUpClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP)
    leftUpClickHandler[eventKey] = null;
  };
        leftUpClickHandler[eventKey] = null
    }
  // 鼠标右击事件
  let rightClickHandler;
  const addRightClickEvent = (sid, cb) => {
    if (rightClickHandler) removeRightClickEvent();
    // 鼠标右击事件
    let rightClickHandler
    const addRightClickEvent = (sid, cb) => {
        if (rightClickHandler) removeRightClickEvent()
    rightClickHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas);
        rightClickHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
    rightClickHandler.setInputAction(function (click) {
      const pick = viewer?.scene.pick(click.position);
      cb(click, pick, viewer);
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  };
        rightClickHandler.setInputAction(function (click) {
            const pick = viewer?.scene.pick(click.position)
            cb(click, pick, viewer)
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
  // 移除鼠标右键事件
  const removeRightClickEvent = () => {
    if (!rightClickHandler) return;
    rightClickHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    // 移除鼠标右键事件
    const removeRightClickEvent = () => {
        if (!rightClickHandler) return
        rightClickHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    rightClickHandler = null;
  };
        rightClickHandler = null
    }
  // 鼠标移动事件
  let LeftMounseHandler;
  const addLeftmounseEvent = (sid, cb) => {
    if (LeftMounseHandler) removeLeftmounseEvent();
    LeftMounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas);
    LeftMounseHandler.setInputAction(function (event) {
      const cartesian3 = viewer?.scene.globe.pick(
        viewer?.camera.getPickRay(event.startPosition),
        viewer?.scene
      );
      cb(cartesian3, viewer);
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  };
    // 鼠标移动事件
    let LeftMounseHandler
    const addLeftmounseEvent = (sid, cb) => {
        if (LeftMounseHandler) removeLeftmounseEvent()
        LeftMounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
        LeftMounseHandler.setInputAction(function (event) {
            const cartesian3 = viewer?.scene.globe.pick(
                viewer?.camera.getPickRay(event.startPosition),
                viewer?.scene
            )
            cb(cartesian3, viewer)
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    }
  // 移除鼠标移动事件
  const removeLeftmounseEvent = () => {
    if (LeftMounseHandler == null) return;
    LeftMounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    // 移除鼠标移动事件
    const removeLeftmounseEvent = () => {
        if (LeftMounseHandler == null) return
        LeftMounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    LeftMounseHandler = null;
  };
        LeftMounseHandler = null
    }
  let MounseHandler;
  const addMounseHandler = (sid, cb) => {
    if (MounseHandler == null) removeMounseEvent();
    let MounseHandler
    const addMounseHandler = (sid, cb) => {
        if (MounseHandler == null) removeMounseEvent()
    MounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas);
        MounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
    MounseHandler.setInputAction(function (movement) {
      let mouseInfo = _getMouseInfo(movement.endPosition);
        MounseHandler.setInputAction(function (movement) {
            let mouseInfo = _getMouseInfo(movement.endPosition)
      cb(mouseInfo, viewer);
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  };
            cb(mouseInfo, viewer)
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    }
  const _getMouseInfo = position => {
    let scene = viewer.scene;
    let target = scene.pick(position);
    let cartesian = undefined;
    let surfaceCartesian = undefined;
    let wgs84Position = undefined;
    let wgs84SurfacePosition = undefined;
    if (scene.pickPositionSupported) {
      cartesian = scene.pickPosition(position);
    }
    if (cartesian) {
      let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian);
      if (c) {
        wgs84Position = {
          lng: Cesium.Math.toDegrees(c.longitude),
          lat: Cesium.Math.toDegrees(c.latitude),
          alt: c.height,
        };
      }
    }
    if (
      scene.mode === Cesium.SceneMode.SCENE3D &&
      !(viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider)
    ) {
      let ray = scene.camera.getPickRay(position);
      surfaceCartesian = scene.globe.pick(ray, scene);
    } else {
      surfaceCartesian = scene.camera.pickEllipsoid(position, Cesium.Ellipsoid.WGS84);
    }
    if (surfaceCartesian) {
      let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(surfaceCartesian);
      if (c) {
        wgs84SurfacePosition = {
          lng: Cesium.Math.toDegrees(c.longitude),
          lat: Cesium.Math.toDegrees(c.latitude),
          alt: c.height,
        };
      }
    }
    const _getMouseInfo = position => {
        let scene = viewer.scene
        let target = scene.pick(position)
        let cartesian = undefined
        let surfaceCartesian = undefined
        let wgs84Position = undefined
        let wgs84SurfacePosition = undefined
        if (scene.pickPositionSupported) {
            cartesian = scene.pickPosition(position)
        }
        if (cartesian) {
            let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
            if (c) {
                wgs84Position = {
                    lng: Cesium.Math.toDegrees(c.longitude),
                    lat: Cesium.Math.toDegrees(c.latitude),
                    alt: c.height,
                }
            }
        }
        if (
            scene.mode === Cesium.SceneMode.SCENE3D &&
            !(viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider)
        ) {
            let ray = scene.camera.getPickRay(position)
            surfaceCartesian = scene.globe.pick(ray, scene)
        } else {
            surfaceCartesian = scene.camera.pickEllipsoid(position, Cesium.Ellipsoid.WGS84)
        }
        if (surfaceCartesian) {
            let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(surfaceCartesian)
            if (c) {
                wgs84SurfacePosition = {
                    lng: Cesium.Math.toDegrees(c.longitude),
                    lat: Cesium.Math.toDegrees(c.latitude),
                    alt: c.height,
                }
            }
        }
    return {
      target: target,
      windowPosition: position,
      position: cartesian,
      wgs84Position: wgs84Position,
      surfacePosition: surfaceCartesian,
      wgs84SurfacePosition: wgs84SurfacePosition,
    };
  };
        return {
            target: target,
            windowPosition: position,
            position: cartesian,
            wgs84Position: wgs84Position,
            surfacePosition: surfaceCartesian,
            wgs84SurfacePosition: wgs84SurfacePosition,
        }
    }
  // 移除鼠标移动事件
  const removeMounseEvent = () => {
    if (MounseHandler == null) return;
    MounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    // 移除鼠标移动事件
    const removeMounseEvent = () => {
        if (MounseHandler == null) return
        MounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    MounseHandler = null;
  };
        MounseHandler = null
    }
  // 视角变化时间
  let mapViewHandler = null;
  const addCameraMoveEvent = cb => {
    if (mapViewHandler) removeCameraMoveEvent();
    // 视角变化时间
    let mapViewHandler = null
    const addCameraMoveEvent = cb => {
        if (mapViewHandler) removeCameraMoveEvent()
    mapViewHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    mapViewHandler.setInputAction(event => {
      cb(event);
    }, Cesium.ScreenSpaceEventType.WHEEL);
  };
        mapViewHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
        mapViewHandler.setInputAction(event => {
            cb(event)
        }, Cesium.ScreenSpaceEventType.WHEEL)
    }
  const removeCameraMoveEvent = () => {
    if (mapViewHandler == null) return;
    mapViewHandler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL);
    mapViewHandler = null;
  };
    const removeCameraMoveEvent = () => {
        if (mapViewHandler == null) return
        mapViewHandler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL)
        mapViewHandler = null
    }
  // 添加entity
  const addCustomEntityDataSource = (sourceName, entities) => {
    if (!customEntityDataSources[sourceName]) {
      customEntityDataSources[sourceName] = new Cesium.CustomDataSource();
      window.$viewer?.dataSources.add(customEntityDataSources[sourceName]);
    }
    // 添加entity
    const addCustomEntityDataSource = (sourceName, entities) => {
        if (!customEntityDataSources[sourceName]) {
            customEntityDataSources[sourceName] = new Cesium.CustomDataSource()
            window.$viewer?.dataSources.add(customEntityDataSources[sourceName])
        }
    let entity = customEntityDataSources[sourceName].entities.add(entities);
        let entity = customEntityDataSources[sourceName].entities.add(entities)
    return entity;
  };
        return entity
    }
  const clearCustomEntityDataSource = sourceName => {
    if (customEntityDataSources[sourceName]) {
      customEntityDataSources[sourceName]?.entities.removeAll();
    }
  };
    const clearCustomEntityDataSource = sourceName => {
        if (customEntityDataSources[sourceName]) {
            customEntityDataSources[sourceName]?.entities.removeAll()
        }
    }
  const removeAllCustomEntityDataSource = sourceName => {
    if (customEntityDataSources[sourceName]) {
      customEntityDataSources[sourceName]?.entities.removeAll();
      window.$viewer.dataSources.remove(customEntityDataSources[sourceName]);
      delete customEntityDataSources[sourceName];
    }
  };
    const removeAllCustomEntityDataSource = sourceName => {
        if (customEntityDataSources[sourceName]) {
            customEntityDataSources[sourceName]?.entities.removeAll()
            window.$viewer.dataSources.remove(customEntityDataSources[sourceName])
            delete customEntityDataSources[sourceName]
        }
    }
  // 添加entity
  const addCustomImageryProviderDataSource = imageryLayers => {
    return viewer?.imageryLayers.addImageryProvider(imageryLayers);
  };
    // 添加entity
    const addCustomImageryProviderDataSource = imageryLayers => {
        return viewer?.imageryLayers.addImageryProvider(imageryLayers)
    }
  const showCustomImageryProviderDataSource = (imageryLayers, show) => {
    if (imageryLayers) {
      imageryLayers.show = show;
    }
  };
    const showCustomImageryProviderDataSource = (imageryLayers, show) => {
        if (imageryLayers) {
            imageryLayers.show = show
        }
    }
  const removeAllCustomImageryProviderDataSource = imageryLayers => {
    if (imageryLayers) {
      viewer?.imageryLayers.remove(imageryLayers);
    }
  };
    const removeAllCustomImageryProviderDataSource = imageryLayers => {
        if (imageryLayers) {
            viewer?.imageryLayers.remove(imageryLayers)
        }
    }
  // 添加范围的圆
  const addEllipse = ({ longitude, latitude, dist = 7000 }) => {
    if (!longitude && !latitude) return;
    // 定义起点位置
    const position = Cesium.Cartesian3.fromDegrees(longitude, latitude);
    // 画圆
    // 添加范围的圆
    const addEllipse = ({ longitude, latitude, dist = 7000 }) => {
        if (!longitude && !latitude) return
        // 定义起点位置
        const position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
        // 画圆
    viewer?.entities.add({
      position,
      id: 'rangeEllipse',
      name: 'rangeEllipse',
      ellipse: {
        semiMinorAxis: dist,
        semiMajorAxis: dist,
        outline: true,
        material: Cesium.Color.CORNFLOWERBLUE.withAlpha(0.3),
      },
    });
    // 添加距离虚线
    // addDistLine({ longitude, latitude, dist });
  };
        viewer?.entities.add({
            position,
            id: 'rangeEllipse',
            name: 'rangeEllipse',
            ellipse: {
                semiMinorAxis: dist,
                semiMajorAxis: dist,
                outline: true,
                material: Cesium.Color.CORNFLOWERBLUE.withAlpha(0.3),
            },
        })
        // 添加距离虚线
        // addDistLine({ longitude, latitude, dist });
    }
  const addDistLine = ({ longitude, latitude, dist = 7 }) => {
    // 定义起点位置
    const startPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude);
    // 计算目标位置(7公里处)
    const offsetCartesian = Cesium.Cartesian3.fromDegrees(
      longitude,
      latitude +
        Cesium.Math.toDegrees(
          dist / (Cesium.Ellipsoid.WGS84.maximumRadius * Math.cos(Cesium.Math.toRadians(latitude)))
        ) // 7公里的偏移
    );
    // 将目标位置转换为经纬度
    // const offsetCartographic = Cesium.Cartographic.fromCartesian(offsetCartesian);
    // const offsetLongitude = Cesium.Math.toDegrees(offsetCartographic.longitude);
    // const offsetLatitude = Cesium.Math.toDegrees(offsetCartographic.latitude);
    addPolyline({
      id: 'dist_line',
      polyline: {
        width: 5,
        positions: [startPosition, offsetCartesian],
        material: new Cesium.PolylineGlowMaterialProperty({
          glowPower: 0.2,
          taperPower: 0.5,
          color: Cesium.Color.CORNFLOWERBLUE,
        }),
      },
    });
  };
    const addDistLine = ({ longitude, latitude, dist = 7 }) => {
        // 定义起点位置
        const startPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude)
        // 计算目标位置(7公里处)
        const offsetCartesian = Cesium.Cartesian3.fromDegrees(
            longitude,
            latitude +
                Cesium.Math.toDegrees(
                    dist / (Cesium.Ellipsoid.WGS84.maximumRadius * Math.cos(Cesium.Math.toRadians(latitude)))
                ) // 7公里的偏移
        )
        // 将目标位置转换为经纬度
        // const offsetCartographic = Cesium.Cartographic.fromCartesian(offsetCartesian);
        // const offsetLongitude = Cesium.Math.toDegrees(offsetCartographic.longitude);
        // const offsetLatitude = Cesium.Math.toDegrees(offsetCartographic.latitude);
        addPolyline({
            id: 'dist_line',
            polyline: {
                width: 5,
                positions: [startPosition, offsetCartesian],
                material: new Cesium.PolylineGlowMaterialProperty({
                    glowPower: 0.2,
                    taperPower: 0.5,
                    color: Cesium.Color.CORNFLOWERBLUE,
                }),
            },
        })
    }
  // 添加圆
  const addCircle = option => {
    if (!option.longitude && !option.latitude) return;
    // 定义起点位置
    const { longitude, latitude } = option;
    const position = Cesium.Cartesian3.fromDegrees(longitude, latitude);
    viewer.entities.add({
      position,
      id: option.id,
      ellipse: {
        semiMinorAxis: option.radius,
        semiMajorAxis: option.radius,
        height: option.height || 120,
        material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1),
        outline: true,
        outlineColor: Cesium.Color.fromCssColorString(option.color),
        outlineWidth: 3,
      },
    });
  };
    // 添加圆
    const addCircle = option => {
        if (!option.longitude && !option.latitude) return
        // 定义起点位置
        const { longitude, latitude } = option
        const position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
        viewer.entities.add({
            position,
            id: option.id,
            ellipse: {
                semiMinorAxis: option.radius,
                semiMajorAxis: option.radius,
                height: option.height || 120,
                material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1),
                outline: true,
                outlineColor: Cesium.Color.fromCssColorString(option.color),
                outlineWidth: 3,
            },
        })
    }
  //
  /**
   * @description: 添加矩形
   * @param {*} option { id: string, color: string, positions: array[ lng,lat,height ] }
   * @return {*} void 0
   */
  const addPolygon = option => {
    if (option.positions.length === 0) return;
    //
    /**
     * @description: 添加矩形
     * @param {*} option { id: string, color: string, positions: array[ lng,lat,height ] }
     * @return {*} void 0
     */
    const addPolygon = option => {
        if (option.positions.length === 0) return
    let zIndex = {};
        let zIndex = {}
    if (option.zIndex) {
      zIndex = {
        zIndex: option.zIndex,
      };
    }
        if (option.zIndex) {
            zIndex = {
                zIndex: option.zIndex,
            }
        }
    // 定义起点位置
    viewer.entities.add({
      id: option.id,
      polygon: {
        hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(option.positions),
        material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1),
        extrudedHeight: 0,
        outline: true,
        outlineColor: Cesium.Color.fromCssColorString(option.color),
        outlineWidth: 3,
      },
      ...zIndex,
    });
  };
        // 定义起点位置
        viewer.entities.add({
            id: option.id,
            polygon: {
                hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(option.positions),
                material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1),
                extrudedHeight: 0,
                outline: true,
                outlineColor: Cesium.Color.fromCssColorString(option.color),
                outlineWidth: 3,
            },
            ...zIndex,
        })
    }
  // Cesium矢量切片是否加载完成
  const isLoadingCompleted = () => {
    return new Promise((resolve, reject) => {
      const helper = new Cesium.EventHelper();
      helper.add(viewer?.scene.globe.tileLoadProgressEvent, function (e) {
        if (e === 0) {
          resolve(true);
        }
      });
    });
  };
    // Cesium矢量切片是否加载完成
    const isLoadingCompleted = () => {
        return new Promise((resolve, reject) => {
            const helper = new Cesium.EventHelper()
            helper.add(viewer?.scene.globe.tileLoadProgressEvent, function (e) {
                if (e === 0) {
                    resolve(true)
                }
            })
        })
    }
  // 获取屏幕四个角经纬度
  const getScreenCorner = () => {
    const camera = viewer.scene.camera;
    const canvas = viewer.canvas;
    // 获取屏幕四个角经纬度
    const getScreenCorner = () => {
        const camera = viewer.scene.camera
        const canvas = viewer.canvas
    // 获取屏幕左下角和右上角的世界坐标
    const leftBottom = new Cesium.Cartesian2(0, canvas.clientHeight);
    const rightTop = new Cesium.Cartesian2(canvas.clientWidth, 0);
        // 获取屏幕左下角和右上角的世界坐标
        const leftBottom = new Cesium.Cartesian2(0, canvas.clientHeight)
        const rightTop = new Cesium.Cartesian2(canvas.clientWidth, 0)
    // 将屏幕坐标转为世界坐标
    const leftBottomWorld = camera.pickEllipsoid(leftBottom, viewer.scene.globe.ellipsoid);
    const rightTopWorld = camera.pickEllipsoid(rightTop, viewer.scene.globe.ellipsoid);
        // 将屏幕坐标转为世界坐标
        const leftBottomWorld = camera.pickEllipsoid(leftBottom, viewer.scene.globe.ellipsoid)
        const rightTopWorld = camera.pickEllipsoid(rightTop, viewer.scene.globe.ellipsoid)
    // 将世界坐标转为经纬度
    const leftBottomCartographic =
      viewer.scene.globe.ellipsoid.cartesianToCartographic(leftBottomWorld);
    const rightTopCartographic =
      viewer.scene.globe.ellipsoid.cartesianToCartographic(rightTopWorld);
        // 将世界坐标转为经纬度
        const leftBottomCartographic =
            viewer.scene.globe.ellipsoid.cartesianToCartographic(leftBottomWorld)
        const rightTopCartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(rightTopWorld)
    // 获取经纬度
    const leftBottomLonLat = [
      Cesium.Math.toDegrees(leftBottomCartographic.longitude),
      Cesium.Math.toDegrees(leftBottomCartographic.latitude),
    ];
    const rightTopLonLat = [
      Cesium.Math.toDegrees(rightTopCartographic.longitude),
      Cesium.Math.toDegrees(rightTopCartographic.latitude),
    ];
        // 获取经纬度
        const leftBottomLonLat = [
            Cesium.Math.toDegrees(leftBottomCartographic.longitude),
            Cesium.Math.toDegrees(leftBottomCartographic.latitude),
        ]
        const rightTopLonLat = [
            Cesium.Math.toDegrees(rightTopCartographic.longitude),
            Cesium.Math.toDegrees(rightTopCartographic.latitude),
        ]
    // 返回四个角的经纬度
    return {
      lb: leftBottomLonLat,
      rb: [rightTopLonLat[0], leftBottomLonLat[1]], // 右下角
      rt: rightTopLonLat,
      lt: [leftBottomLonLat[0], rightTopLonLat[1]], // 左上角
    };
  };
        // 返回四个角的经纬度
        return {
            lb: leftBottomLonLat,
            rb: [rightTopLonLat[0], leftBottomLonLat[1]], // 右下角
            rt: rightTopLonLat,
            lt: [leftBottomLonLat[0], rightTopLonLat[1]], // 左上角
        }
    }
  // 加载3D建筑模型
  let tileset = null;
    // 加载3D建筑模型
    let tileset = null
  function setBuilding3dModel() {
    try {
      const resource = Cesium.IonResource.fromAssetId(96188);
      tileset = new Cesium.Cesium3DTileset({
        url: resource,
      });
    function setBuilding3dModel() {
        try {
            const resource = Cesium.IonResource.fromAssetId(96188)
            tileset = new Cesium.Cesium3DTileset({
                url: resource,
            })
      tileset.customParams = {
        type: '3DTileset',
      };
            tileset.customParams = {
                type: '3DTileset',
            }
      viewer.scene.primitives.add(tileset);
    } catch (error) {
      console.log(`Error loading tileset: ${error}`);
    }
  }
            viewer.scene.primitives.add(tileset)
        } catch (error) {
            console.log(`Error loading tileset: ${error}`)
        }
    }
  function removeBuilding3dModel() {
    if (tileset) {
      viewer.scene.primitives.remove(tileset);
    }
  }
    function removeBuilding3dModel() {
        if (tileset) {
            viewer.scene.primitives.remove(tileset)
        }
    }
  const viewerDestory = () => {
    viewer && viewer.destroy();
    viewer = null;
    window.$viewer = null
  };
    const viewerDestory = () => {
        viewer && viewer.destroy()
        viewer = null
        window.$viewer = null
    }
  let tilesetArr = [];
    let tilesetArr = []
  const add3Dtileset = () => {
    let url = '/3Dtile/kjds/tileset.json';
    const add3Dtileset = () => {
        let url = '/3Dtile/kjds/tileset.json'
    let tileset = new Cesium.Cesium3DTileset({
      url: url,
    });
        let tileset = new Cesium.Cesium3DTileset({
            url: url,
        })
    tileset.customParams = {
      type: '3DTileset',
    };
        tileset.customParams = {
            type: '3DTileset',
        }
    tilesetArr.push(tileset);
        tilesetArr.push(tileset)
    tilesetArr.forEach(i => viewer?.scene.primitives.add(i));
  };
        tilesetArr.forEach(i => viewer?.scene.primitives.add(i))
    }
  const remove3Dtileset = () => {
    if (tilesetArr.length > 0) {
      tilesetArr.forEach(i => viewer.scene.primitives.remove(i));
    }
    const remove3Dtileset = () => {
        if (tilesetArr.length > 0) {
            tilesetArr.forEach(i => viewer.scene.primitives.remove(i))
        }
    tilesetArr = [];
  };
        tilesetArr = []
    }
  let pointEditHandler;
  // 航点航线编辑相关事件
  const pointInitEvent = (lefet_down, mouse_move, left_up) => {
    if (!pointEditHandler) {
      pointEditHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas);
    }
    let pointEditHandler
    // 航点航线编辑相关事件
    const pointInitEvent = (lefet_down, mouse_move, left_up) => {
        if (!pointEditHandler) {
            pointEditHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
        }
    const events = {
      lefet_down,
      mouse_move,
      left_up,
    };
        const events = {
            lefet_down,
            mouse_move,
            left_up,
        }
    pointEditBindEvent(events);
    pointEditBindEvent(events, Cesium.KeyboardEventModifier.CTRL);
    pointEditBindEvent(events, Cesium.KeyboardEventModifier.ALT);
    pointEditBindEvent(events, Cesium.KeyboardEventModifier.SHIFT);
    pointEditBindEvent(events, Cesium.KeyboardEventModifier.META);
  };
        pointEditBindEvent(events)
        pointEditBindEvent(events, Cesium.KeyboardEventModifier.CTRL)
        pointEditBindEvent(events, Cesium.KeyboardEventModifier.ALT)
        pointEditBindEvent(events, Cesium.KeyboardEventModifier.SHIFT)
        pointEditBindEvent(events, Cesium.KeyboardEventModifier.META)
    }
  const pointEditBindEvent = (events, e) => {
    if (pointEditHandler) {
      pointEditHandler.setInputAction(
        events.lefet_down(e),
        Cesium.ScreenSpaceEventType.LEFT_DOWN,
        e
      );
      pointEditHandler.setInputAction(
        events.mouse_move(e),
        Cesium.ScreenSpaceEventType.MOUSE_MOVE,
        e
      );
      pointEditHandler.setInputAction(events.left_up(e), Cesium.ScreenSpaceEventType.LEFT_UP, e);
    }
  };
    const pointEditBindEvent = (events, e) => {
        if (pointEditHandler) {
            pointEditHandler.setInputAction(
                events.lefet_down(e),
                Cesium.ScreenSpaceEventType.LEFT_DOWN,
                e
            )
            pointEditHandler.setInputAction(
                events.mouse_move(e),
                Cesium.ScreenSpaceEventType.MOUSE_MOVE,
                e
            )
            pointEditHandler.setInputAction(events.left_up(e), Cesium.ScreenSpaceEventType.LEFT_UP, e)
        }
    }
  const pointUnInitEvent = () => {
    pointEditUnBindEvent();
    pointEditUnBindEvent(Cesium.KeyboardEventModifier.CTRL);
    pointEditUnBindEvent(Cesium.KeyboardEventModifier.ALT);
    pointEditUnBindEvent(Cesium.KeyboardEventModifier.SHIFT);
    pointEditUnBindEvent(Cesium.KeyboardEventModifier.META);
    const pointUnInitEvent = () => {
        pointEditUnBindEvent()
        pointEditUnBindEvent(Cesium.KeyboardEventModifier.CTRL)
        pointEditUnBindEvent(Cesium.KeyboardEventModifier.ALT)
        pointEditUnBindEvent(Cesium.KeyboardEventModifier.SHIFT)
        pointEditUnBindEvent(Cesium.KeyboardEventModifier.META)
    pointEditHandler = null;
  };
        pointEditHandler = null
    }
  const pointEditUnBindEvent = e => {
    pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN, e);
    pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE, e);
    pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP, e);
  };
    const pointEditUnBindEvent = e => {
        pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN, e)
        pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE, e)
        pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP, e)
    }
  return {
    _init,
    patternMap,
    loadLAYER,
    roadPattern,
    switchModel,
    switchDarkModel,
    removeAllDataSource,
    removeAllPoint,
    removeById,
    getEntityById,
    addPoint,
    addPolyline,
    updateEntityPosition,
    flyTo,
    addLeftClickEvent,
    removeLeftClickEvent,
    addRightClickEvent,
    removeRightClickEvent,
    addLeftmounseEvent,
    removeLeftmounseEvent,
    return {
        _init,
        patternMap,
        loadLAYER,
        roadPattern,
        switchModel,
        switchDarkModel,
        removeAllDataSource,
        removeAllPoint,
        removeById,
        getEntityById,
        addPoint,
        addPolyline,
        updateEntityPosition,
        flyTo,
        addLeftClickEvent,
        removeLeftClickEvent,
        addRightClickEvent,
        removeRightClickEvent,
        addLeftmounseEvent,
        removeLeftmounseEvent,
    addLeftUpClickEvent,
    removeLeftUpClickEvent,
        addLeftUpClickEvent,
        removeLeftUpClickEvent,
    addLeftDownClickEvent,
    removeLeftDownClickEvent,
        addLeftDownClickEvent,
        removeLeftDownClickEvent,
    addMounseHandler,
    removeMounseEvent,
        addMounseHandler,
        removeMounseEvent,
    addCameraMoveEvent,
    removeCameraMoveEvent,
    addCircle,
    addPolygon,
    addEllipse,
    isLoadingCompleted,
    getScreenCorner,
    setBuilding3dModel,
    removeBuilding3dModel,
        addCameraMoveEvent,
        removeCameraMoveEvent,
        addCircle,
        addPolygon,
        addEllipse,
        isLoadingCompleted,
        getScreenCorner,
        setBuilding3dModel,
        removeBuilding3dModel,
    viewerDestory,
        viewerDestory,
    globalCesium: window.globalCesium || Cesium,
        globalCesium: window.globalCesium || Cesium,
    addCustomEntityDataSource,
    clearCustomEntityDataSource,
    removeAllCustomEntityDataSource,
    _getMouseInfo,
        addCustomEntityDataSource,
        clearCustomEntityDataSource,
        removeAllCustomEntityDataSource,
        _getMouseInfo,
    addCustomImageryProviderDataSource,
    showCustomImageryProviderDataSource,
    removeAllCustomImageryProviderDataSource,
        addCustomImageryProviderDataSource,
        showCustomImageryProviderDataSource,
        removeAllCustomImageryProviderDataSource,
    addCustomLayers,
    removeCustomLayers,
    add3Dtileset,
    remove3Dtileset,
        addCustomLayers,
        removeCustomLayers,
        add3Dtileset,
        remove3Dtileset,
    // 航线规划---航点航线
    pointInitEvent,
    pointUnInitEvent,
  };
        // 航线规划---航点航线
        pointInitEvent,
        pointUnInitEvent,
    }
}
src/utils/cesium/AmapMercatorTilingScheme/CoordTransform.js
@@ -1,178 +1,148 @@
// 定义一些常量
const BD_FACTOR = (3.14159265358979324 * 3000.0) / 180.0;
const PI = 3.1415926535897932384626;
const RADIUS = 6378245.0;
const EE = 0.00669342162296594323;
const BD_FACTOR = (3.14159265358979324 * 3000.0) / 180.0
const PI = 3.1415926535897932384626
const RADIUS = 6378245.0
const EE = 0.00669342162296594323
class CoordTransform {
    /**
     * BD-09(百度坐标系) To GCJ-02(火星坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     */
    static BD09ToGCJ02(lng, lat) {
        let x = +lng - 0.0065;
        let y = +lat - 0.006;
        let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR);
        let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_FACTOR);
        let gg_lng = z * Math.cos(theta);
        let gg_lat = z * Math.sin(theta);
        return [gg_lng, gg_lat];
    }
    /**
     * BD-09(百度坐标系) To GCJ-02(火星坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     */
    static BD09ToGCJ02(lng, lat) {
        let x = +lng - 0.0065
        let y = +lat - 0.006
        let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR)
        let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_FACTOR)
        let gg_lng = z * Math.cos(theta)
        let gg_lat = z * Math.sin(theta)
        return [gg_lng, gg_lat]
    }
    /**
     * GCJ-02(火星坐标系) To BD-09(百度坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     * @constructor
     */
    static GCJ02ToBD09(lng, lat) {
        lat = +lat;
        lng = +lng;
        let z =
            Math.sqrt(lng * lng + lat * lat) +
            0.00002 * Math.sin(lat * BD_FACTOR);
        let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_FACTOR);
        let bd_lng = z * Math.cos(theta) + 0.0065;
        let bd_lat = z * Math.sin(theta) + 0.006;
        return [bd_lng, bd_lat];
    }
    /**
     * GCJ-02(火星坐标系) To BD-09(百度坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     * @constructor
     */
    static GCJ02ToBD09(lng, lat) {
        lat = +lat
        lng = +lng
        let z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * BD_FACTOR)
        let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_FACTOR)
        let bd_lng = z * Math.cos(theta) + 0.0065
        let bd_lat = z * Math.sin(theta) + 0.006
        return [bd_lng, bd_lat]
    }
    /**
     * WGS-84(世界大地坐标系) To GCJ-02(火星坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     */
    static WGS84ToGCJ02(lng, lat) {
        lat = +lat;
        lng = +lng;
        if (this.out_of_china(lng, lat)) {
            return [lng, lat];
        } else {
            let d = this.delta(lng, lat);
            return [lng + d[0], lat + d[1]];
        }
    }
    /**
     * WGS-84(世界大地坐标系) To GCJ-02(火星坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     */
    static WGS84ToGCJ02(lng, lat) {
        lat = +lat
        lng = +lng
        if (this.out_of_china(lng, lat)) {
            return [lng, lat]
        } else {
            let d = this.delta(lng, lat)
            return [lng + d[0], lat + d[1]]
        }
    }
    /**
     * GCJ-02(火星坐标系) To WGS-84(世界大地坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     * @constructor
     */
    static GCJ02ToWGS84(lng, lat) {
        lat = +lat;
        lng = +lng;
        if (this.out_of_china(lng, lat)) {
            return [lng, lat];
        } else {
            let d = this.delta(lng, lat);
            let mgLng = lng + d[0];
            let mgLat = lat + d[1];
            return [lng * 2 - mgLng, lat * 2 - mgLat];
        }
    }
    /**
     * GCJ-02(火星坐标系) To WGS-84(世界大地坐标系)
     * @param lng
     * @param lat
     * @returns {number[]}
     * @constructor
     */
    static GCJ02ToWGS84(lng, lat) {
        lat = +lat
        lng = +lng
        if (this.out_of_china(lng, lat)) {
            return [lng, lat]
        } else {
            let d = this.delta(lng, lat)
            let mgLng = lng + d[0]
            let mgLat = lat + d[1]
            return [lng * 2 - mgLng, lat * 2 - mgLat]
        }
    }
    /**
     *
     * @param lng
     * @param lat
     * @returns {number[]}
     */
    static delta(lng, lat) {
        let dLng = this.transformLng(lng - 105, lat - 35);
        let dLat = this.transformLat(lng - 105, lat - 35);
        const radLat = (lat / 180) * PI;
        let magic = Math.sin(radLat);
        magic = 1 - EE * magic * magic;
        const sqrtMagic = Math.sqrt(magic);
        dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI);
        dLat =
            (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI);
        return [dLng, dLat];
    }
    /**
     *
     * @param lng
     * @param lat
     * @returns {number[]}
     */
    static delta(lng, lat) {
        let dLng = this.transformLng(lng - 105, lat - 35)
        let dLat = this.transformLat(lng - 105, lat - 35)
        const radLat = (lat / 180) * PI
        let magic = Math.sin(radLat)
        magic = 1 - EE * magic * magic
        const sqrtMagic = Math.sqrt(magic)
        dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI)
        dLat = (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI)
        return [dLng, dLat]
    }
    /**
     *
     * @param lng
     * @param lat
     * @returns {number}
     */
    static transformLng(lng, lat) {
        lat = +lat;
        lng = +lng;
        let ret =
            300.0 +
            lng +
            2.0 * lat +
            0.1 * lng * lng +
            0.1 * lng * lat +
            0.1 * Math.sqrt(Math.abs(lng));
        ret +=
            ((20.0 * Math.sin(6.0 * lng * PI) +
                20.0 * Math.sin(2.0 * lng * PI)) *
                2.0) /
            3.0;
        ret +=
            ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) *
                2.0) /
            3.0;
        ret +=
            ((150.0 * Math.sin((lng / 12.0) * PI) +
                300.0 * Math.sin((lng / 30.0) * PI)) *
                2.0) /
            3.0;
        return ret;
    }
    /**
     *
     * @param lng
     * @param lat
     * @returns {number}
     */
    static transformLng(lng, lat) {
        lat = +lat
        lng = +lng
        let ret =
            300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
        ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0
        ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0
        return ret
    }
    /**
     *
     * @param lng
     * @param lat
     * @returns {number}
     */
    static transformLat(lng, lat) {
        lat = +lat;
        lng = +lng;
        let ret =
            -100.0 +
            2.0 * lng +
            3.0 * lat +
            0.2 * lat * lat +
            0.1 * lng * lat +
            0.2 * Math.sqrt(Math.abs(lng));
        ret +=
            ((20.0 * Math.sin(6.0 * lng * PI) +
                20.0 * Math.sin(2.0 * lng * PI)) *
                2.0) /
            3.0;
        ret +=
            ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) *
                2.0) /
            3.0;
        ret +=
            ((160.0 * Math.sin((lat / 12.0) * PI) +
                320 * Math.sin((lat * PI) / 30.0)) *
                2.0) /
            3.0;
        return ret;
    }
    /**
     *
     * @param lng
     * @param lat
     * @returns {number}
     */
    static transformLat(lng, lat) {
        lat = +lat
        lng = +lng
        let ret =
            -100.0 +
            2.0 * lng +
            3.0 * lat +
            0.2 * lat * lat +
            0.1 * lng * lat +
            0.2 * Math.sqrt(Math.abs(lng))
        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
        ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0
        ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0
        return ret
    }
    /**
     * 判断是否在国内。不在国内不做偏移
     * @param lng
     * @param lat
     * @returns {boolean}
     */
    static out_of_china(lng, lat) {
        lat = +lat;
        lng = +lng;
        return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
    }
    /**
     * 判断是否在国内。不在国内不做偏移
     * @param lng
     * @param lat
     * @returns {boolean}
     */
    static out_of_china(lng, lat) {
        lat = +lat
        lng = +lng
        return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)
    }
}
export default CoordTransform;
export default CoordTransform
src/utils/cesium/AmapMercatorTilingScheme/index.js
@@ -8,46 +8,40 @@
 * Copyright (c) 2024 by GuLiMmo, All Rights Reserved.
 */
import {
    WebMercatorProjection,
    WebMercatorTilingScheme,
    Math,
    Cartographic,
    Cartesian2,
} from 'cesium';
import CoordTransform from './CoordTransform';
    WebMercatorProjection,
    WebMercatorTilingScheme,
    Math,
    Cartographic,
    Cartesian2,
} from 'cesium'
import CoordTransform from './CoordTransform'
class AmapMercatorTilingScheme extends WebMercatorTilingScheme {
    constructor() {
        super();
    constructor() {
        super()
        let projection = new WebMercatorProjection();
        let projection = new WebMercatorProjection()
        this._projection.project = function (cartographic, result) {
            result = CoordTransform.WGS84ToGCJ02(
                Math.toDegrees(cartographic.longitude),
                Math.toDegrees(cartographic.latitude),
            );
            result = projection.project(
                new Cartographic(
                    Math.toRadians(result[0]),
                    Math.toRadians(result[1]),
                ),
            );
            return new Cartesian2(result.x, result.y);
        };
        this._projection.project = function (cartographic, result) {
            result = CoordTransform.WGS84ToGCJ02(
                Math.toDegrees(cartographic.longitude),
                Math.toDegrees(cartographic.latitude)
            )
            result = projection.project(
                new Cartographic(Math.toRadians(result[0]), Math.toRadians(result[1]))
            )
            return new Cartesian2(result.x, result.y)
        }
        this._projection.unproject = function (cartesian, result) {
            let cartographic = projection.unproject(cartesian);
            result = CoordTransform.GCJ02ToWGS84(
                Math.toDegrees(cartographic.longitude),
                Math.toDegrees(cartographic.latitude),
            );
            return new Cartographic(
                Math.toRadians(result[0]),
                Math.toRadians(result[1]),
            );
        };
    }
        this._projection.unproject = function (cartesian, result) {
            let cartographic = projection.unproject(cartesian)
            result = CoordTransform.GCJ02ToWGS84(
                Math.toDegrees(cartographic.longitude),
                Math.toDegrees(cartographic.latitude)
            )
            return new Cartographic(Math.toRadians(result[0]), Math.toRadians(result[1]))
        }
    }
}
export default AmapMercatorTilingScheme;
export default AmapMercatorTilingScheme
src/utils/cesium/ImageTrailMaterial.js
@@ -1,85 +1,80 @@
import * as Cesium from 'cesium';
import * as Cesium from 'cesium'
/**
 * 定义Cesium材质对象
 */
class ImageTrailMaterial {
    constructor(options = {}) {
        this._definitionChanged = new Cesium.Event();
        this._color = void 0;
        this._colorSubscription = void 0;
        this._speed = void 0;
        this._speedSubscription = void 0;
        this._image = void 0;
        this._imageSubscription = void 0;
        this._repeat = void 0;
        this._repeatSubscription = void 0;
        this.color = options.color || Cesium.Color.fromBytes(0, 0, 255, 255);
        this.speed = options.speed || 1;
        this.image = options.image;
        this.repeat = new Cesium.Cartesian2(
            options.repeat?.x || 1,
            options.repeat?.y || 1,
        );
    }
    constructor(options = {}) {
        this._definitionChanged = new Cesium.Event()
        this._color = void 0
        this._colorSubscription = void 0
        this._speed = void 0
        this._speedSubscription = void 0
        this._image = void 0
        this._imageSubscription = void 0
        this._repeat = void 0
        this._repeatSubscription = void 0
        this.color = options.color || Cesium.Color.fromBytes(0, 0, 255, 255)
        this.speed = options.speed || 1
        this.image = options.image
        this.repeat = new Cesium.Cartesian2(options.repeat?.x || 1, options.repeat?.y || 1)
    }
    get isConstant() {
        return false;
    }
    get isConstant() {
        return false
    }
    get definitionChanged() {
        return this._definitionChanged;
    }
    get definitionChanged() {
        return this._definitionChanged
    }
    getType() {
        return Cesium.Material.ImageTrailMaterialType;
    }
    getType() {
        return Cesium.Material.ImageTrailMaterialType
    }
    getValue(time, result) {
        if (!result) {
            result = {};
        }
        result.color = Cesium.Property.getValueOrUndefined(this._color, time);
        result.image = Cesium.Property.getValueOrUndefined(this._image, time);
        result.repeat = Cesium.Property.getValueOrUndefined(this._repeat, time);
        result.speed = this._speed;
        return result;
    }
    getValue(time, result) {
        if (!result) {
            result = {}
        }
        result.color = Cesium.Property.getValueOrUndefined(this._color, time)
        result.image = Cesium.Property.getValueOrUndefined(this._image, time)
        result.repeat = Cesium.Property.getValueOrUndefined(this._repeat, time)
        result.speed = this._speed
        return result
    }
    equals(other) {
        return (
            this === other ||
            (other instanceof ImageTrailMaterial &&
                Cesium.Property.equals(this._color, other._color) &&
                Cesium.Property.equals(this._image, other._image) &&
                Cesium.Property.equals(this._repeat, other._repeat) &&
                Cesium.Property.equals(this._speed, other._speed))
        );
    }
    equals(other) {
        return (
            this === other ||
            (other instanceof ImageTrailMaterial &&
                Cesium.Property.equals(this._color, other._color) &&
                Cesium.Property.equals(this._image, other._image) &&
                Cesium.Property.equals(this._repeat, other._repeat) &&
                Cesium.Property.equals(this._speed, other._speed))
        )
    }
}
Object.defineProperties(ImageTrailMaterial.prototype, {
    color: Cesium.createPropertyDescriptor('color'),
    speed: Cesium.createPropertyDescriptor('speed'),
    image: Cesium.createPropertyDescriptor('image'),
    repeat: Cesium.createPropertyDescriptor('repeat'),
});
    color: Cesium.createPropertyDescriptor('color'),
    speed: Cesium.createPropertyDescriptor('speed'),
    image: Cesium.createPropertyDescriptor('image'),
    repeat: Cesium.createPropertyDescriptor('repeat'),
})
//材质类型
Cesium.Material.ImageTrailMaterialType = 'PolylineImageTrail';
Cesium.Material.ImageTrailMaterialType = 'PolylineImageTrail'
//添加材质到缓冲区中
Cesium.Material._materialCache.addMaterial(
    Cesium.Material.ImageTrailMaterialType,
    {
        fabric: {
            type: Cesium.Material.ImageTrailMaterialType,
            //uniform变量
            uniforms: {
                color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
                image: Cesium.Material.DefaultImageId,
                speed: 1,
                repeat: new Cesium.Cartesian2(1, 1),
            },
            //
            source: `
Cesium.Material._materialCache.addMaterial(Cesium.Material.ImageTrailMaterialType, {
    fabric: {
        type: Cesium.Material.ImageTrailMaterialType,
        //uniform变量
        uniforms: {
            color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
            image: Cesium.Material.DefaultImageId,
            speed: 1,
            repeat: new Cesium.Cartesian2(1, 1),
        },
        //
        source: `
                    uniform sampler2D image; 
                    uniform float speed;
                    uniform vec4 color;
@@ -95,13 +90,12 @@
                        return material;
                    }
                    `,
        },
        translucent: function () {
            return true;
        },
    },
);
export default ImageTrailMaterial;
    },
    translucent: function () {
        return true
    },
})
export default ImageTrailMaterial
//之前的航线材质编写
// source: `
src/utils/cesium/common.js
@@ -6,189 +6,154 @@
 * @FilePath: /bigScreen/src/utils/cesium/common.js
 * @Description:
 */
import * as Cesium from 'cesium';
import JsZip from 'jszip';
import _ from 'lodash';
import axios from 'axios';
import { analyzeKmzFile, XMLToJSON } from './kmz';
import { getCenterPoint, getLnglatDist, getShortestDistance } from './mapUtil';
import * as Cesium from 'cesium'
import JsZip from 'jszip'
import _ from 'lodash'
import axios from 'axios'
import { analyzeKmzFile, XMLToJSON } from './kmz'
import { getCenterPoint, getLnglatDist, getShortestDistance } from './mapUtil'
// 图斑航线计算
export const polygonRoutePlanning = (polygonList, startPostion) => {
    // 起始点位
    const { longitude, latitude } = startPostion;
    // 计算中心点
    const polygonCenterArr = polygonList.map((polygon) => {
        const newPolygon = [
            ...new Set(polygon.map((lnglat) => lnglat.join(','))),
        ];
        return {
            center: getCenterPoint(polygon),
            polygon: newPolygon.map((item) => item.split(',')),
        };
    });
    // 机场到中心点的距离排序
    const airportDistanceArr = polygonCenterArr.sort((prev, next) => {
        const prevDistance = getLnglatDist(
            longitude,
            latitude,
            prev.center.lng,
            prev.center.lat,
        );
        const nextDistance = getLnglatDist(
            longitude,
            latitude,
            next.center.lng,
            next.center.lat,
        );
        return prevDistance - nextDistance;
    });
    // 起始点位
    const { longitude, latitude } = startPostion
    // 计算中心点
    const polygonCenterArr = polygonList.map(polygon => {
        const newPolygon = [...new Set(polygon.map(lnglat => lnglat.join(',')))]
        return {
            center: getCenterPoint(polygon),
            polygon: newPolygon.map(item => item.split(',')),
        }
    })
    // 机场到中心点的距离排序
    const airportDistanceArr = polygonCenterArr.sort((prev, next) => {
        const prevDistance = getLnglatDist(longitude, latitude, prev.center.lng, prev.center.lat)
        const nextDistance = getLnglatDist(longitude, latitude, next.center.lng, next.center.lat)
        return prevDistance - nextDistance
    })
    const sortPolygon = [];
    function getFirstPolygon(arr, start) {
        const { slongitude, slatitude } = start;
        // 机场到中心点的距离排序
        const airportDistanceArr = arr.sort((prev, next) => {
            const prevDistance = getLnglatDist(
                slongitude,
                slatitude,
                prev.center.lng,
                prev.center.lat,
            );
            const nextDistance = getLnglatDist(
                slongitude,
                slatitude,
                next.center.lng,
                next.center.lat,
            );
            return prevDistance - nextDistance;
        });
        const polygon = _.cloneDeep(airportDistanceArr[0]);
        if (polygon === void 0) return;
        sortPolygon.push(polygon);
        airportDistanceArr.splice(0, 1);
        if (airportDistanceArr.length > 0) {
            getFirstPolygon(airportDistanceArr, {
                slongitude: polygon.center.lng,
                slatitude: polygon.center.lat,
            });
        }
    }
    getFirstPolygon(polygonCenterArr, {
        slongitude: longitude,
        slatitude: latitude,
    });
    // 计算图斑内点位飞行顺序
    let result = [[longitude, latitude]];
    sortPolygon.forEach((item, index) => {
        const { polygon } = item;
        // 取出当前图斑之前最后一个点
        const prevPolygon = result[result.length - 1];
        const [slng, slat] = prevPolygon;
        const nextPolygon = airportDistanceArr[index + 1];
        // 求出距离上一个点最近的点,作为第一个点
        const sequence = polygon.sort((prev, next) => {
            const [prevLng, prevLat] = prev;
            const [nextLng, nextLat] = next;
            const prevDistance = getLnglatDist(slng, slat, prevLng, prevLat);
            const nextDistance = getLnglatDist(slng, slat, nextLng, nextLat);
            return prevDistance - nextDistance;
        });
        // 第一个点位
        const firstLnglat = [...sequence[0]];
        // 去除第一个点位
        const cloneSequence = _.cloneDeep(sequence);
        cloneSequence.splice(0, 1);
        if (nextPolygon) {
            // 获取两个经纬度组两个最近的点位
            const { index: lnglatIndex } = getShortestDistance(
                cloneSequence,
                nextPolygon.polygon,
            );
            const lastLnglat = _.cloneDeep(cloneSequence[lnglatIndex[0]]);
            // 删除飞行的最后一个点
            cloneSequence.splice(lnglatIndex[0], 1);
            const centerLnglatList = cloneSequence.sort((prev, next) => {
                const [prevLng, prevLat] = prev;
                const [nextLng, nextLat] = next;
                const prevDistance = getLnglatDist(
                    longitude,
                    latitude,
                    prevLng,
                    prevLat,
                );
                const nextDistance = getLnglatDist(
                    longitude,
                    latitude,
                    nextLng,
                    nextLat,
                );
                return prevDistance - nextDistance;
            });
            result = [...result, firstLnglat, ...centerLnglatList, lastLnglat];
        } else {
            // const last = polygon.sort((prev, next) => {
            //   const [prevLng, prevLat] = prev;
            //   const [nextLng, nextLat] = next;
            //   const prevDistance = getLnglatDist(longitude, latitude, prevLng, prevLat);
            //   const nextDistance = getLnglatDist(longitude, latitude, nextLng, nextLat);
            //   return prevDistance - nextDistance;
            // });
            result = [...result, ...sequence];
            // result = [...result, ...last]
        }
    });
    return result;
};
    const sortPolygon = []
    function getFirstPolygon(arr, start) {
        const { slongitude, slatitude } = start
        // 机场到中心点的距离排序
        const airportDistanceArr = arr.sort((prev, next) => {
            const prevDistance = getLnglatDist(slongitude, slatitude, prev.center.lng, prev.center.lat)
            const nextDistance = getLnglatDist(slongitude, slatitude, next.center.lng, next.center.lat)
            return prevDistance - nextDistance
        })
        const polygon = _.cloneDeep(airportDistanceArr[0])
        if (polygon === void 0) return
        sortPolygon.push(polygon)
        airportDistanceArr.splice(0, 1)
        if (airportDistanceArr.length > 0) {
            getFirstPolygon(airportDistanceArr, {
                slongitude: polygon.center.lng,
                slatitude: polygon.center.lat,
            })
        }
    }
    getFirstPolygon(polygonCenterArr, {
        slongitude: longitude,
        slatitude: latitude,
    })
    // 计算图斑内点位飞行顺序
    let result = [[longitude, latitude]]
    sortPolygon.forEach((item, index) => {
        const { polygon } = item
        // 取出当前图斑之前最后一个点
        const prevPolygon = result[result.length - 1]
        const [slng, slat] = prevPolygon
        const nextPolygon = airportDistanceArr[index + 1]
        // 求出距离上一个点最近的点,作为第一个点
        const sequence = polygon.sort((prev, next) => {
            const [prevLng, prevLat] = prev
            const [nextLng, nextLat] = next
            const prevDistance = getLnglatDist(slng, slat, prevLng, prevLat)
            const nextDistance = getLnglatDist(slng, slat, nextLng, nextLat)
            return prevDistance - nextDistance
        })
        // 第一个点位
        const firstLnglat = [...sequence[0]]
        // 去除第一个点位
        const cloneSequence = _.cloneDeep(sequence)
        cloneSequence.splice(0, 1)
        if (nextPolygon) {
            // 获取两个经纬度组两个最近的点位
            const { index: lnglatIndex } = getShortestDistance(cloneSequence, nextPolygon.polygon)
            const lastLnglat = _.cloneDeep(cloneSequence[lnglatIndex[0]])
            // 删除飞行的最后一个点
            cloneSequence.splice(lnglatIndex[0], 1)
            const centerLnglatList = cloneSequence.sort((prev, next) => {
                const [prevLng, prevLat] = prev
                const [nextLng, nextLat] = next
                const prevDistance = getLnglatDist(longitude, latitude, prevLng, prevLat)
                const nextDistance = getLnglatDist(longitude, latitude, nextLng, nextLat)
                return prevDistance - nextDistance
            })
            result = [...result, firstLnglat, ...centerLnglatList, lastLnglat]
        } else {
            // const last = polygon.sort((prev, next) => {
            //   const [prevLng, prevLat] = prev;
            //   const [nextLng, nextLat] = next;
            //   const prevDistance = getLnglatDist(longitude, latitude, prevLng, prevLat);
            //   const nextDistance = getLnglatDist(longitude, latitude, nextLng, nextLat);
            //   return prevDistance - nextDistance;
            // });
            result = [...result, ...sequence]
            // result = [...result, ...last]
        }
    })
    return result
}
export const getWaylineFilePoints = async (fileUrl) => {
    const fileRes = await analyzeKmzFile(fileUrl);
    const waylineContent = await fileRes['fileInfoObj']?.['wpmz/waylines.wpml'];
    const xml = XMLToJSON(waylineContent);
    const placemarkArr = xml?.Document?.Folder.Placemark;
    const points = placemarkArr.map((placemark) => {
        const lnglat = placemark.Point.coordinates?.['#text'].split(',');
        return {
            longitude: lnglat[0],
            latitude: lnglat[1],
        };
    });
    return points;
};
export const getWaylineFilePoints = async fileUrl => {
    const fileRes = await analyzeKmzFile(fileUrl)
    const waylineContent = await fileRes['fileInfoObj']?.['wpmz/waylines.wpml']
    const xml = XMLToJSON(waylineContent)
    const placemarkArr = xml?.Document?.Folder.Placemark
    const points = placemarkArr.map(placemark => {
        const lnglat = placemark.Point.coordinates?.['#text'].split(',')
        return {
            longitude: lnglat[0],
            latitude: lnglat[1],
        }
    })
    return points
}
// 传入方向,计算移动点位经纬度
export function movePosition(lon, lat, heading, direction) {
    // 计算朝向角度的弧度值(Cesium 是基于地理坐标系,heading=0 指向正北)
    const headingRad = Cesium.Math.toRadians(heading);
    const moveStep = 0.00005; // 移动步长
    let newLon = lon;
    let newLat = lat;
    // 计算朝向角度的弧度值(Cesium 是基于地理坐标系,heading=0 指向正北)
    const headingRad = Cesium.Math.toRadians(heading)
    const moveStep = 0.00005 // 移动步长
    let newLon = lon
    let newLat = lat
    switch (direction) {
        case "W": // 向前(heading 方向)
            newLon += moveStep * Math.sin(headingRad);
            newLat += moveStep * Math.cos(headingRad);
            break;
    switch (direction) {
        case 'W': // 向前(heading 方向)
            newLon += moveStep * Math.sin(headingRad)
            newLat += moveStep * Math.cos(headingRad)
            break
        case "S": // 向后(反方向)
            newLon -= moveStep * Math.sin(headingRad);
            newLat -= moveStep * Math.cos(headingRad);
            break;
        case 'S': // 向后(反方向)
            newLon -= moveStep * Math.sin(headingRad)
            newLat -= moveStep * Math.cos(headingRad)
            break
        case "D": // 向右(heading + 90°)
            newLon += moveStep * Math.cos(headingRad);
            newLat -= moveStep * Math.sin(headingRad);
            break;
        case 'D': // 向右(heading + 90°)
            newLon += moveStep * Math.cos(headingRad)
            newLat -= moveStep * Math.sin(headingRad)
            break
        case "A": // 向左(heading - 90°)
            newLon -= moveStep * Math.cos(headingRad);
            newLat += moveStep * Math.sin(headingRad);
            break;
        case 'A': // 向左(heading - 90°)
            newLon -= moveStep * Math.cos(headingRad)
            newLat += moveStep * Math.sin(headingRad)
            break
        default:
            console.warn("无效方向");
            return null;
    }
        default:
            console.warn('无效方向')
            return null
    }
    return { longitude: newLon, latitude: newLat };
    return { longitude: newLon, latitude: newLat }
}
src/utils/cesium/compressImage.js
@@ -7,49 +7,49 @@
 * @return {*}
 */
function compressImage(src, quality, maxWidth, callback) {
    const img = new Image();
    img.setAttribute('crossOrigin', 'Anonymous');
    img.onload = function () {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        let width = img.width;
        let height = img.height;
    const img = new Image()
    img.setAttribute('crossOrigin', 'Anonymous')
    img.onload = function () {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        let width = img.width
        let height = img.height
        if (width > maxWidth) {
            height *= maxWidth / width;
            width = maxWidth;
        }
        if (width > maxWidth) {
            height *= maxWidth / width
            width = maxWidth
        }
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(img, 0, 0, width, height);
        canvas.width = width
        canvas.height = height
        ctx.drawImage(img, 0, 0, width, height)
        const newData = canvas.toDataURL('image/jpeg', quality);
        // 使用atob()将base64转换为二进制字符串
        const binaryString = window.atob(newData.split(',')[1]);
        const mimeString = newData.split(',')[0].split(':')[1].split(';')[0];
        // 创建Blob对象
        const array = [];
        for (let i = 0; i < binaryString.length; i++) {
            array.push(binaryString.charCodeAt(i));
        }
        const blob = new Blob([new Uint8Array(array)], { type: mimeString });
        const newData = canvas.toDataURL('image/jpeg', quality)
        // 使用atob()将base64转换为二进制字符串
        const binaryString = window.atob(newData.split(',')[1])
        const mimeString = newData.split(',')[0].split(':')[1].split(';')[0]
        // 创建Blob对象
        const array = []
        for (let i = 0; i < binaryString.length; i++) {
            array.push(binaryString.charCodeAt(i))
        }
        const blob = new Blob([new Uint8Array(array)], { type: mimeString })
        callback(blob);
    };
    img.src = src;
        callback(blob)
    }
    img.src = src
    return src;
    return src
}
export default function imageCompress(src, quality, maxWidth) {
    // 使用例子
    return compressImage(src, quality, maxWidth, function (blob) {
        // 创建一个新的图片URL
        const imageUrl = URL.createObjectURL(blob);
        // 可以在这里使用imageUrl,比如设置为img元素的src
        // document.getElementById('your-image-element').src = imageUrl;
        // 当不需要这个URL的时候,释放它
        URL.revokeObjectURL(imageUrl);
    });
    // 使用例子
    return compressImage(src, quality, maxWidth, function (blob) {
        // 创建一个新的图片URL
        const imageUrl = URL.createObjectURL(blob)
        // 可以在这里使用imageUrl,比如设置为img元素的src
        // document.getElementById('your-image-element').src = imageUrl;
        // 当不需要这个URL的时候,释放它
        URL.revokeObjectURL(imageUrl)
    })
}
src/utils/cesium/compressImage2.js
@@ -8,39 +8,39 @@
 * Copyright (c) 2024 by GuLiMmo, All Rights Reserved.
 */
export default function compressImage(
    src,
    maxWidth,
    maxHeight,
    outputFormat = 'image/jpeg',
    quality = 0.7,
    src,
    maxWidth,
    maxHeight,
    outputFormat = 'image/jpeg',
    quality = 0.7
) {
    return new Promise((resolve, reject) => {
        const image = new Image();
        image.setAttribute('crossOrigin', 'Anonymous');
        image.src = src;
        image.onload = () => {
            let width = image.width;
            let height = image.height;
    return new Promise((resolve, reject) => {
        const image = new Image()
        image.setAttribute('crossOrigin', 'Anonymous')
        image.src = src
        image.onload = () => {
            let width = image.width
            let height = image.height
            if (width > maxWidth) {
                height *= maxWidth / width;
                width = maxWidth;
            }
            if (width > maxWidth) {
                height *= maxWidth / width
                width = maxWidth
            }
            if (height > maxHeight) {
                width *= maxHeight / height;
                height = maxHeight;
            }
            if (height > maxHeight) {
                width *= maxHeight / height
                height = maxHeight
            }
            const canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(image, 0, 0, width, height);
            const canvas = document.createElement('canvas')
            canvas.width = width
            canvas.height = height
            const ctx = canvas.getContext('2d')
            ctx.drawImage(image, 0, 0, width, height)
            const newDataUrl = canvas.toDataURL(outputFormat, quality);
            resolve(newDataUrl);
        };
        image.onerror = reject;
    });
            const newDataUrl = canvas.toDataURL(outputFormat, quality)
            resolve(newDataUrl)
        }
        image.onerror = reject
    })
}
src/utils/cesium/frustum/CreateFrustum.js
@@ -1,275 +1,255 @@
// * 创建视锥
import * as Cesium from 'cesium';
import * as Cesium from 'cesium'
/* eslint-disable new-cap */
/* eslint-disable no-undef */
export default class CreateFrustum {
  constructor(viewer, options) {
    this.position = options.position;
    this.viewer = viewer;
    this.fov = options.fov || 0;
    this.near = options.near || 0;
    this.far = options.far || 0;
    this.heading = options.heading || 0;
    this.pitch = options.pitch || 0;
    this.roll = options.roll || 0;
    this.width = options.width;
    this.height = options.height;
    this.add();
  }
    constructor(viewer, options) {
        this.position = options.position
        this.viewer = viewer
        this.fov = options.fov || 0
        this.near = options.near || 0
        this.far = options.far || 0
        this.heading = options.heading || 0
        this.pitch = options.pitch || 0
        this.roll = options.roll || 0
        this.width = options.width
        this.height = options.height
        this.add()
    }
  UpdateWidth(value) {
    this.width = value;
    this.add();
  }
  UpdateHeight(value) {
    this.height = value;
    this.add();
  }
  UpdateFov(value) {
    this.fov = value;
    this.add();
  }
  UpdateNear(value) {
    this.near = value;
    this.add();
  }
  UpdateFar(value) {
    this.far = value;
    this.add();
  }
  UpdateHeading(value) {
    this.heading = value;
    this.add();
  }
  UpdatePitch(value) {
    this.pitch = value;
    this.add();
  }
  UpdateRoll(value) {
    this.roll = value;
    this.add();
  }
  UpdataPosition(position) {
    if (!position) return;
    this.position = position;
    this.add();
  }
    UpdateWidth(value) {
        this.width = value
        this.add()
    }
    UpdateHeight(value) {
        this.height = value
        this.add()
    }
    UpdateFov(value) {
        this.fov = value
        this.add()
    }
    UpdateNear(value) {
        this.near = value
        this.add()
    }
    UpdateFar(value) {
        this.far = value
        this.add()
    }
    UpdateHeading(value) {
        this.heading = value
        this.add()
    }
    UpdatePitch(value) {
        this.pitch = value
        this.add()
    }
    UpdateRoll(value) {
        this.roll = value
        this.add()
    }
    UpdataPosition(position) {
        if (!position) return
        this.position = position
        this.add()
    }
  // 更新视锥体的姿态
  Update(position, headingPitchRoll) {
    this.position = Cesium.Cartesian3.fromDegrees(
      position.longitude,
      position.latitude,
      position.altitude,
    );
    this.orientation = Cesium.Transforms.headingPitchRollQuaternion(
      this.position,
      new Cesium.HeadingPitchRoll.fromDegrees(
        headingPitchRoll.heading,
        headingPitchRoll.pitch,
        headingPitchRoll.roll,
      ),
    );
    this.add();
  }
    // 更新视锥体的姿态
    Update(position, headingPitchRoll) {
        this.position = Cesium.Cartesian3.fromDegrees(
            position.longitude,
            position.latitude,
            position.altitude
        )
        this.orientation = Cesium.Transforms.headingPitchRollQuaternion(
            this.position,
            new Cesium.HeadingPitchRoll.fromDegrees(
                headingPitchRoll.heading,
                headingPitchRoll.pitch,
                headingPitchRoll.roll
            )
        )
        this.add()
    }
  // 创建视锥体和轮廓线
  add() {
    this.clear();
    this.addFrustum();
    this.addOutline();
    this.addCenterline();
  }
    // 创建视锥体和轮廓线
    add() {
        this.clear()
        this.addFrustum()
        this.addOutline()
        this.addCenterline()
    }
  // 清除视锥体和轮廓线
  clear() {
    this.clearFrustum();
    this.clearOutline();
    this.clearCenterline();
  }
    // 清除视锥体和轮廓线
    clear() {
        this.clearFrustum()
        this.clearOutline()
        this.clearCenterline()
    }
  // 清除视锥体
  clearFrustum() {
    if (this.frustumPrimitive) {
      this.viewer.scene.primitives.remove(this.frustumPrimitive);
      this.frustumPrimitive = null;
    }
  }
    // 清除视锥体
    clearFrustum() {
        if (this.frustumPrimitive) {
            this.viewer.scene.primitives.remove(this.frustumPrimitive)
            this.frustumPrimitive = null
        }
    }
  // 清除轮廓线
  clearOutline() {
    if (this.outlinePrimitive) {
      this.viewer.scene.primitives.remove(this.outlinePrimitive);
      this.outlinePrimitive = null;
    }
  }
    // 清除轮廓线
    clearOutline() {
        if (this.outlinePrimitive) {
            this.viewer.scene.primitives.remove(this.outlinePrimitive)
            this.outlinePrimitive = null
        }
    }
  clearCenterline() {
    if (this.centerDataSource) {
      this.centerDataSource.entities.removeAll();
      this.viewer.dataSources.remove(this.centerDataSource);
      this.centerDataSource = null;
    }
  }
    clearCenterline() {
        if (this.centerDataSource) {
            this.centerDataSource.entities.removeAll()
            this.viewer.dataSources.remove(this.centerDataSource)
            this.centerDataSource = null
        }
    }
  // 创建视锥体
  addFrustum() {
    const frustum = new Cesium.PerspectiveFrustum({
      // 查看的视场角,绕Z轴旋转,以弧度方式输入
      fov: Cesium.Math.toRadians(this.fov),
      // 视锥体的宽度/高度
      aspectRatio: this.width / this.height,
      // 近面距视点的距离
      near: this.near,
      // 远面距视点的距离
      far: this.far,
    });
    const position = Cesium.Cartesian3.fromDegrees(
      this.position.longitude,
      this.position.latitude,
      this.position.altitude,
    );
    const geometry = new Cesium.FrustumGeometry({
      frustum: frustum,
      origin: position,
      orientation: Cesium.Transforms.headingPitchRollQuaternion(
        position,
        new Cesium.HeadingPitchRoll.fromDegrees(
          this.heading,
          this.pitch,
          this.roll,
        ),
      ),
      vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
    });
    const instance = new Cesium.GeometryInstance({
      geometry: geometry,
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(
          Cesium.Color.fromBytes(0, 213, 144, 20),
        ),
      },
    });
    const primitive = new Cesium.Primitive({
      geometryInstances: instance,
      appearance: new Cesium.PerInstanceColorAppearance({
        closed: true,
        flat: true,
      }),
      asynchronous: false,
    });
    this.frustumPrimitive = this.viewer.scene.primitives.add(primitive);
  }
    // 创建视锥体
    addFrustum() {
        const frustum = new Cesium.PerspectiveFrustum({
            // 查看的视场角,绕Z轴旋转,以弧度方式输入
            fov: Cesium.Math.toRadians(this.fov),
            // 视锥体的宽度/高度
            aspectRatio: this.width / this.height,
            // 近面距视点的距离
            near: this.near,
            // 远面距视点的距离
            far: this.far,
        })
        const position = Cesium.Cartesian3.fromDegrees(
            this.position.longitude,
            this.position.latitude,
            this.position.altitude
        )
        const geometry = new Cesium.FrustumGeometry({
            frustum: frustum,
            origin: position,
            orientation: Cesium.Transforms.headingPitchRollQuaternion(
                position,
                new Cesium.HeadingPitchRoll.fromDegrees(this.heading, this.pitch, this.roll)
            ),
            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
        })
        const instance = new Cesium.GeometryInstance({
            geometry: geometry,
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    Cesium.Color.fromBytes(0, 213, 144, 20)
                ),
            },
        })
        const primitive = new Cesium.Primitive({
            geometryInstances: instance,
            appearance: new Cesium.PerInstanceColorAppearance({
                closed: true,
                flat: true,
            }),
            asynchronous: false,
        })
        this.frustumPrimitive = this.viewer.scene.primitives.add(primitive)
    }
  // 创建轮廓线
  addOutline() {
    const frustum = new Cesium.PerspectiveFrustum({
      // 查看的视场角度,绕Z轴旋转,以弧度方式输入
      // The angle of the field of view (FOV), in radians.
      // This angle will be used as the horizontal FOV if the width is greater than the height, otherwise it will be the vertical FOV.
      fov: Cesium.Math.toRadians(this.fov),
      // 视锥体的宽度/高度
      aspectRatio: this.width / this.height,
      // 近面距视点的距离
      near: this.near,
      // 远面距视点的距离
      far: this.far,
    });
    const position = Cesium.Cartesian3.fromDegrees(
      this.position.longitude,
      this.position.latitude,
      this.position.altitude,
    );
    const geometry = new Cesium.FrustumOutlineGeometry({
      frustum: frustum,
      origin: position,
      orientation: Cesium.Transforms.headingPitchRollQuaternion(
        position,
        new Cesium.HeadingPitchRoll.fromDegrees(
          this.heading,
          this.pitch,
          this.roll,
        ),
      ),
      vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
    });
    const instance = new Cesium.GeometryInstance({
      geometry: geometry,
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(
          Cesium.Color.fromBytes(0, 213, 144, 255),
        ),
      },
    });
    const primitive = new Cesium.Primitive({
      geometryInstances: instance,
      appearance: new Cesium.PerInstanceColorAppearance({
        closed: true,
        flat: true,
      }),
      asynchronous: false,
    });
    this.outlinePrimitive = this.viewer.scene.primitives.add(primitive);
  }
    // 创建轮廓线
    addOutline() {
        const frustum = new Cesium.PerspectiveFrustum({
            // 查看的视场角度,绕Z轴旋转,以弧度方式输入
            // The angle of the field of view (FOV), in radians.
            // This angle will be used as the horizontal FOV if the width is greater than the height, otherwise it will be the vertical FOV.
            fov: Cesium.Math.toRadians(this.fov),
            // 视锥体的宽度/高度
            aspectRatio: this.width / this.height,
            // 近面距视点的距离
            near: this.near,
            // 远面距视点的距离
            far: this.far,
        })
        const position = Cesium.Cartesian3.fromDegrees(
            this.position.longitude,
            this.position.latitude,
            this.position.altitude
        )
        const geometry = new Cesium.FrustumOutlineGeometry({
            frustum: frustum,
            origin: position,
            orientation: Cesium.Transforms.headingPitchRollQuaternion(
                position,
                new Cesium.HeadingPitchRoll.fromDegrees(this.heading, this.pitch, this.roll)
            ),
            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
        })
        const instance = new Cesium.GeometryInstance({
            geometry: geometry,
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    Cesium.Color.fromBytes(0, 213, 144, 255)
                ),
            },
        })
        const primitive = new Cesium.Primitive({
            geometryInstances: instance,
            appearance: new Cesium.PerInstanceColorAppearance({
                closed: true,
                flat: true,
            }),
            asynchronous: false,
        })
        this.outlinePrimitive = this.viewer.scene.primitives.add(primitive)
    }
  addCenterline() {
    this.centerDataSource = new Cesium.CustomDataSource();
    this.viewer.dataSources.add(this.centerDataSource);
    addCenterline() {
        this.centerDataSource = new Cesium.CustomDataSource()
        this.viewer.dataSources.add(this.centerDataSource)
    const position = Cesium.Cartesian3.fromDegrees(
      this.position.longitude,
      this.position.latitude,
      this.position.altitude,
    );
        const position = Cesium.Cartesian3.fromDegrees(
            this.position.longitude,
            this.position.latitude,
            this.position.altitude
        )
    let matrix = Cesium.Matrix3.fromQuaternion(
      Cesium.Transforms.headingPitchRollQuaternion(
        position,
        new Cesium.HeadingPitchRoll.fromDegrees(
          this.heading,
          this.pitch,
          this.roll,
        ),
      ),
      new Cesium.Matrix3(),
    );
        let matrix = Cesium.Matrix3.fromQuaternion(
            Cesium.Transforms.headingPitchRollQuaternion(
                position,
                new Cesium.HeadingPitchRoll.fromDegrees(this.heading, this.pitch, this.roll)
            ),
            new Cesium.Matrix3()
        )
    let right1 = Cesium.Matrix3.getColumn(matrix, 0, new Cesium.Cartesian3());
    let up1 = Cesium.Matrix3.getColumn(matrix, 1, new Cesium.Cartesian3());
    let direction = Cesium.Matrix3.getColumn(
      matrix,
      2,
      new Cesium.Cartesian3(),
    );
        let right1 = Cesium.Matrix3.getColumn(matrix, 0, new Cesium.Cartesian3())
        let up1 = Cesium.Matrix3.getColumn(matrix, 1, new Cesium.Cartesian3())
        let direction = Cesium.Matrix3.getColumn(matrix, 2, new Cesium.Cartesian3())
    // const direction = new Cartesian3(-0.10668226241650887, 0.8103322335050215, -0.5761775474872814)
        // const direction = new Cartesian3(-0.10668226241650887, 0.8103322335050215, -0.5761775474872814)
    let frontDirect = Cesium.Cartesian3.multiplyByScalar(
      direction,
      this.far,
      new Cesium.Cartesian3(),
    );
    let bottomCenter = Cesium.Cartesian3.add(
      position,
      frontDirect,
      new Cesium.Cartesian3(),
    );
        let frontDirect = Cesium.Cartesian3.multiplyByScalar(
            direction,
            this.far,
            new Cesium.Cartesian3()
        )
        let bottomCenter = Cesium.Cartesian3.add(position, frontDirect, new Cesium.Cartesian3())
    // 创建Entity来显示中心线
    this.centerDataSource.entities.add({
      name: 'Center Line of Frustum',
      polyline: {
        positions: [position, bottomCenter],
        width: 1,
        // material: Cesium.Color.RED.withAlpha(0.5)
        material: new Cesium.PolylineDashMaterialProperty({
          color: Cesium.Color.fromBytes(0, 213, 144, 255),
          dashLength: 30.0,
          gapColor: Cesium.Color.TRANSPARENT,
          gapWidth: 1.0,
        }),
      },
    });
  }
        // 创建Entity来显示中心线
        this.centerDataSource.entities.add({
            name: 'Center Line of Frustum',
            polyline: {
                positions: [position, bottomCenter],
                width: 1,
                // material: Cesium.Color.RED.withAlpha(0.5)
                material: new Cesium.PolylineDashMaterialProperty({
                    color: Cesium.Color.fromBytes(0, 213, 144, 255),
                    dashLength: 30.0,
                    gapColor: Cesium.Color.TRANSPARENT,
                    gapWidth: 1.0,
                }),
            },
        })
    }
}
src/utils/cesium/kmz.js
@@ -1,91 +1,82 @@
import axios from 'axios';
import JsZip from 'jszip';
import axios from 'axios'
import JsZip from 'jszip'
const noWmpl = ['Folder', 'Placemark', 'Point', 'coordinates'];
const noWmpl = ['Folder', 'Placemark', 'Point', 'coordinates']
/**
 * @description: 读取kmz文件解析出kml文件
 * @param {string} filePath 文件地址
 * @return {*}
 */
export const analyzeKmzFile = (filePath) => {
  return (
    axios({
      url: filePath,
      method: 'get',
      responseType: 'arraybuffer',
      authorization: false
    })
      // .get(filePath, { responseType: 'arraybuffer' },)
      .then((fileRes) => fileRes.data)
      .then((kmzData) => JsZip.loadAsync(kmzData)) // 解压kmz文件
      .then((zipFile) => {
        const files = {};
        Object.keys(zipFile.files).forEach((key) => {
          files[key] = zipFile.files[key].async('text');
        });
        return {
          zip: zipFile,
          fileInfoObj: files,
        };
      })
  );
};
export const analyzeKmzFile = filePath => {
    return (
        axios({
            url: filePath,
            method: 'get',
            responseType: 'arraybuffer',
            authorization: false,
        })
            // .get(filePath, { responseType: 'arraybuffer' },)
            .then(fileRes => fileRes.data)
            .then(kmzData => JsZip.loadAsync(kmzData)) // 解压kmz文件
            .then(zipFile => {
                const files = {}
                Object.keys(zipFile.files).forEach(key => {
                    files[key] = zipFile.files[key].async('text')
                })
                return {
                    zip: zipFile,
                    fileInfoObj: files,
                }
            })
    )
}
export const getKmlParams = (source, isWpml, params) => {
  let regx = null;
  if (isWpml) {
    if (params.mode) {
      regx = new RegExp(
        `<wpml:${params.name}>${params.findRegx}<\\/wpml:${params.name}>`,
        params.mode,
      );
    } else {
      regx = new RegExp(
        `<wpml:${params.name}>${params.findRegx}<\\/wpml:${params.name}>`,
      );
    }
  } else {
    if (params.mode) {
      regx = new RegExp(
        `<${params.name}>${params.findRegx}<\\/${params.name}>`,
        params.mode,
      );
    } else {
      regx = new RegExp(
        `<${params.name}>${params.findRegx}<\\/${params.name}>`,
      );
    }
  }
  return source?.match(regx);
};
    let regx = null
    if (isWpml) {
        if (params.mode) {
            regx = new RegExp(
                `<wpml:${params.name}>${params.findRegx}<\\/wpml:${params.name}>`,
                params.mode
            )
        } else {
            regx = new RegExp(`<wpml:${params.name}>${params.findRegx}<\\/wpml:${params.name}>`)
        }
    } else {
        if (params.mode) {
            regx = new RegExp(`<${params.name}>${params.findRegx}<\\/${params.name}>`, params.mode)
        } else {
            regx = new RegExp(`<${params.name}>${params.findRegx}<\\/${params.name}>`)
        }
    }
    return source?.match(regx)
}
export const generateKmlFormat = (settingParmas) => {
  let paramGroup = '';
  Object.keys(settingParmas).forEach((key) => {
    if (
      Object.prototype.toString.call(settingParmas[key]) === '[object Object]'
    ) {
      let parmaStr = '';
      Object.keys(settingParmas[key]).forEach((v) => {
        const xml = noWmpl.includes(key)
          ? `<${v}>${settingParmas[key][v]}</${v}>`
          : `<wpml:${v}>${settingParmas[key][v]}</wpml:${v}>`;
        parmaStr += xml;
      });
      const xml = noWmpl.includes(key)
        ? `<${key}>${parmaStr}</${key}>`
        : `<wpml:${key}>${parmaStr}</wpml:${key}>`;
      paramGroup += xml;
    } else {
      const xml = noWmpl.includes(key)
        ? `<${key}>${settingParmas[key]}</${key}>`
        : `<wpml:${key}>${settingParmas[key]}</wpml:${key}>`;
      paramGroup += xml;
    }
  });
  return paramGroup;
};
export const generateKmlFormat = settingParmas => {
    let paramGroup = ''
    Object.keys(settingParmas).forEach(key => {
        if (Object.prototype.toString.call(settingParmas[key]) === '[object Object]') {
            let parmaStr = ''
            Object.keys(settingParmas[key]).forEach(v => {
                const xml = noWmpl.includes(key)
                    ? `<${v}>${settingParmas[key][v]}</${v}>`
                    : `<wpml:${v}>${settingParmas[key][v]}</wpml:${v}>`
                parmaStr += xml
            })
            const xml = noWmpl.includes(key)
                ? `<${key}>${parmaStr}</${key}>`
                : `<wpml:${key}>${parmaStr}</wpml:${key}>`
            paramGroup += xml
        } else {
            const xml = noWmpl.includes(key)
                ? `<${key}>${settingParmas[key]}</${key}>`
                : `<wpml:${key}>${settingParmas[key]}</wpml:${key}>`
            paramGroup += xml
        }
    })
    return paramGroup
}
/**
 * @description: JSON转XML
@@ -94,125 +85,125 @@
 * @return {*} string
 */
export const JSONToXML = (obj, rootName, isEnd) => {
  let xml = '';
    let xml = ''
  const buildXml = (obj, rootName) => {
    let xml = '';
    if (Array.isArray(obj)) {
      obj.forEach((item) => {
        const str = !noWmpl.includes(rootName) && isEnd ? 'wpml:' : '';
        xml += `<${str}${rootName}>${buildXml(item)}</${str}${rootName}>`;
      });
    } else if (typeof obj === 'object') {
      Object.keys(obj).forEach((key) => {
        if (key === '#text') {
          xml += obj[key];
        } else {
          const str = !noWmpl.includes(key) && isEnd ? 'wpml:' : '';
          if (key === 'Placemark') {
            xml += `${buildXml(obj[key], key)}`;
          } else if (key === 'action') {
            if (Array.isArray(obj[key])) {
              xml += `${buildXml(obj[key], key)}`;
            } else {
              xml += `<${str}${key}>${buildXml(obj[key], key)}</${str}${key}>`;
            }
          } else {
            xml += `<${str}${key}>${buildXml(obj[key], key)}</${str}${key}>`;
          }
        }
      });
    } else {
      xml += obj;
    }
    return xml;
  };
    const buildXml = (obj, rootName) => {
        let xml = ''
        if (Array.isArray(obj)) {
            obj.forEach(item => {
                const str = !noWmpl.includes(rootName) && isEnd ? 'wpml:' : ''
                xml += `<${str}${rootName}>${buildXml(item)}</${str}${rootName}>`
            })
        } else if (typeof obj === 'object') {
            Object.keys(obj).forEach(key => {
                if (key === '#text') {
                    xml += obj[key]
                } else {
                    const str = !noWmpl.includes(key) && isEnd ? 'wpml:' : ''
                    if (key === 'Placemark') {
                        xml += `${buildXml(obj[key], key)}`
                    } else if (key === 'action') {
                        if (Array.isArray(obj[key])) {
                            xml += `${buildXml(obj[key], key)}`
                        } else {
                            xml += `<${str}${key}>${buildXml(obj[key], key)}</${str}${key}>`
                        }
                    } else {
                        xml += `<${str}${key}>${buildXml(obj[key], key)}</${str}${key}>`
                    }
                }
            })
        } else {
            xml += obj
        }
        return xml
    }
  const header = isEnd ? '<?xml version="1.0" encoding="UTF-8"?>' : '';
  xml += `${header}
    const header = isEnd ? '<?xml version="1.0" encoding="UTF-8"?>' : ''
    xml += `${header}
  <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.5">
    <Document>
      ${buildXml(obj, rootName)}
    </Document>
  </kml>`;
  return xml;
};
  </kml>`
    return xml
}
export const getTagNameFromXml = (xmlString) => {
  const parser = new DOMParser();
  const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
  const element = xmlDoc.documentElement;
  if (element && element.tagName) {
    return element.tagName; // 返回的是类似 "WPML:USEGLOBALHEADINGPARAM" 的全大写形式
  }
  return null;
};
export const getTagNameFromXml = xmlString => {
    const parser = new DOMParser()
    const xmlDoc = parser.parseFromString(xmlString, 'text/xml')
    const element = xmlDoc.documentElement
    if (element && element.tagName) {
        return element.tagName // 返回的是类似 "WPML:USEGLOBALHEADINGPARAM" 的全大写形式
    }
    return null
}
// 将xml转为json
const deepParse = (xml) => {
  let obj = {};
  // 如果是文档节点,遍历其子节点
  if (xml.nodeType === 1) {
    // element node
    // 处理子节点
    if (xml.childNodes.length > 0) {
      for (let i = 0; i < xml.childNodes.length; i++) {
        const item = xml.childNodes[i];
        const nodeName = item.nodeName.replace('wpml:', '');
const deepParse = xml => {
    let obj = {}
    // 如果是文档节点,遍历其子节点
    if (xml.nodeType === 1) {
        // element node
        // 处理子节点
        if (xml.childNodes.length > 0) {
            for (let i = 0; i < xml.childNodes.length; i++) {
                const item = xml.childNodes[i]
                const nodeName = item.nodeName.replace('wpml:', '')
        // 检查是否是文本节点
        if (item.nodeType === 3) {
          // text node
          // 处理文本节点的内容
          if (item.nodeValue.trim() !== '') {
            obj[nodeName] = item.nodeValue.trim();
          }
        } else if (item.nodeType === 1) {
          // element node
          // 递归调用处理子节点
          if (obj[nodeName] === undefined) {
            const nodeValue = deepParse(item);
            if (nodeValue[nodeName] === undefined) {
              obj[nodeName] = nodeValue;
            } else {
              obj[nodeName] = nodeValue[nodeName];
            }
          } else {
            if (!obj[nodeName].push) {
              const old = obj[nodeName];
              obj[nodeName] = [];
              obj[nodeName].push(old);
            }
            const nodeValue = deepParse(item);
            if (nodeValue[nodeName] === undefined) {
              obj[nodeName].push(nodeValue);
            }
          }
        }
      }
    }
  } else if (xml.nodeType === 3) {
    // text node
    // 处理文本节点的内容
    obj = xml.nodeValue.trim();
  }
  return obj;
};
                // 检查是否是文本节点
                if (item.nodeType === 3) {
                    // text node
                    // 处理文本节点的内容
                    if (item.nodeValue.trim() !== '') {
                        obj[nodeName] = item.nodeValue.trim()
                    }
                } else if (item.nodeType === 1) {
                    // element node
                    // 递归调用处理子节点
                    if (obj[nodeName] === undefined) {
                        const nodeValue = deepParse(item)
                        if (nodeValue[nodeName] === undefined) {
                            obj[nodeName] = nodeValue
                        } else {
                            obj[nodeName] = nodeValue[nodeName]
                        }
                    } else {
                        if (!obj[nodeName].push) {
                            const old = obj[nodeName]
                            obj[nodeName] = []
                            obj[nodeName].push(old)
                        }
                        const nodeValue = deepParse(item)
                        if (nodeValue[nodeName] === undefined) {
                            obj[nodeName].push(nodeValue)
                        }
                    }
                }
            }
        }
    } else if (xml.nodeType === 3) {
        // text node
        // 处理文本节点的内容
        obj = xml.nodeValue.trim()
    }
    return obj
}
/**
 * @description: XML转JSON
 * @param {string} xmlStr xml字符串
 * @return {*} string
 */
export const XMLToJSON = (xmlStr) => {
  const parser = new DOMParser();
  const xmlDoc = parser.parseFromString(xmlStr, 'text/xml');
  const xmlObj = deepParse(xmlDoc.documentElement);
  if (Reflect.has(xmlObj, 'Document')) {
    return xmlObj;
  } else {
    return {
      Document: xmlObj,
    };
  }
};
export const XMLToJSON = xmlStr => {
    const parser = new DOMParser()
    const xmlDoc = parser.parseFromString(xmlStr, 'text/xml')
    const xmlObj = deepParse(xmlDoc.documentElement)
    if (Reflect.has(xmlObj, 'Document')) {
        return xmlObj
    } else {
        return {
            Document: xmlObj,
        }
    }
}
src/utils/cesium/mapUtil.js
@@ -1,148 +1,134 @@
import * as Cesium from 'cesium';
import * as turf from '@turf/turf';
import * as Cesium from 'cesium'
import * as turf from '@turf/turf'
export const getLngLatDistance = (lat1, lng1, lat2, lng2) => {
  const radLat1 = (lat1 * Math.PI) / 180.0
  const radLat2 = (lat2 * Math.PI) / 180.0
  const a = radLat1 - radLat2
  const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
  let s =
    2 *
    Math.asin(
      Math.sqrt(
        Math.pow(Math.sin(a / 2), 2) +
        Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2),
      ),
    )
  s = s * 6378.137 // EARTH_RADIUS;
  s = Math.round(s * 10000) / 10000
  return s * 1000
    const radLat1 = (lat1 * Math.PI) / 180.0
    const radLat2 = (lat2 * Math.PI) / 180.0
    const a = radLat1 - radLat2
    const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
    let s =
        2 *
        Math.asin(
            Math.sqrt(
                Math.pow(Math.sin(a / 2), 2) +
                    Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
            )
        )
    s = s * 6378.137 // EARTH_RADIUS;
    s = Math.round(s * 10000) / 10000
    return s * 1000
}
// 获取限polyline长度
export const getPolylineLength = (entity) => {
  let length = 0
export const getPolylineLength = entity => {
    let length = 0
  // 获取Polyline的所有顶点位置
  const positions = entity.polyline.positions.getValue()
    // 获取Polyline的所有顶点位置
    const positions = entity.polyline.positions.getValue()
  for (let i = 0; i < positions.length - 1; ++i) {
    const startPosition = positions[i]
    const endPosition = positions[i + 1]
    for (let i = 0; i < positions.length - 1; ++i) {
        const startPosition = positions[i]
        const endPosition = positions[i + 1]
    // 使用Cesium提供的distanceBetween函数计算两个顶点之间的距离
    const distance = Cesium.Cartesian3.distance(startPosition, endPosition)
        // 使用Cesium提供的distanceBetween函数计算两个顶点之间的距离
        const distance = Cesium.Cartesian3.distance(startPosition, endPosition)
    // 将每个顶点之间的距离相加得到总长度
    length += distance
  }
        // 将每个顶点之间的距离相加得到总长度
        length += distance
    }
  return length
    return length
}
// 创建三角广告牌
export const createTriangleMarker = (title, color) => {
  // 创建canvas绘制广告牌
  const billboard = document.createElement('canvas')
  billboard.width = 30
  billboard.height = 30
  const ctx = billboard.getContext('2d')
  ctx.beginPath()
  ctx.moveTo(0, 0)
  ctx.lineTo(30, 0)
  ctx.lineTo(15, 22)
  ctx.fillStyle = color
  ctx.fill()
  ctx.font = '18px serif'
  ctx.fillStyle = '#ffffff'
  ctx.fillText(title, 10, 15)
  ctx.closePath()
  return billboard
    // 创建canvas绘制广告牌
    const billboard = document.createElement('canvas')
    billboard.width = 30
    billboard.height = 30
    const ctx = billboard.getContext('2d')
    ctx.beginPath()
    ctx.moveTo(0, 0)
    ctx.lineTo(30, 0)
    ctx.lineTo(15, 22)
    ctx.fillStyle = color
    ctx.fill()
    ctx.font = '18px serif'
    ctx.fillStyle = '#ffffff'
    ctx.fillText(title, 10, 15)
    ctx.closePath()
    return billboard
}
export const createCircleBillboard = (title, color) => {
  const billboard = document.createElement('canvas')
  const ctx = billboard.getContext('2d')
  ctx.beginPath()
  ctx.ellipse(150, 90, 11, 11, 0, 0, Math.PI * 2)
  ctx.fillStyle = color
  ctx.fill()
  ctx.font = 'bold 15px serif'
  ctx.textAlign = 'center'
  ctx.fillStyle = '#ffffff'
  ctx.fillText(title, 150, 95)
  ctx.closePath()
  return billboard
    const billboard = document.createElement('canvas')
    const ctx = billboard.getContext('2d')
    ctx.beginPath()
    ctx.ellipse(150, 90, 11, 11, 0, 0, Math.PI * 2)
    ctx.fillStyle = color
    ctx.fill()
    ctx.font = 'bold 15px serif'
    ctx.textAlign = 'center'
    ctx.fillStyle = '#ffffff'
    ctx.fillText(title, 150, 95)
    ctx.closePath()
    return billboard
}
// 获取当前经纬度海拔
export const getHaeHeight = (start, end) => {
  const ellipsoid = Cesium.Ellipsoid.WGS84 // 选择合适的椭圆体模型
  // const { longitude, latitude, height } = start
  // const { longitude: endLng, latitude: endLat, height: endHeight } = end
  // const startC3Position = new Cesium.Cartographic(longitude, latitude, height)
  // const endC3Position = new Cesium.Cartographic(endLng, endLat, endHeight)
  // const startCartesianPosition = ellipsoid.cartographicToCartesian(startC3Position)
  // const endCartesianPosition = ellipsoid.cartographicToCartesian(endC3Position)
  // // 计算两个位置之间的距离
  // const distance = new Cesium.EllipsoidGeodesic(startCartesianPosition, endCartesianPosition, ellipsoid)
  // return distance
  const { longitude, latitude, height } = end
  const cartographic = Cesium.Cartographic.fromDegrees(
    longitude,
    latitude,
    height,
  )
  const cartesianPosition = ellipsoid.cartographicToCartesian(cartographic)
  const haeHeight = ellipsoid.cartesianToCartographic(cartesianPosition).height
  return haeHeight
    const ellipsoid = Cesium.Ellipsoid.WGS84 // 选择合适的椭圆体模型
    // const { longitude, latitude, height } = start
    // const { longitude: endLng, latitude: endLat, height: endHeight } = end
    // const startC3Position = new Cesium.Cartographic(longitude, latitude, height)
    // const endC3Position = new Cesium.Cartographic(endLng, endLat, endHeight)
    // const startCartesianPosition = ellipsoid.cartographicToCartesian(startC3Position)
    // const endCartesianPosition = ellipsoid.cartographicToCartesian(endC3Position)
    // // 计算两个位置之间的距离
    // const distance = new Cesium.EllipsoidGeodesic(startCartesianPosition, endCartesianPosition, ellipsoid)
    // return distance
    const { longitude, latitude, height } = end
    const cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude, height)
    const cartesianPosition = ellipsoid.cartographicToCartesian(cartographic)
    const haeHeight = ellipsoid.cartesianToCartographic(cartesianPosition).height
    return haeHeight
}
// Cesium Cartesian3 转正常经纬度
export const cartesian3Convert = (cartesian3Position, viewer) => {
  // 转换为经纬度
  const ellipsoid = viewer.scene.globe.ellipsoid
  const cartographicPosition = Cesium.Cartographic.fromCartesian(
    cartesian3Position,
    ellipsoid,
  )
  const longitude = Cesium.Math.toDegrees(cartographicPosition.longitude)
  const latitude = Cesium.Math.toDegrees(cartographicPosition.latitude)
  const height = cartographicPosition.height
    // 转换为经纬度
    const ellipsoid = viewer.scene.globe.ellipsoid
    const cartographicPosition = Cesium.Cartographic.fromCartesian(cartesian3Position, ellipsoid)
    const longitude = Cesium.Math.toDegrees(cartographicPosition.longitude)
    const latitude = Cesium.Math.toDegrees(cartographicPosition.latitude)
    const height = cartographicPosition.height
  //   console.log('经度: ' + longitude);
  //   console.log('纬度: ' + latitude);
  //   console.log('高度: ' + height);
    //   console.log('经度: ' + longitude);
    //   console.log('纬度: ' + latitude);
    //   console.log('高度: ' + height);
  return {
    longitude,
    latitude,
    height,
  }
    return {
        longitude,
        latitude,
        height,
    }
}
// Cesium Cartesian2 转正常经纬度
export const cartesian2Convert = (position, viewer) => {
  const ellipsoid = viewer.scene.globe.ellipsoid
  const c3Position = viewer.scene.globe.pick(
    viewer.camera.getPickRay(position),
    viewer.scene,
  )
  const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
  const longitude = Cesium.Math.toDegrees(c2Postion.longitude)
  const latitude = Cesium.Math.toDegrees(c2Postion.latitude)
  return { longitude, latitude }
    const ellipsoid = viewer.scene.globe.ellipsoid
    const c3Position = viewer.scene.globe.pick(viewer.camera.getPickRay(position), viewer.scene)
    const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
    const longitude = Cesium.Math.toDegrees(c2Postion.longitude)
    const latitude = Cesium.Math.toDegrees(c2Postion.latitude)
    return { longitude, latitude }
}
// 根据经纬度获取距离
export const getLnglatDist = (lng1, lat1, lng2, lat2) => {
  const start = new Cesium.Cartesian3.fromDegrees(
    Number(lng1),
    Number(lat1),
    0,
  )
  const end = new Cesium.Cartesian3.fromDegrees(Number(lng2), Number(lat2), 0)
  return Cesium.Cartesian3.distance(start, end)
    const start = new Cesium.Cartesian3.fromDegrees(Number(lng1), Number(lat1), 0)
    const end = new Cesium.Cartesian3.fromDegrees(Number(lng2), Number(lat2), 0)
    return Cesium.Cartesian3.distance(start, end)
}
/**
@@ -150,37 +136,37 @@
 * @param coordinateList {Array<Array<Object>>} [[{lat, lng}]]
 * @return { Object } {lat lng}
 */
export const getCenterPoint = (coordinateList) => {
  coordinateList = coordinateList.map((item) => {
    const [lng, lat] = item
    return [{ lat, lng }]
  })
  const geoCoordinateListFlat = coordinateList.reduce((s, v) => {
    return (s = s.concat(v))
  }, [])
  const total = geoCoordinateListFlat.length
  let X = 0
  let Y = 0
  let Z = 0
  for (const g of geoCoordinateListFlat) {
    const lat = (g.lat * Math.PI) / 180
    const lon = (g.lng * Math.PI) / 180
    const x = Math.cos(lat) * Math.cos(lon)
    const y = Math.cos(lat) * Math.sin(lon)
    const z = Math.sin(lat)
    X += x
    Y += y
    Z += z
  }
export const getCenterPoint = coordinateList => {
    coordinateList = coordinateList.map(item => {
        const [lng, lat] = item
        return [{ lat, lng }]
    })
    const geoCoordinateListFlat = coordinateList.reduce((s, v) => {
        return (s = s.concat(v))
    }, [])
    const total = geoCoordinateListFlat.length
    let X = 0
    let Y = 0
    let Z = 0
    for (const g of geoCoordinateListFlat) {
        const lat = (g.lat * Math.PI) / 180
        const lon = (g.lng * Math.PI) / 180
        const x = Math.cos(lat) * Math.cos(lon)
        const y = Math.cos(lat) * Math.sin(lon)
        const z = Math.sin(lat)
        X += x
        Y += y
        Z += z
    }
  X = X / total
  Y = Y / total
  Z = Z / total
  const Lon = Math.atan2(Y, X)
  const Hyp = Math.sqrt(X * X + Y * Y)
  const Lat = Math.atan2(Z, Hyp)
    X = X / total
    Y = Y / total
    Z = Z / total
    const Lon = Math.atan2(Y, X)
    const Hyp = Math.sqrt(X * X + Y * Y)
    const Lat = Math.atan2(Z, Hyp)
  return { lng: (Lon * 180) / Math.PI, lat: (Lat * 180) / Math.PI }
    return { lng: (Lon * 180) / Math.PI, lat: (Lat * 180) / Math.PI }
}
/**
@@ -190,183 +176,174 @@
 * @return {*} { index: 1 }
 */
export const getShortestDistance = (lnglat1, lnglat2) => {
  const arr = []
  lnglat1.forEach((v, i) => {
    const [lng, lat] = v
    lnglat2.forEach((s, i2) => {
      const [vLng, vLat] = s
      const distance = getLnglatDist(lng, lat, vLng, vLat)
      arr.push({
        distance,
        index: [i, i2],
        lnglat: [v, s],
      })
    })
  })
  const newArr = arr.sort((a, b) => a.distance - b.distance)
  return newArr[0]
    const arr = []
    lnglat1.forEach((v, i) => {
        const [lng, lat] = v
        lnglat2.forEach((s, i2) => {
            const [vLng, vLat] = s
            const distance = getLnglatDist(lng, lat, vLng, vLat)
            arr.push({
                distance,
                index: [i, i2],
                lnglat: [v, s],
            })
        })
    })
    const newArr = arr.sort((a, b) => a.distance - b.distance)
    return newArr[0]
}
// 获取当前经纬度地形数据
export const getLnglatAltitude = (longitude, latitude, viewer) => {
  return new Promise((resolve, reject) => {
    // 假设 viewer 已经初始化并且 terrainProvider 是有效的
    const terrainProvider = viewer?.terrainProvider
    return new Promise((resolve, reject) => {
        // 假设 viewer 已经初始化并且 terrainProvider 是有效的
        const terrainProvider = viewer?.terrainProvider
    // 创建 Cartographic 对象
    const cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude)
        // 创建 Cartographic 对象
        const cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude)
    // 获取地形数据的Promise
    const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, [
      cartographic,
    ])
        // 获取地形数据的Promise
        const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, [cartographic])
    // 使用 Cesium.when 处理 Promise
    promise
      .then(function (updatedPositions) {
        // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
        const updatedPosition = updatedPositions[0]
        const height = updatedPosition.height
        // 使用 Cesium.when 处理 Promise
        promise
            .then(function (updatedPositions) {
                // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
                const updatedPosition = updatedPositions[0]
                const height = updatedPosition.height
        resolve({
          longitude,
          latitude,
          height,
        })
        // 在这里,你可以使用 height 值进行后续操作
      })
      .catch(function (error) {
        // console.error('获取高程时发生错误:', error);
        reject(error)
      })
  })
                resolve({
                    longitude,
                    latitude,
                    height,
                })
                // 在这里,你可以使用 height 值进行后续操作
            })
            .catch(function (error) {
                // console.error('获取高程时发生错误:', error);
                reject(error)
            })
    })
}
// 批量获取经纬度对应高度信息
export const getPositionsHeight = (data, viewer, droneHeight = null) => {
  return new Promise((resolve, reject) => {
    if (!data || !data.length) {
      resolve([])
    return new Promise((resolve, reject) => {
        if (!data || !data.length) {
            resolve([])
      return
    }
            return
        }
    // 假设 viewer 已经初始化并且 terrainProvider 是有效的
    const terrainProvider = viewer?.terrainProvider
        // 假设 viewer 已经初始化并且 terrainProvider 是有效的
        const terrainProvider = viewer?.terrainProvider
    // 创建 Cartographic 对象
    const cartographics = data.map((item) => {
      const [lng, lat] = item?.['Point']?.['coordinates']?.['#text'].split(',')
        // 创建 Cartographic 对象
        const cartographics = data.map(item => {
            const [lng, lat] = item?.['Point']?.['coordinates']?.['#text'].split(',')
      return Cesium.Cartographic.fromDegrees(Number(lng), Number(lat))
    })
            return Cesium.Cartographic.fromDegrees(Number(lng), Number(lat))
        })
    // 获取地形数据的Promise
    const promise = Cesium.sampleTerrainMostDetailed(
      terrainProvider,
      cartographics,
    )
        // 获取地形数据的Promise
        const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, cartographics)
    // 使用 Cesium.when 处理 Promise
    promise
      .then(function (updatedPositions) {
        // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
        const newPosition = updatedPositions.map((item, index) => {
          const longitude = Cesium.Math.toDegrees(item.longitude)
          const latitude = Cesium.Math.toDegrees(item.latitude)
        // 使用 Cesium.when 处理 Promise
        promise
            .then(function (updatedPositions) {
                // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
                const newPosition = updatedPositions.map((item, index) => {
                    const longitude = Cesium.Math.toDegrees(item.longitude)
                    const latitude = Cesium.Math.toDegrees(item.latitude)
          let FinalHeight = Number(data[index]?.['ellipsoidHeight']?.['#text']) + Number(item.height)
                    let FinalHeight =
                        Number(data[index]?.['ellipsoidHeight']?.['#text']) + Number(item.height)
          if (droneHeight) {
            FinalHeight = Number(data[index]?.['ellipsoidHeight']?.['#text']) + droneHeight
          }
                    if (droneHeight) {
                        FinalHeight = Number(data[index]?.['ellipsoidHeight']?.['#text']) + droneHeight
                    }
          return {
            ...data[index],
            longitude,
            latitude,
            FinalHeight,
            customHeight: Number(item.height),
          }
        })
                    return {
                        ...data[index],
                        longitude,
                        latitude,
                        FinalHeight,
                        customHeight: Number(item.height),
                    }
                })
        resolve(newPosition)
        // 在这里,你可以使用 height 值进行后续操作
      })
      .catch(function (error) {
        // console.error('获取高程时发生错误:', error);
        reject(error)
      })
  })
                resolve(newPosition)
                // 在这里,你可以使用 height 值进行后续操作
            })
            .catch(function (error) {
                // console.error('获取高程时发生错误:', error);
                reject(error)
            })
    })
}
// 获取面中最高点
export const getPolygonMaxHeight = (turfPolygon, viewer) => {
  return new Promise((resolve, reject) => {
    const turfExtent = turf.bbox(turfPolygon)
    return new Promise((resolve, reject) => {
        const turfExtent = turf.bbox(turfPolygon)
    const turfSamplePoints = turf.pointGrid(turfExtent, 0.01, {
      units: 'kilometers',
      mask: turfPolygon,
    })
        const turfSamplePoints = turf.pointGrid(turfExtent, 0.01, {
            units: 'kilometers',
            mask: turfPolygon,
        })
    // 假设 viewer 已经初始化并且 terrainProvider 是有效的
    const terrainProvider = viewer?.terrainProvider
        // 假设 viewer 已经初始化并且 terrainProvider 是有效的
        const terrainProvider = viewer?.terrainProvider
    const cesiumSamplePoints = []
    for (let i = 0; i < turfSamplePoints.features.length; i++) {
      const coord = turfSamplePoints.features[i].geometry.coordinates
      cesiumSamplePoints.push(
        Cesium.Cartographic.fromDegrees(coord[0], coord[1]),
      )
    }
        const cesiumSamplePoints = []
        for (let i = 0; i < turfSamplePoints.features.length; i++) {
            const coord = turfSamplePoints.features[i].geometry.coordinates
            cesiumSamplePoints.push(Cesium.Cartographic.fromDegrees(coord[0], coord[1]))
        }
    // 获取地形数据的Promise
    const promise = Cesium.sampleTerrainMostDetailed(
      terrainProvider,
      cesiumSamplePoints,
    )
        // 获取地形数据的Promise
        const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, cesiumSamplePoints)
    promise
      .then(function (updatedPositions) {
        const newPosition = updatedPositions.map((item) => Number(item.height))
        promise
            .then(function (updatedPositions) {
                const newPosition = updatedPositions.map(item => Number(item.height))
        resolve(Math.max(...newPosition))
      })
      .catch(function (error) {
        reject(error)
      })
  })
                resolve(Math.max(...newPosition))
            })
            .catch(function (error) {
                reject(error)
            })
    })
}
// 展示当前的高度
export const getWaylineShowHeight = (positions) => {
  const { lng, lat } = getCenterPoint(positions)
  let maxDist = 0
  positions.forEach((item) => {
    const [lng1, lat1] = item
    let pointsDist = getLnglatDist(lng1, lat1, lng, lat)
    if (pointsDist > maxDist) {
      maxDist = pointsDist
    }
  })
  return {
    lng,
    lat,
    showHeight: maxDist * 8,
  }
export const getWaylineShowHeight = positions => {
    const { lng, lat } = getCenterPoint(positions)
    let maxDist = 0
    positions.forEach(item => {
        const [lng1, lat1] = item
        let pointsDist = getLnglatDist(lng1, lat1, lng, lat)
        if (pointsDist > maxDist) {
            maxDist = pointsDist
        }
    })
    return {
        lng,
        lat,
        showHeight: maxDist * 8,
    }
}
// 获取当前面是否有交叉点
export const isIntersection = (coordinates) => {
  const polyDikuai = turf.polygon([coordinates])
  const result = turf.kinks(polyDikuai)
  const resultFeatures = result.features
  if (resultFeatures.length == 0) {
    //无相交
    return false
  } else {
    //有相交
    return true
  }
export const isIntersection = coordinates => {
    const polyDikuai = turf.polygon([coordinates])
    const result = turf.kinks(polyDikuai)
    const resultFeatures = result.features
    if (resultFeatures.length == 0) {
        //无相交
        return false
    } else {
        //有相交
        return true
    }
}
src/utils/cesium/use-kmz-tsa.js
@@ -1,685 +1,675 @@
import _ from 'lodash';
import JSZIP from 'jszip';
import { JSONToXML } from './kmz';
import { getDateFromTimestamp } from '@/utils/date';
import _ from 'lodash'
import JSZIP from 'jszip'
import { JSONToXML } from './kmz'
import { getDateFromTimestamp } from '@/utils/date'
export default function kmzFile() {
  // 云台信息
  const droneModel = {
    52: '0',
    53: '1',
    66: '0',
    67: '1',
    80: '0',
    81: '1',
  };
  // 创建图斑航线
  const create = async (waylineBasicInfo, lnglats, spotList) => {
    try {
      const date = new Date();
      const username = window.localStorage.getItem('bs_username');
      const updateTime = date.getTime();
      const fileName = '图斑航线规划_' + date.getTime();
      // 无人机机型、云台型号、航线高度
      const { droneEnumValue, payloadEnumValue, height } = waylineBasicInfo;
      const defaultHeight = height || 100;
      // 起始点位 (参考点位-具体以机场为准)
      const startPoint = lnglats[0];
      const takeOffPoint = [startPoint[1], startPoint[0], 0].join(',');
      // template.xml对象模版
      const fileTemplate = {
        author: { '#text': username },
        createTime: { '#text': updateTime },
        updateTime: { '#text': updateTime },
        missionConfig: {
          // 飞向首航点模式
          flyToWaylineMode: { '#text': 'safely' },
          // 航线结束动作
          finishAction: { '#text': 'goHome' },
          // 失控是否继续执行航线
          exitOnRCLost: { '#text': 'goContinue' },
          // 失控动作类型
          executeRCLostAction: { '#text': 'goBack' },
          // 安全起飞高度
          takeOffSecurityHeight: { '#text': 20 },
          // 参考起飞点
          takeOffRefPoint: { '#text': takeOffPoint },
          // 参考起飞点海拔高度
          takeOffRefPointAGLHeight: { '#text': 0 },
          // 全局航线过渡速度
          globalTransitionalSpeed: { '#text': 10 },
          // 全局返航高度
          globalRTHHeight: { '#text': defaultHeight },
          // 无人机参数
          droneInfo: {
            droneEnumValue: { '#text': droneEnumValue },
            droneSubEnumValue: {
              '#text': droneModel[payloadEnumValue],
            },
          },
          // 云台参数
          payloadInfo: {
            payloadEnumValue: { '#text': payloadEnumValue },
            payloadSubEnumValue: {
              '#text': droneModel[payloadEnumValue],
            },
            payloadPositionIndex: { '#text': 0 },
          },
        },
        Folder: {
          // 预定义模板类型 - 航点飞行
          templateType: { '#text': 'waypoint' },
          // 是否使用全局航线过渡速度
          useGlobalTransitionalSpeed: { '#text': 0 },
          templateId: { '#text': 0 },
          // 坐标系参数信息
          waylineCoordinateSysParam: {
            // 经纬度坐标系 - 固定值
            coordinateMode: { '#text': 'WGS84' },
            // 航点高程参考平面    - 相对高度
            heightMode: { '#text': 'relativeToStartPoint' },
          },
          // 全局航线飞行速度
          autoFlightSpeed: { '#text': 10 },
          // 云台俯仰角控制模式
          gimbalPitchMode: { '#text': 'usePointSetting' },
          // 全局高度
          globalHeight: { '#text': '100' },
          // 全局偏航角模式参数 - 可使用当前默认值
          globalWaypointHeadingParam: {
            waypointHeadingMode: { '#text': 'followWayline' },
            waypointHeadingAngle: { '#text': 0 },
            waypointPoiPoint: {
              '#text': '0.000000,0.000000,0.000000',
            },
            waypointHeadingPathMode: { '#text': 'followBadArc' },
            waypointHeadingPoiIndex: { '#text': 0 },
          },
          // 全局航点类型 - 直线飞行,飞行器到点停
          globalWaypointTurnMode: {
            '#text': 'toPointAndStopWithDiscontinuityCurvature',
          },
          // 全局航段轨迹是否尽量贴合直线
          globalUseStraightLine: { '#text': 1 },
          // 航点点位信息 - 位置、事件等
          Placemark: [],
          // payloadParam: {
          //   payloadPositionIndex: { '#text': 0 },
          //   focusMode: { '#text': 'firstPoint' },
          //   meteringMode: { '#text': 'average' },
          //   returnMode: { '#text': 'singleReturnFirst' },
          //   samplingRate: { '#text': '240000' },
          //   scanningMode: { '#text': 'repetitive' },
          //   imageFormat: { '#text': 'wide,zoom' },
          // },
        },
      };
      // 航点创建
      const polygonNo = {
        no: '',
        index: 0,
      };
      lnglats.forEach((lnglat, index) => {
        const obj = spotList.find((spot) =>
          spot.dkfw.find((item) => _.isEqual(item, lnglat)),
        );
        let fileSuffix = '';
        if (obj) {
          if (polygonNo.no === obj.dkbh) {
            polygonNo.index++;
          } else {
            polygonNo.no = obj.dkbh;
            polygonNo.index = 1;
          }
          fileSuffix = `图斑航线拍摄(${obj.dkbh}-${polygonNo.index})`;
        } else {
          fileSuffix = '图斑航线拍摄(起点)';
        }
        const placemark = {
          Point: {
            // 航点经纬度
            coordinates: { '#text': `${lnglat[0]},${lnglat[1]}` },
          },
          // 航点index
          index: { '#text': index },
          // 全局航线高度(椭球高)
          ellipsoidHeight: { '#text': defaultHeight },
          // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度)
          height: { '#text': defaultHeight },
          // 航点飞行速度
          waypointSpeed: { '#text': 10 },
          // 沿航线方向 - 可使用当前默认值
          waypointHeadingParam: {
            waypointHeadingMode: { '#text': 'followWayline' },
            waypointHeadingAngle: { '#text': 0 },
            waypointPoiPoint: {
              '#text': '0.000000,0.000000,0.000000',
            },
            waypointHeadingPathMode: { '#text': 'followBadArc' },
            waypointHeadingPoiIndex: { '#text': 0 },
          },
          // 航点类型
          waypointTurnParam: {
            waypointTurnMode: {
              '#text': 'toPointAndStopWithDiscontinuityCurvature',
            },
            waypointTurnDampingDist: { '#text': 0.2 },
          },
          // 是否全局参数
          useGlobalHeight: { '#text': 1 },
          useGlobalSpeed: { '#text': 1 },
          useGlobalHeadingParam: { '#text': 1 },
          useGlobalTurnParam: { '#text': 1 },
          useStraightLine: { '#text': 1 },
          // 事件组
          actionGroup: {
            actionGroupId: { '#text': index },
            actionGroupStartIndex: { '#text': index },
            actionGroupEndIndex: { '#text': index },
            actionGroupMode: { '#text': 'sequence' },
            actionTrigger: {
              actionTriggerType: { '#text': 'reachPoint' },
            },
            // 单个事件 - 如果是多个事件action可改成数组 action: [{}]
            action: {
              actionId: { '#text': 0 },
              actionActuatorFunc: { '#text': 'takePhoto' },
              actionActuatorFuncParam: {
                fileSuffix: { '#text': fileSuffix },
                payloadPositionIndex: { '#text': '0' },
                useGlobalPayloadLensIndex: { '#text': '1' },
              },
            },
          },
        };
        fileTemplate.Folder.Placemark.push(placemark);
      });
      const fileWaylines = waylinesContext(fileTemplate);
    // 云台信息
    const droneModel = {
        52: '0',
        53: '1',
        66: '0',
        67: '1',
        80: '0',
        81: '1',
    }
    // 创建图斑航线
    const create = async (waylineBasicInfo, lnglats, spotList) => {
        try {
            const date = new Date()
            const username = window.localStorage.getItem('bs_username')
            const updateTime = date.getTime()
            const fileName = '图斑航线规划_' + date.getTime()
            // 无人机机型、云台型号、航线高度
            const { droneEnumValue, payloadEnumValue, height } = waylineBasicInfo
            const defaultHeight = height || 100
            // 起始点位 (参考点位-具体以机场为准)
            const startPoint = lnglats[0]
            const takeOffPoint = [startPoint[1], startPoint[0], 0].join(',')
            // template.xml对象模版
            const fileTemplate = {
                author: { '#text': username },
                createTime: { '#text': updateTime },
                updateTime: { '#text': updateTime },
                missionConfig: {
                    // 飞向首航点模式
                    flyToWaylineMode: { '#text': 'safely' },
                    // 航线结束动作
                    finishAction: { '#text': 'goHome' },
                    // 失控是否继续执行航线
                    exitOnRCLost: { '#text': 'goContinue' },
                    // 失控动作类型
                    executeRCLostAction: { '#text': 'goBack' },
                    // 安全起飞高度
                    takeOffSecurityHeight: { '#text': 20 },
                    // 参考起飞点
                    takeOffRefPoint: { '#text': takeOffPoint },
                    // 参考起飞点海拔高度
                    takeOffRefPointAGLHeight: { '#text': 0 },
                    // 全局航线过渡速度
                    globalTransitionalSpeed: { '#text': 10 },
                    // 全局返航高度
                    globalRTHHeight: { '#text': defaultHeight },
                    // 无人机参数
                    droneInfo: {
                        droneEnumValue: { '#text': droneEnumValue },
                        droneSubEnumValue: {
                            '#text': droneModel[payloadEnumValue],
                        },
                    },
                    // 云台参数
                    payloadInfo: {
                        payloadEnumValue: { '#text': payloadEnumValue },
                        payloadSubEnumValue: {
                            '#text': droneModel[payloadEnumValue],
                        },
                        payloadPositionIndex: { '#text': 0 },
                    },
                },
                Folder: {
                    // 预定义模板类型 - 航点飞行
                    templateType: { '#text': 'waypoint' },
                    // 是否使用全局航线过渡速度
                    useGlobalTransitionalSpeed: { '#text': 0 },
                    templateId: { '#text': 0 },
                    // 坐标系参数信息
                    waylineCoordinateSysParam: {
                        // 经纬度坐标系 - 固定值
                        coordinateMode: { '#text': 'WGS84' },
                        // 航点高程参考平面    - 相对高度
                        heightMode: { '#text': 'relativeToStartPoint' },
                    },
                    // 全局航线飞行速度
                    autoFlightSpeed: { '#text': 10 },
                    // 云台俯仰角控制模式
                    gimbalPitchMode: { '#text': 'usePointSetting' },
                    // 全局高度
                    globalHeight: { '#text': '100' },
                    // 全局偏航角模式参数 - 可使用当前默认值
                    globalWaypointHeadingParam: {
                        waypointHeadingMode: { '#text': 'followWayline' },
                        waypointHeadingAngle: { '#text': 0 },
                        waypointPoiPoint: {
                            '#text': '0.000000,0.000000,0.000000',
                        },
                        waypointHeadingPathMode: { '#text': 'followBadArc' },
                        waypointHeadingPoiIndex: { '#text': 0 },
                    },
                    // 全局航点类型 - 直线飞行,飞行器到点停
                    globalWaypointTurnMode: {
                        '#text': 'toPointAndStopWithDiscontinuityCurvature',
                    },
                    // 全局航段轨迹是否尽量贴合直线
                    globalUseStraightLine: { '#text': 1 },
                    // 航点点位信息 - 位置、事件等
                    Placemark: [],
                    // payloadParam: {
                    //   payloadPositionIndex: { '#text': 0 },
                    //   focusMode: { '#text': 'firstPoint' },
                    //   meteringMode: { '#text': 'average' },
                    //   returnMode: { '#text': 'singleReturnFirst' },
                    //   samplingRate: { '#text': '240000' },
                    //   scanningMode: { '#text': 'repetitive' },
                    //   imageFormat: { '#text': 'wide,zoom' },
                    // },
                },
            }
            // 航点创建
            const polygonNo = {
                no: '',
                index: 0,
            }
            lnglats.forEach((lnglat, index) => {
                const obj = spotList.find(spot => spot.dkfw.find(item => _.isEqual(item, lnglat)))
                let fileSuffix = ''
                if (obj) {
                    if (polygonNo.no === obj.dkbh) {
                        polygonNo.index++
                    } else {
                        polygonNo.no = obj.dkbh
                        polygonNo.index = 1
                    }
                    fileSuffix = `图斑航线拍摄(${obj.dkbh}-${polygonNo.index})`
                } else {
                    fileSuffix = '图斑航线拍摄(起点)'
                }
                const placemark = {
                    Point: {
                        // 航点经纬度
                        coordinates: { '#text': `${lnglat[0]},${lnglat[1]}` },
                    },
                    // 航点index
                    index: { '#text': index },
                    // 全局航线高度(椭球高)
                    ellipsoidHeight: { '#text': defaultHeight },
                    // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度)
                    height: { '#text': defaultHeight },
                    // 航点飞行速度
                    waypointSpeed: { '#text': 10 },
                    // 沿航线方向 - 可使用当前默认值
                    waypointHeadingParam: {
                        waypointHeadingMode: { '#text': 'followWayline' },
                        waypointHeadingAngle: { '#text': 0 },
                        waypointPoiPoint: {
                            '#text': '0.000000,0.000000,0.000000',
                        },
                        waypointHeadingPathMode: { '#text': 'followBadArc' },
                        waypointHeadingPoiIndex: { '#text': 0 },
                    },
                    // 航点类型
                    waypointTurnParam: {
                        waypointTurnMode: {
                            '#text': 'toPointAndStopWithDiscontinuityCurvature',
                        },
                        waypointTurnDampingDist: { '#text': 0.2 },
                    },
                    // 是否全局参数
                    useGlobalHeight: { '#text': 1 },
                    useGlobalSpeed: { '#text': 1 },
                    useGlobalHeadingParam: { '#text': 1 },
                    useGlobalTurnParam: { '#text': 1 },
                    useStraightLine: { '#text': 1 },
                    // 事件组
                    actionGroup: {
                        actionGroupId: { '#text': index },
                        actionGroupStartIndex: { '#text': index },
                        actionGroupEndIndex: { '#text': index },
                        actionGroupMode: { '#text': 'sequence' },
                        actionTrigger: {
                            actionTriggerType: { '#text': 'reachPoint' },
                        },
                        // 单个事件 - 如果是多个事件action可改成数组 action: [{}]
                        action: {
                            actionId: { '#text': 0 },
                            actionActuatorFunc: { '#text': 'takePhoto' },
                            actionActuatorFuncParam: {
                                fileSuffix: { '#text': fileSuffix },
                                payloadPositionIndex: { '#text': '0' },
                                useGlobalPayloadLensIndex: { '#text': '1' },
                            },
                        },
                    },
                }
                fileTemplate.Folder.Placemark.push(placemark)
            })
            const fileWaylines = waylinesContext(fileTemplate)
      return {
        fileName,
        template: fileTemplate,
        waylines: fileWaylines,
      };
    } catch (error) {
      console.log(error);
      return false;
    }
  };
            return {
                fileName,
                template: fileTemplate,
                waylines: fileWaylines,
            }
        } catch (error) {
            console.log(error)
            return false
        }
    }
  // 创建正常航线
  const createNoramlWaylines = (waylineBasicInfo, lnglats) => {
    try {
      const date = new Date();
      const username = window.localStorage.getItem('bs_username');
      const updateTime = date.getTime();
      const { year, month, day, hours, minutes } =
        getDateFromTimestamp(updateTime);
      const fileName = '新建航线_' + year + month + day + hours + minutes;
      // 无人机机型、云台型号、航线高度
      const { droneEnumValue, payloadEnumValue, height, waylineName } =
        waylineBasicInfo;
      const defaultHeight = height || 100;
      // 起始点位 (参考点位-具体以机场为准)
      const startPoint = lnglats[0];
      const takeOffPoint = [startPoint.latitude, startPoint.longitude, 0].join(
        ',',
      );
      // template.xml对象模版
      const fileTemplate = {
        author: { '#text': username },
        createTime: { '#text': updateTime },
        updateTime: { '#text': updateTime },
        missionConfig: {
          // 飞向首航点模式
          flyToWaylineMode: { '#text': 'safely' },
          // 航线结束动作
          finishAction: { '#text': 'goHome' },
          // 失控是否继续执行航线
          exitOnRCLost: { '#text': 'goContinue' },
          // 失控动作类型
          executeRCLostAction: { '#text': 'goBack' },
          // 安全起飞高度
          takeOffSecurityHeight: { '#text': 20 },
          // 参考起飞点
          takeOffRefPoint: { '#text': takeOffPoint },
          // 参考起飞点海拔高度
          takeOffRefPointAGLHeight: { '#text': 0 },
          // 全局航线过渡速度
          globalTransitionalSpeed: { '#text': 10 },
          // 全局返航高度
          globalRTHHeight: { '#text': defaultHeight },
          // 无人机参数
          droneInfo: {
            droneEnumValue: { '#text': droneEnumValue },
            droneSubEnumValue: {
              '#text': droneModel[payloadEnumValue],
            },
          },
          // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞)
          autoRerouteInfo: {
            missionAutoRerouteMode: { '#text': 1 },
            transitionalAutoRerouteMode: { '#text': 1 },
          },
          // 云台参数
          payloadInfo: {
            payloadEnumValue: { '#text': payloadEnumValue },
            payloadSubEnumValue: {
              '#text': droneModel[payloadEnumValue],
            },
            payloadPositionIndex: { '#text': 0 },
          },
        },
        Folder: {
          // 预定义模板类型 - 航点飞行
          templateType: { '#text': 'waypoint' },
          // 是否使用全局航线过渡速度
          useGlobalTransitionalSpeed: { '#text': 0 },
          templateId: { '#text': 0 },
          // 坐标系参数信息
          waylineCoordinateSysParam: {
            // 经纬度坐标系 - 固定值
            coordinateMode: { '#text': 'WGS84' },
            // 航点高程参考平面    - 相对高度
            heightMode: { '#text': 'relativeToStartPoint' },
          },
          // 全局航线飞行速度
          autoFlightSpeed: { '#text': 10 },
          // 云台俯仰角控制模式
          gimbalPitchMode: { '#text': 'usePointSetting' },
          // 全局高度
          globalHeight: { '#text': '100' },
          // 全局偏航角模式参数 - 可使用当前默认值
          globalWaypointHeadingParam: {
            waypointHeadingMode: { '#text': 'followWayline' },
            waypointHeadingAngle: { '#text': 0 },
            waypointPoiPoint: {
              '#text': '0.000000,0.000000,0.000000',
            },
            waypointHeadingPathMode: { '#text': 'followBadArc' },
            waypointHeadingPoiIndex: { '#text': 0 },
          },
          // 全局航点类型 - 直线飞行,飞行器到点停
          globalWaypointTurnMode: {
            '#text': 'toPointAndStopWithDiscontinuityCurvature',
          },
          // 全局航段轨迹是否尽量贴合直线
          globalUseStraightLine: { '#text': 1 },
          // 航点点位信息 - 位置、事件等
          Placemark: [],
          payloadParam: {
            payloadPositionIndex: { '#text': 0 },
            focusMode: { '#text': 'firstPoint' },
            meteringMode: { '#text': 'average' },
            returnMode: { '#text': 'singleReturnFirst' },
            samplingRate: { '#text': '240000' },
            scanningMode: { '#text': 'repetitive' },
            imageFormat: { '#text': 'wide,zoom' },
          },
        },
      };
      lnglats.forEach((lnglat, index) => {
        const placemark = {
          Point: {
            // 航点经纬度
            coordinates: {
              '#text': `${lnglat.longitude},${lnglat.latitude}`,
            },
          },
          // 航点index
          index: { '#text': index },
          // 全局航线高度(椭球高)
          ellipsoidHeight: { '#text': lnglat.height },
          // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度)
          height: { '#text': lnglat.height },
          // 航点飞行速度
          waypointSpeed: { '#text': lnglat?.speed || 10 },
          // 沿航线方向 - 可使用当前默认值
          waypointHeadingParam: {
            waypointHeadingMode: { '#text': 'followWayline' },
            waypointHeadingAngle: { '#text': 0 },
            waypointPoiPoint: {
              '#text': '0.000000,0.000000,0.000000',
            },
            waypointHeadingPathMode: { '#text': 'followBadArc' },
            waypointHeadingPoiIndex: { '#text': 0 },
          },
          // 航点类型
          waypointTurnParam: {
            waypointTurnMode: {
              '#text': 'toPointAndStopWithDiscontinuityCurvature',
            },
            waypointTurnDampingDist: { '#text': 0.2 },
          },
          // 是否全局参数
          useGlobalHeight: { '#text': 1 },
          useGlobalSpeed: { '#text': 0 },
          useGlobalHeadingParam: { '#text': 1 },
          useGlobalTurnParam: { '#text': 1 },
          useStraightLine: { '#text': 1 },
        };
        if (lnglat?.actions) {
          const actionGroup = {
            actionGroupId: { '#text': index },
            actionGroupStartIndex: { '#text': index },
            actionGroupEndIndex: { '#text': index },
            actionGroupMode: { '#text': 'sequence' },
            actionTrigger: {
              actionTriggerType: { '#text': 'reachPoint' },
            },
            // 单个事件 - 如果是多个事件action可改成数组 action: [{}]
            // action: [{
            //   actionId: { '#text': 0 },
            //   actionActuatorFunc: { '#text': '' },
            //   actionActuatorFuncParam: {},
            // }],
            action: [],
          };
          lnglat?.actions.forEach((action, index) => {
            const singleAction = {
              actionId: { '#text': index },
              actionActuatorFunc: { '#text': '' },
              actionActuatorFuncParam: {},
            };
            // actionGroup.action['actionActuatorFunc'] = { '#text': action.key }
            // action.params.forEach(p => {
            //   if (p.value || p.value !== '') {
            //     actionGroup.action['actionActuatorFuncParam'][p.key] = { '#text': p.value }
            //   }
            // })
            singleAction['actionActuatorFunc'] = {
              '#text': action.key,
            };
            action.params.forEach((p) => {
              if (p.value || p.value !== '') {
                singleAction['actionActuatorFuncParam'][p.key] = {
                  '#text': p.value,
                };
              }
            });
            if (lnglat?.actions.length > 1) {
              actionGroup.action.push(singleAction);
            } else {
              actionGroup.action = singleAction;
            }
          });
          placemark.actionGroup = actionGroup;
        }
        fileTemplate.Folder.Placemark.push(placemark);
      });
      const fileWaylines = waylinesContext(fileTemplate);
      return {
        fileName: waylineName || fileName,
        template: fileTemplate,
        waylines: fileWaylines,
      };
    } catch (error) {
      console.log(error);
      return error;
    }
  };
    // 创建正常航线
    const createNoramlWaylines = (waylineBasicInfo, lnglats) => {
        try {
            const date = new Date()
            const username = window.localStorage.getItem('bs_username')
            const updateTime = date.getTime()
            const { year, month, day, hours, minutes } = getDateFromTimestamp(updateTime)
            const fileName = '新建航线_' + year + month + day + hours + minutes
            // 无人机机型、云台型号、航线高度
            const { droneEnumValue, payloadEnumValue, height, waylineName } = waylineBasicInfo
            const defaultHeight = height || 100
            // 起始点位 (参考点位-具体以机场为准)
            const startPoint = lnglats[0]
            const takeOffPoint = [startPoint.latitude, startPoint.longitude, 0].join(',')
            // template.xml对象模版
            const fileTemplate = {
                author: { '#text': username },
                createTime: { '#text': updateTime },
                updateTime: { '#text': updateTime },
                missionConfig: {
                    // 飞向首航点模式
                    flyToWaylineMode: { '#text': 'safely' },
                    // 航线结束动作
                    finishAction: { '#text': 'goHome' },
                    // 失控是否继续执行航线
                    exitOnRCLost: { '#text': 'goContinue' },
                    // 失控动作类型
                    executeRCLostAction: { '#text': 'goBack' },
                    // 安全起飞高度
                    takeOffSecurityHeight: { '#text': 20 },
                    // 参考起飞点
                    takeOffRefPoint: { '#text': takeOffPoint },
                    // 参考起飞点海拔高度
                    takeOffRefPointAGLHeight: { '#text': 0 },
                    // 全局航线过渡速度
                    globalTransitionalSpeed: { '#text': 10 },
                    // 全局返航高度
                    globalRTHHeight: { '#text': defaultHeight },
                    // 无人机参数
                    droneInfo: {
                        droneEnumValue: { '#text': droneEnumValue },
                        droneSubEnumValue: {
                            '#text': droneModel[payloadEnumValue],
                        },
                    },
                    // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞)
                    autoRerouteInfo: {
                        missionAutoRerouteMode: { '#text': 1 },
                        transitionalAutoRerouteMode: { '#text': 1 },
                    },
                    // 云台参数
                    payloadInfo: {
                        payloadEnumValue: { '#text': payloadEnumValue },
                        payloadSubEnumValue: {
                            '#text': droneModel[payloadEnumValue],
                        },
                        payloadPositionIndex: { '#text': 0 },
                    },
                },
                Folder: {
                    // 预定义模板类型 - 航点飞行
                    templateType: { '#text': 'waypoint' },
                    // 是否使用全局航线过渡速度
                    useGlobalTransitionalSpeed: { '#text': 0 },
                    templateId: { '#text': 0 },
                    // 坐标系参数信息
                    waylineCoordinateSysParam: {
                        // 经纬度坐标系 - 固定值
                        coordinateMode: { '#text': 'WGS84' },
                        // 航点高程参考平面    - 相对高度
                        heightMode: { '#text': 'relativeToStartPoint' },
                    },
                    // 全局航线飞行速度
                    autoFlightSpeed: { '#text': 10 },
                    // 云台俯仰角控制模式
                    gimbalPitchMode: { '#text': 'usePointSetting' },
                    // 全局高度
                    globalHeight: { '#text': '100' },
                    // 全局偏航角模式参数 - 可使用当前默认值
                    globalWaypointHeadingParam: {
                        waypointHeadingMode: { '#text': 'followWayline' },
                        waypointHeadingAngle: { '#text': 0 },
                        waypointPoiPoint: {
                            '#text': '0.000000,0.000000,0.000000',
                        },
                        waypointHeadingPathMode: { '#text': 'followBadArc' },
                        waypointHeadingPoiIndex: { '#text': 0 },
                    },
                    // 全局航点类型 - 直线飞行,飞行器到点停
                    globalWaypointTurnMode: {
                        '#text': 'toPointAndStopWithDiscontinuityCurvature',
                    },
                    // 全局航段轨迹是否尽量贴合直线
                    globalUseStraightLine: { '#text': 1 },
                    // 航点点位信息 - 位置、事件等
                    Placemark: [],
                    payloadParam: {
                        payloadPositionIndex: { '#text': 0 },
                        focusMode: { '#text': 'firstPoint' },
                        meteringMode: { '#text': 'average' },
                        returnMode: { '#text': 'singleReturnFirst' },
                        samplingRate: { '#text': '240000' },
                        scanningMode: { '#text': 'repetitive' },
                        imageFormat: { '#text': 'wide,zoom' },
                    },
                },
            }
            lnglats.forEach((lnglat, index) => {
                const placemark = {
                    Point: {
                        // 航点经纬度
                        coordinates: {
                            '#text': `${lnglat.longitude},${lnglat.latitude}`,
                        },
                    },
                    // 航点index
                    index: { '#text': index },
                    // 全局航线高度(椭球高)
                    ellipsoidHeight: { '#text': lnglat.height },
                    // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度)
                    height: { '#text': lnglat.height },
                    // 航点飞行速度
                    waypointSpeed: { '#text': lnglat?.speed || 10 },
                    // 沿航线方向 - 可使用当前默认值
                    waypointHeadingParam: {
                        waypointHeadingMode: { '#text': 'followWayline' },
                        waypointHeadingAngle: { '#text': 0 },
                        waypointPoiPoint: {
                            '#text': '0.000000,0.000000,0.000000',
                        },
                        waypointHeadingPathMode: { '#text': 'followBadArc' },
                        waypointHeadingPoiIndex: { '#text': 0 },
                    },
                    // 航点类型
                    waypointTurnParam: {
                        waypointTurnMode: {
                            '#text': 'toPointAndStopWithDiscontinuityCurvature',
                        },
                        waypointTurnDampingDist: { '#text': 0.2 },
                    },
                    // 是否全局参数
                    useGlobalHeight: { '#text': 1 },
                    useGlobalSpeed: { '#text': 0 },
                    useGlobalHeadingParam: { '#text': 1 },
                    useGlobalTurnParam: { '#text': 1 },
                    useStraightLine: { '#text': 1 },
                }
                if (lnglat?.actions) {
                    const actionGroup = {
                        actionGroupId: { '#text': index },
                        actionGroupStartIndex: { '#text': index },
                        actionGroupEndIndex: { '#text': index },
                        actionGroupMode: { '#text': 'sequence' },
                        actionTrigger: {
                            actionTriggerType: { '#text': 'reachPoint' },
                        },
                        // 单个事件 - 如果是多个事件action可改成数组 action: [{}]
                        // action: [{
                        //   actionId: { '#text': 0 },
                        //   actionActuatorFunc: { '#text': '' },
                        //   actionActuatorFuncParam: {},
                        // }],
                        action: [],
                    }
                    lnglat?.actions.forEach((action, index) => {
                        const singleAction = {
                            actionId: { '#text': index },
                            actionActuatorFunc: { '#text': '' },
                            actionActuatorFuncParam: {},
                        }
                        // actionGroup.action['actionActuatorFunc'] = { '#text': action.key }
                        // action.params.forEach(p => {
                        //   if (p.value || p.value !== '') {
                        //     actionGroup.action['actionActuatorFuncParam'][p.key] = { '#text': p.value }
                        //   }
                        // })
                        singleAction['actionActuatorFunc'] = {
                            '#text': action.key,
                        }
                        action.params.forEach(p => {
                            if (p.value || p.value !== '') {
                                singleAction['actionActuatorFuncParam'][p.key] = {
                                    '#text': p.value,
                                }
                            }
                        })
                        if (lnglat?.actions.length > 1) {
                            actionGroup.action.push(singleAction)
                        } else {
                            actionGroup.action = singleAction
                        }
                    })
                    placemark.actionGroup = actionGroup
                }
                fileTemplate.Folder.Placemark.push(placemark)
            })
            const fileWaylines = waylinesContext(fileTemplate)
            return {
                fileName: waylineName || fileName,
                template: fileTemplate,
                waylines: fileWaylines,
            }
        } catch (error) {
            console.log(error)
            return error
        }
    }
  // 创建面状航线
  const createPlanarWayline = (waylineBasicInfo, lnglats) => {};
    // 创建面状航线
    const createPlanarWayline = (waylineBasicInfo, lnglats) => {}
  // 创建点状航线
  const createPointWayLines = (
    waylineBasicInfo,
    points,
    settingInfo,
    dockPosition,
  ) => {
    try {
      const { droneEnumValue, payloadEnumValue, waylineName } =
        waylineBasicInfo;
    // 创建点状航线
    const createPointWayLines = (waylineBasicInfo, points, settingInfo, dockPosition) => {
        try {
            const { droneEnumValue, payloadEnumValue, waylineName } = waylineBasicInfo
      const { imageFormat, heightMode, globalHeight, autoFlightSpeed,gimbalPitchMode,
        waypointTurnMode,waypointHeadingMode,finishAction,globalTransitionalSpeed  } =
        settingInfo;
            const {
                imageFormat,
                heightMode,
                globalHeight,
                autoFlightSpeed,
                gimbalPitchMode,
                waypointTurnMode,
                waypointHeadingMode,
                finishAction,
                globalTransitionalSpeed,
            } = settingInfo
      const date = new Date();
      const username = window.localStorage.getItem('bs_username');
      const updateTime = date.getTime();
      const { year, month, day, hours, minutes } =
        getDateFromTimestamp(updateTime);
      const fileName = '新建航线_' + year + month + day + hours + minutes;
      // 无人机机型、云台型号、航线高度
            const date = new Date()
            const username = window.localStorage.getItem('bs_username')
            const updateTime = date.getTime()
            const { year, month, day, hours, minutes } = getDateFromTimestamp(updateTime)
            const fileName = '新建航线_' + year + month + day + hours + minutes
            // 无人机机型、云台型号、航线高度
      const defaultHeight = 100;
      // 起始点位 (参考点位-具体以机场为准)
      const takeOffPoint = [
        dockPosition.latitude,
        dockPosition.longitude,
        0,
      ].join(',');
            const defaultHeight = 100
            // 起始点位 (参考点位-具体以机场为准)
            const takeOffPoint = [dockPosition.latitude, dockPosition.longitude, 0].join(',')
      // template.xml对象模版
      const fileTemplate = {
        author: { '#text': username },
        createTime: { '#text': updateTime },
        updateTime: { '#text': updateTime },
        missionConfig: {
          // 飞向首航点模式
          flyToWaylineMode: { '#text': 'safely' },
          // 航线结束动作
          finishAction: { '#text': finishAction || 'goHome' },
          // 失控是否继续执行航线
          exitOnRCLost: { '#text': 'executeLostAction' },
          // 失控动作类型
          executeRCLostAction: { '#text': 'goBack' },
          // 安全起飞高度
          takeOffSecurityHeight: { '#text': 120 },
          // 参考起飞点
          takeOffRefPoint: { '#text': takeOffPoint },
          // 参考起飞点海拔高度
          takeOffRefPointAGLHeight: { '#text': 0 },
          // 全局航线过渡速度
          globalTransitionalSpeed: { '#text': globalTransitionalSpeed || 10 },
          // 全局返航高度
          globalRTHHeight: { '#text': defaultHeight },
          // 无人机参数
          droneInfo: {
            droneEnumValue: { '#text': droneEnumValue },
            droneSubEnumValue: {
              '#text': droneModel[payloadEnumValue],
            },
          },
          // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞)
          autoRerouteInfo: {
            missionAutoRerouteMode: { '#text': 1 },
            transitionalAutoRerouteMode: { '#text': 1 },
          },
          // 云台参数
          payloadInfo: {
            payloadEnumValue: { '#text': payloadEnumValue },
            payloadSubEnumValue: {
              '#text': droneModel[payloadEnumValue],
            },
            payloadPositionIndex: { '#text': 0 },
          },
        },
        Folder: {
          // 预定义模板类型 - 航点飞行
          templateType: { '#text': 'waypoint' },
          // 是否使用全局航线过渡速度
          useGlobalTransitionalSpeed: { '#text': 0 },
          templateId: { '#text': 0 },
          // 坐标系参数信息
          waylineCoordinateSysParam: {
            // 经纬度坐标系 - 固定值
            coordinateMode: { '#text': 'WGS84' },
            // 航点高程参考平面    - 相对高度
            heightMode: heightMode,
          },
          // 全局航线飞行速度
          autoFlightSpeed: { '#text': autoFlightSpeed || 10 },
          // 云台俯仰角控制模式
          gimbalPitchMode: { '#text': gimbalPitchMode || 'manual' },
          // 全局高度
          globalHeight: { '#text': globalHeight || '100' },
          // 全局偏航角模式参数 - 可使用当前默认值
          globalWaypointHeadingParam: {
            waypointHeadingMode: { '#text': waypointHeadingMode || 'followWayline' },
            waypointHeadingAngle: { '#text': 0 },
            waypointPoiPoint: {
              '#text': '0.000000,0.000000,0.000000',
            },
            waypointHeadingPathMode: { '#text': 'followBadArc' },
            waypointHeadingPoiIndex: { '#text': 0 },
          },
          // 全局航点类型 - 直线飞行,飞行器到点停
          globalWaypointTurnMode: {
            '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature',
          },
          // 全局航段轨迹是否尽量贴合直线
          globalUseStraightLine: { '#text': 1 },
          // 航点点位信息 - 位置、事件等
          Placemark: [],
          payloadParam: {
            payloadPositionIndex: { '#text': 0 },
            focusMode: { '#text': 'firstPoint' },
            meteringMode: { '#text': 'average' },
            returnMode: { '#text': 'singleReturnFirst' },
            samplingRate: { '#text': '240000' },
            scanningMode: { '#text': 'repetitive' },
            imageFormat: imageFormat,
          },
        },
      };
      points.length &&
        points.forEach((detail, ind) => {
          const { Point, index, height, ellipsoidHeight, actionGroup,waypointSpeed } = detail;
            // template.xml对象模版
            const fileTemplate = {
                author: { '#text': username },
                createTime: { '#text': updateTime },
                updateTime: { '#text': updateTime },
                missionConfig: {
                    // 飞向首航点模式
                    flyToWaylineMode: { '#text': 'safely' },
                    // 航线结束动作
                    finishAction: { '#text': finishAction || 'goHome' },
                    // 失控是否继续执行航线
                    exitOnRCLost: { '#text': 'executeLostAction' },
                    // 失控动作类型
                    executeRCLostAction: { '#text': 'goBack' },
                    // 安全起飞高度
                    takeOffSecurityHeight: { '#text': 120 },
                    // 参考起飞点
                    takeOffRefPoint: { '#text': takeOffPoint },
                    // 参考起飞点海拔高度
                    takeOffRefPointAGLHeight: { '#text': 0 },
                    // 全局航线过渡速度
                    globalTransitionalSpeed: { '#text': globalTransitionalSpeed || 10 },
                    // 全局返航高度
                    globalRTHHeight: { '#text': defaultHeight },
                    // 无人机参数
                    droneInfo: {
                        droneEnumValue: { '#text': droneEnumValue },
                        droneSubEnumValue: {
                            '#text': droneModel[payloadEnumValue],
                        },
                    },
                    // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞)
                    autoRerouteInfo: {
                        missionAutoRerouteMode: { '#text': 1 },
                        transitionalAutoRerouteMode: { '#text': 1 },
                    },
                    // 云台参数
                    payloadInfo: {
                        payloadEnumValue: { '#text': payloadEnumValue },
                        payloadSubEnumValue: {
                            '#text': droneModel[payloadEnumValue],
                        },
                        payloadPositionIndex: { '#text': 0 },
                    },
                },
                Folder: {
                    // 预定义模板类型 - 航点飞行
                    templateType: { '#text': 'waypoint' },
                    // 是否使用全局航线过渡速度
                    useGlobalTransitionalSpeed: { '#text': 0 },
                    templateId: { '#text': 0 },
                    // 坐标系参数信息
                    waylineCoordinateSysParam: {
                        // 经纬度坐标系 - 固定值
                        coordinateMode: { '#text': 'WGS84' },
                        // 航点高程参考平面    - 相对高度
                        heightMode: heightMode,
                    },
                    // 全局航线飞行速度
                    autoFlightSpeed: { '#text': autoFlightSpeed || 10 },
                    // 云台俯仰角控制模式
                    gimbalPitchMode: { '#text': gimbalPitchMode || 'manual' },
                    // 全局高度
                    globalHeight: { '#text': globalHeight || '100' },
                    // 全局偏航角模式参数 - 可使用当前默认值
                    globalWaypointHeadingParam: {
                        waypointHeadingMode: { '#text': waypointHeadingMode || 'followWayline' },
                        waypointHeadingAngle: { '#text': 0 },
                        waypointPoiPoint: {
                            '#text': '0.000000,0.000000,0.000000',
                        },
                        waypointHeadingPathMode: { '#text': 'followBadArc' },
                        waypointHeadingPoiIndex: { '#text': 0 },
                    },
                    // 全局航点类型 - 直线飞行,飞行器到点停
                    globalWaypointTurnMode: {
                        '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature',
                    },
                    // 全局航段轨迹是否尽量贴合直线
                    globalUseStraightLine: { '#text': 1 },
                    // 航点点位信息 - 位置、事件等
                    Placemark: [],
                    payloadParam: {
                        payloadPositionIndex: { '#text': 0 },
                        focusMode: { '#text': 'firstPoint' },
                        meteringMode: { '#text': 'average' },
                        returnMode: { '#text': 'singleReturnFirst' },
                        samplingRate: { '#text': '240000' },
                        scanningMode: { '#text': 'repetitive' },
                        imageFormat: imageFormat,
                    },
                },
            }
            points.length &&
                points.forEach((detail, ind) => {
                    const { Point, index, height, ellipsoidHeight, actionGroup, waypointSpeed } = detail
          const placemark = {
            Point,
            // 航点index
            index,
            // 全局航线高度(椭球高)
            ellipsoidHeight,
            // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度)
            height,
            // 航点飞行速度
            waypointSpeed: { '#text': waypointSpeed ||  10 },
            // 沿航线方向 - 可使用当前默认值
            waypointHeadingParam: {
              waypointHeadingMode: { '#text': waypointHeadingMode || 'followWayline' },
              waypointHeadingAngle: { '#text': 0 },
              waypointPoiPoint: {
                '#text': '0.000000,0.000000,0.000000',
              },
              waypointHeadingPathMode: { '#text': 'followBadArc' },
              waypointHeadingPoiIndex: { '#text': 0 },
            },
            // 航点类型
            waypointTurnParam: {
              waypointTurnMode: {
                '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature',
              },
              waypointTurnDampingDist: { '#text': 0.2 },
            },
            // 是否全局参数
            useGlobalHeight: { '#text': 1 },
            useGlobalSpeed: { '#text': 0 },
            useGlobalHeadingParam: { '#text': 1 },
            useGlobalTurnParam: { '#text': 1 },
            useStraightLine: { '#text': 1 },
          };
          if (actionGroup) {
            placemark.actionGroup = actionGroup;
          }
                    const placemark = {
                        Point,
                        // 航点index
                        index,
                        // 全局航线高度(椭球高)
                        ellipsoidHeight,
                        // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度)
                        height,
                        // 航点飞行速度
                        waypointSpeed: { '#text': waypointSpeed || 10 },
                        // 沿航线方向 - 可使用当前默认值
                        waypointHeadingParam: {
                            waypointHeadingMode: {
                                '#text': waypointHeadingMode || 'followWayline',
                            },
                            waypointHeadingAngle: { '#text': 0 },
                            waypointPoiPoint: {
                                '#text': '0.000000,0.000000,0.000000',
                            },
                            waypointHeadingPathMode: { '#text': 'followBadArc' },
                            waypointHeadingPoiIndex: { '#text': 0 },
                        },
                        // 航点类型
                        waypointTurnParam: {
                            waypointTurnMode: {
                                '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature',
                            },
                            waypointTurnDampingDist: { '#text': 0.2 },
                        },
                        // 是否全局参数
                        useGlobalHeight: { '#text': 1 },
                        useGlobalSpeed: { '#text': 0 },
                        useGlobalHeadingParam: { '#text': 1 },
                        useGlobalTurnParam: { '#text': 1 },
                        useStraightLine: { '#text': 1 },
                    }
                    if (actionGroup) {
                        placemark.actionGroup = actionGroup
                    }
          fileTemplate.Folder.Placemark.push(placemark);
        });
                    fileTemplate.Folder.Placemark.push(placemark)
                })
      const fileWaylines = waylinesContext(fileTemplate);
      return {
        fileName: waylineName || fileName,
        template: fileTemplate,
        waylines: fileWaylines,
      };
    } catch (error) {
      console.log(error);
      return error;
    }
  };
            const fileWaylines = waylinesContext(fileTemplate)
            return {
                fileName: waylineName || fileName,
                template: fileTemplate,
                waylines: fileWaylines,
            }
        } catch (error) {
            console.log(error)
            return error
        }
    }
  const save = async (fileInfo) => {
    const JsZip = new JSZIP();
    const { fileName, template, waylines } = fileInfo;
    const templateXml = JSONToXML(template, '', true);
    const waylinesWpml = JSONToXML(waylines, '', true);
    JsZip.file('wpmz/template.kml', templateXml);
    JsZip.file('wpmz/waylines.wpml', waylinesWpml);
    const fileBlob = await JsZip.generateAsync({ type: 'blob' });
    // saveAs(kmzFile, `${fileName}.kmz`)
    return fileBlob;
  };
    const save = async fileInfo => {
        const JsZip = new JSZIP()
        const { fileName, template, waylines } = fileInfo
        const templateXml = JSONToXML(template, '', true)
        const waylinesWpml = JSONToXML(waylines, '', true)
        JsZip.file('wpmz/template.kml', templateXml)
        JsZip.file('wpmz/waylines.wpml', waylinesWpml)
        const fileBlob = await JsZip.generateAsync({ type: 'blob' })
        // saveAs(kmzFile, `${fileName}.kmz`)
        return fileBlob
    }
  const waylinesContext = (templateJson) => {
    const waylinesObj = {
      // 标准模版
      missionConfig: {
        flyToWaylineMode: null,
        finishAction: null,
        exitOnRCLost: null,
        executeRCLostAction: null,
        takeOffSecurityHeight: null,
        globalTransitionalSpeed: null,
        globalRTHHeight: null,
        droneInfo: null,
        payloadInfo: null,
      },
      Folder: {
        templateId: null,
        executeHeightMode: null,
        waylineId: null,
        autoFlightSpeed: null,
        /*
    const waylinesContext = templateJson => {
        const waylinesObj = {
            // 标准模版
            missionConfig: {
                flyToWaylineMode: null,
                finishAction: null,
                exitOnRCLost: null,
                executeRCLostAction: null,
                takeOffSecurityHeight: null,
                globalTransitionalSpeed: null,
                globalRTHHeight: null,
                droneInfo: null,
                payloadInfo: null,
            },
            Folder: {
                templateId: null,
                executeHeightMode: null,
                waylineId: null,
                autoFlightSpeed: null,
                /*
          waylines.wpml和template.xml的Placemark通用
          不同点:
            waylineId = templateId
            ellipsoidHeight、 height 替换成 executeHeight
        */
        Placemark: null,
      },
    };
    Object.keys(waylinesObj).forEach((key) => {
      if (
        Object.prototype.toString.call(waylinesObj[key]) === '[object Object]'
      ) {
        Object.keys(waylinesObj[key]).forEach((item) => {
          waylinesObj[key][item] = templateJson[key][item];
          if (item === 'executeHeightMode') {
            waylinesObj[key][item] =
              templateJson[key].waylineCoordinateSysParam.heightMode;
          }
          if (item === 'waylineId') {
            waylinesObj[key][item] = templateJson[key].templateId;
          }
          if (item === 'Placemark') {
            const placemarks = _.cloneDeep(templateJson[key][item]);
            placemarks.forEach((placemark) => {
              placemark.executeHeight = {
                '#text': placemark.ellipsoidHeight?.['#text'] || '',
              };
              delete placemark.ellipsoidHeight;
              delete placemark.height;
            });
            waylinesObj[key][item] = placemarks;
          }
        });
      } else {
        waylinesObj[key] = templateJson[key];
      }
    });
    return waylinesObj;
  };
                Placemark: null,
            },
        }
        Object.keys(waylinesObj).forEach(key => {
            if (Object.prototype.toString.call(waylinesObj[key]) === '[object Object]') {
                Object.keys(waylinesObj[key]).forEach(item => {
                    waylinesObj[key][item] = templateJson[key][item]
                    if (item === 'executeHeightMode') {
                        waylinesObj[key][item] = templateJson[key].waylineCoordinateSysParam.heightMode
                    }
                    if (item === 'waylineId') {
                        waylinesObj[key][item] = templateJson[key].templateId
                    }
                    if (item === 'Placemark') {
                        const placemarks = _.cloneDeep(templateJson[key][item])
                        placemarks.forEach(placemark => {
                            placemark.executeHeight = {
                                '#text': placemark.ellipsoidHeight?.['#text'] || '',
                            }
                            delete placemark.ellipsoidHeight
                            delete placemark.height
                        })
                        waylinesObj[key][item] = placemarks
                    }
                })
            } else {
                waylinesObj[key] = templateJson[key]
            }
        })
        return waylinesObj
    }
  return {
    create,
    createNoramlWaylines,
    createPlanarWayline,
    createPointWayLines,
    save,
  };
    return {
        create,
        createNoramlWaylines,
        createPlanarWayline,
        createPointWayLines,
        save,
    }
}
Diff truncated after the above file
src/utils/crypto.js src/utils/date.js src/utils/flow.js src/utils/formatter.js src/utils/func.js src/utils/http/config.js src/utils/http/enums.js src/utils/module.js src/utils/rem.js src/utils/sensitive.js src/utils/sm2.js src/utils/staticData/device.js src/utils/staticData/enums.js src/utils/store.js src/utils/util.js src/utils/validate.js src/utils/websocket/connect-websocket.js src/utils/websocket/drone-ws-control.js src/views/Home/Footer.vue src/views/Home/components/HomeLeft/InspectionRaskDetails.vue src/views/Home/useEventOperate/useEventOperate.js src/views/Home/useUavHome/useUavHome.js src/websocket/index.js src/websocket/util/config.js