Commit fbfab9c1c3d41760f2dcb8d52749aef7f24cc25f

Authored by xp.Huang
2 parents 6fcb269e 14290afd

Merge branch 'ft' into 'main_dev'

fix(src/packages): 图表地图 地图右侧配置回显省份选择城市选择

See merge request yunteng/thingskit-view!112
... ... @@ -46,6 +46,7 @@ export const getPlatformInfo = () => defHttp.get({ url: Api.PLATFORM })
46 46 export const getConfigurationList = (params: object) => {
47 47 return defHttp.get({ url: `${Api.CONFIGURATION}`, params })
48 48 }
  49 +
49 50 //组态设置是否公开或私有
50 51 export const setConfigurationIsShare = (params: string,isShare:boolean,data:object) => {
51 52 return defHttp.post({
... ... @@ -53,3 +54,15 @@ export const setConfigurationIsShare = (params: string,isShare:boolean,data:obje
53 54 data
54 55 })
55 56 }
  57 +
  58 +// 获取设备状态,在线 or 离线时间
  59 +export const getDeviceActiveTime = (entityId: string) => {
  60 + return defHttp.get(
  61 + {
  62 + url: `/plugins/telemetry/DEVICE/${entityId}/values/attributes?keys=active`,
  63 + },
  64 + {
  65 + joinPrefix: false,
  66 + }
  67 + );
  68 +};
\ No newline at end of file
... ...
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { CreateComponentType } from '@/packages/index.d'
  3 +import { OverrideMapAmapConfig } from './index'
  4 +import { chartInitConfig } from '@/settings/designSetting'
  5 +import cloneDeep from 'lodash/cloneDeep'
  6 +import dataJson from './data.json'
  7 +
  8 +export type dataExtraInfoType = typeof dataJson.markers[number]['extraInfo'] //data.json下的extraInfo类型
  9 +
  10 +export type dataJsonType = typeof dataJson //data.json类型
  11 +
  12 +export type dataJsonMarkersType = typeof dataJson.markers[number] //data.json markers类型
  13 +
  14 +export enum ThemeEnum {
  15 + NORMAL = 'normal',
  16 + DARK = 'dark',
  17 + LIGHT = 'light',
  18 + WHITES_MOKE = 'whitesmoke',
  19 + FRESH = 'fresh',
  20 + GREY = 'grey',
  21 + GRAFFITI = 'graffiti',
  22 + MACARON = 'macaron',
  23 + BLUE = 'blue',
  24 + DARKBLUE = 'darkblue',
  25 + WINE = 'wine',
  26 + WEIXIN = 'tileLayer'
  27 +}
  28 +
  29 +export enum LangEnum {
  30 + ZH_CN = 'zh_cn',
  31 + EN = 'en',
  32 + ZH_EN = 'zh_en'
  33 +}
  34 +
  35 +export enum ViewModeEnum {
  36 + PLANE = '2D',
  37 + STEREOSCOPIC = '3D'
  38 +}
  39 +
  40 +export enum FeaturesEnum {
  41 + BG = 'bg',
  42 + POINT = 'point',
  43 + ROAD = 'road',
  44 + BUILDING = 'building'
  45 +}
  46 +
  47 +export enum MarkerEnum {
  48 + // 圆圈
  49 + CIRCLE_MARKER = 'CircleMarker',
  50 + // 定位标点
  51 + MARKER = 'Marker',
  52 + // 暂无
  53 + NONE = 'none'
  54 +}
  55 +
  56 +export const option = {
  57 + dataset: dataJson,
  58 + mapOptions: {
  59 + pitch: 60,
  60 + skyColor: '#53A9DE',
  61 + amapKey: 'd5f3e16589dbecae64d05fe90e2ba4f2',
  62 + amapStyleKey: ThemeEnum.DARK,
  63 + amapStyleKeyCustom: '',
  64 + amapLon: 104.108689,
  65 + amapLat: 30.66176,
  66 + amapZindex: 11,
  67 + marker: {
  68 + fillColor: '#E98984FF',
  69 + fillOpacity: 0.5,
  70 + strokeColor: 'white',
  71 + strokeWeight: 2,
  72 + strokeOpacity: 0.5,
  73 + zIndex: 10,
  74 + bubble: true,
  75 + cursor: 'pointer',
  76 + clickable: true
  77 + },
  78 + mapMarkerType: MarkerEnum.MARKER,
  79 + viewMode: ViewModeEnum.PLANE,
  80 + lang: LangEnum.ZH_CN,
  81 + features: [FeaturesEnum.BG, FeaturesEnum.POINT, FeaturesEnum.ROAD, FeaturesEnum.BUILDING]
  82 + }
  83 +}
  84 +
  85 +export default class Config extends PublicConfigClass implements CreateComponentType {
  86 + public key = OverrideMapAmapConfig.key
  87 + public attr = { ...chartInitConfig, w: 1000, h: 800, zIndex: -1 }
  88 + public chartConfig = cloneDeep(OverrideMapAmapConfig)
  89 + public option = cloneDeep(option)
  90 +}
... ...
  1 +<template>
  2 + <collapse-item name="基础" :expanded="true">
  3 + <setting-item-box name="语言类型" :alone="true">
  4 + <setting-item>
  5 + <n-select size="small" v-model:value="optionData.mapOptions.lang" :options="langOptions" />
  6 + </setting-item>
  7 + </setting-item-box>
  8 + <setting-item-box name="Key" :alone="true">
  9 + <setting-item name="请务必使用自己的高德应用 key">
  10 + <n-input v-model:value="optionData.mapOptions.amapKey" size="small"></n-input>
  11 + </setting-item>
  12 + </setting-item-box>
  13 + <setting-item-box name="自定义地图样式ID" :alone="true">
  14 + <setting-item>
  15 + <n-input size="small" v-model:value="optionData.mapOptions.amapStyleKeyCustom" />
  16 + </setting-item>
  17 + </setting-item-box>
  18 + </collapse-item>
  19 + <collapse-item name="地图" :expanded="true">
  20 + <setting-item-box name="主题">
  21 + <setting-item>
  22 + <n-select size="small" v-model:value="optionData.mapOptions.amapStyleKey" :options="themeOptions" />
  23 + </setting-item>
  24 + </setting-item-box>
  25 + <setting-item-box name="内容" :alone="true">
  26 + <n-checkbox-group v-model:value="optionData.mapOptions.features">
  27 + <n-space item-style="display: flex;">
  28 + <n-checkbox :value="item.value" :label="item.label" v-for="(item, index) in featuresOptions" :key="index" />
  29 + </n-space>
  30 + </n-checkbox-group>
  31 + </setting-item-box>
  32 + <setting-item-box name="位置">
  33 + <setting-item name="经度">
  34 + <n-input-number v-model:value="optionData.mapOptions.amapLon" :show-button="false" size="small">
  35 + <template #suffix>°</template>
  36 + </n-input-number>
  37 + </setting-item>
  38 + <setting-item name="纬度">
  39 + <n-input-number v-model:value="optionData.mapOptions.amapLat" :show-button="false" size="small">
  40 + <template #suffix>°</template>
  41 + </n-input-number>
  42 + </setting-item>
  43 + <setting-item name="初始缩放">
  44 + <n-input-number v-model:value="optionData.mapOptions.amapZindex" :min="0" size="small"></n-input-number>
  45 + </setting-item>
  46 + </setting-item-box>
  47 + <setting-item-box name="模式" :alone="true">
  48 + <setting-item>
  49 + <n-radio-group v-model:value="optionData.mapOptions.viewMode" name="radiogroup">
  50 + <n-space>
  51 + <n-radio v-for="song in viewModeOptions" :key="song.value" :value="song.value">
  52 + {{ song.label }}
  53 + </n-radio>
  54 + </n-space>
  55 + </n-radio-group>
  56 + </setting-item>
  57 + </setting-item-box>
  58 + <template v-if="optionData.mapOptions.viewMode === '3D'">
  59 + <setting-item-box>
  60 + <setting-item name="天空色">
  61 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.mapOptions.skyColor"></n-color-picker>
  62 + </setting-item>
  63 + <setting-item name="俯仰角">
  64 + <n-input-number v-model:value="optionData.mapOptions.pitch" :min="0" :max="83" size="small"></n-input-number>
  65 + </setting-item>
  66 + </setting-item-box>
  67 + </template>
  68 + </collapse-item>
  69 + <collapse-item name="标记" :expanded="true">
  70 + <setting-item-box name="样式">
  71 + <setting-item name="类型">
  72 + <n-select size="small" v-model:value="optionData.mapOptions.mapMarkerType" :options="MarkerOptions" />
  73 + </setting-item>
  74 + <setting-item name="颜色">
  75 + <n-color-picker v-model:value="optionData.mapOptions.marker.fillColor" size="small"></n-color-picker>
  76 + </setting-item>
  77 + </setting-item-box>
  78 + </collapse-item>
  79 +</template>
  80 +
  81 +<script setup lang="ts">
  82 +import { PropType } from 'vue'
  83 +import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config'
  84 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  85 +
  86 +defineProps({
  87 + optionData: {
  88 + type: Object as PropType<typeof option>,
  89 + required: true
  90 + }
  91 +})
  92 +
  93 +const themeOptions = [
  94 + {
  95 + value: ThemeEnum.NORMAL,
  96 + label: '标准'
  97 + },
  98 + {
  99 + value: ThemeEnum.DARK,
  100 + label: '幻影黑'
  101 + },
  102 + {
  103 + value: ThemeEnum.LIGHT,
  104 + label: '月光银'
  105 + },
  106 + {
  107 + value: ThemeEnum.WHITES_MOKE,
  108 + label: '远山黛'
  109 + },
  110 + {
  111 + value: ThemeEnum.FRESH,
  112 + label: '草色青'
  113 + },
  114 + {
  115 + value: ThemeEnum.GREY,
  116 + label: '雅士灰'
  117 + },
  118 + {
  119 + value: ThemeEnum.GRAFFITI,
  120 + label: '涂鸦'
  121 + },
  122 + {
  123 + value: ThemeEnum.MACARON,
  124 + label: '马卡龙'
  125 + },
  126 + {
  127 + value: ThemeEnum.BLUE,
  128 + label: '靛青蓝'
  129 + },
  130 + {
  131 + value: ThemeEnum.DARKBLUE,
  132 + label: '极夜蓝'
  133 + },
  134 + {
  135 + value: ThemeEnum.WINE,
  136 + label: '酱籽'
  137 + },
  138 + {
  139 + value: ThemeEnum.WEIXIN,
  140 + label: '卫星'
  141 + }
  142 +]
  143 +
  144 +const langOptions = [
  145 + {
  146 + value: LangEnum.ZH_CN,
  147 + label: '中文简体'
  148 + },
  149 + {
  150 + value: LangEnum.EN,
  151 + label: '英文'
  152 + },
  153 + {
  154 + value: LangEnum.ZH_EN,
  155 + label: '中英文对照'
  156 + }
  157 +]
  158 +
  159 +const viewModeOptions = [
  160 + {
  161 + value: ViewModeEnum.PLANE,
  162 + label: '2D'
  163 + },
  164 + {
  165 + value: ViewModeEnum.STEREOSCOPIC,
  166 + label: '3D'
  167 + }
  168 +]
  169 +
  170 +const featuresOptions = [
  171 + {
  172 + value: FeaturesEnum.BG,
  173 + label: '显示地图背景'
  174 + },
  175 + {
  176 + value: FeaturesEnum.POINT,
  177 + label: '显示标识'
  178 + },
  179 + {
  180 + value: FeaturesEnum.ROAD,
  181 + label: '显示道路'
  182 + },
  183 + {
  184 + value: FeaturesEnum.BUILDING,
  185 + label: '显示建筑'
  186 + }
  187 +]
  188 +
  189 +const MarkerOptions = [
  190 + {
  191 + value: MarkerEnum.CIRCLE_MARKER,
  192 + label: '圆形标点'
  193 + },
  194 + {
  195 + value: MarkerEnum.MARKER,
  196 + label: '定位标点'
  197 + },
  198 + {
  199 + value: MarkerEnum.NONE,
  200 + label: '隐藏标点'
  201 + }
  202 +]
  203 +</script>
... ...
  1 +{
  2 + "markers": [
  3 + {
  4 + "name": "模拟11111111111",
  5 + "value": 20,
  6 + "position": [103.856504, 30.687278],
  7 + "extraInfo": {
  8 + "tbDeviceId": "@xxxxxxxxxxx",
  9 + "name": "模拟11111111111",
  10 + "alias": "模拟11111111111",
  11 + "organizationDTO": {
  12 + "name": "模拟11111111111"
  13 + },
  14 + "deviceState": "INACTIVE",
  15 + "deviceProfile": {
  16 + "transportType": "MQTT"
  17 + },
  18 + "deviceInfo": {
  19 + "address": "四川省",
  20 + "longitude": 103.856504,
  21 + "latitude": 30.687278
  22 + }
  23 + }
  24 + },
  25 + {
  26 + "name": "模拟22222222222",
  27 + "value": 30,
  28 + "position": [104.095368, 30.716787],
  29 + "extraInfo": {
  30 + "tbDeviceId": "@xxxxxxxxxxxxxxx",
  31 + "name": "模拟22222222222",
  32 + "alias": "模拟22222222222",
  33 + "organizationDTO": {
  34 + "name": "模拟22222222222"
  35 + },
  36 + "deviceState": "INACTIVE",
  37 + "deviceProfile": {
  38 + "transportType": "TCP"
  39 + },
  40 + "deviceInfo": {
  41 + "address": "四川省",
  42 + "longitude": 104.095368,
  43 + "latitude": 30.716787
  44 + }
  45 + }
  46 + }
  47 + ]
  48 +}
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Charts/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, conKey, chartKey } = useWidgetKey('OverrideMapAmap', true)
  6 +
  7 +export const OverrideMapAmapConfig: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '高德地图',
  12 + category: ChatCategoryEnum.MAP,
  13 + categoryName: ChatCategoryEnumName.MAP,
  14 + package: PackagesCategoryEnum.CHARTS,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'map_amap.png'
  17 +}
