wuxiang 2 年 前
コミット
ed9ec1460d
7 ファイル変更632 行追加607 行削除
  1. 275 279
      package-lock.json
  2. 2 0
      package.json
  3. BIN
      public/static/enemy.glb
  4. BIN
      public/static/friend.glb
  5. 5 2
      src/main.js
  6. 289 304
      src/views/situation/index.vue
  7. 61 22
      vue.config.js

ファイルの差分が大きいため隠しています
+ 275 - 279
package-lock.json


+ 2 - 0
package.json

@@ -14,6 +14,8 @@
   "main": "background.js",
   "dependencies": {
     "@jiaminghi/data-view": "^2.10.0",
+    "cesium": "1.93",
+    "copy-webpack-plugin": "5.0",
     "core-js": "^3.6.5",
     "echarts": "^4.9.0",
     "element-ui": "^2.15.13",

BIN
public/static/enemy.glb


BIN
public/static/friend.glb


+ 5 - 2
src/main.js

@@ -5,8 +5,7 @@ import 'element-ui/lib/theme-chalk/index.css';
 import router from './router'
 import store from './store'
 import echarts from 'echarts'
-import 'echarts/map/js/china'
-import 'echarts/map/js/world'
+import 'echarts/map/js/china' 
 import websocket from 'vue-native-websocket'
 import wst from  '@/utils/websocket'
 import SvgIcon from '@/components/svgIcon/index.vue'// svg component
@@ -14,6 +13,10 @@ import '@/assets/svg'  // 导入图标资源
 // 将自动注册所有组件为全局组件
 import dataV from '@jiaminghi/data-view'
 import VueWorker from 'vue-worker' // Web worker插件
+import * as Cesium from 'cesium/Cesium'
+import widget from 'cesium/Widgets/widgets.css'
+Vue.prototype.Cesium = Cesium
+Vue.prototype.Widgets = widget
 Vue.use(VueWorker)
 Vue.use(dataV)
 Vue.use(websocket, 'ws://localhost:1234', {// 这里要填的是服务器的地址,可以换一个在线服务器wss://echo.websocket.org

+ 289 - 304
src/views/situation/index.vue

@@ -3,267 +3,149 @@
     <el-row :gutter="10" style="height:100%;">
 
       <el-col style="height:100%;position: relative;" :span="24">
-        <el-radio-group class="model" v-model="pattern" label="size control" size="small">
-          <el-radio-button label="local" @click="echartsChange()">本地态势</el-radio-button>
-          <el-radio-button label="remote" @click="echartsChange()">远端态势</el-radio-button>
-          <el-radio-button label="combine" @click="echartsChange()">融合态势</el-radio-button>
-          <el-radio-button label="global" @click="echartsChange()">全局态势</el-radio-button>
-        </el-radio-group>
-        <!-- <dv-decoration-12 class="radar" /> -->
-          <div class="echarts-box">
-            <div id="mapEchart" class="mapecharts"></div>
-          </div>
-      </el-col>
-
-      <!-- <el-col :span="6" style="display: flex;flex-direction: column; height: 100%;">
-      <el-card class=" tableHeight">
+        <el-card class="table1">
           <div slot="header" class="clearfix">
-            <span>实例信息</span>
+            <span>兵力装备显示</span>
           </div>
-          <el-table @current-change="instanceChange" :data="instancetable" :row-style="{height:'20px'}" :cell-style="{padding:'0px'}" style="font-size: 10px;width: 100%;" height="100%" highlight-current-row border>
-            <el-table-column prop="instanceID" label="实例ID"></el-table-column>
-            <el-table-column prop="instanceName" label="实例名称"></el-table-column>
+          <el-table :data="maptable" @current-change="instanceChange" :row-style="{ height: '20px' }" :cell-style="{ padding: '0px' }">
+            <el-table-column prop="platID" label="ID"></el-table-column>
+            <el-table-column prop="platName" label="名称"></el-table-column>
+            <el-table-column prop="isEnemy" label="敌我属性"></el-table-column>
           </el-table>
-      </el-card>
-      <el-card class=" tableHeight">
+        </el-card>
+        <el-card class="table2">
           <div slot="header" class="clearfix">
-            <span>初始化参数</span>
+            <span>战损显示</span>
           </div>
-          <el-table :data="propertyinittable" :row-style="{height:'20px'}" :cell-style="{padding:'0px'}" style="font-size: 10px;width: 100%;" height="100%" highlight-current-row border>
-            <el-table-column prop="key" label="属性"></el-table-column>
-            <el-table-column prop="value" label="值"></el-table-column>
+          <el-table :data="healthtable" @current-change="instanceChange" :row-style="{ height: '20px' }" :cell-style="{ padding: '0px' }">
+            <el-table-column prop="platID" label="ID"></el-table-column>
+            <el-table-column prop="platName" label="名称"></el-table-column>
+            <el-table-column prop="platState" label="健康度"></el-table-column>
           </el-table>
-      </el-card>
-      <el-card class=" tableHeight">
-          <div slot="header" class="clearfix">
-            <span>运行状态</span>
-          </div>
-          <el-table :data="propertycontroltable" :row-style="{height:'20px'}" :cell-style="{padding:'0px'}" style="font-size: 10px;width: 100%;" height="100%" highlight-current-row border>
-            <el-table-column prop="key" label="属性"></el-table-column>
-            <el-table-column prop="value" label="值"></el-table-column>
-          </el-table>
-      </el-card>
-    </el-col> -->
+        </el-card>
+        <div class="main-layout">
+          <div id="cesiumContainer" class="mapecharts"></div>
+        </div>
+      </el-col>
     </el-row>
   </div>
 </template>
 <script>
 import { mapGetters } from 'vuex'
+
+import friendplane from "../../../public/static/friend.glb"
+import enemyplane from "../../../public/static/enemy.glb"
 export default ({
   computed: {
     ...mapGetters([
       'map',
-      'init',
-      'platforms',
-      'instances',
-      'properties',
-      'platformShow'
+      'init'
     ]),
   },
-  watch: {
-    map: {
-      handler: function (val, oldVal) {
-      
-      }
-    },
-    init: {
-      handler: function (val, oldVal) {
-        console.log(val)
-      }
-    },
-    platforms: {
-      handler: function (val, oldVal) {
-
-      }
-    },
-    instances: {
-      handler: function (val, oldVal) {
-
-        this.instancetable = val
-      }
-    },
-    platformID: {
-      handler: function (val, oldVal) {
-        this.$wst.send({
-          url: 'getRadarInstances',
-          data: { PlatformID: val }
-        })
-
-      }
-    },
-    properties: {
-      handler: function (val, oldVal) {
-        this.propertyinittable = val.InitParams
-        this.propertycontroltable = val.CtrlParams
-      }
-    },
-    platformShow: {
-      handler: function (val, oldVal) {
-        this.resizeDom()
-      }
-    }
-  },
+  
   data() {
     return {
-      pattern: "global",
+      pattern: "two-dimensional",
       instancetable: null,
       propertyinittable: null,
       propertycontroltable: null,
       timer: null,
+      viewer: null,
       mapEchart: null,
-      mapOption: {
-        aria: {
-          show: true
+      maptable: [
+        {
+          'platID': '1001',
+          'platName': '弹道导弹1',
+          'isEnemy': '我方'
         },
-        tooltip: {
-          formatter: '{a}&name:{b}&location:{c}',
+        {
+          'platID': '1002',
+          'platName': '弹道导弹2',
+          'isEnemy': '我方'
         },
-        legend: {
-          orient: 'vertical',
-          left: 'left',
-          data: ['categoryA', 'categoryB', 'categoryC']
+        // {
+        //   'platID': '1003',
+        //   'platName': '弹道导弹3',
+        //   'isEnemy': '我方'
+        // },
+        // {
+        //   'platID': '1004',
+        //   'platName': '弹道导弹4',
+        //   'isEnemy': '我方'
+        // },
+        // {
+        //   'platID': '1005',
+        //   'platName': '弹道导弹5',
+        //   'isEnemy': '我方'
+        // },
+        // {
+        //   'platID': '1006',
+        //   'platName': '弹道导弹6',
+        //   'isEnemy': '我方'
+        // },
+        // {
+        //   'platID': '1007',
+        //   'platName': '弹道导弹7',
+        //   'isEnemy': '我方'
+        // },
+        {
+          'platID': '6001',
+          'platName': 'THADD系统1',
+          'isEnemy': '敌方'
         },
-        geo: {
-          map: "china",
-          // zoom: 1,
-          // center: [120.397128, 25.916527],
-          roam: true,
-          scaleLimit: {
-            min: 1,
-            max: 20
-          },
-          label: {
-            color: "#fff",
-            show: true
-          },
-          emphasis: {
-            label: {
-              color: "#fff",
-              show: true
-            },
-            itemStyle: {
-              areaColor: {
-                x: 0,
-                y: 0,
-                x2: 0,
-                y2: 1,
-                colorStops: [
-                  {
-                    offset: 0,
-                    color: "#073684" // 0% 处的颜色
-                  },
-                  {
-                    offset: 1,
-                    color: "#2B91B7" // 100% 处的颜色
-                  }
-                ]
-              }
-            }
-          },
-          itemStyle: {
-            areaColor: {
-              x: 0,
-              y: 0,
-              x2: 0,
-              y2: 1,
-              colorStops: [
-                {
-                  offset: 0,
-                  color: "#073684" // 0% 处的颜色
-                },
-                {
-                  offset: 1,
-                  color: "#061E3D" // 100% 处的颜色
-                }
-              ]
-            },
-            borderColor: "#87ADCB",
-            shadowColor: "rgba(10,76,139,1)",
-            shadowOffsetY: 0,
-            shadowBlur: 60,
-            borderWidth: 1
-          },
-          tooltip: {
-            show: false
-          }
+        {
+          'platID': '6002',
+          'platName': 'THADD系统2',
+          'isEnemy': '敌方'
         },
-
-        series: [
-          {
-            name: '我方飞机',
-            type: 'scatter',
-            coordinateSystem: 'geo',
-            symbol: 'image://' + require('@/assets/image/redairplane.png'),
-            symbolSize: 20,
-            data: null,
-            label: {
-              normal: {
-                formatter: '{b}',
-                position: 'right',
-                show: false
-              },
-              emphasis: {
-                show: true
-              }
-            },
-            itemStyle: {
-              normal: {
-                color: '#ddb926'
-                //color: '#0000ff'
-              }
-            }
-          },
-          {
-            name: '我方dddd',
-            type: 'scatter',
-            coordinateSystem: 'geo',
-            symbol: 'image://' + require('@/assets/image/redmissile.png'),
-            symbolSize: 20,
-            data: null,
-            label: {
-              normal: {
-                formatter: '{b}',
-                position: 'right',
-                show: false
-              },
-              emphasis: {
-                show: true
-              }
-            },
-            itemStyle: {
-              normal: {
-                color: '#ddb926'
-                //color: '#0000ff'
-              }
-            }
-          },
-          {
-            name: '敌方',
-            type: 'scatter',
-            coordinateSystem: 'geo',
-            symbol: 'image://' + require('@/assets/image/blueairplane.png'),
-            symbolSize: 20,
-            data: null,
-            label: {
-              normal: {
-                formatter: '{b}',
-                position: 'right',
-                show: false
-              },
-              emphasis: {
-                show: true
-              }
-            },
-            itemStyle: {
-              normal: {
-                color: '#ff0000'
-              }
-            }
-          },
-
-
-        ]
-      }
+      ],
+      healthtable: [
+        {
+          'platID': '1001',
+          'platName': '弹道导弹1',
+          'platState': "85%"
+        },
+        {
+          'platID': '1002',
+          'platName': '弹道导弹2',
+          'platState': "90%"
+        },
+        // {
+        //   'platID': '1003',
+        //   'platName': '弹道导弹3',
+        //   'platState': "90%"
+        // },
+        // {
+        //   'platID': '1004',
+        //   'platName': '弹道导弹4',
+        //   'platState': "95%"
+        // },
+        // {
+        //   'platID': '1005',
+        //   'platName': '弹道导弹5',
+        //   'platState': "100%"
+        // },
+        // {
+        //   'platID': '1006',
+        //   'platName': '弹道导弹6',
+        //   'platState': "100%"
+        // },
+        // {
+        //   'platID': '1007',
+        //   'platName': '弹道导弹7',
+        //   'platState': "100%"
+        // },
+        {
+          'platID': '6001',
+          'platName': 'THADD系统1',
+          'platState': "80%"
+        },
+        {
+          'platID': '6002',
+          'platName': 'THADD系统2',
+          'platState': '80%'
+        },
+      ]
 
 
 
@@ -271,84 +153,134 @@ export default ({
 
   },
   mounted() {
-    this.echartsInit();
-  },
-  activated() {
-    this.echartsInit();
-    // 页面加载设置高度自适应
-    window.onresize = () => {
-
-      this.resizeDom()
-    };
-    // 页面加载设置高度自适应
-    this.resizeDom()
-    
-    this.setTimer();
     
-
+    this.cesiumInit();
+    if (this.init == 100) {
+      this.$wst.send({url:"getLocalMap"});
+      this.setTimer();
+    }
   },
-  deactivated() {
+  beforeDestroy() {
     this.timerDestory()
   },
   methods: {
     setTimer() {
-      if(this.timer == null) {
-      this.timer = setInterval(() => {
-        setTimeout(this.echartsInit(), 0);
-        
-      }, 1000)
+      if (this.timer == null) {
+        this.timer = setInterval(() => {
+          
+        }, 1000)
       }
     },
     //初始化echarts
-    echartsInit() {
-      if (this.mapEchart == null) {
-          this.mapEchart = this.$echarts.init(document.getElementById('mapEchart'))
-        }
-      if (this.pattern == 'local') {
-        if (this.init == 100) { this.$wst.send({ url: 'getLocalMap' }) }
-        if (this.map != null && this.map.type == 'local') { this.submitForm('mapEchart') }
-      } else
-      if (this.pattern == 'remote') {
-        if (this.init == 100) { this.$wst.send({ url: 'getRemoteMap' }) }
-        if (this.map != null && this.map.type == 'remote') { this.submitForm('mapEchart') }
-      } else
-      if (this.pattern == 'combine') {
-        if (this.init == 100) { this.$wst.send({ url: 'getCombineMap' }) }
-        if (this.map != null && this.map.type == 'combine') { this.submitForm('mapEchart') }
-      } else
-      if (this.pattern == 'global') {
-        if (this.init == 100) { this.$wst.send({ url: 'getGlobalMap' }) }
-        if (this.map != null && this.map.type == 'global') { this.submitForm('mapEchart') }
-        
-      }
-      this.mapEchart.setOption(this.mapOption);
-      // this.resizeDom()
+    cesiumInit() {
+      this.viewer = new this.Cesium.Viewer('cesiumContainer', {
+        animation: false, // 是否显示时间轴动画
+        baseLayerPicker: false,
+        homeButton: false,
+        geocoder: false,
+        timeline: false,
+        fullscreenButton: false,
+        sceneModePicker: false,
+        navigationHelpButton: false,
+        selectionIndicator: false,
+        imageryProvider:  new this.Cesium.WebMapServiceImageryProvider({
+          url: 'http://localhost:8080/geoserver/map/wms',
+            // 这里是自定义的图层名称
+            layers: 'map',
+            parameters: {
+                service: 'WMS',
+                format: 'image/png',
+                transparent: true
+            }
+        }),
+
+      });
+      // imageryProvider:  new this.Cesium.WebMapTileServiceImageryProvider({
+      //     url: "http://localhost:8080/geoserver/gwc/service/wmts/rest/map:map/{style}/{TileMatrixSet}/{TileMatrixSet}:13/{TileRow}/{TileCol}?format=image/png",
+      //     layer: 'map:map',
+      //     style: 'raster',
+      //     format: 'image/png',
+      //     tileMatrixSetID: 'EPSG:900913',      //一般使用EPSG:3857坐标系
+      //     tileMatrixLabels: ['13'],
+      //     tilingScheme: new this.Cesium.WebMercatorTilingScheme(),
+      //     maximumLevel: 13,
+      //     rectangle: new this.Cesium.Rectangle.fromDegrees(106.43, 17.47, 132.97, 35.56)
+      //   }),
 
+      // });
+      this.viewer._cesiumWidget._creditContainer.style.display = "none";
+      this.viewer.camera.setView({
+        destination: new this.Cesium.Cartesian3.fromDegrees(117.918977,25.0,1500000),
+        // 方向,俯视和仰视的视角
+        // orientation:{
+        //   heading: this.Cesium.Math.toRadians(90),//坐标系旋转90度
+        //   pitch: this.Cesium.Math.toRadians(-45) ,//设置俯仰角度为-45度
+        // }
+      })
+      this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 1500000;  //相机高度的最大值
     },
-    //通过窗体高宽计算容器高宽,渲染echart图表的div的宽高度以达到自适应目的
-    resizeDom() {
-      console.log("高度自适应")
-      this.mapEchart.resize()
+    removeAllModel(){
+      this.viewer.entities.removeAll(); // 移除全部模型
     },
-    echartsChange() {
-      this.timerDestory()
-      this.echartsInit();
-      // this.setTimer();
+    initFriendModel(){
+      this.map.data.friend.forEach((element) => {
+        console.log(element.value[0])
+        console.log(element.value[1])
+        console.log(element.value[2])
+
+        this.viewer.entities.add({
+
+          name: element.name,
+
+          position: this.Cesium.Cartesian3.fromDegrees(element.value[0], element.value[1], element.value[2]),
+
+          model: {
+
+          uri: friendplane,
+
+          minimumPixelSize: 128,
+
+          maximumScale: 2000,
+
+          },
+
+          });
+     });
     },
+    initEnemyModel(){
+      this.map.data.enemy.forEach((element) => {
+        console.log(element.value[0])
+        console.log(element.value[1])
+        console.log(element.value[2])
+
+        this.viewer.entities.add({
+
+          name: element.name,
+
+          id: element.value[0], 
+
+          position: this.Cesium.Cartesian3.fromDegrees(element.value[0], element.value[1], element.value[2]),
+
+          model: {
+
+          uri: enemyplane,
+
+          minimumPixelSize: 228,
+
+          maximumScale: 4000,
+
+          },
+
+          });
+     });
+
+    },
+    //通过窗体高宽计算容器高宽,渲染echart图表的div的宽高度以达到自适应目的
     timerDestory() {
       if (this.timer) {
         clearInterval(this.timer);
-        this.timer == null;
       }
     },
-    submitForm(map) {
-      console.log("放入数据")
-      this.mapOption.series[0].data = this.map.data.friend;
-      // this.mapOption.series[1].data = this.map.data.friend.Missiles;
-      this.mapOption.series[2].data = this.map.data.enemy;
-      this.mapEchart.setOption(this.mapOption);
-      console.log(this.mapOption);
-    },
     instanceChange(val) {
 
       if (val.instanceName.includes("信号侦察")) {
@@ -357,44 +289,88 @@ export default ({
           data: { InstanceID: val.instanceID }
         })
       } else
-      if (val.instanceName.includes("导航")) {
+        if (val.instanceName.includes("导航")) {
           this.$wst.send({
             url: 'getNavParams',
             data: { InstanceID: val.instanceID }
           })
 
-      } else
-      if (val.instanceName.includes("雷达")) {
+        } else
+          if (val.instanceName.includes("雷达")) {
             this.$wst.send({
               url: 'getRadarParams',
               data: { InstanceID: val.instanceID }
             })
 
-      } else
-      if (val.instanceName.includes("电子攻击")) {
+          } else
+            if (val.instanceName.includes("电子攻击")) {
               this.$wst.send({
                 url: 'getECMParams',
                 data: { InstanceID: val.instanceID }
-            })
-      }
+              })
+            }
 
     }
   },
+  watch: {
+    init: {
+      handler: function (val, oldVal) {
+        console.log(val)
+        this.setTimer();
+      }
+    },
+    map: {
+      handler: function (val, oldVal) {
+        if(this.viewer != null){
+        this.removeAllModel();
+        this.initFriendModel();
+        this.initEnemyModel();
+        }
+      }
+    }
+  },  
 })
 </script>
 <style scoped>
 .model {
   position: absolute;
   top: 20px;
-  left: 20px;
+  left: 100px;
   z-index: 999;
 }
 
-.radar {
+.table1 {
   position: absolute;
-  top: 20px;
+  top: 10px;
+  left: 10px;
+  z-index: 999;
+  width: 400px;
+  height: 400px;
+
+}
+
+.table1 /deep/ .el-card__header {
+  background-color: #11144e;
+  color: white;
+}
+
+.table2 {
+  position: absolute;
+  top: 430px;
   right: 20px;
+  z-index: 999;
+  width: 400px;
+  height: 400px;
+
+}
+
+.table2 /deep/ .el-card__header {
+  background-color: #11144e;
+  color: white;
 }
+
+
+
 .box-card {
   min-height: 100%;
   height: 100%;
@@ -408,6 +384,14 @@ export default ({
 .echarts-box {
   height: 100%;
   width: 100%;
+  background-image: url('~@/assets/image/map-bg.png');
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+}
+
+.main-layout {
+  height: 100%;
+  width: 100%;
 }
 
 .container {
@@ -427,4 +411,5 @@ export default ({
 .tableHeight /deep/ .el-card__body {
   height: calc(100% - 95px) !important;
 
-}</style>  
+}
+</style>  

+ 61 - 22
vue.config.js

@@ -1,3 +1,7 @@
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const webpack = require('webpack') 
+const cesiumSource = 'node_modules/cesium/Source'
+const cesiumWorkers = '../Build/Cesium/Workers'
 const path = require("path");
 function resolve(dir) {
   return path.join(__dirname, dir);
@@ -19,8 +23,29 @@ module.exports = {
     transpileDependencies: [], // babel-loader 默认会跳过 node_modules 依赖。
     productionSourceMap: false, // 是否为生产环境构建生成 source map
   
-    //调整内部的 webpack 配置
-    configureWebpack: () => { },
+    configureWebpack: {
+      plugins: [
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' }]),
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' }]),
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }]),
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers' }]),
+   
+        new webpack.DefinePlugin({
+          CESIUM_BASE_URL: JSON.stringify('./')
+        })
+      ],
+      module: {
+        unknownContextCritical: false,
+        unknownContextRegExp: /\/cesium\/cesium\/Source\/Core\/buildModuleUrl\.js/
+      },
+      // 配置cesium----开始
+      amd: {
+        toUrlUndefined: true
+      },
+      output: {
+        sourcePrefix: ' '
+      }
+     },
     devServer: {
       proxy: {
         '/socket.io':{
@@ -30,9 +55,17 @@ module.exports = {
         },
         '/sockjs-node': {
           target: 'http://192.168.1.6:1234',
-          ws: false,
+          ws: true,
           changeOrigin: true
         }
+        // '/geoserver': {
+        //   target: 'http://localhost:8080',
+        //   ws: true,
+        //   changeOrigin: true,
+        //   // pathRewrite:{
+        //   //   "^/geoserver":""
+        //   // } 
+        // }
           
       }
     },
@@ -42,23 +75,29 @@ module.exports = {
         .set("@", resolve("src"))
         .set("assets", resolve("src/assets"))
         .set("components", resolve("src/components"))
-        .set("public", resolve("public"));
-      // set svg-sprite-loader
-      config.module
-        .rule('svg')
-        .exclude.add(resolve('src/assets'))  // 存放 svg 目录的目录
-        .end()
-      config.module
-        .rule('assets')
-        .test(/\.svg$/)
-        .include.add(resolve('src/assets'))  // 存放 svg 目录的目录
-        .end()
-        .use('svg-sprite-loader')
-        .loader('svg-sprite-loader')
-        .options({
-          symbolId: 'icon-[name]'
-        })
-        .end()
+        .set("public", resolve("public"))
+        .set("cesium",path.resolve(__dirname, cesiumSource))
+    // set svg-sprite-loader
+    config.module
+      .rule('svg')
+      .exclude.add(resolve('src/assets'))  // 存放 svg 目录的目录
+      .end()
+    config.module
+      .rule('assets')
+      .test(/\.svg$/)
+      .include.add(resolve('src/assets'))  // 存放 svg 目录的目录
+      .end()
+      .use('svg-sprite-loader')
+      .loader('svg-sprite-loader')
+      .options({
+        symbolId: 'icon-[name]'
+      })
+      .end()
+    config.module
+      .rule('glb')
+      .test(/\.glb$/)
+      .use('url-loader')
+      .loader('url-loader')
+      .end();
     }
-
-  }
+  }

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません