From 42f42dc88214f283b43c422f37e10ab45c5c5578 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期三, 12 三月 2025 17:32:13 +0800 Subject: [PATCH] 1. 新增绘图模式的切换 2. 新增行政区划的切换展示 --- src/utils/map/util.js | 2 src/views/historymode/HistoryMode.vue | 14 + src/model/FactorDatas.js | 56 ++++++- src/model/Factor.js | 41 +++-- src/components.d.ts | 2 src/components/search/SearchBar.vue | 4 src/views/HomePage.vue | 76 +++++----- src/router/index.js | 6 src/components/map/MapScene.vue | 6 src/components/map/MapToolbox.vue | 9 + src/components/monitor/FactorLegend.vue | 69 ++++++++- /dev/null | 40 ----- src/components/core/CoreMenu.vue | 4 src/stores/toolbox.js | 5 src/views/underwaymix/UnderwayMixMode.vue | 6 src/components/search/OptionDevice.vue | 1 src/components/search/OptionMission.vue | 1 src/utils/map/3dLayer.js | 6 src/utils/map/toolbox.js | 70 +++++++++ 19 files changed, 298 insertions(+), 120 deletions(-) diff --git a/src/components.d.ts b/src/components.d.ts index bdf25d1..d714fd9 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -33,7 +33,6 @@ ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElIcon: typeof import('element-plus/es')['ElIcon'] ElInput: typeof import('element-plus/es')['ElInput'] - ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElOption: typeof import('element-plus/es')['ElOption'] ElPagination: typeof import('element-plus/es')['ElPagination'] ElPopover: typeof import('element-plus/es')['ElPopover'] @@ -43,6 +42,7 @@ ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElSelect: typeof import('element-plus/es')['ElSelect'] ElSlider: typeof import('element-plus/es')['ElSlider'] + ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElTable: typeof import('element-plus/es')['ElTable'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElText: typeof import('element-plus/es')['ElText'] diff --git a/src/components/core/CoreMenu.vue b/src/components/core/CoreMenu.vue index db14d19..8dd635c 100644 --- a/src/components/core/CoreMenu.vue +++ b/src/components/core/CoreMenu.vue @@ -56,6 +56,10 @@ { name: '璧拌埅鐩戞祴', path: 'rmode' + }, + { + name: '璧拌埅铻嶅悎', + path: 'underwaymix' } // { // name: '姹℃煋婧簮2', diff --git a/src/components/map/MapScene.vue b/src/components/map/MapScene.vue index 89a665c..38b1856 100644 --- a/src/components/map/MapScene.vue +++ b/src/components/map/MapScene.vue @@ -42,6 +42,8 @@ import sceneInfoApi from '@/api/sceneInfoApi'; import marks from '@/utils/map/marks'; import MapUtil from '@/utils/map/util'; +import { useToolboxStore } from '@/stores/toolbox'; +import { mapStores } from 'pinia'; const lableMarkMap = new Map(); @@ -56,10 +58,14 @@ sceneMap: new Map() }; }, + computed: { + ...mapStores(useToolboxStore) + }, watch: { // 褰撳垏鎹㈠尯鍘挎椂锛屾竻绌烘墍鏈夐�夐」 districtCode(nV, oV) { if (nV != oV) { + this.toolboxStore.selectedDistrict = nV; this.handelCheckAllChange(false); } } diff --git a/src/components/map/MapToolbox.vue b/src/components/map/MapToolbox.vue index e2d3c45..270d63b 100644 --- a/src/components/map/MapToolbox.vue +++ b/src/components/map/MapToolbox.vue @@ -39,6 +39,15 @@ toolItem: [ { icon: 'fa fa-map-signs', + label: '琛屾斂鍖哄垝', + value: false, + click: function () { + this.value = !this.value; + toolbox.toggleDistrict(this.value); + } + }, + { + icon: 'fa fa-map-signs', label: '鍦扮墿鏍囨敞', value: false, click: function () { diff --git a/src/components/monitor/FactorLegend.vue b/src/components/monitor/FactorLegend.vue index 56fc697..b87e4ce 100644 --- a/src/components/monitor/FactorLegend.vue +++ b/src/components/monitor/FactorLegend.vue @@ -27,6 +27,18 @@ <span class="w-60 m-l-8">{{ item.unit }}</span> </el-row> </div> + <div> + 鍒囨崲缁樺浘妯″紡锛� + <el-switch + v-model="legendType" + width="60" + inline-prompt + style="" + active-text="鍔ㄦ��" + inactive-text="鏍囧噯" + @change="handleChange" + /> + </div> </template> </BaseCard> </template> @@ -43,21 +55,38 @@ default: () => new Factor() } }, + emits: ['change'], data() { - return {}; + return { + // 缁樺浘妯″紡锛宖alse: 鏍囧噯妯″紡锛泃rue锛氬姩鎬佹ā寮� + legendType: false, + legends: [] + }; + }, + watch: { + factor(nValue, oValue) { + if (nValue != oValue && nValue) { + this.legends = this.refreshLegend( + nValue.factorName, + nValue.legendType, + nValue.min, + nValue.max + ); + } + } }, computed: { - legends() { - const res = this.factor - ? this.refreshLegend( - this.factor.factorName, - this.factor.legendType, - this.factor.min, - this.factor.max - ) - : []; - return res; - } + // legends() { + // const res = this.factor + // ? this.refreshLegend( + // this.factor.factorName, + // this.factor.legendType, + // this.factor.min, + // this.factor.max + // ) + // : []; + // return res; + // } }, methods: { /** @@ -108,6 +137,17 @@ } return legendList; + }, + + handleChange(value) { + this.$emit('change', value, () => { + this.legends = this.refreshLegend( + this.factor.factorName, + this.factor.legendType, + this.factor.min, + this.factor.max + ); + }); } } }; @@ -120,4 +160,9 @@ .text-center { text-align: center; } + +.el-switch { + --el-switch-on-color: #1f9956; + --el-switch-off-color: #8b8b8b; +} </style> diff --git a/src/components/search/OptionDevice.vue b/src/components/search/OptionDevice.vue index 0b56362..093e7b8 100644 --- a/src/components/search/OptionDevice.vue +++ b/src/components/search/OptionDevice.vue @@ -77,6 +77,7 @@ this.fetchDevice(); } else { this.handleChange(this.deviceOptions[0].value); + this.$emit('initOver'); } } }; diff --git a/src/components/search/OptionMission.vue b/src/components/search/OptionMission.vue index dd8ea00..fec314e 100644 --- a/src/components/search/OptionMission.vue +++ b/src/components/search/OptionMission.vue @@ -60,6 +60,7 @@ } else { this.index = 0; this.handleChange(0); + this.$emit('initOver'); } } }; diff --git a/src/components/search/SearchBar.vue b/src/components/search/SearchBar.vue index 6c0dad6..a6fe820 100644 --- a/src/components/search/SearchBar.vue +++ b/src/components/search/SearchBar.vue @@ -104,6 +104,10 @@ handleClick() { this.$emit('search', { ...this.formSearch, mission: this.mission }); } + }, + created() { + initCount = 0; + initEvents = []; } }; </script> diff --git a/src/model/Factor.js b/src/model/Factor.js index b9983b1..5a720c1 100644 --- a/src/model/Factor.js +++ b/src/model/Factor.js @@ -60,24 +60,33 @@ this.standardMin = -1; //鐩戞祴鍥犲瓙绫诲瀷瀵瑰簲鐨勬爣鍑嗘渶灏忓�� this.standardMax = -1; //鐩戞祴鍥犲瓙绫诲瀷瀵瑰簲鐨勬爣鍑嗘渶澶у�� - // this.legendType = Legend.S_TYPE; //鍥句緥妯″紡 - this.legendType = Legend.D_TYPE; //鍥句緥妯″紡 + this.legendType = Legend.S_TYPE; //鍥句緥妯″紡 + // this.legendType = Legend.D_TYPE; //鍥句緥妯″紡 - if (options != undefined) { - this.datas = options.datas; - this.heights = options.heights; - this.min = options.min; - this.max = options.max; - this.originMin = options.originMin; - this.originMax = options.originMax; + if (typeof options === 'object') { + for (const key in options) { + if (Object.prototype.hasOwnProperty.call(options, key)) { + const value = options[key]; + this[key] = value; + } + } - this.factorName = options.factorName; - this.factorId = options.factorId; - this.colors = options.colors; - this.bottomColors = options.bottomColors; - this.bottomColor = options.bottomColor; - this.standardMin = options.standardMin; - this.standardMax = options.standardMax; + // this.datas = options.datas; + // this.heights = options.heights; + // this.min = options.min; + // this.max = options.max; + // this.originMin = options.originMin; + // this.originMax = options.originMax; + + // this.factorName = options.factorName; + // this.factorId = options.factorId; + // this.colors = options.colors; + // this.bottomColors = options.bottomColors; + // this.bottomColor = options.bottomColor; + // this.standardMin = options.standardMin; + // this.standardMax = options.standardMax; + + // this.legendType = options.legendType; } } diff --git a/src/model/FactorDatas.js b/src/model/FactorDatas.js index d3c2c1a..eba6446 100644 --- a/src/model/FactorDatas.js +++ b/src/model/FactorDatas.js @@ -1,5 +1,6 @@ import { Factor } from './Factor'; import calculate from '@/utils/map/calculate'; +import { Legend } from './Legend'; /** * @@ -16,12 +17,24 @@ // 鐩戞祴鍥犲瓙鏁版嵁锛孧ap<String, Factor> this.factor = new Map(); - if (options != undefined) { - this.times = options.times; - this.lnglats_GPS = options.lnglats_GPS; - this.lnglats_GD = options.lnglats_GD; - this.coors_GD = options.coors_GD; - this.factor = options.factor; + this.legendType = Legend.S_TYPE; //鍥句緥妯″紡 + + // if (options != undefined) { + // this.times = options.times; + // this.lnglats_GPS = options.lnglats_GPS; + // this.lnglats_GD = options.lnglats_GD; + // this.coors_GD = options.coors_GD; + // this.factor = options.factor; + // this.legendType = options.legendType; + // } + + if (typeof options === 'object') { + for (const key in options) { + if (Object.prototype.hasOwnProperty.call(options, key)) { + const value = options[key]; + this[key] = value; + } + } } } @@ -58,7 +71,9 @@ d.values.forEach((v) => { var f = this.factor[v.factorId]; if (f == undefined) { - f = new Factor(); + f = new Factor({ + legendType: this.legendType + }); this.factor[v.factorId] = f; } f.pushData(v, drawMode == undefined ? 0 : drawMode); @@ -118,17 +133,38 @@ // 璁剧疆缁樺浘鑼冨洿 setRange: function (key, range) { - this.factor[key].setRange(range); + this.legendType = Legend.C_TYPE; + if (key != undefined) { + this.factor[key].setRange(range); + } else { + for (const k in this.factor) { + this.factor[k].setRange(range); + } + } }, // 閲嶇疆缁樺浘鑼冨洿 resetRange: function (key) { - this.factor[key].clearRange(); + this.legendType = Legend.D_TYPE; + if (key != undefined) { + this.factor[key].clearRange(); + } else { + for (const k in this.factor) { + this.factor[k].clearRange(); + } + } }, // 璁剧疆涓烘爣鍑嗙粯鍥捐寖鍥� standardRange: function (key) { - this.factor[key].standardRange(); + this.legendType = Legend.S_TYPE; + if (key != undefined) { + this.factor[key].standardRange(); + } else { + for (const k in this.factor) { + this.factor[k].standardRange(); + } + } }, // 鏍规嵁褰撳墠缁樺浘鑼冨洿閲嶆柊璁$畻缁樺浘楂樺害 diff --git a/src/router/index.js b/src/router/index.js index 1c06db5..47edf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -36,6 +36,12 @@ name: 'realtimeMode', component: () => import('@/views/realtimemode/RealtimeMode.vue') }, + // 璧拌埅铻嶅悎 + { + path: 'underwaymix', + name: 'underwayMixMode', + component: () => import('@/views/underwaymix/UnderwayMixMode.vue') + }, // 椋庨櫓妯″瀷 { path: 'riskmode', diff --git a/src/stores/toolbox.js b/src/stores/toolbox.js index 93a5cf3..986e7a2 100644 --- a/src/stores/toolbox.js +++ b/src/stores/toolbox.js @@ -2,6 +2,9 @@ import { defineStore } from 'pinia'; export const useToolboxStore = defineStore('toolbox', () => { + const selectedDistrict = ref(null); + // 寮�鍏宠鏀垮尯鍒� + const districtStatus = ref(false); // 寮�鍏冲湴鐗╂爣娉� const featuresStatus = ref(false); // 寮�鍏冲崼鏄熷湴鍥� @@ -18,6 +21,8 @@ const sceneSearchStatus = ref(true); return { + selectedDistrict, + districtStatus, featuresStatus, satelliteStatus, controlbarStatus, diff --git a/src/utils/map/3dLayer.js b/src/utils/map/3dLayer.js index 419dd98..9720c1a 100644 --- a/src/utils/map/3dLayer.js +++ b/src/utils/map/3dLayer.js @@ -167,6 +167,12 @@ } export default { + clear() { + if (_cylinder != undefined) { + object3Dlayer.remove(_cylinder); + } + }, + drawMesh: drawMesh, /** * 缁樺埗3D璧拌璺嚎鍥� diff --git a/src/utils/map/toolbox.js b/src/utils/map/toolbox.js index 23c10c5..3c24609 100644 --- a/src/utils/map/toolbox.js +++ b/src/utils/map/toolbox.js @@ -1,9 +1,19 @@ /* eslint-disable no-undef */ -import { map, satellite } from './index_old'; +import { watch } from 'vue'; +import { map, satellite, onMapMounted } from './index_old'; import { useToolboxStore } from '@/stores/toolbox'; import { DialogUtil } from '@/utils/map/dialog'; const toolboxStore = useToolboxStore(); +watch( + () => toolboxStore.selectedDistrict, + (nV, oV) => { + if (nV != oV && toolboxStore.districtStatus) { + if (activeDistrict) map.remove(activeDistrict); + drawDistrict(toolboxStore.selectedDistrict); + } + } +); /** * 鍧愭爣鎷惧彇榧犳爣鐐瑰嚮鍥炶皟浜嬩欢 @@ -38,8 +48,66 @@ } } +let districtPolygonMap = new Map(); +let activeDistrict = undefined; +// 缁樺埗鍖哄幙杈圭晫 +function drawDistrict(districtName, isNew) { + onMapMounted(() => { + if (!isNew && districtPolygonMap.has(districtName)) { + const districtPolygon = districtPolygonMap.get(districtName); + map.remove(districtPolygon); + map.add(districtPolygon); + activeDistrict = districtPolygon; + } else { + // eslint-disable-next-line no-undef + var district = new AMap.DistrictSearch({ + extensions: 'all', //杩斿洖琛屾斂鍖鸿竟鐣屽潗鏍囩瓑鍏蜂綋淇℃伅 + level: 'district' //璁剧疆鏌ヨ琛屾斂鍖虹骇鍒负鍖� + }); + district.search(districtName, function (status, result) { + var bounds = result.districtList[0].boundaries; //鑾峰彇鏈濋槼鍖虹殑杈圭晫淇℃伅 + if (bounds) { + for (var i = 0; i < bounds.length; i++) { + //鐢熸垚琛屾斂鍖哄垝 polygon + // eslint-disable-next-line no-undef + const districtPolygon = new AMap.Polygon({ + map: map, //鏄剧ず璇ヨ鐩栫墿鐨勫湴鍥惧璞� + strokeWeight: 1, //杞粨绾垮搴� + path: bounds[i], //澶氳竟褰㈣疆寤撶嚎鐨勮妭鐐瑰潗鏍囨暟缁� + fillOpacity: 0.6, //澶氳竟褰㈠~鍏呴�忔槑搴� + // fillColor: '#CCF3FF', //澶氳竟褰㈠~鍏呴鑹� + fillColor: '#0077ff', + // strokeColor: '#ffffff' //绾挎潯棰滆壊 + strokeColor: 'white', //绾挎潯棰滆壊 + zIndex: 9 + }); + + districtPolygonMap.set(districtName, districtPolygon); + activeDistrict = districtPolygon; + } + // map.setFitView(); //灏嗚鐩栫墿璋冩暣鍒板悎閫傝閲� + } + }); + } + }); +} + export default { /** + * 寮�鍏宠鏀垮尯鍒� + * @param {boolean} value + */ + toggleDistrict(value) { + if (value) { + if (toolboxStore.selectedDistrict) + drawDistrict(toolboxStore.selectedDistrict); + } else { + if (activeDistrict) map.remove(activeDistrict); + } + toolboxStore.districtStatus = value; + }, + + /** * 寮�鍏冲湴鐗╂爣娉� * @param {boolean} value */ diff --git a/src/utils/map/util.js b/src/utils/map/util.js index e783baf..1b7b3a6 100644 --- a/src/utils/map/util.js +++ b/src/utils/map/util.js @@ -1,5 +1,6 @@ import { map, isDragging } from '@/utils/map/index_old'; import marks from '@/utils/map/marks'; +import Layer from '@/utils/map/3dLayer'; /** * 鍧愭爣闆嗗悎鐨勬渶瑗垮崡瑙掑拰鏈�涓滃寳瑙� @@ -84,6 +85,7 @@ clearMap() { marks.clearMassMarks(); map.clearMap(); + Layer.clear(); }, setFitView(views) { if (views) { diff --git a/src/views/HomePage.vue b/src/views/HomePage.vue index 0d22cf3..e4cf5d3 100644 --- a/src/views/HomePage.vue +++ b/src/views/HomePage.vue @@ -19,45 +19,45 @@ <script setup> import { map, onMapMounted } from '@/utils/map/index_old'; -let districtPolygon; -// 缁樺埗鍖哄幙杈圭晫 -function drawDistrict(districtName, isNew) { - onMapMounted(() => { - if (districtPolygon && !isNew) { - map.remove(districtPolygon); - map.add(districtPolygon); - } else { - // eslint-disable-next-line no-undef - var district = new AMap.DistrictSearch({ - extensions: 'all', //杩斿洖琛屾斂鍖鸿竟鐣屽潗鏍囩瓑鍏蜂綋淇℃伅 - level: 'district' //璁剧疆鏌ヨ琛屾斂鍖虹骇鍒负鍖� - }); - district.search(districtName, function (status, result) { - var bounds = result.districtList[0].boundaries; //鑾峰彇鏈濋槼鍖虹殑杈圭晫淇℃伅 - if (bounds) { - for (var i = 0; i < bounds.length; i++) { - //鐢熸垚琛屾斂鍖哄垝 polygon - // eslint-disable-next-line no-undef - districtPolygon = new AMap.Polygon({ - map: map, //鏄剧ず璇ヨ鐩栫墿鐨勫湴鍥惧璞� - strokeWeight: 1, //杞粨绾垮搴� - path: bounds[i], //澶氳竟褰㈣疆寤撶嚎鐨勮妭鐐瑰潗鏍囨暟缁� - fillOpacity: 0.6, //澶氳竟褰㈠~鍏呴�忔槑搴� - // fillColor: '#CCF3FF', //澶氳竟褰㈠~鍏呴鑹� - fillColor: '#0077ff', - // strokeColor: '#ffffff' //绾挎潯棰滆壊 - strokeColor: 'white', //绾挎潯棰滆壊 - zIndex: 9 - }); - } - map.setFitView(); //灏嗚鐩栫墿璋冩暣鍒板悎閫傝閲� - } - }); - } - }); -} +// let districtPolygon; +// // 缁樺埗鍖哄幙杈圭晫 +// function drawDistrict(districtName, isNew) { +// onMapMounted(() => { +// if (districtPolygon && !isNew) { +// map.remove(districtPolygon); +// map.add(districtPolygon); +// } else { +// // eslint-disable-next-line no-undef +// var district = new AMap.DistrictSearch({ +// extensions: 'all', //杩斿洖琛屾斂鍖鸿竟鐣屽潗鏍囩瓑鍏蜂綋淇℃伅 +// level: 'district' //璁剧疆鏌ヨ琛屾斂鍖虹骇鍒负鍖� +// }); +// district.search(districtName, function (status, result) { +// var bounds = result.districtList[0].boundaries; //鑾峰彇鏈濋槼鍖虹殑杈圭晫淇℃伅 +// if (bounds) { +// for (var i = 0; i < bounds.length; i++) { +// //鐢熸垚琛屾斂鍖哄垝 polygon +// // eslint-disable-next-line no-undef +// districtPolygon = new AMap.Polygon({ +// map: map, //鏄剧ず璇ヨ鐩栫墿鐨勫湴鍥惧璞� +// strokeWeight: 1, //杞粨绾垮搴� +// path: bounds[i], //澶氳竟褰㈣疆寤撶嚎鐨勮妭鐐瑰潗鏍囨暟缁� +// fillOpacity: 0.6, //澶氳竟褰㈠~鍏呴�忔槑搴� +// // fillColor: '#CCF3FF', //澶氳竟褰㈠~鍏呴鑹� +// fillColor: '#0077ff', +// // strokeColor: '#ffffff' //绾挎潯棰滆壊 +// strokeColor: 'white', //绾挎潯棰滆壊 +// zIndex: 9 +// }); +// } +// map.setFitView(); //灏嗚鐩栫墿璋冩暣鍒板悎閫傝閲� +// } +// }); +// } +// }); +// } -drawDistrict('闀垮畞鍖�'); +// drawDistrict('闀垮畞鍖�'); </script> <style scoped> diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue index e7978dd..d2a780e 100644 --- a/src/views/historymode/HistoryMode.vue +++ b/src/views/historymode/HistoryMode.vue @@ -19,6 +19,7 @@ <FactorLegend class="m-t-2" :factor="factorDatas.factor[factorType]" + @change="handleLegendTypeChange" ></FactorLegend> </el-row> <el-row class="historical" justify="center"> @@ -134,12 +135,21 @@ this.sceneStore.searchScene(lng, lat); } }, + handleLegendTypeChange(value, done) { + if (value) { + this.factorDatas.resetRange(); + } else { + this.factorDatas.standardRange(); + } + done(); + this.draw(); + }, draw() { // 鍒锋柊鍥句緥 const factor = this.factorDatas.factor[this.factorType]; sector.clearSector(); - this.drawRoadLine(factor); - // this.drawRoadMap(factor); + // this.drawRoadLine(factor); + this.drawRoadMap(factor); this.drawMassMarks(factor); }, // 缁樺埗3D璧拌璺嚎鍥� diff --git a/src/views/satellitetelemetry/SatelliteTelemetry.vue b/src/views/satellitetelemetry/SatelliteTelemetry.vue deleted file mode 100644 index fd1a40d..0000000 --- a/src/views/satellitetelemetry/SatelliteTelemetry.vue +++ /dev/null @@ -1,40 +0,0 @@ -<template> - <div class="p-events-auto"> - <el-button type="info" icon="Memo" plain @click="drawGrid"> - 缁樺埗缃戞牸 - </el-button> - </div> -</template> -<script setup> -import calculate from '@/utils/map/calculate'; -import grid from '@/utils/map/grid'; -import { gridData } from '../../../test/grid_test_data'; - -function drawGrid() { - // const points = gridData.map((v) => { - // return calculate.wgs84_To_Gcj02(v[0], v[1]); - // }); - // const p1 = points[0]; - // const p2 = points[1]; - // const diffLng = Math.abs(p1[0] - p2[0]); - // const diffLat = Math.abs(p1[1] - p2[1]); - // const bounds = points.map((v) => { - // return { - // // 涓滅粡锛屽寳绾儏鍐典笅 - // lb: [v[0] - diffLng, v[1] - diffLat], - // rt: [v[0] + diffLng, v[1] - diffLat], - // c: v - // }; - // }); - - const bounds = [ - { - lb: [121.360898, 31.222733], - rt: [121.364898, 31.226733], - c: [121.362898, 31.224733] - } - ]; - - grid.drawRectangle(bounds); -} -</script> diff --git a/src/views/underwaymix/UnderwayMixMode.vue b/src/views/underwaymix/UnderwayMixMode.vue new file mode 100644 index 0000000..a26096a --- /dev/null +++ b/src/views/underwaymix/UnderwayMixMode.vue @@ -0,0 +1,6 @@ +<template> + <div class="p-events-none m-t-2"></div> +</template> + +<script setup></script> +<style scoped></style> -- Gitblit v1.9.3