... ...
  1 +<template>
  2 + <div ref="vChartRef"></div>
  3 +</template>
  4 +
  5 +<script setup lang="ts">
  6 +import { ref, PropType, toRefs, watch } from 'vue'
  7 +import AMapLoader from '@amap/amap-jsapi-loader'
  8 +import { CreateComponentType } from '@/packages/index.d'
  9 +import { useChartDataFetch } from '@/hooks'
  10 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  11 +import { MarkerEnum, ThemeEnum, dataExtraInfoType, dataJsonType, dataJsonMarkersType } from './config'
  12 +import { isArray } from '@/utils'
  13 +import djh from './images/djh.png'
  14 +import online from './images/online.png'
  15 +import lx1 from './images/lx1.png'
  16 +import { getDeviceActiveTime } from '@/api/external/common/index'
  17 +import dayjs from 'dayjs'
  18 +
  19 +const props = defineProps({
  20 + chartConfig: {
  21 + type: Object as PropType<CreateComponentType>,
  22 + required: true
  23 + }
  24 +})
  25 +
  26 +let {
  27 + amapKey,
  28 + amapStyleKey,
  29 + amapLon,
  30 + amapLat,
  31 + amapZindex,
  32 + mapMarkerType,
  33 + lang,
  34 + amapStyleKeyCustom,
  35 + features,
  36 + viewMode,
  37 + pitch,
  38 + skyColor,
  39 + marker
  40 +} = toRefs(props.chartConfig.option.mapOptions)
  41 +
  42 +//官方没有高德地图api的ts,所以类型全用的any
  43 +let mapIns: any = null
  44 +let markers: any = []
  45 +let AMapIns: any = null
  46 +const vChartRef = ref<HTMLElement>()
  47 +
  48 +const initMap = (newData: any) => {
  49 + // 初始化
  50 + AMapLoader.load({
  51 + key: amapKey.value, //api服务key--另外需要在public中使用安全密钥!!!
  52 + version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
  53 + plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete'] // 需要使用的的插件列表
  54 + })
  55 + .then(AMap => {
  56 + AMapIns = AMap
  57 + mapIns = new AMap.Map(vChartRef.value, {
  58 + resizeEnable: true,
  59 + zoom: amapZindex.value, // 地图显示的缩放级别
  60 + center: [amapLon.value, amapLat.value],
  61 + lang: lang.value,
  62 + features: features.value,
  63 + pitch: pitch.value, // 地图俯仰角度,有效范围 0 度- 83 度
  64 + skyColor: skyColor.value,
  65 + viewMode: viewMode.value, // 地图模式
  66 + willReadFrequently: true
  67 + })
  68 + dataHandle(props.chartConfig.option.dataset) //处理地图标点
  69 + let satellite = new AMap.TileLayer.Satellite()
  70 + let roadNet = new AMap.TileLayer.RoadNet()
  71 + if (newData.amapStyleKey === ThemeEnum.WEIXIN) {
  72 + mapIns.add([satellite, roadNet])
  73 + } else {
  74 + mapIns.remove([satellite, roadNet])
  75 + mapIns.setMapStyle(
  76 + `amap://styles/${amapStyleKeyCustom.value !== '' ? amapStyleKeyCustom.value : amapStyleKey.value}`
  77 + )
  78 + }
  79 + //点击地图任意地方关闭infoWindow窗体
  80 + mapIns.on('click', () => {
  81 + mapIns.clearInfoWindow()
  82 + })
  83 + })
  84 + .catch(e => {
  85 + console.error(e)
  86 + })
  87 +}
  88 +
  89 +//创建信息弹窗
  90 +const createInfoWindow = async (extraInfo: dataExtraInfoType) => {
  91 + try {
  92 + const { name, alias, organizationDTO, deviceState, deviceProfile, deviceInfo, tbDeviceId } = extraInfo
  93 + if (tbDeviceId.startsWith('@')) return //假的模拟数据则终止
  94 + const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间
  95 + let { lastUpdateTs } = res[0]
  96 + const lastUpdateFormatTs = dayjs(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss')
  97 + return `
  98 + <div style="width:15vw;height:18vh;background-color:white;">
  99 + <div style="margin:0px 10px">
  100 + <div style="display:flex;justify-content:space-between; margin:20px 0px;">
  101 + <div style="font-size:16px;font-weight:bold">${alias || name}</div>
  102 + ${
  103 + deviceState === 'INACTIVE'
  104 + ? `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${djh}" class="mr-1">待激活</div>`
  105 + : deviceState === 'ONLINE'
  106 + ? `<div style="display:flex;align-items:center; ">
  107 + <img style="width:15px;height:15px" src="${online}" class="mr-1">在线</div>`
  108 + : `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${lx1}" class="mr-1">离线</div>`
  109 + }
  110 + </div>
  111 + <div>所属组织:${organizationDTO.name}</div>
  112 + <div style="margin-top:6px;">接入协议:${deviceProfile.transportType}</div>
  113 + <div style="margin-top:6px;">
  114 + 设备位置:${!deviceInfo.address ? '该设备暂无地理位置' : deviceInfo.address}
  115 + </div>
  116 + <div style="margin-top:6px;">
  117 + ${
  118 + deviceState === 'ONLINE' ? '在线' : deviceState === 'INACTIVE' ? '创建' : '离线'
  119 + }时间:${lastUpdateFormatTs}
  120 + </div>
  121 + </div>
  122 + </div>
  123 + `
  124 + } catch (e) {
  125 + console.error(e)
  126 + }
  127 +}
  128 +
  129 +//地图点击
  130 +const mapClick = (markerInstance: any, markerItem: dataJsonMarkersType) => {
  131 + markerInstance.setExtData({
  132 + extraInfo: markerItem.extraInfo
  133 + })
  134 + markerInstance.setLabel({
  135 + content: markerItem.extraInfo.alias || markerItem.extraInfo.name
  136 + })
  137 + markerInstance.on('click', async (e: any) => {
  138 + const { extraInfo } = e.target.getExtData()
  139 + let infoWindow = new AMapIns.InfoWindow({
  140 + content: await createInfoWindow(extraInfo),
  141 + offset: new AMapIns.Pixel(0, -50)
  142 + })
  143 + infoWindow.open(mapIns, e.target.getPosition())
  144 + })
  145 +}
  146 +
  147 +const dataHandle = (newData: dataJsonType) => {
  148 + if (!mapIns && !AMapIns) {
  149 + initMap(props.chartConfig.option)
  150 + return
  151 + }
  152 + if (isArray(newData.markers)) {
  153 + // 先清除旧标记
  154 + mapIns.remove(markers)
  155 + markers = []
  156 + // 记录新标记
  157 + if (mapMarkerType.value === MarkerEnum.MARKER) {
  158 + newData.markers.forEach((markerItem: dataJsonMarkersType) => {
  159 + const markerInstance = new AMapIns.Marker({
  160 + position: [markerItem.position[0], markerItem.position[1]],
  161 + offset: new AMapIns.Pixel(-13, -30)
  162 + })
  163 + // markers.push(markerInstance) 原作者这种方式添加,属于JS API 1.4.8版本的
  164 + // markerInstance.setMap(mapIns)
  165 + mapIns.add(markerInstance)
  166 + mapClick(markerInstance, markerItem)
  167 + })
  168 + } else if (mapMarkerType.value === MarkerEnum.CIRCLE_MARKER) {
  169 + newData.markers.forEach((markerItem: dataJsonMarkersType) => {
  170 + const markerInstance = new AMapIns.CircleMarker({
  171 + center: [
  172 + !markerItem.position[0] ? 0 : markerItem.position[0],
  173 + !markerItem.position[1] ? 0 : markerItem.position[1]
  174 + ],
  175 + radius: markerItem.value, //圆圈半径大小
  176 + ...marker.value
  177 + })
  178 + // markers.push(markerInstance) //原作者这种方式添加,属于JS API 1.4.8版本的
  179 + // markerInstance.setMap(mapIns)
  180 + mapIns.add(markerInstance)
  181 + mapClick(markerInstance, markerItem)
  182 + })
  183 + }
  184 + }
  185 +}
  186 +
  187 +const stopWatch = watch(
  188 + () => props.chartConfig.option.mapOptions,
  189 + option => {
  190 + initMap(option)
  191 + },
  192 + {
  193 + immediate: true,
  194 + deep: true
  195 + }
  196 +)
  197 +
  198 +watch(
  199 + () => props.chartConfig.option.dataset,
  200 + newData => {
  201 + try {
  202 + dataHandle(newData)
  203 + } catch (error) {
  204 + console.log(error)
  205 + }
  206 + },
  207 + {
  208 + deep: false
  209 + }
  210 +)
  211 +
  212 +// 预览
  213 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
  214 + stopWatch()
  215 + dataHandle(newData)
  216 +})
  217 +</script>
... ...
... ... @@ -4,9 +4,12 @@ import { getAreaList } from '@/api/external/common/index'
4 4 import { areaEnum } from '../config'
5 5
6 6 const props = defineProps({
7   - drillingIn:{
8   - type:Boolean,
9   - default:false
  7 + drillingIn: {
  8 + type: Boolean,
  9 + default: false
  10 + },
  11 + optionData: {
  12 + type: Object
10 13 }
11 14 })
12 15
... ... @@ -39,6 +42,8 @@ onMounted(async () => {
39 42 label: '中国',
40 43 value: 'china'
41 44 })
  45 + onHandleSelectProvince(props.optionData?.mapRegion.saveSelect['provinceValue'])
  46 + for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i])
42 47 })
43 48
44 49 const onHandleSelectProvince = async (value: number | string) => {
... ...
... ... @@ -22,7 +22,8 @@ export const option = {
22 22 dataset: dataJson,
23 23 mapRegion: {
24 24 adcode: 'china',
25   - showHainanIsLands: true
  25 + showHainanIsLands: true,
  26 + saveSelect:{}
26 27 },
27 28 tooltip: {
28 29 show: true,
... ...
... ... @@ -39,7 +39,7 @@
39 39 ></n-input-number>
40 40 </SettingItem>
41 41 </SettingItemBox>
42   - <SelectCity :drillingIn="optionData.drillingIn" @submit="onHandleSelectValues" />
  42 + <SelectCity :optionData="optionData" :drillingIn="optionData.drillingIn" @submit="onHandleSelectValues" />
43 43 <SettingItemBox name="区域颜色">
44 44 <SettingItem name="0%处颜色">
45 45 <n-color-picker
... ... @@ -300,6 +300,7 @@ const mapRegion = computed(() => {
300 300
301 301 const onHandleSelectValues = (values: any) => {
302 302 const { cityValue, countyValue, provinceValue } = values
  303 + props.optionData.mapRegion.saveSelect = values
303 304 props.optionData.mapRegion.adcode = countyValue
304 305 ? countyValue
305 306 : cityValue
... ...
... ... @@ -13,7 +13,7 @@ export const option = {
13 13 // 下拉展示
14 14 isPanel: 0,
15 15 // 默认值
16   - dataset: dayjs().valueOf() as number | number[] | null,
  16 + dataset: [new Date().getTime() - 86400000,new Date().getTime()],
17 17 // 默认值类型
18 18 defaultType: DefaultTypeEnum.STATIC,
19 19 // 动态默认值偏移单位
... ...
... ... @@ -224,5 +224,5 @@ const shortCutSelect = (value: number) => {
224 224 const endTs = Date.now()
225 225 props.optionData.dataset = [startTs, endTs] as any
226 226 }
227   -shortCutSelect(24*60*60*1000)//默认近1天
  227 +// shortCutSelect(24*60*60*1000)//默认近1天
228 228 </script>
... ...
... ... @@ -5,20 +5,21 @@
5 5 :panel="!!chartConfig.option.isPanel"
6 6 :type="chartConfig.option.componentInteractEventKey"
7 7 :style="`width:${w}px;`"
8   - :to="false"
  8 + :to="true"
9 9 @update:value="onChange"
  10 + :shortcuts="rangeShortcuts"
10 11 />
11 12 </template>
12 13
13 14 <script setup lang="ts">
14   -import { PropType, toRefs, shallowReactive, watch ,ref,computed} from 'vue'
15   -import dayjs, {ManipulateType} from 'dayjs'
  15 +import { PropType, toRefs, shallowReactive, watch, ref, computed } from 'vue'
  16 +import dayjs, { ManipulateType } from 'dayjs'
16 17 import { CreateComponentType } from '@/packages/index.d'
17 18 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
18 19 import { useChartInteract } from '@/hooks/external/useChartDateInteract.hook'
19 20 import { InteractEventOn } from '@/enums/eventEnum'
20   -import {ComponentInteractEventEnum, ComponentInteractParamsEnum, DefaultTypeEnum} from './interact'
21   -import quarterOfYear from 'dayjs/plugin/quarterOfYear';
  21 +import { ComponentInteractEventEnum, ComponentInteractParamsEnum, DefaultTypeEnum } from './interact'
  22 +import quarterOfYear from 'dayjs/plugin/quarterOfYear'
22 23
23 24 const props = defineProps({
24 25 chartConfig: {
... ... @@ -28,8 +29,24 @@ const props = defineProps({
28 29 })
29 30
30 31 const { w, h } = toRefs(props.chartConfig.attr)
  32 +
31 33 const rangeDate = ref<number | number[]>()
32 34
  35 +const rangeShortcuts = {
  36 + 昨天: () => {
  37 + const cur = new Date().getTime()
  38 + return [cur - 86400000, cur] as const
  39 + },
  40 + 最近7天: () => {
  41 + const cur = new Date().getTime()
  42 + return [cur - 604800000, cur] as const
  43 + },
  44 + 最近30天: () => {
  45 + const cur = new Date().getTime()
  46 + return [cur - 2592000000, cur] as const
  47 + }
  48 +}
  49 +
33 50 const option = shallowReactive({
34 51 dataset: props.chartConfig.option.dataset
35 52 })
... ... @@ -38,36 +55,35 @@ const isRange = computed(() => {
38 55 return props.chartConfig.option.componentInteractEventKey.endsWith('range')
39 56 })
40 57
41   -
42 58 // 监听事件改变
43 59 const onChange = (v: number | number[] | null) => {
44 60 if (isRange.value) {
45 61 let dateStart = null
46 62 let dateEnd = null
47 63 let daterange = null
48   - if(v instanceof Array){
  64 + if (v instanceof Array) {
49 65 dateStart = v[0]
50 66 dateEnd = v[1]
51 67 daterange = `${v[0]}-${v[1]}`
52 68 }
53 69 // 存储到联动数据
54 70 useChartInteract(
55   - props.chartConfig,
56   - useChartEditStore,
57   - {
58   - [ComponentInteractParamsEnum.DATE_START]: dateStart,
59   - [ComponentInteractParamsEnum.DATE_END]: dateEnd,
60   - [ComponentInteractParamsEnum.DATE_RANGE]: daterange
61   - },
62   - InteractEventOn.CHANGE
  71 + props.chartConfig,
  72 + useChartEditStore,
  73 + {
  74 + [ComponentInteractParamsEnum.DATE_START]: dateStart,
  75 + [ComponentInteractParamsEnum.DATE_END]: dateEnd,
  76 + [ComponentInteractParamsEnum.DATE_RANGE]: daterange
  77 + },
  78 + InteractEventOn.CHANGE
63 79 )
64 80 } else {
65 81 // 存储到联动数据
66 82 useChartInteract(
67   - props.chartConfig,
68   - useChartEditStore,
69   - { [ComponentInteractParamsEnum.DATE]: v },
70   - InteractEventOn.CHANGE
  83 + props.chartConfig,
  84 + useChartEditStore,
  85 + { [ComponentInteractParamsEnum.DATE]: v },
  86 + InteractEventOn.CHANGE
71 87 )
72 88 }
73 89 }
... ... @@ -87,7 +103,7 @@ const getDiffDate = (type: ComponentInteractEventEnum, date: dayjs.Dayjs) => {
87 103 case ComponentInteractEventEnum.YEAR:
88 104 case ComponentInteractEventEnum.YEAR_RANGE:
89 105 date = date.startOf('year')
90   - break
  106 + break
91 107 case ComponentInteractEventEnum.QUARTER:
92 108 case ComponentInteractEventEnum.QUARTER_RANGE:
93 109 date = date.startOf('quarter')
... ... @@ -99,48 +115,50 @@ const getDiffDate = (type: ComponentInteractEventEnum, date: dayjs.Dayjs) => {
99 115 }
100 116
101 117 watch(
102   - () => {
103   - return {
104   - type: props.chartConfig.option.componentInteractEventKey as ComponentInteractEventEnum,
105   - defaultType: props.chartConfig.option.defaultType as string,
106   - differValue: props.chartConfig.option.differValue as number[],
107   - differUnit: props.chartConfig.option.differUnit as ManipulateType[],
108   - dataset: props.chartConfig.option.dataset as number | number[] | null,
109   - };
110   - },
111   - (newData, oldData) => {
112   - const hasTypeChanged = newData.type !== oldData?.type;
113   - const hasDefaultTypeChanged = newData.defaultType !== oldData?.defaultType;
114   - const hasDifferValueChanged = newData.differValue !== oldData?.differValue;
115   - const hasDifferUnitChanged = newData.differUnit !== oldData?.differUnit;
  118 + () => {
  119 + return {
  120 + type: props.chartConfig.option.componentInteractEventKey as ComponentInteractEventEnum,
  121 + defaultType: props.chartConfig.option.defaultType as string,
  122 + differValue: props.chartConfig.option.differValue as number[],
  123 + differUnit: props.chartConfig.option.differUnit as ManipulateType[],
  124 + dataset: props.chartConfig.option.dataset as number | number[] | null
  125 + }
  126 + },
  127 + (newData, oldData) => {
  128 + const hasTypeChanged = newData.type !== oldData?.type
  129 + const hasDefaultTypeChanged = newData.defaultType !== oldData?.defaultType
  130 + const hasDifferValueChanged = newData.differValue !== oldData?.differValue
  131 + const hasDifferUnitChanged = newData.differUnit !== oldData?.differUnit
116 132
117   - if (hasTypeChanged || hasDefaultTypeChanged || hasDifferValueChanged || hasDifferUnitChanged) {
118   - if (newData.defaultType === DefaultTypeEnum.NONE) {
119   - props.chartConfig.option.dataset = null;
120   - } else if (newData.defaultType === DefaultTypeEnum.DYNAMIC) {
121   - let date = dayjs();
122   - if (isRange.value) {
123   - props.chartConfig.option.dataset = [
124   - getDiffDate(newData.type,date.add(newData.differValue[0], newData.differUnit[0])).valueOf(),
125   - getDiffDate(newData.type,date.add(newData.differValue[1], newData.differUnit[1])).valueOf(),
126   - ];
127   - } else {
128   - props.chartConfig.option.dataset = getDiffDate(newData.type,date.add(newData.differValue[0], newData.differUnit[0])).valueOf()
129   - }
  133 + if (hasTypeChanged || hasDefaultTypeChanged || hasDifferValueChanged || hasDifferUnitChanged) {
  134 + if (newData.defaultType === DefaultTypeEnum.NONE) {
  135 + props.chartConfig.option.dataset = null
  136 + } else if (newData.defaultType === DefaultTypeEnum.DYNAMIC) {
  137 + let date = dayjs()
  138 + if (isRange.value) {
  139 + props.chartConfig.option.dataset = [
  140 + getDiffDate(newData.type, date.add(newData.differValue[0], newData.differUnit[0])).valueOf(),
  141 + getDiffDate(newData.type, date.add(newData.differValue[1], newData.differUnit[1])).valueOf()
  142 + ]
  143 + } else {
  144 + props.chartConfig.option.dataset = getDiffDate(
  145 + newData.type,
  146 + date.add(newData.differValue[0], newData.differUnit[0])
  147 + ).valueOf()
130 148 }
131 149 }
132   - option.dataset = props.chartConfig.option.dataset;
133   - onChange(option.dataset);
134   - },
135   - {
136   - immediate: true,
137 150 }
138   -);
139   -
  151 + option.dataset = props.chartConfig.option.dataset
  152 + onChange(option.dataset)
  153 + },
  154 + {
  155 + immediate: true
  156 + }
  157 +)
140 158
141 159 watch(
142 160 () => props.chartConfig.option.shortcut,
143   - (newData) => {
  161 + newData => {
144 162 if (!newData) return
145 163 const startTs = Date.now() - newData
146 164 const endTs = Date.now()
... ... @@ -153,7 +171,6 @@ watch(
153 171 )
154 172 </script>
155 173
156   -
157 174 <style lang="scss" scoped>
158 175 @include deep() {
159 176 .n-input {
... ... @@ -162,4 +179,4 @@ watch(
162 179 align-items: center;
163 180 }
164 181 }
165   -</style>
\ No newline at end of file
  182 +</style>
... ...
... ... @@ -21,6 +21,7 @@ import { OverrideLineGradientsConfig } from '@/packages/components/external/Char
21 21 import { OverrideProcessConfig } from '@/packages/components/external/Charts/Mores/OverrideProcess'
22 22 import { OverridePieCircleConfig } from '@/packages/components/external/Charts/Pies/OverridePieCircle'
23 23 import { OverrideMapBaseConfig } from '@/packages/components/external/Charts/Maps/OverrideMapBase'
  24 +import { OverrideMapAmapConfig } from '@/packages/components/external/Charts/Maps/OverrideMapAmap'
24 25 import { OverrideVideoConfig } from '@/packages/components/external/Informations/Mores/OverrideVideo'
25 26 import { OverrideWaterPoloConfig } from '@/packages/components/external/Charts/Mores/OverrideWaterPolo'
26 27 import { OverrideDialConfig } from '@/packages/components/external/Charts/Mores/OverrideDial'
... ... @@ -104,6 +105,7 @@ export function useInjectLib(packagesList: EPackagesType) {
104 105 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideProcessConfig)//重写图表下的native ui
105 106 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverridePieCircleConfig)//重写图表下的饼图
106 107 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideMapBaseConfig)//重写图表下的地图
  108 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideMapAmapConfig)//重写图表下的高德地图
107 109 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideWaterPoloConfig)//重写图表下的水球图
108 110 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideDialConfig)//重写图表下的表盘
109 111 //
... ...
... ... @@ -16,7 +16,8 @@ export const hideAsideComponentsObj = {
16 16 'VPieCircle' //饼图-环形
17 17 ],
18 18 Maps: [
19   - 'VMapBase' //地图(可选省份)
  19 + 'VMapBase', //地图(可选省份)
  20 + 'VMapAmap', //高德地图
20 21 ],
21 22 Mores: [
22 23 'VProcess', //NaiveUI-进度
... ... @@ -45,6 +46,7 @@ export const hideAsideComponentsObj = {
45 46 'VLineGradients', //双折线渐变面积图
46 47 'VPieCircle', //饼图-环形
47 48 'VMapBase', //地图(可选省份)
  49 + 'VMapAmap',//高德地图
48 50 'VProcess', //NaiveUI-进度
49 51 'VTextGradient', //渐变文字
50 52 'VTextBarrage', //弹幕文字
... ...
  1 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  2 +import { canvasCut, downloadTextFile, JSONStringify } from '@/utils'
  3 +const chartEditStore = useChartEditStore()
  4 +
  5 +// 导出
  6 +export const exportHandle = () => {
  7 + // 取消选中
  8 + chartEditStore.setTargetSelectChart(undefined)
  9 +
  10 + // 导出数据
  11 + downloadTextFile(
  12 + JSONStringify(chartEditStore.getStorageInfo || []),
  13 + undefined,
  14 + 'json'
  15 + )
  16 +
  17 + // 导出图片
  18 + const range = document.querySelector('.go-edit-range') as HTMLElement
  19 + const watermark = document.getElementById('go-edit-watermark')
  20 + // 隐藏边距线
  21 + if (!range || !watermark) {
  22 + window['$message'].error('导出失败!')
  23 + return
  24 + }
  25 +
  26 + // 记录缩放比例
  27 + const scaleTemp = chartEditStore.getEditCanvas.scale
  28 + // 百分百展示页面
  29 + chartEditStore.setScale(1, true)
  30 + // 展示水印
  31 + // THINGS_KIT 隐藏水印
  32 + watermark.style.display = 'none'
  33 +
  34 + //注释导出图片逻辑
  35 + // setTimeout(() => {
  36 + // canvasCut(range, () => {
  37 + // // 隐藏水印
  38 + // if (watermark) watermark.style.display = 'none'
  39 + // // 还原页面大小
  40 + // chartEditStore.setScale(scaleTemp, true)
  41 + // })
  42 + // }, 600)
  43 +}
... ...
... ... @@ -78,7 +78,7 @@ import { EditEnum } from '@/enums/pageEnum'
78 78 import { StorageEnum } from '@/enums/storageEnum'
79 79 import { useRoute } from 'vue-router'
80 80 import { GoSystemSet } from '@/components/GoSystemSet/index'
81   -import { exportHandle } from './utils'
  81 +import { exportHandle } from './external'// THINGS_KIT 修改引入路径
82 82 import { useFile } from './hooks/useFile.hooks'
83 83 import { useSyncUpdate } from './hooks/useSyncUpdate.hook'
84 84 import { BtnListType, TypeEnum } from './index.d'
... ...