feat: 大屏
This commit is contained in:
107
src/packages/components/Charts/Maps/MapAmap/config.ts
Normal file
107
src/packages/components/Charts/Maps/MapAmap/config.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { MapAmapConfig } from './index'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import dataJson from './data.json'
|
||||
|
||||
export enum ThemeEnum {
|
||||
NORMAL = 'normal',
|
||||
DARK = 'dark',
|
||||
LIGHT = 'light',
|
||||
WHITES_MOKE = 'whitesmoke',
|
||||
FRESH = 'fresh',
|
||||
GREY = 'grey',
|
||||
GRAFFITI = 'graffiti',
|
||||
MACARON = 'macaron',
|
||||
BLUE = 'blue',
|
||||
DARKBLUE = 'darkblue',
|
||||
WINE = 'wine'
|
||||
}
|
||||
|
||||
export enum LangEnum {
|
||||
ZH_CN = 'zh_cn',
|
||||
EN = 'en',
|
||||
ZH_EN = 'zh_en'
|
||||
}
|
||||
|
||||
export enum ViewModeEnum {
|
||||
PLANE = '2D',
|
||||
STEREOSCOPIC = '3D'
|
||||
}
|
||||
|
||||
export const ShowHideEnum = {
|
||||
SHOW: true,
|
||||
HIDE: false
|
||||
}
|
||||
|
||||
export enum FeaturesEnum {
|
||||
BG = 'bg',
|
||||
POINT = 'point',
|
||||
ROAD = 'road',
|
||||
BUILDING = 'building'
|
||||
}
|
||||
|
||||
export enum MarkerEnum {
|
||||
// 圆圈
|
||||
CIRCLE_MARKER = 'CircleMarker',
|
||||
// 定位标点
|
||||
MARKER = 'Marker',
|
||||
// 暂无
|
||||
NONE = 'none'
|
||||
}
|
||||
|
||||
export const option = {
|
||||
dataset: dataJson,
|
||||
mapOptions: {
|
||||
pitch: 60,
|
||||
skyColor: '#53A9DE',
|
||||
amapKey: '',
|
||||
amapStyleKey: ThemeEnum.DARK,
|
||||
amapStyleKeyCustom: '',
|
||||
amapLon: 116.397428,
|
||||
amapLat: 39.90923,
|
||||
amapZindex: 11,
|
||||
marker: {
|
||||
fillColor: '#E98984FF',
|
||||
fillOpacity: 0.5,
|
||||
strokeColor: 'white',
|
||||
strokeWeight: 2,
|
||||
strokeOpacity: 0.5,
|
||||
zIndex: 10,
|
||||
bubble: true,
|
||||
cursor: 'pointer',
|
||||
clickable: true
|
||||
},
|
||||
mapMarkerType: MarkerEnum.CIRCLE_MARKER,
|
||||
viewMode: ViewModeEnum.PLANE,
|
||||
showLabel: ShowHideEnum.SHOW,
|
||||
satelliteTileLayer: {
|
||||
show: ShowHideEnum.HIDE,
|
||||
zIndex: 1,
|
||||
opacity: 1,
|
||||
zooms: [3, 18]
|
||||
},
|
||||
roadNetTileLayer: {
|
||||
show: ShowHideEnum.HIDE,
|
||||
zIndex: 2,
|
||||
opacity: 1,
|
||||
zooms: [3, 18]
|
||||
},
|
||||
trafficTileLayer: {
|
||||
show: ShowHideEnum.HIDE,
|
||||
zIndex: 3,
|
||||
opacity: 1,
|
||||
zooms: [3, 18]
|
||||
},
|
||||
lang: LangEnum.ZH_CN,
|
||||
features: [FeaturesEnum.BG, FeaturesEnum.POINT, FeaturesEnum.ROAD, FeaturesEnum.BUILDING]
|
||||
}
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = MapAmapConfig.key
|
||||
public attr = { ...chartInitConfig, w: 1000, h: 800, zIndex: -1 }
|
||||
public chartConfig = cloneDeep(MapAmapConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
||||
290
src/packages/components/Charts/Maps/MapAmap/config.vue
Normal file
290
src/packages/components/Charts/Maps/MapAmap/config.vue
Normal file
@@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<collapse-item name="基础" :expanded="true">
|
||||
<setting-item-box name="语言类型" :alone="true">
|
||||
<setting-item>
|
||||
<n-select size="small" v-model:value="optionData.mapOptions.lang" :options="langOptions" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="Key" :alone="true">
|
||||
<setting-item name="请务必使用自己的高德应用 key">
|
||||
<n-input v-model:value="optionData.mapOptions.amapKey" size="small"></n-input>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="自定义地图样式ID" :alone="true">
|
||||
<setting-item>
|
||||
<n-input size="small" v-model:value="optionData.mapOptions.amapStyleKeyCustom" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
<collapse-item name="地图" :expanded="true">
|
||||
<setting-item-box name="主题">
|
||||
<setting-item>
|
||||
<n-select size="small" v-model:value="optionData.mapOptions.amapStyleKey" :options="themeOptions" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="显示要素" :alone="true">
|
||||
<n-checkbox-group v-model:value="optionData.mapOptions.features">
|
||||
<n-space item-style="display: flex;">
|
||||
<n-checkbox :value="item.value" :label="item.label" v-for="(item, index) in featuresOptions" :key="index" />
|
||||
</n-space>
|
||||
</n-checkbox-group>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="文字标注" :alone="true">
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.mapOptions.showLabel" size="small" />
|
||||
<n-text>是否显示</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="位置">
|
||||
<setting-item name="经度">
|
||||
<n-input-number v-model:value="optionData.mapOptions.amapLon" :show-button="false" size="small">
|
||||
<template #suffix>°</template>
|
||||
</n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="纬度">
|
||||
<n-input-number v-model:value="optionData.mapOptions.amapLat" :show-button="false" size="small">
|
||||
<template #suffix>°</template>
|
||||
</n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="初始缩放">
|
||||
<n-input-number v-model:value="optionData.mapOptions.amapZindex" :min="0" size="small"></n-input-number>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="模式" :alone="true">
|
||||
<setting-item>
|
||||
<n-radio-group v-model:value="optionData.mapOptions.viewMode" name="radiogroup">
|
||||
<n-space>
|
||||
<n-radio v-for="song in viewModeOptions" :key="song.value" :value="song.value">
|
||||
{{ song.label }}
|
||||
</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<template v-if="optionData.mapOptions.viewMode === '3D'">
|
||||
<setting-item-box>
|
||||
<setting-item name="天空色">
|
||||
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.mapOptions.skyColor"></n-color-picker>
|
||||
</setting-item>
|
||||
<setting-item name="俯仰角">
|
||||
<n-input-number v-model:value="optionData.mapOptions.pitch" :min="0" :max="83" size="small"></n-input-number>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</template>
|
||||
</collapse-item>
|
||||
<collapse-item name="标记" :expanded="true">
|
||||
<setting-item-box name="样式">
|
||||
<setting-item name="类型">
|
||||
<n-select size="small" v-model:value="optionData.mapOptions.mapMarkerType" :options="MarkerOptions" />
|
||||
</setting-item>
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="optionData.mapOptions.marker.fillColor" size="small"></n-color-picker>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
<collapse-item name="图层" :expanded="true">
|
||||
<setting-item-box name="卫星图层">
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.mapOptions.satelliteTileLayer.show" size="small" />
|
||||
<n-text>是否显示</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="叠加顺序值">
|
||||
<n-input-number
|
||||
v-model:value="optionData.mapOptions.satelliteTileLayer.zIndex"
|
||||
:min="0"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.mapOptions.satelliteTileLayer.opacity"
|
||||
:min="0"
|
||||
:max="1"
|
||||
step="0.1"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="缩放级别范围">
|
||||
<n-slider v-model:value="optionData.mapOptions.satelliteTileLayer.zooms" range :step="1" :max="18" :min="3" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="路网图层">
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.mapOptions.roadNetTileLayer.show" size="small" />
|
||||
<n-text>是否显示</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="叠加顺序值">
|
||||
<n-input-number
|
||||
v-model:value="optionData.mapOptions.roadNetTileLayer.zIndex"
|
||||
:min="0"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.mapOptions.roadNetTileLayer.opacity"
|
||||
:min="0"
|
||||
:max="1"
|
||||
step="0.1"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="缩放级别范围">
|
||||
<n-slider v-model:value="optionData.mapOptions.roadNetTileLayer.zooms" range :step="1" :max="18" :min="3" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="实时交通">
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.mapOptions.trafficTileLayer.show" size="small" />
|
||||
<n-text>是否显示</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="叠加顺序值">
|
||||
<n-input-number
|
||||
v-model:value="optionData.mapOptions.trafficTileLayer.zIndex"
|
||||
:min="0"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.mapOptions.trafficTileLayer.opacity"
|
||||
:min="0"
|
||||
:max="1"
|
||||
step="0.1"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="缩放级别范围">
|
||||
<n-slider v-model:value="optionData.mapOptions.trafficTileLayer.zooms" range :step="1" :max="18" :min="3" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, ShowHideEnum, FeaturesEnum } from './config'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<typeof option>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const themeOptions = [
|
||||
{
|
||||
value: ThemeEnum.NORMAL,
|
||||
label: '标准'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.DARK,
|
||||
label: '幻影黑'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.LIGHT,
|
||||
label: '月光银'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.WHITES_MOKE,
|
||||
label: '远山黛'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.FRESH,
|
||||
label: '草色青'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.GREY,
|
||||
label: '雅士灰'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.GRAFFITI,
|
||||
label: '涂鸦'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.MACARON,
|
||||
label: '马卡龙'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.BLUE,
|
||||
label: '靛青蓝'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.DARKBLUE,
|
||||
label: '极夜蓝'
|
||||
},
|
||||
{
|
||||
value: ThemeEnum.WINE,
|
||||
label: '酱籽'
|
||||
}
|
||||
]
|
||||
|
||||
const langOptions = [
|
||||
{
|
||||
value: LangEnum.ZH_CN,
|
||||
label: '中文简体'
|
||||
},
|
||||
{
|
||||
value: LangEnum.EN,
|
||||
label: '英文'
|
||||
},
|
||||
{
|
||||
value: LangEnum.ZH_EN,
|
||||
label: '中英文对照'
|
||||
}
|
||||
]
|
||||
|
||||
const viewModeOptions = [
|
||||
{
|
||||
value: ViewModeEnum.PLANE,
|
||||
label: '2D'
|
||||
},
|
||||
{
|
||||
value: ViewModeEnum.STEREOSCOPIC,
|
||||
label: '3D'
|
||||
}
|
||||
]
|
||||
|
||||
const featuresOptions = [
|
||||
{
|
||||
value: FeaturesEnum.BG,
|
||||
label: '区域面'
|
||||
},
|
||||
{
|
||||
value: FeaturesEnum.POINT,
|
||||
label: '标注'
|
||||
},
|
||||
{
|
||||
value: FeaturesEnum.ROAD,
|
||||
label: '道路'
|
||||
},
|
||||
{
|
||||
value: FeaturesEnum.BUILDING,
|
||||
label: '建筑物'
|
||||
}
|
||||
]
|
||||
|
||||
const MarkerOptions = [
|
||||
{
|
||||
value: MarkerEnum.CIRCLE_MARKER,
|
||||
label: '圆形标点'
|
||||
},
|
||||
{
|
||||
value: MarkerEnum.MARKER,
|
||||
label: '定位标点'
|
||||
},
|
||||
{
|
||||
value: MarkerEnum.NONE,
|
||||
label: '隐藏标点'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
19
src/packages/components/Charts/Maps/MapAmap/data.json
Normal file
19
src/packages/components/Charts/Maps/MapAmap/data.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"markers": [
|
||||
{
|
||||
"name": "某某地市",
|
||||
"value": 10,
|
||||
"position": [116.300467, 39.907761]
|
||||
},
|
||||
{
|
||||
"name": "某某地市",
|
||||
"value": 15,
|
||||
"position": [116.400567, 39.908761]
|
||||
},
|
||||
{
|
||||
"name": "某某地市",
|
||||
"value": 20,
|
||||
"position": [116.200467, 39.937761]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
src/packages/components/Charts/Maps/MapAmap/index.ts
Normal file
14
src/packages/components/Charts/Maps/MapAmap/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
|
||||
export const MapAmapConfig: ConfigType = {
|
||||
key: 'MapAmap',
|
||||
chartKey: 'VMapAmap',
|
||||
conKey: 'VCMapAmap',
|
||||
title: '高德地图',
|
||||
category: ChatCategoryEnum.MAP,
|
||||
categoryName: ChatCategoryEnumName.MAP,
|
||||
package: PackagesCategoryEnum.CHARTS,
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: 'map_amap.png'
|
||||
}
|
||||
164
src/packages/components/Charts/Maps/MapAmap/index.vue
Normal file
164
src/packages/components/Charts/Maps/MapAmap/index.vue
Normal file
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div ref="vChartRef"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, PropType, toRefs, watch } from 'vue'
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { MarkerEnum, ThemeEnum } from './config'
|
||||
import { isArray } from '@/utils'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
let {
|
||||
amapKey,
|
||||
amapStyleKey,
|
||||
amapLon,
|
||||
amapLat,
|
||||
amapZindex,
|
||||
mapMarkerType,
|
||||
lang,
|
||||
amapStyleKeyCustom,
|
||||
features,
|
||||
viewMode,
|
||||
showLabel,
|
||||
pitch,
|
||||
skyColor,
|
||||
marker,
|
||||
satelliteTileLayer,
|
||||
roadNetTileLayer,
|
||||
trafficTileLayer
|
||||
} = toRefs(props.chartConfig.option.mapOptions)
|
||||
|
||||
let mapIns: any = null
|
||||
let markers: any = []
|
||||
let AMapIns: any = null
|
||||
const vChartRef = ref<HTMLElement>()
|
||||
|
||||
const initMap = (newData: any) => {
|
||||
// 初始化
|
||||
AMapLoader.load({
|
||||
key: amapKey.value, //api服务key--另外需要在public中使用安全密钥!!!
|
||||
version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
||||
plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete'] // 需要使用的的插件列表
|
||||
})
|
||||
.then(AMap => {
|
||||
AMapIns = AMap
|
||||
mapIns = new AMap.Map(vChartRef.value, {
|
||||
resizeEnable: true,
|
||||
zoom: amapZindex.value, // 地图显示的缩放级别
|
||||
center: [amapLon.value, amapLat.value],
|
||||
lang: lang.value,
|
||||
features: features.value,
|
||||
pitch: pitch.value, // 地图俯仰角度,有效范围 0 度- 83 度
|
||||
skyColor: skyColor.value,
|
||||
viewMode: viewMode.value, // 地图模式
|
||||
showLabel: showLabel.value, // 是否显示地图文字标记
|
||||
willReadFrequently: true
|
||||
})
|
||||
dataHandle(props.chartConfig.option.dataset)
|
||||
|
||||
let satelliteLayer = new AMap.TileLayer.Satellite({
|
||||
zIndex: satelliteTileLayer.value.zIndex,
|
||||
opacity: satelliteTileLayer.value.opacity,
|
||||
zooms: satelliteTileLayer.value.zooms
|
||||
})
|
||||
let roadNetLayer = new AMap.TileLayer.RoadNet({
|
||||
zIndex: roadNetTileLayer.value.zIndex,
|
||||
opacity: roadNetTileLayer.value.opacity,
|
||||
zooms: roadNetTileLayer.value.zooms
|
||||
})
|
||||
let trafficLayer = new AMap.TileLayer.Traffic({
|
||||
zIndex: trafficTileLayer.value.zIndex,
|
||||
opacity: trafficTileLayer.value.opacity,
|
||||
zooms: trafficTileLayer.value.zooms
|
||||
})
|
||||
mapIns.remove([satelliteLayer, roadNetLayer, trafficLayer])
|
||||
if (satelliteTileLayer.value.show) {
|
||||
mapIns.add([satelliteLayer])
|
||||
}
|
||||
if (roadNetTileLayer.value.show) {
|
||||
mapIns.add([roadNetLayer])
|
||||
}
|
||||
if (trafficTileLayer.value.show) {
|
||||
mapIns.add([trafficLayer])
|
||||
}
|
||||
|
||||
mapIns.setMapStyle(
|
||||
`amap://styles/${amapStyleKeyCustom.value !== '' ? amapStyleKeyCustom.value : amapStyleKey.value}`
|
||||
)
|
||||
})
|
||||
.catch(e => {})
|
||||
}
|
||||
|
||||
const dataHandle = (newData: any) => {
|
||||
if (!mapIns && !AMapIns) {
|
||||
initMap(props.chartConfig.option)
|
||||
return
|
||||
}
|
||||
if (isArray(newData.markers)) {
|
||||
// 先清除旧标记
|
||||
mapIns.remove(markers)
|
||||
markers = []
|
||||
// 记录新标记
|
||||
if (mapMarkerType.value === MarkerEnum.MARKER) {
|
||||
newData.markers.forEach((markerItem: any) => {
|
||||
const markerInstance = new AMapIns.Marker({
|
||||
position: [markerItem.position[0], markerItem.position[1]],
|
||||
offset: new AMapIns.Pixel(-13, -30)
|
||||
})
|
||||
markers.push(markerInstance)
|
||||
markerInstance.setMap(mapIns)
|
||||
})
|
||||
} else if (mapMarkerType.value === MarkerEnum.CIRCLE_MARKER) {
|
||||
newData.markers.forEach((markerItem: any) => {
|
||||
const markerInstance = new AMapIns.CircleMarker({
|
||||
center: [markerItem.position[0], markerItem.position[1]],
|
||||
radius: markerItem.value,
|
||||
...marker.value
|
||||
})
|
||||
markers.push(markerInstance)
|
||||
markerInstance.setMap(mapIns)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const stopWatch = watch(
|
||||
() => props.chartConfig.option.mapOptions,
|
||||
option => {
|
||||
initMap(option)
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.chartConfig.option.dataset,
|
||||
newData => {
|
||||
try {
|
||||
dataHandle(newData)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: false
|
||||
}
|
||||
)
|
||||
|
||||
// 预览
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
stopWatch()
|
||||
dataHandle(newData)
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user