Compare commits

..

13 Commits

Author SHA1 Message Date
2e606513f5 add 道路分析接口获取数据 2025-11-18 16:01:57 +08:00
1c76c7d23c add title 2025-11-17 09:28:04 +08:00
802df4d446 add title从ini取 2025-11-03 17:00:28 +08:00
46c6b952fc fix bug 2025-10-27 10:48:12 +08:00
a562e2cea8 add 样式 2025-10-27 09:46:51 +08:00
af252cd65e fix 2025-10-24 09:02:28 +08:00
444bded88f add 字体 2025-10-23 10:23:50 +08:00
964ce7cede fix bug修复 2025-10-16 16:02:23 +08:00
ce70fd98ec add json编辑功能 2025-10-15 09:27:20 +08:00
7d22506f18 add json 编辑 2025-10-14 17:23:54 +08:00
328700ec89 fix 2025-10-10 18:31:44 +08:00
2ad6bc1b47 add 导出 2025-10-10 15:32:47 +08:00
41f9034f54 ## 机动路线规划 2025-10-10 11:38:34 +08:00
20 changed files with 4869 additions and 2082 deletions

View File

@ -4,6 +4,5 @@
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": false,
"printWidth": 120
"bracketSpacing": false
}

View File

@ -1,29 +1,3 @@
# kxfx
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
## 机动路线规划

421
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@
},
"dependencies": {
"@babel/preset-env": "^7.28.3",
"axios": "0.21.0",
"axios": "^1.13.2",
"echarts": "^5.4.3",
"element-ui": "2.9.2",
"file-saver": "^2.0.5",

View File

@ -1,6 +1,6 @@
[http]
port=8081
address=127.0.0.1
port=8381
address=192.168.3.35
[title]
msg=道路堪选分析

4
public/config/config.js Normal file
View File

@ -0,0 +1,4 @@
window.config = {
// baseUrl: 'http://192.168.3.35:8381',
baseUrl: '/api'
}

View File

@ -1,16 +1,16 @@
{
"startPoint": "114.26344,27.800982",
"endPoint": "114.284668,27.794961",
"startPoint": "114.312888,27.796612",
"endPoint": "114.336525,27.767989",
"viaPoints": [
{
"time": "1694352000000",
"points": "114.272329,27.797299"
"points": "114.334239,27.779261"
}
],
"avoidPoints": [
{
"time": "1694352003000",
"points": "114.27882,27.792857"
"points": ""
}
],
"avoidAreas": [

View File

@ -11,6 +11,7 @@
rel="stylesheet"
type="text/css"
/>
<script src="./config/config.js" type="text/javascript"></script>
<script src="./map/Cesium/Cesium.js" type="text/javascript"></script>
<link href="./map/mars3d/mars3d.css" rel="stylesheet" type="text/css" />
<script src="./map/mars3d/mars3d.js" type="text/javascript"></script>

View File

@ -17,7 +17,7 @@ export default {
return {
routerMap: {
1: '/',
// 2: '/residentAnalysis ',
2: '/residentAnalysis',
},
}
},

View File

@ -1,11 +1,57 @@
@font-face {
font-family: 'Dengxian';
src: url('@/assets/scss/Dengxian.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
/* 全局强制继承 */
html, body, #app, .cesium-widget, .mars3d-container,
.mars3d-popup, .mars3d-tooltip, .mars3d-contextmenu,
.mars3d-measure-result, .cesium-credit-text,
.el-button, .el-input, .el-select, .el-table, .el-form, .el-dialog,
.el-message, .el-notification, .el-tooltip,
.el-menu, .el-breadcrumb, .el-pagination,
.el-radio, .el-checkbox, .el-tag, .el-badge,
.el-alert, .el-steps, .el-tabs, .el-calendar,
.el-date-picker, .el-cascader, .el-transfer,
.el-slider, .el-upload,
.el-empty, .el-result,
.el-loading-text,.el-table,
.el-table__body-wrapper span,
.el-table__footer-wrapper span,
.el-table__header-wrapper span,
.el-table__fixed span,
.el-table__fixed-right span,
.vxe-table--render-default .vxe-cell--title,
.vxe-table--render-default .vxe-cell--label,
.vxe-toolbar *,
.vxe-pager *,
.vxe-modal--wrapper *,
.vxe-tooltip--wrapper * {
font-family: 'DengXian', sans-serif !important;
}
/* 覆盖 mars3d 所有内部 UI */
.mars3d-draw-tooltip,
.mars3d-measure-tooltip,
.mars3d-contextmenu *,
.mars3d-popup *,
.mars3d-measure-result *,
.mars3d-control-btn {
font-family: 'DengXian', sans-serif !important;
}
.Dengxian {
font-family: 'Dengxian' !important;
}
body,
html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Arial, sans-serif;
font-family: 'Dengxian' !important;
user-select: none;
scrollbar-width: none;
-ms-overflow-style: none;
@ -33,3 +79,20 @@ html {
.flex-warp {
flex-wrap: wrap;
}
.el-form-item {
display: flex!important;
justify-content: space-between;
margin-bottom: 12px!important;
}
.el-form-item__label {
letter-spacing: -1px;
min-width: 130px!important;
padding: 0!important;
white-space: nowrap; /* 强制不换行 */
flex-shrink: 0;
font-size: 16px!important;
}
.el-input__inner {
height: 24px;
line-height: 24px;
}

View File

@ -10,6 +10,9 @@ import 'vxe-pc-ui/es/style.css'
import VxeUITable from 'vxe-table'
import 'vxe-table/es/style.css'
import axios from 'axios'
Vue.prototype.$http = axios
Vue.config.productionTip = false

View File

@ -6,13 +6,13 @@ import residentAnalysis from '@/views/residentAnalysis/index.vue'
Vue.use(VueRouter)
const routes = [
// {
// path: '/',
// name: 'home',
// component: HomeView,
// },
{
path: '/',
name: 'home',
component: HomeView,
},
{
path: '/residentAnalysis',
name: 'residentAnalysis',
component: residentAnalysis,
},

162
src/utils/map.js Normal file
View File

@ -0,0 +1,162 @@
/**
* 极简 WKT -> GeoJSON
* 支持 POINT / LINESTRING / POLYGON
* @param {String} wkt
* @return {Object} GeoJSON
*/
function wktToGeoJSON (wkt) {
const trim = str => str.trim()
const split = (str, d) => str.split(d).map(trim)
// 1. 提取类型 + 坐标字符串
const [head, coords] = split(wkt, '(')
const type = trim(head).toUpperCase()
const coordStr = coords.replace(/\)$/, '')
// 2. 通用“数字对”解析
const parseRing = ring =>
split(ring, ',').map(p => {
const [x, y] = split(p, ' ').map(Number)
return [x, y] // GeoJSON 里经度在前
})
// 3. 按类型组装
switch (type) {
case 'POINT': {
const [x, y] = split(coordStr, ' ').map(Number)
return { type: 'Point', coordinates: [x, y] }
}
case 'LINESTRING':
return { type: 'LineString', coordinates: parseRing(coordStr) }
case 'POLYGON': {
// 可能带孔,先按“), (”切
const rings = coordStr.split(/\s*\),\s*\(/).map(parseRing)
return { type: 'Polygon', coordinates: rings }
}
default:
throw new Error('暂不支持该 WKT 类型:' + type)
}
}
/* 拿当前视野四至(容错版) */
function getBounds(map) {
let rect = map.camera.computeViewRectangle()
if (!rect) {
// 高空/2D 模式下 computeViewRectangle 会失效,用四个角点兜底
const canvas = map.scene.canvas
const ellipsoid = Cesium.Ellipsoid.WGS84
const cv = (x, y) => map.camera.pickEllipsoid(
new Cesium.Cartesian2(x, y), ellipsoid
)
const ptNW = cv(0, 0)
const ptSE = cv(canvas.clientWidth, canvas.clientHeight)
// 如果仍 pick 不到,就缩小范围再试(再不行就返回一个默认矩形)
if (!ptNW || !ptSE) {
rect = map.camera.computeViewRectangle(
ellipsoid,
Cesium.Math.toRadians(0.1) // 0.1° 容差
)
if (!rect) {
// 终极保底:以相机位置为中心 ±0.1°
const c = map.camera.positionCartographic
const d = 0.1
return {
west : Cesium.Math.toDegrees(c.longitude) - d,
east : Cesium.Math.toDegrees(c.longitude) + d,
south: Cesium.Math.toDegrees(c.latitude) - d,
north: Cesium.Math.toDegrees(c.latitude) + d
}
}
} else {
// pick 成功
const nw = Cesium.Cartographic.fromCartesian(ptNW)
const se = Cesium.Cartographic.fromCartesian(ptSE)
return {
west : Cesium.Math.toDegrees(nw.longitude),
north: Cesium.Math.toDegrees(nw.latitude),
east : Cesium.Math.toDegrees(se.longitude),
south: Cesium.Math.toDegrees(se.latitude)
}
}
}
// 正常能算到
return {
west : Cesium.Math.toDegrees(rect.west),
south: Cesium.Math.toDegrees(rect.south),
east : Cesium.Math.toDegrees(rect.east),
north: Cesium.Math.toDegrees(rect.north)
}
}
/* 计算当前地图层级zoom */
function getZoom(map) {
const height = map.camera.positionCartographic.height
// 经验公式Cesium 高度 -> WebMercator zoom
return Math.floor(29.5 - Math.log(height) / Math.LN2)
}
/* 画布像素边界 */
function getViewportPxBounds(map) {
const cvs = map.scene.canvas
return { left: 0, top: 0, right: cvs.clientWidth, bottom: cvs.clientHeight }
}
/* 像素 -> 经纬度四至 */
function pxToLatLngBounds(px, map) {
const pick = (x, y) => {
const cart = map.camera.pickEllipsoid(
new Cesium.Cartesian2(x, y),
Cesium.Ellipsoid.WGS84
)
if (!cart) return null
const c = Cesium.Cartographic.fromCartesian(cart)
return { lng: Cesium.Math.toDegrees(c.longitude), lat: Cesium.Math.toDegrees(c.latitude) }
}
const nw = pick(px.left, px.top)
const se = pick(px.right, px.bottom)
// 兜底:高空 pick 不到就用相机矩形
if (!nw || !se) {
const rect = map.camera.computeViewRectangle() || {}
return {
west : Cesium.Math.toDegrees(rect.west || 0),
south: Cesium.Math.toDegrees(rect.south || 0),
east : Cesium.Math.toDegrees(rect.east || 0),
north: Cesium.Math.toDegrees(rect.north || 0)
}
}
return { west: nw.lng, north: nw.lat, east: se.lng, south: se.lat }
}
var GRID_SIZE_DEG = 0.05 // 0.05° ≈ 5 km 一格
var CACHE_MIN = 30 * 60 * 1000 // 30 min
/* 经纬度 → 格子 key */
function lonLatToGridKey (lon, lat) {
const x = Math.floor(lon / GRID_SIZE_DEG)
const y = Math.floor(lat / GRID_SIZE_DEG)
return `${x}_${y}`
}
/* 取格子中心点(方便防抖) */
function gridKeyToCenter (key) {
const [x, y] = key.split('_').map(Number)
return {
lon: (x + 0.5) * GRID_SIZE_DEG,
lat: (y + 0.5) * GRID_SIZE_DEG
}
}
export {
wktToGeoJSON,
getBounds,
getZoom,
getViewportPxBounds,
pxToLatLngBounds,
lonLatToGridKey,
gridKeyToCenter,
}

View File

@ -16,18 +16,22 @@
<script>
import {setStorage, getStorage} from '@/utils/localStorage.js'
import iniParser from 'ini-parser'
export default {
name: '',
data() {
return {
tabList: [
// {id: 1, label: '机动路线规划'},
{id: 1, label: '临时部署驻地分析'},
{id: 1, label: '道路通过性分析'},
// {id: 2, label: '临时部署驻地分析'},
],
activeIndex: 1,
}
},
created() {
this.getTitle()
},
mounted() {
this.activeIndex = getStorage('activeIndex') || 1
},
@ -36,6 +40,17 @@ export default {
setStorage('activeIndex', 1)
},
methods: {
getTitle() {
fetch('./config.ini')
.then(response => response.text())
.then(text => {
const parsedData = iniParser.parse(text);
this.tabList[0].label = parsedData.title.msg || '道路通过性分析'
})
.catch(() => {
this.tabList[0].label = '道路通过性分析'
})
},
setActiveIndex(id) {
if (this.activeIndex !== id) {
this.activeIndex = id
@ -64,7 +79,7 @@ $label_height: 50px;
line-height: $label_height;
padding: 0 30px;
margin-right: 20px;
font-family: 'HarmonyOS Sans';
// font-family: 'HarmonyOS Sans';
font-weight: 400;
font-size: 20px;
cursor: pointer;

View File

@ -81,12 +81,21 @@
</div>
</el-form-item>
</el-form>
<input type="file" ref="fileInput" @change="handleFileUpload" style="display: none" />
<input
type="file"
ref="fileInput"
@change="handleFileUpload"
style="display: none"
/>
<div class="importJson" @click="triggerFileUpload">导入json文件</div>
</div>
<div class="control-panel">
<div class="title">隐蔽添加</div>
<el-form label-width="120px" label-position="left" size="mini">
<el-form
label-width="120px"
label-position="left"
size="mini"
>
<el-form-item label="缓冲半径m">
<el-input v-model="hideform.radius"></el-input>
</el-form-item>
@ -103,7 +112,12 @@
<span>参与路线规划</span>
</div>
</div>
<el-form @submit.native.prevent="calculateShortestPath" label-width="120px" label-position="left" size="mini">
<el-form
@submit.native.prevent="calculateShortestPath"
label-width="120px"
label-position="left"
size="mini"
>
<el-form-item label="宽度">
<el-input v-model="inputform.width"></el-input>
</el-form-item>
@ -111,7 +125,10 @@
<el-input v-model="inputform.load" placeholder=""></el-input>
</el-form-item>
<el-form-item label="最小转弯半径">
<el-input v-model="inputform.minTurnRadius" placeholder=""></el-input>
<el-input
v-model="inputform.minTurnRadius"
placeholder=""
></el-input>
</el-form-item>
</el-form>
<div class="importJson" @click="openDialog">数据选择</div>
@ -139,7 +156,7 @@
inputform.minTurnRadius || 0
}}最大车辆载重{{ inputform.load || 0 }}
</div>
<vxe-table ref="xTable" :data="infoList" style="max-height: 50vh; overflow: hidden; overflow-y: auto">
<vxe-table ref="xTable" :data="infoList" style="max-height: 50vh;overflow: hidden;overflow-y: auto;">
<vxe-column field="编码" title="编码" width="65px"></vxe-column>
<vxe-column field="名称" title="名称" width="80px"></vxe-column>
<vxe-column field="宽度" title="路宽"></vxe-column>
@ -148,23 +165,23 @@
<vxe-column field="水深" title="水深"></vxe-column>
<vxe-column field="净空高" title="净空高" width="65px"></vxe-column>
</vxe-table>
<vxe-table :data="factoriesWithVehicles" style="margin-top: 10px">
<vxe-table :data="factoriesWithVehicles" style="margin-top: 10px;">
<vxe-column field="options.style.properties.FID_1" title="厂房id"></vxe-column>
<vxe-column field="area" title="面积(㎡)">
<template v-slot="{row}">
{{ row.area.toFixed(2) }}
<template v-slot="{ row }">
{{ row.area.toFixed(2)}}
</template>
</vxe-column>
<vxe-column field="vehicles" title="车辆">
<template v-slot="{row}">
{{ row.vehicles.map((item) => item.name).join(',') }}
<template v-slot="{ row }">
{{ (row.vehicles.map(item => item.name)).join(',')}}
</template>
</vxe-column>
</vxe-table>
</div>
</div>
<el-dialog :visible.sync="dialogVisible" title="车辆选择" width="800px">
<div style="margin-bottom: 10px">
<div style="margin-bottom: 10px;">
<el-button type="primary" size="mini" @click="handleAdd">新增</el-button>
</div>
<vxe-table
@ -180,37 +197,37 @@
>
<vxe-column type="checkbox" width="50"></vxe-column>
<vxe-column field="name" title="名称" width="100">
<template v-slot="{row}">
<template v-slot="{ row }">
<el-input v-if="row.editing" v-model="row.name" size="mini"></el-input>
<span v-else>{{ row.name }}</span>
</template>
</vxe-column>
<vxe-column field="long" title="长度" width="100">
<template v-slot="{row}">
<template v-slot="{ row }">
<el-input v-if="row.editing" v-model="row.long" size="mini"></el-input>
<span v-else>{{ row.long }}</span>
</template>
</vxe-column>
<vxe-column field="width" title="宽度" width="100">
<template v-slot="{row}">
<template v-slot="{ row }">
<el-input v-if="row.editing" v-model="row.width" size="mini"></el-input>
<span v-else>{{ row.width }}</span>
</template>
</vxe-column>
<vxe-column field="load" title="载重(吨)" width="100">
<template v-slot="{row}">
<template v-slot="{ row }">
<el-input v-if="row.editing" v-model="row.load" size="mini"></el-input>
<span v-else>{{ row.load }}</span>
</template>
</vxe-column>
<vxe-column field="minTurnRadius" title="最小转弯半径">
<template v-slot="{row}">
<template v-slot="{ row }">
<el-input v-if="row.editing" v-model="row.minTurnRadius" size="mini"></el-input>
<span v-else>{{ row.minTurnRadius }}</span>
</template>
</vxe-column>
<vxe-column title="操作" width="100">
<template v-slot="{row}">
<template v-slot="{ row }">
<el-button v-if="!row.editing" type="text" size="mini" @click="handleEdit(row)">编辑</el-button>
<el-button v-else type="text" size="mini" @click="handleSave(row)">保存</el-button>
<el-button type="text" size="mini" @click="handleDelete(row)">删除</el-button>
@ -231,7 +248,7 @@
import Cookies from 'js-cookie'
import axios from 'axios'
import iniParser from 'ini-parser'
import configIni from '/public/config.ini'
import configIni from '/config.ini';
export default {
data() {
@ -304,7 +321,7 @@ export default {
.catch((error) => {})
},
async initMap() {
const parsedData = iniParser.parse(configIni)
const parsedData = iniParser.parse(configIni);
this.viewer = new window.mars3d.Map(
'map',
{
@ -339,7 +356,7 @@ export default {
this.shortestPathLayer = new window.mars3d.layer.GraphicLayer()
this.viewer.addLayer(this.shortestPathLayer)
this.accordFactoryLayer = new window.mars3d.layer.GraphicLayer()
this.viewer.addLayer(this.accordFactoryLayer)
this.loadShapefile() // 拿到路网数据
@ -433,7 +450,7 @@ export default {
outline: false,
},
})
this.graphicLayer.addGraphic(graphicLine)
this.graphicLayer.addGraphic(graphicLine);
})
this.roadNetworkGeoJSONBuild = this.buildGraph(this.roadNetworkGeoJSON)
this.loadFactoryGeoJson() // 拿到厂房数据
@ -483,7 +500,7 @@ export default {
this.accordPoint = graphic
try {
// 创建缓冲区的宽度
const bufferWidth = this.hideform.radius // 避让区的宽度(单位:米)
const bufferWidth = this.hideform.radius; // 避让区的宽度(单位:米)
// 获取绘制的点的坐标
const pointCoordinates = [
graphic.toGeoJSON().geometry.coordinates[0],
@ -497,12 +514,12 @@ export default {
coordinates: pointCoordinates,
},
properties: {},
}
};
// 使用 Turf.js 计算缓冲区
let buffered = turf.buffer(pointFeature, bufferWidth / 1000, {units: 'kilometers'})
let buffered = turf.buffer(pointFeature, bufferWidth / 1000, { units: 'kilometers' });
// 将缓冲区存储到数组中
this.bufferLayerList.push(buffered)
this.bufferLayerList.push(buffered);
const polygon = new window.mars3d.graphic.PolygonEntity({
positions: buffered.geometry.coordinates[0],
style: {
@ -512,19 +529,19 @@ export default {
outlineWidth: 1,
outlineColor: '#ffffff',
},
time: new Date().getTime(),
time: new Date().getTime()
})
this.accordFactoryLayer.addGraphic(polygon)
this.accordFactoryLayer.addGraphic(polygon);
// 检查缓冲区内的厂房
this.checkFactoryInBuffer('point', pointCoordinates)
this.checkFactoryInBuffer('point', pointCoordinates);
} catch (error) {
console.error('缓冲区生成或检查异常:', error)
console.error("缓冲区生成或检查异常:", error);
}
},
})
},
// 获取当前路线的缓冲区
hadBuffer() {
hadBuffer () {
if (this.shortestPathList.length == 0) {
this.$message.warning('请先进行路线规划')
return
@ -534,34 +551,34 @@ export default {
return
}
try {
// =======检查几何对象的类型 缓冲区========
// =======检查几何对象的类型 缓冲区========
for (const feature of this.shortestPathList[0]) {
// this.shortestPathList[0].forEach((feature) => {
// 创建缓冲区的宽度
const bufferWidth = this.hideform.radius // 避让区的宽度(单位:米)
// this.shortestPathList[0].forEach((feature) => {
// 创建缓冲区的宽度
const bufferWidth = this.hideform.radius; // 避让区的宽度(单位:米)
if (feature.geometry.type === 'LineString') {
const positions = feature.geometry.coordinates[0]
const positions = feature.geometry.coordinates[0];
// 确保每条线至少有 2 个点
if (positions.length < 2) {
console.warn('无效的线,跳过:', feature)
return
console.warn('无效的线,跳过:', feature);
return;
}
try {
// 使用 Turf.js 计算缓冲区
var buffered = turf.buffer(feature, bufferWidth / 1000, {units: 'kilometers'})
var buffered = turf.buffer(feature, bufferWidth / 1000, { units: 'kilometers' });
// 将缓冲区存储到数组中
this.bufferLayerList.push(buffered)
this.bufferLayerList.push(buffered);
} catch (error) {
console.error('缓冲分析异常:', error)
console.error("缓冲分析异常:", error);
}
} else if (feature.geometry.type === 'MultiLineString') {
// 遍历每个线段
feature.geometry.coordinates.forEach((lineCoordinates) => {
// 检查每个线段是否有效
if (lineCoordinates.length < 2) {
console.warn('多线段中的无效的线段,跳过:', lineCoordinates)
return
console.warn('多线段中的无效的线段,跳过:', lineCoordinates);
return;
}
// 创建单个线段的 GeoJSON 特征
@ -571,27 +588,27 @@ export default {
type: 'LineString',
coordinates: lineCoordinates,
},
properties: feature.properties,
}
properties: feature.properties
};
try {
// 使用 Turf.js 计算缓冲区
var buffered = turf.buffer(lineFeature, bufferWidth / 1000, {units: 'kilometers'})
var buffered = turf.buffer(lineFeature, bufferWidth / 1000, { units: 'kilometers' });
// 将缓冲区存储到数组中
this.bufferLayerList.push(buffered)
this.bufferLayerList.push(buffered);
} catch (error) {
console.error('缓冲分析异常:', error)
console.error("缓冲分析异常:", error);
}
})
});
} else {
console.warn('不支持的几何类型:', feature.geometry.type)
console.warn('不支持的几何类型:', feature.geometry.type);
}
}
}
// 去筛选在缓存区的厂房
this.checkFactoryInBuffer('line')
} catch (error) {
console.error('处理路径列表时发生错误:', error)
this.checkFactoryInBuffer('line');
}catch (error) {
console.error("处理路径列表时发生错误:", error);
}
},
checkFactoryInBuffer(type, pointInfo) {
@ -612,106 +629,106 @@ export default {
// 检查几何对象的类型
if (factory.geometry.type === 'MultiPolygon') {
// 创建多边形集合MultiPolygon
const factoryMultiPoly = turf.multiPolygon(factory.geometry.coordinates)
const factoryMultiPoly = turf.multiPolygon(factory.geometry.coordinates);
// 计算整个多边形集合的面积
const area = turf.area(factoryMultiPoly)
const area = turf.area(factoryMultiPoly);
// 计算工厂多边形集合的边界框
const [minX, minY, maxX, maxY] = turf.bbox(factoryMultiPoly)
const [minX, minY, maxX, maxY] = turf.bbox(factoryMultiPoly);
// 筛选与工厂边界框相交的缓冲区
const candidates = this.bufferLayerList.filter((buffer) => {
const [bminX, bminY, bmaxX, bmaxY] = turf.bbox(buffer)
return !(bmaxX < minX || bminX > maxX || bmaxY < minY || bminY > maxY)
})
const [bminX, bminY, bmaxX, bmaxY] = turf.bbox(buffer);
return !(bmaxX < minX || bminX > maxX || bmaxY < minY || bminY > maxY);
});
// 精确相交检测
let isInside = false
let isInside = false;
for (const buffer of candidates) {
if (turf.booleanIntersects(factoryMultiPoly, buffer)) {
// 如果工厂在缓冲区内,绘制所有多边形
isInside = true
this.drawFactory(factory.geometry.coordinates, factory, area, pointInfo)
break
isInside = true;
this.drawFactory(factory.geometry.coordinates, factory, area, pointInfo);
break;
}
}
// 如果工厂不在任何缓冲区内
resolve()
resolve();
} else {
reject(new Error('不支持的几何类型'))
reject(new Error('不支持的几何类型'));
}
})
})
});
// 确保所有工厂处理完成后进行排序
Promise.allSettled(factoryPromises)
.then(async (results) => {
// 只有路线隐蔽规划需要塞入车辆 点的不需要
// 所有工厂处理完成,进行排序 按照距离近到远
this.accordFactoryInfo.sort((a, b) => a.distance - b.distance)
this.accordFactoryInfo.sort((a, b) => a.distance - b.distance);
// 拿到当前的车队车辆信息 并且算出面积 按照从大到小排序
const areaList = JSON.parse(Cookies.get('minTurnRadius'))
areaList.map((item) => {
item.area = Number(item.long) * Number(item.width)
})
areaList.sort((a, b) => b.area - a.area)
areaList.sort((a, b) => b.area - a.area);
// 初始化每个工厂的剩余面积
this.accordFactoryInfo.forEach((factory) => {
factory.remainingArea = factory.area // 记录每个工厂的剩余可用面积
factory.vehicles = [] // 确保每个工厂都有一个 vehicles 属性
})
this.accordFactoryInfo.forEach(factory => {
factory.remainingArea = factory.area; // 记录每个工厂的剩余可用面积
factory.vehicles = []; // 确保每个工厂都有一个 vehicles 属性
});
// 遍历每个车辆,尝试塞入工厂
areaList.forEach((vehicle) => {
let isPlaced = false
let isPlaced = false;
// 遍历每个工厂,尝试塞入车辆
for (let i = 0; i < this.accordFactoryInfo.length; i++) {
const factory = this.accordFactoryInfo[i]
const factory = this.accordFactoryInfo[i];
// 检查工厂是否还有剩余面积
if (factory.remainingArea >= vehicle.area) {
// 塞入车辆
factory.vehicles.push({
...vehicle,
remainingArea: factory.remainingArea - vehicle.area, // 记录车辆塞入后的工厂剩余面积
})
remainingArea: factory.remainingArea - vehicle.area // 记录车辆塞入后的工厂剩余面积
});
// 更新工厂的剩余面积
factory.remainingArea -= vehicle.area
factory.remainingArea -= vehicle.area;
// 标记车辆已放置
isPlaced = true
break
isPlaced = true;
break;
}
}
// 如果车辆没有被放置,可以在这里处理(例如记录日志或显示警告)
if (!isPlaced) {
console.warn(`车辆 ${vehicle.id} 无法放置在任何工厂中`)
console.warn(`车辆 ${vehicle.id} 无法放置在任何工厂中`);
}
})
});
// 更新 this.accordFactoryInfo
this.accordFactoryInfo = this.accordFactoryInfo.map((factory) => {
this.accordFactoryInfo = this.accordFactoryInfo.map(factory => {
// 确保每个工厂都有 vehicles 属性
if (!factory.vehicles) {
factory.vehicles = []
factory.vehicles = [];
}
// 确保 remainingArea 是一个数字且大于 0
factory.area = factory.area > 0 ? factory.area : 0
return factory
})
factory.area = factory.area > 0 ? factory.area : 0;
return factory;
});
// 过滤出有车辆的工厂
const factoriesWithVehicles = this.accordFactoryInfo.filter((factory) => factory.vehicles.length > 0)
const factoriesWithVehicles = this.accordFactoryInfo.filter(factory => factory.vehicles.length > 0);
this.factoriesWithVehicles = factoriesWithVehicles
await this.showAreaInfoDialog(factoriesWithVehicles)
await this.showAreaInfoDialog(factoriesWithVehicles);
})
.catch((error) => {
console.error('数据有问题', error)
})
});
},
drawFactory(factoryMultiPoly, factory, area, pointInfo) {
// 获取当前多边形集合的中心点
const center = turf.center(turf.multiPolygon(factory.geometry.coordinates))
const center = turf.center(turf.multiPolygon(factory.geometry.coordinates));
// 将中心点转换为 Mars3D 的 LngLatPoint 对象
const popupPosition = new mars3d.LngLatPoint(center.geometry.coordinates[0], center.geometry.coordinates[1])
const popupPosition = new mars3d.LngLatPoint(center.geometry.coordinates[0], center.geometry.coordinates[1]);
// 遍历每个多边形集合
factory.geometry.coordinates[0].forEach((coordGroup) => {
// 创建一个多边形图形
@ -723,39 +740,35 @@ export default {
outline: true,
outlineWidth: 1,
outlineColor: '#ffffff',
properties: {...factory.properties},
properties: { ...factory.properties },
},
time: new Date().getTime(),
time: new Date().getTime()
})
this.accordFactoryLayer.addGraphic(graphic)
this.accordFactoryLayer.addGraphic(graphic);
// 计算多边形中心与参考点的距离
const point = pointInfo && pointInfo.length > 0 ? pointInfo : this.form.endPoint.split(',').map(Number)
const distance = turf.distance(center.geometry.coordinates, point, {units: 'kilometers'}) * 1000 // 米
const distance = turf.distance(center.geometry.coordinates, point, { units: 'kilometers' }) * 1000; // 米
// 将多边形图形添加到地图层
this.accordFactoryInfo.push({
...graphic,
distance: distance,
popupPosition: popupPosition,
area:
this.hideform.redundancy && this.hideform.redundancy != 0 && area > 0
? area * (100 - this.hideform.redundancy) * 0.01
: area > 0
? area
: 0, // 如果 area 不是有效值,设置为 0 或其他默认值
area: this.hideform.redundancy && this.hideform.redundancy != 0 && area > 0
? area * (100 - this.hideform.redundancy) * 0.01
: area > 0
? area
: 0, // 如果 area 不是有效值,设置为 0 或其他默认值
})
})
},
// 显示面积信息弹框的方法
async showAreaInfoDialog(info) {
const graphics = this.accordFactoryLayer.getGraphics()
const promises = []
const graphics = this.accordFactoryLayer.getGraphics();
const promises = [];
info.forEach((item) => {
graphics.forEach((ele) => {
if (
ele.options.time === item.options.time &&
ele.options.style.properties.FID_1 === item.options.style.properties.FID_1
) {
const textInfo = `${item.area.toFixed(2)}\n${item.vehicles.map((e) => e.name).join(',')}`
if (ele.options.time === item.options.time && ele.options.style.properties.FID_1 === item.options.style.properties.FID_1) {
const textInfo = `${item.area.toFixed(2)}\n${item.vehicles.map(e => e.name).join(',')}`
const labelGraphic = new window.mars3d.graphic.LabelEntity({
id: 'label',
position: item.popupPosition,
@ -768,34 +781,34 @@ export default {
outlineColor: '#000000',
background: true,
backgroundColor: '#2f705f',
},
}
})
// 使用 Promise 确保标签添加完成后继续执行
const promise = new Promise((resolve, reject) => {
this.accordFactoryLayer.addGraphic(labelGraphic, () => {
resolve()
})
})
resolve();
});
});
promises.push(promise)
promises.push(promise);
}
})
})
this.$message.success('路线隐蔽规划成功')
const popupPositionList = info.map((item) => item.popupPosition)
let minLng = Infinity
let maxLng = -Infinity
let minLat = Infinity
let maxLat = -Infinity
this.$message.success("路线隐蔽规划成功")
const popupPositionList = info.map(item => item.popupPosition)
let minLng = Infinity;
let maxLng = -Infinity;
let minLat = Infinity;
let maxLat = -Infinity;
popupPositionList.forEach((point) => {
if (point.lng < minLng) minLng = point.lng
if (point.lng > maxLng) maxLng = point.lng
if (point.lat < minLat) minLat = point.lat
if (point.lat > maxLat) maxLat = point.lat
})
popupPositionList.forEach(point => {
if (point.lng < minLng) minLng = point.lng;
if (point.lng > maxLng) maxLng = point.lng;
if (point.lat < minLat) minLat = point.lat;
if (point.lat > maxLat) maxLat = point.lat;
});
// 创建一个矩形区域,包含所有点
const rectangle = Cesium.Rectangle.fromDegrees(minLng, minLat, maxLng, maxLat)
const rectangle = Cesium.Rectangle.fromDegrees(minLng, minLat, maxLng, maxLat);
this.viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
@ -806,29 +819,29 @@ export default {
orientation: {
heading: Cesium.Math.toRadians(0), // 方位角
pitch: Cesium.Math.toRadians(-90), // 俯仰角
roll: 0.0, // 翻滚角
roll: 0.0 // 翻滚角
},
duration: 2, // 飞行动画持续时间,单位为秒
})
duration: 2 // 飞行动画持续时间,单位为秒
});
},
// 弹框
async openDialog() {
this.multipleSelection = []
await fetch('./data/minTurnRadius.json')
.then((response) => {
return response.json()
})
.then(async (data) => {
this.dialogVisible = true
this.tableData = data
await this.$nextTick(() => {
this.multipleSelection = JSON.parse(Cookies.get('minTurnRadius'))
this.multipleSelection.forEach((item) => {
this.$refs.vxeTable.setCheckboxRowKey(item.id, true)
})
.then((response) => {
return response.json()
})
.then(async (data) => {
this.dialogVisible = true;
this.tableData = data
await this.$nextTick(() => {
this.multipleSelection = JSON.parse(Cookies.get('minTurnRadius'))
this.multipleSelection.forEach((item) => {
this.$refs.vxeTable.setCheckboxRowKey(item.id, true)
})
})
.catch((error) => {})
})
.catch((error) => {})
},
handleSelectionChange({records}) {
this.multipleSelection = records
@ -866,39 +879,35 @@ export default {
load: null,
minTurnRadius: null,
editing: true,
}
this.tableData.push(newRow)
};
this.tableData.push(newRow);
},
handleDelete(row) {
const index = this.tableData.findIndex((item) => item.id === row.id)
const index = this.tableData.findIndex(item => item.id === row.id);
if (index !== -1) {
this.tableData.splice(index, 1)
this.tableData.splice(index, 1);
}
},
handleEdit(row) {
this.$set(row, 'editing', true)
this.$set(row, 'editing', true);
},
handleSave(row) {
this.$set(row, 'editing', false)
this.$set(row, 'editing', false);
},
// 保存列表数据
suerCofirm() {
const parsedData = iniParser.parse(configIni)
axios
.post(
`http://${parsedData.http.address}:${parsedData.http.port}/api/equpment`,
JSON.stringify(this.tableData),
{
headers: {
Authorization: 'Bearer your_token_here',
'Content-Type': 'application/json',
},
}
)
.then((response) => {
this.$message.success('保存成功')
})
.catch((error) => {})
const parsedData = iniParser.parse(configIni);
axios.post(`http://${parsedData.http.address}:${parsedData.http.port}/api/equpment`, JSON.stringify(this.tableData), {
headers: {
'Authorization': 'Bearer your_token_here',
'Content-Type': 'application/json'
}
})
.then(response => {
this.$message.success('保存成功')
})
.catch(error => {
});
},
// 导入json文件
triggerFileUpload() {
@ -965,12 +974,21 @@ export default {
}
},
addPointToMap(type, point, time) {
const coords = time ? point.points.split(',').map(Number) : point.split(',').map(Number)
const coords = time
? point.points.split(',').map(Number)
: point.split(',').map(Number)
const graphic = new window.mars3d.graphic.PointEntity({
position: new window.mars3d.LngLatPoint(coords[0], coords[1]),
style: {
pixelSize: 10,
color: type === 'startPoint' ? 'red' : type === 'endPoint' ? 'red' : type === 'viaPoints' ? 'blue' : 'orange',
color:
type === 'startPoint'
? 'red'
: type === 'endPoint'
? 'red'
: type === 'viaPoints'
? 'blue'
: 'orange',
label: {
text:
type === 'startPoint'
@ -1004,7 +1022,9 @@ export default {
addPolygonToMap(type, area, time) {
const coords = JSON.parse(area.points)
const graphic = new window.mars3d.graphic.PolygonEntity({
positions: coords.map((coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])),
positions: coords.map(
(coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])
),
style: {
color: 'red',
opacity: 0.4,
@ -1059,55 +1079,94 @@ export default {
}
} else if (type === 'viaPoints') {
if (!row.points) {
const graphic = this.viaPoints.find((viaPoint) => viaPoint.style.time === row.time)
if (this.form.viaPoints.length === 1 && this.form.viaPoints[0].points === '') {
const graphic = this.viaPoints.find(
(viaPoint) => viaPoint.style.time === row.time
)
if (
this.form.viaPoints.length === 1 &&
this.form.viaPoints[0].points === ''
) {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.viaPoints[0].points = ''
graphic?.remove()
this.viaPoints = this.viaPoints.filter((viaPoint) => viaPoint.style.time !== row.time)
this.viaPoints = this.viaPoints.filter(
(viaPoint) => viaPoint.style.time !== row.time
)
} else {
this.form.viaPoints = this.form.viaPoints.filter((viaPoint) => viaPoint.time !== row.time)
this.form.viaPoints = this.form.viaPoints.filter(
(viaPoint) => viaPoint.time !== row.time
)
}
graphic?.remove()
this.viaPoints = this.viaPoints.filter((viaPoint) => viaPoint.style.time !== row.time)
this.viaPoints = this.viaPoints.filter(
(viaPoint) => viaPoint.style.time !== row.time
)
} else {
const graphic = this.viaPoints.find((viaPoint) => viaPoint.style.time === row.time)
const graphic = this.viaPoints.find(
(viaPoint) => viaPoint.style.time === row.time
)
this.updatePointPosition(graphic, row.points)
}
} else if (type === 'avoidPoints') {
if (!row.points) {
const graphic = this.avoidPoints.find((avoidPoint) => avoidPoint.style.time === row.time)
if (this.form.avoidPoints.length === 1 && this.form.avoidPoints[0].points === '') {
const graphic = this.avoidPoints.find(
(avoidPoint) => avoidPoint.style.time === row.time
)
if (
this.form.avoidPoints.length === 1 &&
this.form.avoidPoints[0].points === ''
) {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.avoidPoints[0].points = ''
} else {
this.form.avoidPoints = this.form.avoidPoints.filter((avoidPoint) => avoidPoint.time !== row.time)
this.form.avoidPoints = this.form.avoidPoints.filter(
(avoidPoint) => avoidPoint.time !== row.time
)
}
graphic?.remove()
this.avoidPoints = this.avoidPoints.filter((avoidPoint) => avoidPoint.style.time !== row.time)
this.avoidPoints = this.avoidPoints.filter(
(avoidPoint) => avoidPoint.style.time !== row.time
)
} else {
const graphic = this.avoidPoints.find((avoidPoint) => avoidPoint.style.time === row.time)
const graphic = this.avoidPoints.find(
(avoidPoint) => avoidPoint.style.time === row.time
)
this.updatePointPosition(graphic, row.points)
}
} else if (type === 'avoidAreas') {
if (!row.points) {
const graphic = this.avoidAreas.find((avoidArea) => avoidArea.style.time === row.time)
if (this.form.avoidAreas.length === 1 && this.form.avoidAreas[0].points === '') {
const graphic = this.avoidAreas.find(
(avoidArea) => avoidArea.style.time === row.time
)
if (
this.form.avoidAreas.length === 1 &&
this.form.avoidAreas[0].points === ''
) {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.avoidAreas[0].points = ''
} else {
this.form.avoidAreas = this.form.avoidAreas.filter((avoidArea) => avoidArea.time !== row.time)
this.form.avoidAreas = this.form.avoidAreas.filter(
(avoidArea) => avoidArea.time !== row.time
)
}
graphic?.remove()
this.avoidAreas = this.avoidAreas.filter((avoidArea) => avoidArea.style.time !== row.time)
this.avoidAreas = this.avoidAreas.filter(
(avoidArea) => avoidArea.style.time !== row.time
)
} else {
const graphic = this.avoidAreas.find((avoidArea) => avoidArea.style.time === row.time)
const graphic = this.avoidAreas.find(
(avoidArea) => avoidArea.style.time === row.time
)
this.updatePolygonPosition(graphic, row.points)
}
}
},
handleEmptyArray(type) {
if (type === 'viaPoints' && this.form.viaPoints.length === 1 && this.form.viaPoints[0].points === '') {
if (
type === 'viaPoints' &&
this.form.viaPoints.length === 1 &&
this.form.viaPoints[0].points === ''
) {
this.form.viaPoints = []
} else if (
type === 'avoidPoints' &&
@ -1115,7 +1174,11 @@ export default {
this.form.avoidPoints[0].points === ''
) {
this.form.avoidPoints = []
} else if (type === 'avoidAreas' && this.form.avoidAreas.length === 1 && this.form.avoidAreas[0].points === '') {
} else if (
type === 'avoidAreas' &&
this.form.avoidAreas.length === 1 &&
this.form.avoidAreas[0].points === ''
) {
this.form.avoidAreas = []
}
},
@ -1130,7 +1193,9 @@ export default {
if (!graphic) return
try {
const coords = JSON.parse(pointsStr)
graphic.positions = coords.map((coord) => new window.mars3d.LngLatPoint(coord[0], coord[1]))
graphic.positions = coords.map(
(coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])
)
} catch (error) {
graphic.remove()
}
@ -1285,7 +1350,9 @@ export default {
success: (graphic) => {
this.avoidAreas.push(graphic)
const avoidAreasGeoJSON = graphic.toGeoJSON()
const points = JSON.stringify(avoidAreasGeoJSON.geometry.coordinates[0])
const points = JSON.stringify(
avoidAreasGeoJSON.geometry.coordinates[0]
)
if (
this.form.avoidAreas.length == 1 &&
this.form.avoidAreas[0].points == '' &&
@ -1318,8 +1385,11 @@ export default {
}
// 计算边权重(距离,单位:米)
const distance =
turf.distance(turf.point(coords[0][0]), turf.point(coords[coords.length - 1][0]), {units: 'kilometers'}) *
1000
turf.distance(
turf.point(coords[0][0]),
turf.point(coords[coords.length - 1][0]),
{units: 'kilometers'}
) * 1000
// 构建邻接表(双向图)
graph[startNode] = graph[startNode] || {}
@ -1348,17 +1418,22 @@ export default {
return nearestNode
},
// 3. 路径规划主函数(经纬度坐标输入) - 支持途经点 + 避让点/区域
async planRoute(startCoord, endCoord, viaPoints = [], avoidObstacles = null) {
async planRoute(
startCoord,
endCoord,
viaPoints = [],
avoidObstacles = null
) {
const {graph, nodeCoords} = this.roadNetworkGeoJSONBuild
// 按顺序组合点:起点 -> 途经点 -> 终点
const points = [startCoord]
const points = [startCoord];
if (viaPoints && viaPoints.length > 0) {
viaPoints.forEach((viaPoint) => {
points.push(viaPoint.geometry.coordinates)
})
points.push(viaPoint.geometry.coordinates);
});
}
points.push(endCoord)
points.push(endCoord);
const fullPath = []
const infoList = []
for (let i = 0; i < points.length - 1; i++) {
@ -1382,7 +1457,8 @@ export default {
for (const [node, coord] of Object.entries(nodeCoords)) {
const pt = turf.point(coord)
avoidObstacles.features.forEach((ob) => {
if (turf.booleanPointInPolygon(pt.geometry, ob.geometry)) obstacleNodes.push(node)
if (turf.booleanPointInPolygon(pt.geometry, ob.geometry))
obstacleNodes.push(node)
})
}
obstacleNodes.forEach((node) => delete tempGraph[node])
@ -1395,7 +1471,10 @@ export default {
delete tempGraph[node][targetNode]
continue
}
const line = turf.lineString([nodeCoords[node], nodeCoords[targetNode]])
const line = turf.lineString([
nodeCoords[node],
nodeCoords[targetNode],
])
avoidObstacles.features.forEach((area) => {
if (turf.booleanCrosses(line, area)) {
delete tempGraph[node][targetNode]
@ -1421,17 +1500,21 @@ export default {
if (!this.join) {
segment = this.roadNetworkGeoJSON.features.find(
(f) =>
(f.properties.FNODE_ == currentNode && f.properties.TNODE_ == nextNode) ||
(f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)
(f.properties.FNODE_ == currentNode &&
f.properties.TNODE_ == nextNode) ||
(f.properties.FNODE_ == nextNode &&
f.properties.TNODE_ == currentNode)
)
} else {
segment = this.roadNetworkGeoJSON.features.find(
(f) =>
((f.properties.FNODE_ == currentNode && f.properties.TNODE_ == nextNode) ||
(f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)) &&
f.properties.载重吨 >= this.inputform.load &&
f.properties.宽度 >= this.inputform.width &&
f.properties.曲率半 <= this.inputform.minTurnRadius
(f) =>
((f.properties.FNODE_ == currentNode &&
f.properties.TNODE_ == nextNode) ||
(f.properties.FNODE_ == nextNode &&
f.properties.TNODE_ == currentNode) ) &&
f.properties.载重吨 >= this.inputform.load &&
f.properties.宽度 >= this.inputform.width &&
f.properties.曲率半 <= this.inputform.minTurnRadius
)
}
if (segment) {
@ -1451,13 +1534,20 @@ export default {
this.shortestPathLayer.clear()
this.shortestPathList = []
this.infoList = []
const startPoint = turf.point(this.pointQD.toGeoJSON().geometry.coordinates).geometry.coordinates // 起点
const endPoint = turf.point(this.pointZD.toGeoJSON().geometry.coordinates).geometry.coordinates // 终点
const startPoint = turf.point(
this.pointQD.toGeoJSON().geometry.coordinates
).geometry.coordinates // 起点
const endPoint = turf.point(this.pointZD.toGeoJSON().geometry.coordinates)
.geometry.coordinates // 终点
// 途经点
const viaPointsGeoJSON = this.viaPoints.map((point) => point.toGeoJSON()) || []
const viaPointsTurf = viaPointsGeoJSON.map((p) => turf.point(p.geometry.coordinates))
const viaPointsGeoJSON =
this.viaPoints.map((point) => point.toGeoJSON()) || []
const viaPointsTurf = viaPointsGeoJSON.map((p) =>
turf.point(p.geometry.coordinates)
)
// 避让点
const avoidPointsGeoJSON = this.avoidPoints.map((point) => point.toGeoJSON()) || []
const avoidPointsGeoJSON =
this.avoidPoints.map((point) => point.toGeoJSON()) || []
const avoidPointsPolygons = avoidPointsGeoJSON.map((point) => {
return turf.circle(
turf.point(point.geometry.coordinates),
@ -1466,9 +1556,18 @@ export default {
)
})
// 避让区域
const avoidAreasGeoJSON = this.avoidAreas.map((area) => area.toGeoJSON({closure: true})) || []
const obstaclesGeoJSON = turf.featureCollection([...avoidPointsPolygons, ...avoidAreasGeoJSON])
const route = await this.planRoute(startPoint, endPoint, viaPointsTurf, obstaclesGeoJSON)
const avoidAreasGeoJSON =
this.avoidAreas.map((area) => area.toGeoJSON({closure: true})) || []
const obstaclesGeoJSON = turf.featureCollection([
...avoidPointsPolygons,
...avoidAreasGeoJSON,
])
const route = await this.planRoute(
startPoint,
endPoint,
viaPointsTurf,
obstaclesGeoJSON
)
this.drawPath(route)
},
@ -1489,7 +1588,9 @@ export default {
this.infoList = path.infoList.map((item) => item.properties)
},
/** 隐蔽规划 */
concealed() {},
concealed() {
},
},
}
</script>
@ -1563,14 +1664,14 @@ export default {
display: flex;
justify-content: space-between;
}
.control-panel .title .joinCheck {
.control-panel .title .joinCheck {
font-size: 14px;
color: #555;
}
.el-checkbox {
margin-right: 5px !important;
margin-right: 5px!important;
}
.importJson {
display: flex;
flex-direction: row;
@ -1620,4 +1721,6 @@ export default {
.popDiloag .popDiloag-title {
font-weight: 500;
}
.popDiloag .popDiloag-p {
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,25 +21,35 @@ module.exports = defineConfig({
})
/* 2. 追加 ES5 规则(只转 src不转 node_modules */
config.module.rules.push({
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: {ie: '11'}, // 强制 ES5
corejs: 3,
useBuiltIns: 'entry',
},
],
],
},
// config.module.rules.push({
// test: /\.js$/,
// include: path.resolve(__dirname, 'src'),
// use: {
// loader: 'babel-loader',
// options: {
// presets: [
// [
// '@babel/preset-env',
// {
// targets: {ie: '11'}, // 强制 ES5
// corejs: 3,
// useBuiltIns: 'entry',
// },
// ],
// ],
// },
// },
// })
},
devServer: {
client: { overlay: false },
proxy: {
'/api': {
target: 'http://192.168.3.35:8381',
changeOrigin: true,
pathRewrite: { '^/api': '' },
},
})
},
},
css: {