Commit df592377 authored by xuchaozou's avatar xuchaozou

chore: 使用新版地图,剔除对老版地图依赖

parent 37561869
Pipeline #95277 failed with stages
......@@ -94,9 +94,9 @@
"@wangeditor/editor-for-react": "^1.0.6",
"@wisdom-cesium/cesium": "1.1.12",
"@wisdom-cesium/krpano": "^1.0.29-60",
"@wisdom-map/amap":"^2.0.15",
"@wisdom-map/arcgismap":"^2.0.97",
"@wisdom-map/basemap":"^2.0.4",
"@wisdom-map/gis-component": "^1.0.22",
"@wisdom-map/gis-utils": "^1.0.19",
"@wisdom-map/pd-map": "^1.0.105",
"@wisdom-utils/components": "0.1.337",
"@wisdom-utils/utils": "0.1.377",
"ace-builds": "^1.4.12",
......@@ -290,4 +290,4 @@
"whatwg-fetch": "3.0.0",
"yorkie": "^2.0.0"
}
}
\ No newline at end of file
}
......@@ -8,7 +8,6 @@ import 'sanitize.css/sanitize.css';
import React from 'react';
import ReactDOM from 'react-dom';
// import { ArcGISMap as MapComponent } from '@wisdom-map/arcgismap';
import { ConfigProvider } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import { ConnectedRouter } from 'connected-react-router/immutable';
......
/* eslint-disable no-new */
import React, { useEffect, useState, useRef } from 'react';
import { ArcGISMap, Drawtool, geomUtils } from '@wisdom-map/arcgismap';
// import { AMapScene, PointLayer } from '@wisdom-map/Amap';
import {
Modal,
Form,
......@@ -114,12 +112,12 @@ const Map = props => {
mapRef.current.changeBoundWidthValue(obj.layers[index].boundWidth);
break;
case 'areaName':
Drawtool.deactivate(false);
// Drawtool.deactivate(false);
obj.layers[index].areaName = changedFields[0].value[changedFields[0].value.length - 1];
mapRef.current.changeAreaName(obj.layers[index].areaName);
break;
case 'schemename':
Drawtool.deactivate(false);
// Drawtool.deactivate(false);
let setttings;
obj.layers.forEach(item => {
if (item.schemename === changedFields[0].value) {
......@@ -146,36 +144,36 @@ const Map = props => {
};
// 选择范围
const onTangleClick = e => {
Drawtool.activate({
view: mapInfo.current,
action: 'extent',
drawEnd: data => {
const geom = geomUtils.toGeometry({
type: 'extent',
xmin: data.rings[0][0][0],
xmax: data.rings[0][2][0],
ymin: data.rings[0][0][1],
ymax: data.rings[0][1][1],
});
form.setFieldsValue({
extent: `${data.rings[0][0][0]},${data.rings[0][0][1]},${data.rings[0][2][0]},${data.rings[0][1][1]
}`,
});
mapRef.current.gotoGeometry(geom);
},
});
// Drawtool.activate({
// view: mapInfo.current,
// action: 'extent',
// drawEnd: data => {
// const geom = geomUtils.toGeometry({
// type: 'extent',
// xmin: data.rings[0][0][0],
// xmax: data.rings[0][2][0],
// ymin: data.rings[0][0][1],
// ymax: data.rings[0][1][1],
// });
// form.setFieldsValue({
// extent: `${data.rings[0][0][0]},${data.rings[0][0][1]},${data.rings[0][2][0]},${data.rings[0][1][1]
// }`,
// });
// mapRef.current.gotoGeometry(geom);
// },
// });
};
const onFinish = () => {
console.log(form.getFieldValue('extent'));
console.log(Drawtool.graphic, 'Drawtool');
if (!Drawtool.graphic) {
notification.error({
message: '提示',
duration: 3,
description: '请选择复位范围再保存',
});
return;
}
// console.log(form.getFieldValue('extent'));
// console.log(Drawtool.graphic, 'Drawtool');
// if (!Drawtool.graphic) {
// notification.error({
// message: '提示',
// duration: 3,
// description: '请选择复位范围再保存',
// });
// return;
// }
const obj = form.getFieldsValue();
const jsConfig = {
......@@ -271,7 +269,7 @@ const Map = props => {
</div>
<div className={styles.mapBox}>
{canLoadMap && (
<ArcGISMap ref={mapRef} getMapInfo={e => getMapInfo(e)} config={mapsettings} />
// <ArcGISMap ref={mapRef} getMapInfo={e => getMapInfo(e)} config={mapsettings} />
)}
</div>
</div>
......
......@@ -5,24 +5,11 @@
/* eslint-disable no-new */
import React, { useEffect, useState, useRef, useMemo } from 'react';
import { SketchPicker } from 'react-color';
import {
ArcGISMap,
ArcGISSceneMap,
Drawtool,
EditTool,
geomUtils,
PipenetStylesCenter,
MapImageLayer,
GraphicsLayer,
watchUtils,
SimpleFillSymbol,
Graphic,
EditAndDrawPanel,
Handles,
ImageTileLayer
} from '@wisdom-map/arcgismap';
import { checkInternalNetwork } from '@/utils/utils';
import { getPipenetLayer } from '@wisdom-map/basemap';
import {PdMap} from '@wisdom-map/pd-map'
import { mapConfig } from '@wisdom-map/gis-utils'
import { PipenetStylesCenter , EditPanel as EditAndDrawPanel } from '@wisdom-map/gis-component'
import mapDataJson from './mapData.json';
import {
Form,
......@@ -57,6 +44,7 @@ import { GetWebSiteConfig } from '@/services/gis/gis';
import { SetServiceConfig, GetSpriteSheet } from '@/services/webConfig/api';
import { formatTimeStr } from 'antd/lib/statistic/utils';
import styles from './index.less';
import { isString } from 'lodash';
const { Option } = Select;
const defaultMap = {
basemaps: [
......@@ -152,6 +140,12 @@ const widgets = [
bottom: 45,
config: {},
},
{
label: '滤镜',
right: 20,
bottom: 150,
config: {},
}
];
const Map = props => {
const { visible, onCancel, schemename } = props;
......@@ -173,12 +167,18 @@ const Map = props => {
const [name, setName] = useState('');
const [Schemename, setSchemename] = useState({});
const [radio, setRadio] = useState();
const mapRef = useRef();
// const mapRef = useRef();
const PdSceneRef = useRef(null)
const mapApiRef = useRef(null)
const viewRef = useRef(null)
const styleRef = useRef();
const mapInfo = useRef(null);
const [keep, setKeep] = useState('');
const [keepSave, setKeepSave] = useState('');
const [map, setMap] = useState(null);
// const [map, setMap] = useState(null);
const [PdScene, setPdScene] = useState(null)
const [color, setColor] = useState('');
const [colorList, setColorList] = useState('');
const [keepColor, setKeepColor] = useState('');
......@@ -202,7 +202,7 @@ const Map = props => {
const [hide, setHide] = useState(false);
const [hideChange, setHideChange] = useState(null);
const [keepNameCustomPointExtent, setKeepNameCustomPointExtent] = useState(''); // 保存方案初始自定义区域
const mapHandles = useRef(new Handles())
const mapHandles = useRef(null)
useEffect(() => {
GetWebSiteConfig({ client: 'sandbox' })
......@@ -268,7 +268,7 @@ const Map = props => {
});
let hh = {};
hh.rings = rings;
data.geometry = geomUtils.toGeometry(hh);
data.geometry = hh;
setResultData({ ...data });
}
} else {
......@@ -419,7 +419,7 @@ const Map = props => {
});
let hh = {};
hh.rings = rings;
data.geometry = geomUtils.toGeometry(hh);
data.geometry = PdSceneRef.current.geomUtils.toGeometry(hh);
setResultData({ ...data });
}
} else {
......@@ -510,25 +510,78 @@ const Map = props => {
aa = i.id;
}
});
// const pandagis1 = new ImageTileLayer({
// id: aa,
// url: `/PandaGIS/MapServer/${aa}`,
// layerType: 'PipenetLayertest',
// title: aa,
// customParameters : {}
// });
viewObject.map.add(pandagis1);
}
}
setRadio1(form.getFieldsValue().customFlag);
setAreaFlag(0);
};
const getPdScene = PdScene => {
PdSceneRef.current = PdScene
mapApiRef.current = PdScene.getApi({
productName : "webgis",
version : "1.0.4"
})
const view = PdScene.mapView.getMapInstance()
viewRef.current = view
view.map.layers.map(item => {
if (item.layerType && item.layerType == 'PipenetLayertest') {
view.map.remove(item);
}
})
setPdScene(PdScene)
if (form.getFieldsValue().exportScheme == 'pandagis') {
let data = view.map.layers.find(
item => item.layerType && item.layerType == 'PipenetLayertest',
);
if (!data) {
// 用户自定义创建的管网图
let aa = '';
mapsettings.map(i => {
if (i.schemename == form.getFieldsValue().schemename) {
aa = i.id;
}
});
const {ImageTileLayer} = mapApiRef.current
const pandagis1 = new ImageTileLayer({
id: aa,
url: `/PandaGIS/MapServer/${aa}`,
layerType: 'PipenetLayertest',
title: aa,
customParameters : {}
});
viewObject.map.add(pandagis1);
exportScheme: 'pandagis',
customParameters : {
cityCode : PdScene.extentInfos.cityCode,
scheme : PdScene.extentInfos.scheme,
layerInfo : PdScene.layerInfo
}
})
view.map.add(pandagis1);
}
}
setRadio1(form.getFieldsValue().customFlag);
setAreaFlag(0);
};
}
// 选择颜色
const checkColor = color => {
form.setFieldsValue({ backgroundColor: color });
setColor(color);
mapRef.current.updateAreaColor(color);
PdSceneRef.current.changeMapBaseConfig({
type: "areaColor",
data: {
"color": color
}
})
// mapRef.current.updateAreaColor(color);
};
// 表单修改后对地图进行配置
......@@ -541,11 +594,23 @@ const Map = props => {
switch (changedFields[0].name[0]) {
case 'backgroundOpacity':
obj[index].backgroundOpacity = changedFields[0].value / 100;
mapRef.current.changeBackgroundOpacity(obj[index].backgroundOpacity);
// mapRef.current.changeBackgroundOpacity(obj[index].backgroundOpacity);
PdSceneRef.current.changeMapBaseConfig({
type: "backgroundOpacity",
data: {
"opacity": obj[index].backgroundOpacity
}
})
break;
case 'boundWidth':
obj[index].boundWidth = changedFields[0].value;
mapRef.current.changeBoundWidthValue(obj[index].boundWidth);
// mapRef.current.changeBoundWidthValue(obj[index].boundWidth);
PdSceneRef.current.changeMapBaseConfig({
type: "boundWidth",
data: {
"width": obj[index].boundWidth
}
})
break;
case 'areaName':
obj[index].areaName = changedFields[0].value[changedFields[0].value.length - 1];
......@@ -554,22 +619,47 @@ const Map = props => {
if (radio == 1) {
if (keepNameArea === changedFields[0].value[changedFields[0].value.length - 1]) {
if (keepNameArea !== '') {
mapRef.current.changeAreaName(keepNameArea, keepDraw);
PdSceneRef.current.changeMapBaseConfig({
type: "areaName",
data: {
"areaName": keepNameArea,
geom : keepDraw
}
})
// mapRef.current.changeAreaName(keepNameArea, keepDraw);
setDraw(1);
} else {
setDraw(0);
mapRef.current.changeAreaName(obj[index].areaName);
// mapRef.current.changeAreaName(obj[index].areaName);
PdSceneRef.current.changeMapBaseConfig({
type: "areaName",
data: {
"areaName": obj[index].areaName,
}
})
}
} else {
setDraw(0);
mapRef.current.changeAreaName(obj[index].areaName);
// mapRef.current.changeAreaName(obj[index].areaName);
PdSceneRef.current.changeMapBaseConfig({
type: "areaName",
data: {
"areaName": obj[index].areaName,
}
})
}
setAreaFlag(1);
setFlag(0);
Drawtool.deactivate(false);
PdSceneRef.current.mapView.DrawTool.deactivate(false);
setArea('');
} else {
mapRef.current.changeAreaName(obj[index].areaName);
PdSceneRef.current.changeMapBaseConfig({
type: "areaName",
data: {
"areaName": obj[index].areaName,
}
})
// mapRef.current.changeAreaName(obj[index].areaName);
}
setNewDraw(0);
......@@ -592,11 +682,11 @@ const Map = props => {
// setFirstList({ ...aa });
break;
case 'schemename':
const filterLyrs = mapInfo.current?.map.layers.filter(item => {
const filterLyrs = viewRef.current?.map.layers.filter(item => {
return item.pipenetImark;
});
if (filterLyrs.length) {
mapInfo.current.map.removeMany(filterLyrs);
viewRef.current.map.removeMany(filterLyrs);
}
setKeepDataDraw([]);
setRadio1('');
......@@ -631,7 +721,10 @@ const Map = props => {
});
let list = {};
list.layers = dalist;
mapRef.current.mapchange(dalist);
const pipentLayer = list.layers.find(i => i.layerType.toLowerCase() == "pipenetlayer")
PdSceneRef.current.changePipePlan(pipentLayer.schemename,list.layers)
// mapRef.current.mapchange(dalist);
// setFirstList({ ...list });
})
.catch(err => {
......@@ -650,7 +743,7 @@ const Map = props => {
}
});
setArea('');
Drawtool.deactivate(false);
PdSceneRef.current.mapView.DrawTool.deactivate(false);
let setttings;
obj.forEach(item => {
......@@ -695,7 +788,7 @@ const Map = props => {
});
let hh = {};
hh.rings = rings;
data.geometry = geomUtils.toGeometry(hh);
data.geometry = PdSceneRef.current.geomUtils.toGeometry(hh);
setResultData({ ...data });
}
} else {
......@@ -724,8 +817,10 @@ const Map = props => {
setRadio(setttings.exportScheme || 'pandagis');
}
setRadio1(setttings.customFlag);
mapRef.current.mapchange(obj);
// debugger
const pipentLayer = obj.find(i => i.layerType.toLowerCase() == "pipenetlayer")
PdSceneRef.current.changePipePlan(pipentLayer.schemename,obj)
// mapRef.current.mapchange(obj);
break;
default:
......@@ -736,14 +831,14 @@ const Map = props => {
// 选择范围
const onTangleClick = e => {
let aa = 0;
Drawtool.activate({
view: mapInfo.current,
PdScene.mapView.DrawTool.activate({
view: viewRef.current,
action: 'extent',
drawEnd: data => {
aa = 1;
setLoad(false);
setArea(data);
const geom1 = geomUtils.toGeometry({
const geom1 = PdSceneRef.current.geomUtils.toGeometry({
type: 'extent',
xmin: data.rings[0][0][0],
xmax: data.rings[0][2][0],
......@@ -754,7 +849,9 @@ const Map = props => {
extent: `${data.rings[0][0][0]},${data.rings[0][1][1]},${data.rings[0][2][0]},${data.rings[0][0][1]
}`,
});
mapRef.current.gotoGeometry(geom1);
PdSceneRef.current.gotoGeometry({
geometry : geom1
})
},
});
setTimeout(() => {
......@@ -763,13 +860,17 @@ const Map = props => {
};
useEffect(() => {
if(!map) return
const viewObject = map
if(!(PdScene && mapApiRef.current)) return
const {Handles, watchUtils} = mapApiRef.current
// const viewObject = map
if(!mapHandles.current) {
mapHandles.current = new Handles()
}
if(mapHandles.current) {
mapHandles.current.removeAll()
mapHandles.current.add(watchUtils.watch(viewObject, ['zoom'], newzoom => {
mapHandles.current.add(watchUtils.watch(viewRef.current, ['zoom'], newzoom => {
// 鼠标滚动隐藏管网图
viewObject.map.layers.find(layer => {
viewRef.current.map.layers.find(layer => {
if (layer.layerType == 'PipenetLayer') {
layer.visible = false;
}
......@@ -779,7 +880,7 @@ const Map = props => {
return () => {
mapHandles.current && mapHandles.current.removeAll()
}
}, [map])
}, [PdScene])
useEffect(() => {
if (name && !hide) {
......@@ -798,7 +899,14 @@ const Map = props => {
});
let area1 = form.getFieldsValue().areaName;
mapRef.current.changeAreaName(area1[area1.length - 1], geom1);
PdSceneRef.current.changeMapBaseConfig({
type: "areaName",
data: {
"areaName": area1[area1.length - 1],
geom : geom1
}
})
// mapRef.current.changeAreaName(area1[area1.length - 1], geom1);
form.setFieldsValue({
customPointExtent: geom1,
});
......@@ -824,7 +932,7 @@ const Map = props => {
let aa = JSON.parse(form.getFieldsValue().customPointExtent);
form.setFieldsValue({ customPointExtent: aa.geometry });
}
Drawtool.deactivate(false);
PdSceneRef.current.mapView.DrawTool.deactivate(false);
};
// 提交
......@@ -945,7 +1053,7 @@ const Map = props => {
setDraw(0);
}
setSetttingsSave(mapObj);
Drawtool.deactivate(false);
PdSceneRef.current.mapView.DrawTool.deactivate(false);
// setArea('');
setKeepSave('');
......@@ -960,29 +1068,46 @@ const Map = props => {
});
};
const pandagis = useMemo(() => new ImageTileLayer({
id: keep.id,
url: `/PandaGIS/MapServer/${keep.id}`,
layerType: 'PipenetLayertest',
title: keep.id,
customParameters : {}
}), [keep])
const pandagis = useMemo(() => {
if(!(PdScene && mapApiRef.current)) return
const {ImageTileLayer} = mapApiRef.current
const image = new ImageTileLayer({
id: keep.id,
url: `/PandaGIS/MapServer/${keep.id}`,
layerType: 'PipenetLayertest',
title: keep.id,
exportScheme: 'pandagis',
customParameters : {
cityCode : PdScene.extentInfos.cityCode,
scheme : PdScene.extentInfos.scheme,
layerInfo : PdScene.layerInfo
}
})
return image
}, [keep, PdScene])
const onChange = e => {
const { layer } = getPipenetLayer(mapInfo.current?.map);
if (layer) {
layer.visible = false;
const layers = PdSceneRef.current?.pipentImage?.data?.layers
if(layers) {
layers.map(layer => {
layer.visible = false
})
}
// const { layer } = getPipenetLayer(mapInfo.current?.map);
// if (layer) {
// layer.visible = false;
// }
if (e.target.value == 'arcgis') {
// 选择前端绘制时,如果界面有自定义的管网图就隐藏,打开组件自动生成前端管网图
mapInfo.current.map.layers.forEach(item => {
viewRef.current.map.layers.forEach(item => {
if (item.layerType && item.layerType == 'PipenetLayertest') {
mapInfo.current.map.remove(item);
viewRef.current.map.remove(item);
}
});
} else {
// 选择后端绘制时创建自定义的管网图,前端管网被组件关闭自动销毁
mapInfo.current.map.add(pandagis);
// mapInfo.current.map.add(pandagis);
viewRef.current.map.add(pandagis)
}
setRadio(e.target.value);
};
......@@ -991,14 +1116,27 @@ const Map = props => {
setResultData(null);
if (e.target.value == 0) {
let data = form.getFieldsValue().areaName;
mapRef.current.changeAreaName(data[data.length - 1]);
// mapRef.current.changeAreaName(data[data.length - 1]);
PdSceneRef.current.changeMapBaseConfig({
type: "areaName",
data: {
"areaName": data[data.length - 1],
}
})
setButState(false);
Drawtool.deactivate();
PdSceneRef.current.mapView.DrawTool.deactivate();
setRadio1(e.target.value);
} else {
if (keepDraw) {
let area1 = form.getFieldsValue().areaName;
mapRef.current.changeAreaName(area1[area1.length - 1], keepDraw);
// mapRef.current.changeAreaName(area1[area1.length - 1], keepDraw);
PdSceneRef.current.changeMapBaseConfig({
type: "areaName",
data: {
"areaName": area1[area1.length - 1],
geom : keepDraw
}
})
let data = {};
data.type = keepType;
let rings = [];
......@@ -1007,7 +1145,7 @@ const Map = props => {
});
let hh = {};
hh.rings = rings;
data.geometry = geomUtils.toGeometry(hh);
data.geometry = PdSceneRef.current.geomUtils.toGeometry(hh);
setResultData({ ...data });
}
if (draw == 0) {
......@@ -1038,10 +1176,33 @@ const Map = props => {
// 颜色选择
const colorChange = value => {
form.setFieldsValue({ boundColor: value.hex });
mapRef.current.changeBoundColor(value.hex);
PdSceneRef.current.changeMapBaseConfig({
type: "boundColor",
data: {
"color": value.hex
}
})
// mapRef.current.changeBoundColor(value.hex);
setColorList(value.hex);
};
const getDrawDefaultGraphic = (resultData) => {
if(isString(resultData)) {
return resultData
}
if(resultData.geometry ) {
if(!(resultData.geometry.clone && resultData.geometry.spatialReference)) {
return {
...resultData,
geometry : PdSceneRef.current.geomUtils.toGeometry(resultData.geometry)
}
} else {
return resultData
}
}
return mapConfig.layer_name_edgelayer_arcgismap
}
return (
<div className={styles.mapContent}>
<div
......@@ -1213,7 +1374,13 @@ const Map = props => {
}}
onCancel={() => {
form.setFieldsValue({ boundColor: keepColor });
mapRef.current.changeBoundColor(keepColor);
PdSceneRef.current.changeMapBaseConfig({
type: "boundColor",
data: {
"color": value.hex
}
})
// mapRef.current.changeBoundColor(keepColor);
setColorList(keepColor);
}}
>
......@@ -1352,33 +1519,33 @@ const Map = props => {
</div>
<div className={styles.mapBox}>
{canLoadMap && (
<ArcGISSceneMap
ref={mapRef}
filterMap={true}
getMapInfo={e => getMapInfo(e)}
widgets={widgets}
config={firstList}
client="sandbox"
<PdMap
getPdScene = {getPdScene}
widgets = {widgets}
config = {firstList?.layers}
client = "sandbox"
/>
)}
{radio == 'arcgis' && map && name && Schemename? (
{radio == 'arcgis' && PdScene && name && Schemename ? (
<PipenetStylesCenter
schemeName={Schemename.schemename}
mapServerName={name}
view={map}
schemeName={PdScene.pipenetLayer.schemename}
mapServerName={PdScene.pipenetLayer.id}
view={PdScene.mapView.getMapInstance()}
savaCallback={onSave}
ref={styleRef}
pipenetLayer={Schemename}
pipenetLayer={PdScene.pipenetLayer}
PdScene = {PdScene}
/>
) : (
<></>
)}
{radio1 == 1 && butState ? (
{radio1 == 1 && butState && PdScene? (
<>
<EditAndDrawPanel
view={mapInfo.current}
PdScene = {PdScene}
view={viewRef.current}
editType={['POLYGON', 'EXTENT', 'CIRCLE']}
defaultGraphic={resultData || 'edgelayer-arcgismap'}
defaultGraphic={getDrawDefaultGraphic(resultData || mapConfig.layer_name_edgelayer_arcgismap)}
areaName={
form.getFieldsValue().areaName &&
form.getFieldsValue().areaName[form.getFieldsValue().areaName.length - 1]
......
......@@ -3,9 +3,8 @@ import React, { useEffect, useState, useRef } from 'react';
import SiteModal from '@/components/Modal/SiteModa';
import { Spin } from 'antd';
import { GetMetaDataPreview, GetTransformationGeom } from '@/services/gis/gis';
import { ArcGISSceneMap } from '@wisdom-map/arcgismap';
import {PdMap} from '@wisdom-map/pd-map'
import axios from 'axios';
import { getConditionList } from '@wisdom-map/basemap';
const VectorPreviewModal = props => {
const { metaData, visible } = props;
......@@ -67,7 +66,7 @@ const VectorPreviewModal = props => {
id: metaData?.GISServerProjectName,
title: metaData?.GISServerProjectName,
icon: '',
layerType: '',
layerType: 'PipenetLayer',
url: `/PandaGIS/MapServer/${metaData?.GISServerProjectName}`,
opacity: '1.0',
showLegend: true,
......@@ -80,7 +79,7 @@ const VectorPreviewModal = props => {
origin: '',
tileMatrix: '',
wmtsUrl: '',
schemename: '',
schemename: '测试方案',
roles: '',
areaName: '',
boundColor: '#86c8f8',
......@@ -141,9 +140,9 @@ const VectorPreviewModal = props => {
<Spin spinning={isLoading}>
<div style={{ width: '1000px', height: '500px' }}>
{currentMeta && (
<ArcGISSceneMap
getMapInfo={e => getMapInfo(e)}
config={currentMeta}
<PdMap
getPdScene={e => getMapInfo(e)}
config={currentMeta?.layers}
client="sandbox"
widgets={[]}
/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment