Commit e268d6d0c39f5f384600e630570b00b43c5dd108
Merge branch 'ft' into 'main_dev'
feat(src/packages): 优化三维模型拖动时,webgl上下文丢失问题 See merge request yunteng/thingskit-view!134
Showing
24 changed files
with
193 additions
and
176 deletions
@@ -111,7 +111,7 @@ export const getVideoUrl = (id: string) => | @@ -111,7 +111,7 @@ export const getVideoUrl = (id: string) => | ||
111 | }) | 111 | }) |
112 | 112 | ||
113 | //获取行政区域 | 113 | //获取行政区域 |
114 | -export const getGeoJsonMap = (code: number, level: string) => | 114 | +export const getGeoJsonMap = (code: number | string, level: string) => |
115 | defHttp.get({ | 115 | defHttp.get({ |
116 | url: `${Api.GEOJSONURL}${code}/${level}` | 116 | url: `${Api.GEOJSONURL}${code}/${level}` |
117 | }) | 117 | }) |
@@ -14,6 +14,26 @@ export const enum areaEnum { | @@ -14,6 +14,26 @@ export const enum areaEnum { | ||
14 | TOWN = 'TOWN' //镇 | 14 | TOWN = 'TOWN' //镇 |
15 | } | 15 | } |
16 | 16 | ||
17 | +//父级地区编码和级别接口 | ||
18 | +export interface HistoryParentType { | ||
19 | + adcode: string | number | ||
20 | + level: string | ||
21 | +} | ||
22 | + | ||
23 | +//数据源接口 | ||
24 | +export interface dataPointI { | ||
25 | + name: string | ||
26 | + value: number[] | ||
27 | + adcode: number | ||
28 | + height: number | ||
29 | + itemStyle: { | ||
30 | + color: string | ||
31 | + opacity: number | ||
32 | + borderWidth: number | ||
33 | + borderColor: string | ||
34 | + } | ||
35 | +} | ||
36 | + | ||
17 | export const includes = [] | 37 | export const includes = [] |
18 | 38 | ||
19 | export const option = { | 39 | export const option = { |
@@ -41,6 +61,9 @@ export const option = { | @@ -41,6 +61,9 @@ export const option = { | ||
41 | emphasis: { | 61 | emphasis: { |
42 | label: { | 62 | label: { |
43 | show: true, | 63 | show: true, |
64 | + formatter: function (params: Recordable) { | ||
65 | + return params.data.name ? params.data.name : ' ' | ||
66 | + }, | ||
44 | textStyle: { | 67 | textStyle: { |
45 | color: '#000', | 68 | color: '#000', |
46 | fontSize: 14 | 69 | fontSize: 14 |
@@ -59,6 +82,9 @@ export const option = { | @@ -59,6 +82,9 @@ export const option = { | ||
59 | regionHeight: 3, | 82 | regionHeight: 3, |
60 | label: { | 83 | label: { |
61 | show: true, | 84 | show: true, |
85 | + formatter: function (params: Recordable) { | ||
86 | + return params.data.name ? params.data.name : ' ' | ||
87 | + }, | ||
62 | textStyle: { | 88 | textStyle: { |
63 | color: '#fff', | 89 | color: '#fff', |
64 | fontSize: 14 | 90 | fontSize: 14 |
@@ -12,7 +12,7 @@ import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue | @@ -12,7 +12,7 @@ import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue | ||
12 | import * as echarts from 'echarts' | 12 | import * as echarts from 'echarts' |
13 | import { registerMap } from 'echarts/core' | 13 | import { registerMap } from 'echarts/core' |
14 | import 'echarts-gl' | 14 | import 'echarts-gl' |
15 | -import config, { areaEnum } from './config' | 15 | +import config, { areaEnum, dataPointI, HistoryParentType } from './config' |
16 | import { getGeoJsonMap } from '@/api/external/common' | 16 | import { getGeoJsonMap } from '@/api/external/common' |
17 | import dataMaps from './data.json' | 17 | import dataMaps from './data.json' |
18 | 18 | ||
@@ -73,28 +73,26 @@ props.chartConfig.option = { | @@ -73,28 +73,26 @@ props.chartConfig.option = { | ||
73 | 73 | ||
74 | //地图点击返回 | 74 | //地图点击返回 |
75 | const watchAdcode = async () => { | 75 | const watchAdcode = async () => { |
76 | + stopWatch() | ||
76 | if (props.chartConfig.option.drillingIn) { | 77 | if (props.chartConfig.option.drillingIn) { |
77 | //如果是从右边配置里设置的,比如点击四川省,然后点击返回 | 78 | //如果是从右边配置里设置的,比如点击四川省,然后点击返回 |
78 | const savePopParent = saveHistoryParent.value.pop() | 79 | const savePopParent = saveHistoryParent.value.pop() |
79 | - let saveAdcode: any = savePopParent?.adcode | ||
80 | - saveLevelStr.level = savePopParent?.level as string | 80 | + let saveAdcode = savePopParent?.adcode as string | number |
81 | + saveLevelStr.level = savePopParent?.level | ||
81 | if (!savePopParent) { | 82 | if (!savePopParent) { |
82 | saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode) | 83 | saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode) |
83 | - saveLevelStr.level = (regionMapParentArea as any)[props.chartConfig.option.mapRegion.saveSelect.levelStr] | 84 | + saveLevelStr.level = (regionMapParentArea as Recordable)[props.chartConfig.option.mapRegion.saveSelect.levelStr] |
84 | } | 85 | } |
85 | if (saveAdcode === 0) { | 86 | if (saveAdcode === 0) { |
86 | saveAdcode = 'china' | 87 | saveAdcode = 'china' |
87 | saveLevelStr.level = 'COUNTRY' | 88 | saveLevelStr.level = 'COUNTRY' |
88 | } | 89 | } |
89 | - await getGeojson(saveAdcode) | 90 | + const exist = await getGeojson(saveAdcode) |
90 | const adcode = saveAdcode === 100000 ? 'china' : saveAdcode | 91 | const adcode = saveAdcode === 100000 ? 'china' : saveAdcode |
91 | - props.chartConfig.option.geo3D.map = adcode | ||
92 | - props.chartConfig.option.series.forEach((item: any) => { | ||
93 | - if (item.type === 'map3D') item.map = adcode | ||
94 | - item.data = props.chartConfig.option.dataset | ||
95 | - }) | ||
96 | - handleSetOption(chartInstance.value, props.chartConfig.option) | ||
97 | - handleDataPoint(adcode) | 92 | + if (exist) { |
93 | + //fix解决点击下钻返回后页面为空问题 | ||
94 | + props.chartConfig.option.mapRegion.adcode = adcode | ||
95 | + } | ||
98 | } | 96 | } |
99 | } | 97 | } |
100 | 98 | ||
@@ -106,46 +104,40 @@ const regionMapParentArea = { | @@ -106,46 +104,40 @@ const regionMapParentArea = { | ||
106 | } | 104 | } |
107 | 105 | ||
108 | //地图点击 | 106 | //地图点击 |
109 | -const handleMap3DClick = async (params: any) => { | 107 | +const handleMap3DClick = async (params: Recordable) => { |
110 | if (props.chartConfig.option.drillingIn) { | 108 | if (props.chartConfig.option.drillingIn) { |
111 | const { name } = params | 109 | const { name } = params |
112 | - saveGeojson.value?.features.forEach((item: any) => { | 110 | + saveGeojson.value?.features.forEach((item: Recordable) => { |
113 | if (item.properties.name === name) { | 111 | if (item.properties.name === name) { |
114 | const level = item.properties.level.toUpperCase() | 112 | const level = item.properties.level.toUpperCase() |
115 | const adcode = item.properties.adcode | 113 | const adcode = item.properties.adcode |
116 | if (level === 'DISTRICT') return | 114 | if (level === 'DISTRICT') return |
117 | - if(String(adcode).startsWith('15') && level===areaEnum.CITY) return | 115 | + if (String(adcode).startsWith('15') && level === areaEnum.CITY) return |
118 | props.chartConfig.option.mapRegion.adcode = adcode | 116 | props.chartConfig.option.mapRegion.adcode = adcode |
119 | saveLevelStr.level = level | 117 | saveLevelStr.level = level |
120 | handleDataPoint(adcode) | 118 | handleDataPoint(adcode) |
121 | saveHistoryParent.value.push({ | 119 | saveHistoryParent.value.push({ |
122 | adcode: item.properties.parent.adcode, | 120 | adcode: item.properties.parent.adcode, |
123 | - level: (regionMapParentArea as any)[level] | 121 | + level: (regionMapParentArea as Recordable)[level] |
124 | }) | 122 | }) |
125 | } | 123 | } |
126 | }) | 124 | }) |
127 | } | 125 | } |
128 | } | 126 | } |
129 | 127 | ||
130 | -const saveGeojson: any = ref({}) // 保存geojson | 128 | +const saveGeojson: Recordable = ref({}) // 保存geojson |
131 | 129 | ||
132 | const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000 | 130 | const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000 |
133 | 131 | ||
134 | -const saveLevelStr = reactive({ | ||
135 | - // 地区级别 | ||
136 | - level: '' | 132 | +// 保存地区级别 |
133 | +const saveLevelStr = reactive<{ level: string | undefined }>({ | ||
134 | + level: '' | ||
137 | }) | 135 | }) |
138 | 136 | ||
139 | -//父级地区编码和级别接口 | ||
140 | -interface HistoryParentType { | ||
141 | - adcode: number | ||
142 | - level: string | ||
143 | -} | ||
144 | - | ||
145 | const saveHistoryParent = ref<HistoryParentType[]>([]) | 137 | const saveHistoryParent = ref<HistoryParentType[]>([]) |
146 | 138 | ||
147 | //动态注册地图 | 139 | //动态注册地图 |
148 | -const getGeojson = (regionId: any) => { | 140 | +const getGeojson = (regionId: number | string) => { |
149 | try { | 141 | try { |
150 | return new Promise<boolean>(resolve => { | 142 | return new Promise<boolean>(resolve => { |
151 | const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别 | 143 | const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别 |
@@ -171,11 +163,10 @@ const getGeojson = (regionId: any) => { | @@ -171,11 +163,10 @@ const getGeojson = (regionId: any) => { | ||
171 | } | 163 | } |
172 | } | 164 | } |
173 | 165 | ||
174 | - | ||
175 | //传adcode 获取上级 | 166 | //传adcode 获取上级 |
176 | const getParentAdcode = (adcode: number) => { | 167 | const getParentAdcode = (adcode: number) => { |
177 | let adcodeNum = 100000 | 168 | let adcodeNum = 100000 |
178 | - saveGeojson.value?.features.forEach((item: any) => { | 169 | + saveGeojson.value?.features.forEach((item: Recordable) => { |
179 | if (item.properties.adcode === adcode) { | 170 | if (item.properties.adcode === adcode) { |
180 | adcodeNum = item.properties.parent.adcode | 171 | adcodeNum = item.properties.parent.adcode |
181 | } | 172 | } |
@@ -200,13 +191,13 @@ const initMap = async () => { | @@ -200,13 +191,13 @@ const initMap = async () => { | ||
200 | await nextTick().then(() => { | 191 | await nextTick().then(() => { |
201 | handleSetOption(chartInstance.value, props.chartConfig.option) | 192 | handleSetOption(chartInstance.value, props.chartConfig.option) |
202 | }) | 193 | }) |
203 | - chartInstance.value.on('click', (e: any) => { | 194 | + chartInstance.value.on('click', (e: Recordable) => { |
204 | handleMap3DClick(e) | 195 | handleMap3DClick(e) |
205 | }) | 196 | }) |
206 | } | 197 | } |
207 | 198 | ||
208 | // 手动触发渲染 | 199 | // 手动触发渲染 |
209 | -const handleSetOption = (instance: any, option: any) => { | 200 | +const handleSetOption = (instance: any, option: Recordable) => { |
210 | if (!instance) return | 201 | if (!instance) return |
211 | try { | 202 | try { |
212 | instance.clear() | 203 | instance.clear() |
@@ -221,22 +212,22 @@ onMounted(() => { | @@ -221,22 +212,22 @@ onMounted(() => { | ||
221 | }) | 212 | }) |
222 | 213 | ||
223 | //处理数据标点 | 214 | //处理数据标点 |
224 | -const handleDataPoint = (newData: any) => { | 215 | +const handleDataPoint = (newData: string | number) => { |
225 | if (newData === 'china') { | 216 | if (newData === 'china') { |
226 | props.chartConfig.option.dataset = dataMaps | 217 | props.chartConfig.option.dataset = dataMaps |
227 | } else { | 218 | } else { |
228 | - props.chartConfig.option.dataset = dataMaps.filter((item: any) => item.adcode === newData) | 219 | + props.chartConfig.option.dataset = dataMaps.filter((item: dataPointI) => item.adcode === newData) |
229 | } | 220 | } |
230 | } | 221 | } |
231 | 222 | ||
232 | //监听地图展示区域发生变化 | 223 | //监听地图展示区域发生变化 |
233 | watch( | 224 | watch( |
234 | () => `${props.chartConfig.option.mapRegion.adcode}`, | 225 | () => `${props.chartConfig.option.mapRegion.adcode}`, |
235 | - async (newData: any) => { | 226 | + async (newData: string | number) => { |
236 | try { | 227 | try { |
237 | await getGeojson(newData) | 228 | await getGeojson(newData) |
238 | props.chartConfig.option.geo3D.map = newData | 229 | props.chartConfig.option.geo3D.map = newData |
239 | - props.chartConfig.option.series.forEach((item: any) => { | 230 | + props.chartConfig.option.series.forEach((item: Recordable) => { |
240 | if (item.type === 'map3D') { | 231 | if (item.type === 'map3D') { |
241 | item.map = newData | 232 | item.map = newData |
242 | item.data = props.chartConfig.option.dataset | 233 | item.data = props.chartConfig.option.dataset |
@@ -254,7 +245,7 @@ watch( | @@ -254,7 +245,7 @@ watch( | ||
254 | ) | 245 | ) |
255 | 246 | ||
256 | // 监听地图右侧配置项变化 | 247 | // 监听地图右侧配置项变化 |
257 | -watch( | 248 | +const stopWatch = watch( |
258 | props.chartConfig.option, | 249 | props.chartConfig.option, |
259 | async newData => { | 250 | async newData => { |
260 | try { | 251 | try { |
@@ -273,7 +264,7 @@ watch( | @@ -273,7 +264,7 @@ watch( | ||
273 | () => props.chartConfig.option.dataset, | 264 | () => props.chartConfig.option.dataset, |
274 | newData => { | 265 | newData => { |
275 | try { | 266 | try { |
276 | - props.chartConfig.option.series.forEach((item: any) => { | 267 | + props.chartConfig.option.series.forEach((item: Recordable) => { |
277 | if (item.type === 'map3D') { | 268 | if (item.type === 'map3D') { |
278 | item.data = newData | 269 | item.data = newData |
279 | } | 270 | } |
@@ -129,7 +129,7 @@ const loadList = async () => { | @@ -129,7 +129,7 @@ const loadList = async () => { | ||
129 | } | 129 | } |
130 | 130 | ||
131 | const handleSubmit = () => { | 131 | const handleSubmit = () => { |
132 | - searchParams.deviceProfileIds = [searchParams.deviceProfileIds] as any | 132 | + // searchParams.deviceProfileIds = [searchParams.deviceProfileIds] as any |
133 | emit('searchParams', searchPage, searchParams) | 133 | emit('searchParams', searchPage, searchParams) |
134 | handleCancel() | 134 | handleCancel() |
135 | } | 135 | } |
@@ -88,10 +88,11 @@ export const option = { | @@ -88,10 +88,11 @@ export const option = { | ||
88 | amapLon: 104.108689, | 88 | amapLon: 104.108689, |
89 | amapLat: 30.66176, | 89 | amapLat: 30.66176, |
90 | amapZindex: 11, | 90 | amapZindex: 11, |
91 | - typeMarker: '', | 91 | + iconMarker: '1.png', |
92 | mpBorderConfig: { | 92 | mpBorderConfig: { |
93 | - value: 'Border01', | 93 | + value: 'Border01' |
94 | }, | 94 | }, |
95 | + bgColor: 'rgba(255, 255, 255, 0.1)', | ||
95 | marker: { | 96 | marker: { |
96 | fillColor: '#E98984FF', | 97 | fillColor: '#E98984FF', |
97 | fillOpacity: 0.5, | 98 | fillOpacity: 0.5, |
@@ -81,8 +81,8 @@ | @@ -81,8 +81,8 @@ | ||
81 | size="small" | 81 | size="small" |
82 | placeholder="请选择您要使用的图标" | 82 | placeholder="请选择您要使用的图标" |
83 | style="width: 250px" | 83 | style="width: 250px" |
84 | - :value="typeMarkerValue" | ||
85 | - :options="typeMarkerOptions" | 84 | + :value="iconMarkerValue" |
85 | + :options="iconMarkerOptions" | ||
86 | :render-label="renderOption" | 86 | :render-label="renderOption" |
87 | clearable | 87 | clearable |
88 | filterable | 88 | filterable |
@@ -92,16 +92,6 @@ | @@ -92,16 +92,6 @@ | ||
92 | </setting-item-box> | 92 | </setting-item-box> |
93 | <setting-item-box name="弹窗选择" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER"> | 93 | <setting-item-box name="弹窗选择" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER"> |
94 | <setting-item name="弹窗选择"> | 94 | <setting-item name="弹窗选择"> |
95 | - <!-- <NSelect | ||
96 | - size="small" | ||
97 | - placeholder="请选择您要使用的弹窗" | ||
98 | - style="width: 250px" | ||
99 | - :value="mapSelectBorderValue" | ||
100 | - :options="mapSelectBorderOption.option" | ||
101 | - @update:value="mapSelectBorderHandle" | ||
102 | - clearable | ||
103 | - filterable | ||
104 | - /> --> | ||
105 | <NSelect | 95 | <NSelect |
106 | size="small" | 96 | size="small" |
107 | placeholder="请选择您要使用的弹窗" | 97 | placeholder="请选择您要使用的弹窗" |
@@ -115,11 +105,16 @@ | @@ -115,11 +105,16 @@ | ||
115 | /> | 105 | /> |
116 | </setting-item> | 106 | </setting-item> |
117 | </setting-item-box> | 107 | </setting-item-box> |
108 | + <setting-item-box name="弹窗背景" v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.MARKER"> | ||
109 | + <div style="width: 10vw"> | ||
110 | + <n-color-picker :modes="['rgb']" v-model:value="optionData.mapOptions.bgColor" size="small"></n-color-picker> | ||
111 | + </div> | ||
112 | + </setting-item-box> | ||
118 | </collapse-item> | 113 | </collapse-item> |
119 | </template> | 114 | </template> |
120 | 115 | ||
121 | <script setup lang="ts"> | 116 | <script setup lang="ts"> |
122 | -import { PropType, ref, computed, h, onMounted, reactive } from 'vue' | 117 | +import { PropType, ref, computed, h, onMounted } from 'vue' |
123 | import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config' | 118 | import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config' |
124 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | 119 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
125 | import { NEllipsis, NImage, NSelect, NSpace, SelectOption } from 'naive-ui' | 120 | import { NEllipsis, NImage, NSelect, NSpace, SelectOption } from 'naive-ui' |
@@ -234,7 +229,7 @@ const featuresOptions = [ | @@ -234,7 +229,7 @@ const featuresOptions = [ | ||
234 | const MarkerOptions = [ | 229 | const MarkerOptions = [ |
235 | // { | 230 | // { |
236 | // value: MarkerEnum.CIRCLE_MARKER, | 231 | // value: MarkerEnum.CIRCLE_MARKER, |
237 | - // label: '圆形标点' | 232 | + // label: '圆形标点' //在地图里点击无效,所以注释,有需要自行打开即可 |
238 | // }, | 233 | // }, |
239 | { | 234 | { |
240 | value: MarkerEnum.MARKER, | 235 | value: MarkerEnum.MARKER, |
@@ -246,17 +241,7 @@ const MarkerOptions = [ | @@ -246,17 +241,7 @@ const MarkerOptions = [ | ||
246 | } | 241 | } |
247 | ] | 242 | ] |
248 | 243 | ||
249 | -onMounted(() => { | ||
250 | - props.optionData.mapOptions.typeMarker = getMarkerImagePath(props.optionData.mapOptions.typeMarker || 'position1.png') | ||
251 | - typeMarkerValue.value = props.optionData.mapOptions.typeMarker || 'position1.png' | ||
252 | - mapSelectBorderValue.value = | ||
253 | - `${props.optionData.mapOptions.mpBorderConfig.value.toLocaleLowerCase()}.png` || 'border01.png' | ||
254 | -}) | ||
255 | - | ||
256 | -const typeMarkerValue = ref<string | null>('position1.png') | ||
257 | - | ||
258 | -const mapSelectBorderValue = ref<string | null>('border01.png') | ||
259 | - | 244 | +/**通用函数封装 */ |
260 | const isHref = (url: string) => { | 245 | const isHref = (url: string) => { |
261 | try { | 246 | try { |
262 | new URL(url) | 247 | new URL(url) |
@@ -265,81 +250,86 @@ const isHref = (url: string) => { | @@ -265,81 +250,86 @@ const isHref = (url: string) => { | ||
265 | return false | 250 | return false |
266 | } | 251 | } |
267 | } | 252 | } |
253 | +const renderCommonOption = (option: SelectOption, src: string) => { | ||
254 | + return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [ | ||
255 | + h(NImage, { | ||
256 | + width: 25, | ||
257 | + src, | ||
258 | + previewDisabled: true, | ||
259 | + style: { height: '25px' } | ||
260 | + } as Recordable), | ||
261 | + h(NEllipsis, null, () => option.label) | ||
262 | + ]) | ||
263 | +} | ||
264 | +const getImagePath = (path: string, name: string) => { | ||
265 | + return isHref(name) ? name : new URL(`${path}/${name}`, import.meta.url).href | ||
266 | +} | ||
267 | +/** */ | ||
268 | + | ||
269 | +/** 图标选择 */ | ||
270 | +const iconMarkerValue = ref<string | null>('1.png') | ||
268 | 271 | ||
269 | -// import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去 | ||
270 | -const typeMarkerOptions = computed(() => { | 272 | +// import.meta.glob 这里没有封装,不能通过传值传进去 |
273 | +const iconMarkerOptions = computed(() => { | ||
271 | const pathList = import.meta.glob('./images/marker/*') | 274 | const pathList = import.meta.glob('./images/marker/*') |
272 | return Object.keys(pathList).map(item => { | 275 | return Object.keys(pathList).map(item => { |
273 | const imgName = item.split('/').at(-1) | 276 | const imgName = item.split('/').at(-1) |
274 | return { | 277 | return { |
275 | label: imgName, | 278 | label: imgName, |
276 | value: imgName | 279 | value: imgName |
277 | - } as SelectOption | 280 | + } |
278 | }) | 281 | }) |
279 | }) | 282 | }) |
280 | // | 283 | // |
281 | 284 | ||
282 | -const getMarkerImagePath = (name: string) => { | ||
283 | - return isHref(name) ? name : new URL(`./images/marker/${name}`, import.meta.url).href | ||
284 | -} | 285 | +const getMarkerImagePath = (name: string) => getImagePath('./images/marker', name) |
285 | 286 | ||
286 | -const renderOption = (option: SelectOption) => { | ||
287 | - return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [ | ||
288 | - h(NImage, { | ||
289 | - width: 25, | ||
290 | - src: getMarkerImagePath(option.value as string), | ||
291 | - previewDisabled: true, | ||
292 | - style: { height: '25px' } | ||
293 | - } as Recordable), | ||
294 | - h(NEllipsis, null, () => option.label) | ||
295 | - ]) | ||
296 | -} | 287 | +const renderOption = (option: SelectOption) => renderCommonOption(option, getMarkerImagePath(option.value as string)) |
297 | 288 | ||
298 | const selectHandle = (value: string) => { | 289 | const selectHandle = (value: string) => { |
299 | - typeMarkerValue.value = value | ||
300 | - props.optionData.mapOptions.typeMarker = getMarkerImagePath(value) | 290 | + iconMarkerValue.value = value |
291 | + props.optionData.mapOptions.iconMarker = getMarkerImagePath(value) | ||
301 | } | 292 | } |
293 | +/** */ | ||
294 | + | ||
295 | +/** 弹窗选择 */ | ||
296 | +const mapSelectBorderValue = ref<string | null>('border01.png') | ||
302 | 297 | ||
303 | const needBorder = ['border01.png', 'border02.png', 'border03.png', 'border05.png', 'border07.png'] | 298 | const needBorder = ['border01.png', 'border02.png', 'border03.png', 'border05.png', 'border07.png'] |
304 | 299 | ||
305 | -// import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去 | 300 | +// import.meta.glob 这里没有封装,不能通过传值传进去 |
306 | const mapBorderOptions = computed(() => { | 301 | const mapBorderOptions = computed(() => { |
307 | const pathList = import.meta.glob('../../../../../../assets/images/chart/decorates/*') | 302 | const pathList = import.meta.glob('../../../../../../assets/images/chart/decorates/*') |
308 | return Object.keys(pathList) | 303 | return Object.keys(pathList) |
309 | .map(item => { | 304 | .map(item => { |
310 | const imgName = item.split('/').at(-1) as string | 305 | const imgName = item.split('/').at(-1) as string |
311 | - if (needBorder.includes(imgName)) { | ||
312 | - return { | ||
313 | - label: imgName, | ||
314 | - value: imgName | ||
315 | - } as SelectOption | ||
316 | - } | 306 | + if (!needBorder.includes(imgName)) return |
307 | + return { | ||
308 | + label: imgName, | ||
309 | + value: imgName | ||
310 | + } as SelectOption | ||
317 | }) | 311 | }) |
318 | .filter(Boolean) as SelectOption[] | 312 | .filter(Boolean) as SelectOption[] |
319 | }) | 313 | }) |
320 | // | 314 | // |
321 | 315 | ||
322 | -const getMapBorderImagePath = (name: string) => { | ||
323 | - return isHref(name) ? name : new URL(`../../../../../../assets/images/chart/decorates/${name}`, import.meta.url).href | ||
324 | -} | 316 | +const getMapBorderImagePath = (name: string) => getImagePath('../../../../../../assets/images/chart/decorates', name) |
325 | 317 | ||
326 | -const renderMapBorderOption = (option: SelectOption) => { | ||
327 | - return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [ | ||
328 | - h(NImage, { | ||
329 | - width: 25, | ||
330 | - src: getMapBorderImagePath(option.value as string), | ||
331 | - previewDisabled: true, | ||
332 | - style: { height: '25px' } | ||
333 | - } as Recordable), | ||
334 | - h(NEllipsis, null, () => option.label) | ||
335 | - ]) | ||
336 | -} | 318 | +const renderMapBorderOption = (option: SelectOption) => |
319 | + renderCommonOption(option, getMapBorderImagePath(option.value as string)) | ||
337 | 320 | ||
338 | const selectMapBorderHandle = (value: string) => { | 321 | const selectMapBorderHandle = (value: string) => { |
339 | mapSelectBorderValue.value = value | 322 | mapSelectBorderValue.value = value |
340 | const toLowerValue = value.toLocaleLowerCase() | 323 | const toLowerValue = value.toLocaleLowerCase() |
341 | ;(props.optionData.mapOptions.mpBorderConfig as BaseSelectBorderIF) = { | 324 | ;(props.optionData.mapOptions.mpBorderConfig as BaseSelectBorderIF) = { |
342 | - value: toLowerValue[0]?.toUpperCase() + toLowerValue?.substr(1)?.split('.')[0] | ||
343 | - } | 325 | + value: toLowerValue[0]?.toUpperCase() + toLowerValue?.substring(1)?.split('.')[0] |
326 | + } //这里首字母转大写,动态引入时匹配对应目录也是大写字母开头,即components\Decorates\Borders\Border01 | ||
344 | } | 327 | } |
328 | +/** */ | ||
329 | + | ||
330 | +onMounted(() => { | ||
331 | + iconMarkerValue.value = props.optionData.mapOptions.iconMarker?.split('/')?.at(-1) as string | ||
332 | + props.optionData.mapOptions.iconMarker = getMarkerImagePath(iconMarkerValue.value) | ||
333 | + mapSelectBorderValue.value = `${props.optionData.mapOptions.mpBorderConfig.value?.toLocaleLowerCase()}.png` | ||
334 | +}) | ||
345 | </script> | 335 | </script> |
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/1.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position1.png
1.24 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/2.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position2.png
1.4 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/3.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position3.png
904 Bytes
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/4.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position4.png
1.02 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/5.png
renamed from
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position5.png
970 Bytes
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position10.png
deleted
100644 → 0
1.2 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position11.png
deleted
100644 → 0
1.12 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position12.png
deleted
100644 → 0
1.93 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position13.png
deleted
100644 → 0
1.43 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position6.png
deleted
100644 → 0
1.51 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position7.png
deleted
100644 → 0
1.3 KB
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position8.png
deleted
100644 → 0
897 Bytes
src/packages/components/external/Charts/Maps/OverrideMapAmap/images/marker/position9.png
deleted
100644 → 0
1.61 KB
1 | <template> | 1 | <template> |
2 | <div @mouseenter="handleMouseenter" @mouseleave="handleMouseleave" class="chart-amap" ref="vChartRef"> | 2 | <div @mouseenter="handleMouseenter" @mouseleave="handleMouseleave" class="chart-amap" ref="vChartRef"> |
3 | - <div v-show="showSearchBox" @click.stop="handleOpenSearchBox" class="search-box"></div> | ||
4 | - <search-box :modelShow="modelShow" @searchParams="handleSearchParams" @closeDrawer="handleCloseDrawer"></search-box> | 3 | + <!-- <div v-show="showSearchBox" @click.stop="handleOpenSearchBox" class="search-box"></div> |
4 | + <search-box :modelShow="modelShow" @searchParams="handleSearchParams" @closeDrawer="handleCloseDrawer"></search-box> --> | ||
5 | </div> | 5 | </div> |
6 | </template> | 6 | </template> |
7 | 7 | ||
@@ -16,7 +16,7 @@ import { isArray } from '@/utils' | @@ -16,7 +16,7 @@ import { isArray } from '@/utils' | ||
16 | import djh from './images/djh.png' | 16 | import djh from './images/djh.png' |
17 | import online from './images/online.png' | 17 | import online from './images/online.png' |
18 | import lx1 from './images/lx1.png' | 18 | import lx1 from './images/lx1.png' |
19 | -import positionImg from './images/marker/position1.png' | 19 | +import onLineImg from './images/marker/3.png' |
20 | import { getDeviceActiveTime, getDeviceList } from '@/api/external/common/index' | 20 | import { getDeviceActiveTime, getDeviceList } from '@/api/external/common/index' |
21 | import dayjs from 'dayjs' | 21 | import dayjs from 'dayjs' |
22 | import SearchBox from './components/SearchBox.vue' | 22 | import SearchBox from './components/SearchBox.vue' |
@@ -32,7 +32,7 @@ const modelShow = ref(false) | @@ -32,7 +32,7 @@ const modelShow = ref(false) | ||
32 | 32 | ||
33 | const showSearchBox = ref(false) | 33 | const showSearchBox = ref(false) |
34 | 34 | ||
35 | -let { | 35 | +const { |
36 | amapKey, | 36 | amapKey, |
37 | amapStyleKey, | 37 | amapStyleKey, |
38 | amapLon, | 38 | amapLon, |
@@ -46,8 +46,9 @@ let { | @@ -46,8 +46,9 @@ let { | ||
46 | pitch, | 46 | pitch, |
47 | skyColor, | 47 | skyColor, |
48 | marker, | 48 | marker, |
49 | - typeMarker, | ||
50 | - mpBorderConfig | 49 | + iconMarker, |
50 | + mpBorderConfig, | ||
51 | + bgColor | ||
51 | } = toRefs(props.chartConfig.option.mapOptions) | 52 | } = toRefs(props.chartConfig.option.mapOptions) |
52 | 53 | ||
53 | //官方没有高德地图api的ts,所以类型全用的any | 54 | //官方没有高德地图api的ts,所以类型全用的any |
@@ -104,7 +105,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | @@ -104,7 +105,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | ||
104 | const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间 | 105 | const res = await getDeviceActiveTime(tbDeviceId) //查询设备最后离线时间 |
105 | let { lastUpdateTs } = res[0] | 106 | let { lastUpdateTs } = res[0] |
106 | const lastUpdateFormatTs = dayjs(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss') | 107 | const lastUpdateFormatTs = dayjs(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss') |
107 | - //render方式渲染小组件里的边框组件 | 108 | + //以render方式渲染小组件里的边框组件 |
108 | const BorderInstance = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/index.vue`) | 109 | const BorderInstance = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/index.vue`) |
109 | const config = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/config.ts`) | 110 | const config = await import(`../../../../Decorates/Borders/${mpBorderConfig.value.value}/config.ts`) |
110 | const BorderConfigInstance = new config.default() | 111 | const BorderConfigInstance = new config.default() |
@@ -132,7 +133,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | @@ -132,7 +133,7 @@ const createInfoWindow = async (extraInfo: dataExtraInfoType) => { | ||
132 | </div> | 133 | </div> |
133 | <div style="color:white;">所属组织:${organizationDTO.name}</div> | 134 | <div style="color:white;">所属组织:${organizationDTO.name}</div> |
134 | <div style="margin-top:6px;color:white">接入协议:${deviceProfile.transportType}</div> | 135 | <div style="margin-top:6px;color:white">接入协议:${deviceProfile.transportType}</div> |
135 | - <div style="margin-top:6px;color:white"> | 136 | + <div style="margin-top:6px;color:white;width:15vw;text-overflow: ellipsis;overflow: hidden; word-break: break-all;white-space: nowrap;"> |
136 | 设备位置:${!deviceInfo.address ? '该设备暂无地理位置' : deviceInfo.address} | 137 | 设备位置:${!deviceInfo.address ? '该设备暂无地理位置' : deviceInfo.address} |
137 | </div> | 138 | </div> |
138 | <div style="margin-top:6px;color:white"> | 139 | <div style="margin-top:6px;color:white"> |
@@ -158,10 +159,15 @@ const handleCloseDrawer = () => (modelShow.value = false) | @@ -158,10 +159,15 @@ const handleCloseDrawer = () => (modelShow.value = false) | ||
158 | 159 | ||
159 | const handleSearchParams = async (searchPage: any, params: any) => { | 160 | const handleSearchParams = async (searchPage: any, params: any) => { |
160 | try { | 161 | try { |
162 | + Object.keys(params).forEach(item => { | ||
163 | + if (!params[item]) Reflect.deleteProperty(params, item) | ||
164 | + }) | ||
161 | const { items } = await getDeviceList(searchPage, params) | 165 | const { items } = await getDeviceList(searchPage, params) |
162 | const values = filterDevice(items) | 166 | const values = filterDevice(items) |
163 | if (!values) return | 167 | if (!values) return |
164 | - dataHandle(values) | 168 | + setTimeout(() => { |
169 | + dataHandle(values) | ||
170 | + }, 1000) | ||
165 | } finally { | 171 | } finally { |
166 | handleCloseDrawer() | 172 | handleCloseDrawer() |
167 | } | 173 | } |
@@ -198,10 +204,11 @@ const dataHandle = (newData: dataJsonType) => { | @@ -198,10 +204,11 @@ const dataHandle = (newData: dataJsonType) => { | ||
198 | // 记录新标记 | 204 | // 记录新标记 |
199 | if (mapMarkerType.value === MarkerEnum.MARKER) { | 205 | if (mapMarkerType.value === MarkerEnum.MARKER) { |
200 | newData.markers.forEach((markerItem: dataJsonMarkersType) => { | 206 | newData.markers.forEach((markerItem: dataJsonMarkersType) => { |
207 | + const { deviceState } = markerItem.extraInfo | ||
201 | const markerInstance = new AMapIns.Marker({ | 208 | const markerInstance = new AMapIns.Marker({ |
202 | position: [markerItem.position[0], markerItem.position[1]], | 209 | position: [markerItem.position[0], markerItem.position[1]], |
203 | offset: new AMapIns.Pixel(-13, -30), | 210 | offset: new AMapIns.Pixel(-13, -30), |
204 | - icon: typeMarker.value || positionImg | 211 | + icon: deviceState === 'ONLINE' ? onLineImg : iconMarker.value |
205 | }) | 212 | }) |
206 | // markers.push(markerInstance) 原作者这种方式添加,属于JS API 1.4.8版本的 | 213 | // markers.push(markerInstance) 原作者这种方式添加,属于JS API 1.4.8版本的 |
207 | // markerInstance.setMap(mapIns) | 214 | // markerInstance.setMap(mapIns) |
@@ -255,7 +262,9 @@ watch( | @@ -255,7 +262,9 @@ watch( | ||
255 | // 预览 | 262 | // 预览 |
256 | useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | 263 | useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { |
257 | stopWatch() | 264 | stopWatch() |
258 | - dataHandle(newData) | 265 | + setTimeout(() => { |
266 | + dataHandle(newData) | ||
267 | + }, 1000) | ||
259 | }) | 268 | }) |
260 | </script> | 269 | </script> |
261 | 270 | ||
@@ -271,15 +280,9 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | @@ -271,15 +280,9 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | ||
271 | } | 280 | } |
272 | .amap-info-content .go-border-box { | 281 | .amap-info-content .go-border-box { |
273 | position: absolute; | 282 | position: absolute; |
274 | - transform: scale(0.7); | 283 | + transform: scale(0.68); |
275 | top: -10px; | 284 | top: -10px; |
276 | - /* opacity: 0,8; */ | ||
277 | - /* background-color: rgba(0, 0, 0, 0.1); */ | ||
278 | - background-color:rgba(255,255,255,0.1) | ||
279 | -} | ||
280 | -.amap-info-content .go-border-box svg { | ||
281 | - /* background-color: rgba(0, 0, 0, 0.1); */ | ||
282 | - /* background-color: rgba(255, 255, 255, 0.8); */ | 285 | + background-color: v-bind(bgColor); |
283 | } | 286 | } |
284 | </style> | 287 | </style> |
285 | <style lang="scss" scoped> | 288 | <style lang="scss" scoped> |
@@ -5,7 +5,7 @@ import cloneDeep from 'lodash/cloneDeep' | @@ -5,7 +5,7 @@ import cloneDeep from 'lodash/cloneDeep' | ||
5 | import { chartInitConfig } from '@/settings/designSetting' | 5 | import { chartInitConfig } from '@/settings/designSetting' |
6 | 6 | ||
7 | export const option = { | 7 | export const option = { |
8 | - dataset: [new URL('/src/assets/external/three/test.obj', import.meta.url).href],//三维数据源 | 8 | + dataset: [new URL('/src/assets/external/three/test.obj', import.meta.url).href], //三维数据源 |
9 | backgroundColor: '', //场景背景色 | 9 | backgroundColor: '', //场景背景色 |
10 | backgroundAlpha: 0, //场景透明度 | 10 | backgroundAlpha: 0, //场景透明度 |
11 | enableDamping: false, //是否启用阻尼 | 11 | enableDamping: false, //是否启用阻尼 |
@@ -18,7 +18,9 @@ export const option = { | @@ -18,7 +18,9 @@ export const option = { | ||
18 | */ | 18 | */ |
19 | outputEncoding: 'liner', | 19 | outputEncoding: 'liner', |
20 | clearScene: false, //是否清空场景内容 | 20 | clearScene: false, //是否清空场景内容 |
21 | - lights: [//灯光为数组,type 为 环境光(AmbientLight) | 方向光(DirectionalLight) | 点光(PointLight) | 半球光(HemisphereLight) | 21 | + lightInput: 1, |
22 | + lights: [ | ||
23 | + //灯光为数组,type 为 环境光(AmbientLight) | 方向光(DirectionalLight) | 点光(PointLight) | 半球光(HemisphereLight) | ||
22 | { | 24 | { |
23 | type: 'AmbientLight', | 25 | type: 'AmbientLight', |
24 | label: '环境光(只有颜色)', | 26 | label: '环境光(只有颜色)', |
@@ -54,38 +56,41 @@ export const option = { | @@ -54,38 +56,41 @@ export const option = { | ||
54 | size: 1, | 56 | size: 1, |
55 | show: false | 57 | show: false |
56 | }, | 58 | }, |
57 | - position: [//模型位置 | 59 | + position: [ |
60 | + //模型位置 | ||
58 | { | 61 | { |
59 | x: 0, | 62 | x: 0, |
60 | y: 0, | 63 | y: 0, |
61 | z: 0 | 64 | z: 0 |
62 | } | 65 | } |
63 | ], | 66 | ], |
64 | - rotation: [//模型旋转 | 67 | + rotation: [ |
68 | + //模型旋转 | ||
65 | { | 69 | { |
66 | x: 0, | 70 | x: 0, |
67 | y: 0, | 71 | y: 0, |
68 | z: 0 | 72 | z: 0 |
69 | } | 73 | } |
70 | ], | 74 | ], |
71 | - showFps:false,//是否显示fps | ||
72 | - labels:[ //添加图片/文字标签,暂且支持文字 | 75 | + showFps: false, //是否显示fps |
76 | + labels: [ | ||
77 | + //添加图片/文字标签,暂且支持文字 | ||
73 | { | 78 | { |
74 | - image: "", | ||
75 | - text: "", | 79 | + image: '', |
80 | + text: '', | ||
76 | textStyle: { | 81 | textStyle: { |
77 | - fontFamily: "Arial", | 82 | + fontFamily: 'Arial', |
78 | fontSize: 18, | 83 | fontSize: 18, |
79 | - fontWeight: "normal", | 84 | + fontWeight: 'normal', |
80 | lineHeight: 1, | 85 | lineHeight: 1, |
81 | - color: "#ffffff", | 86 | + color: '#ffffff', |
82 | borderWidth: 8, | 87 | borderWidth: 8, |
83 | borderRadius: 4, | 88 | borderRadius: 4, |
84 | - borderColor: "rgba(0,0,0,1)", | ||
85 | - backgroundColor: "rgba(0, 0, 0, 1)" | 89 | + borderColor: 'rgba(0,0,0,1)', |
90 | + backgroundColor: 'rgba(0, 0, 0, 1)' | ||
86 | }, | 91 | }, |
87 | - position: {x:0, y:0, z:0}, | ||
88 | - scale:{x:1, y:1, z:0}, | 92 | + position: { x: 0, y: 0, z: 0 }, |
93 | + scale: { x: 1, y: 1, z: 0 }, | ||
89 | sid: null | 94 | sid: null |
90 | } | 95 | } |
91 | ] | 96 | ] |
@@ -11,15 +11,15 @@ | @@ -11,15 +11,15 @@ | ||
11 | <n-input-number :min="0" v-model:value="optionData.borderConfig.size" size="small" /> | 11 | <n-input-number :min="0" v-model:value="optionData.borderConfig.size" size="small" /> |
12 | </setting-item> | 12 | </setting-item> |
13 | </setting-item-box> | 13 | </setting-item-box> |
14 | - <setting-item-box name="上传文件"> | 14 | + <setting-item-box name="上传文件"> |
15 | <setting-item> | 15 | <setting-item> |
16 | <FileUpload | 16 | <FileUpload |
17 | - :max="100" | ||
18 | - :fileList="optionData.dataset" | ||
19 | - :threeSupportFileFormat="threeSupportFileFormat" | ||
20 | - :singleFileType="singleFileTypeNotMtl" | ||
21 | - @fileStaticUri="handleFileStaticUri" | ||
22 | - /> | 17 | + :max="100" |
18 | + :fileList="optionData.dataset" | ||
19 | + :threeSupportFileFormat="threeSupportFileFormat" | ||
20 | + :singleFileType="singleFileTypeNotMtl" | ||
21 | + @fileStaticUri="handleFileStaticUri" | ||
22 | + /> | ||
23 | </setting-item> | 23 | </setting-item> |
24 | </setting-item-box> | 24 | </setting-item-box> |
25 | <setting-item-box :alone="true"> | 25 | <setting-item-box :alone="true"> |
@@ -78,8 +78,13 @@ | @@ -78,8 +78,13 @@ | ||
78 | </template> | 78 | </template> |
79 | </setting-item> | 79 | </setting-item> |
80 | </setting-item-box> | 80 | </setting-item-box> |
81 | + <setting-item-box name="灯光选择"> | ||
82 | + <setting-item name="灯光选择((0,环境光),(1,方向光),(2,点光),(3,半球光))"> | ||
83 | + <n-input-number :min="0" :max="3" v-model:value="optionData.lightInput" size="small" /> | ||
84 | + </setting-item> | ||
85 | + </setting-item-box> | ||
81 | <setting-item-box name="灯光配置"> | 86 | <setting-item-box name="灯光配置"> |
82 | - <setting-item v-for="(item, index) in optionData.lights" :name="item.label" :key="index"> | 87 | + <setting-item v-for="(item, index) in [optionData.lights[optionData.lightInput]]" :name="item.label" :key="index"> |
83 | <n-color-picker | 88 | <n-color-picker |
84 | v-if="!includeHemisphereLight.includes(item.type)" | 89 | v-if="!includeHemisphereLight.includes(item.type)" |
85 | size="small" | 90 | size="small" |
@@ -180,15 +185,9 @@ | @@ -180,15 +185,9 @@ | ||
180 | <SettingItem v-if="optionData.enableDamping" name="阻尼值"> | 185 | <SettingItem v-if="optionData.enableDamping" name="阻尼值"> |
181 | <n-input-number v-model:value="optionData.dampingFactor" :min="0" :max="1" size="small"></n-input-number> | 186 | <n-input-number v-model:value="optionData.dampingFactor" :min="0" :max="1" size="small"></n-input-number> |
182 | </SettingItem> | 187 | </SettingItem> |
183 | - <SettingItem name="启用动画"> | ||
184 | - <n-switch v-model:value="optionData.autoPlay" size="small" /> | ||
185 | - </SettingItem> | ||
186 | - <SettingItem name="输出编码"> | 188 | + <SettingItem name="输出编码,可取值为 liner 或 sRGB。linear 是 LinearEncoding 线性编码, sRGB 即 sRGBEncoding rgb 模式编码(sRGBEncoding 能更好的还原材质颜色)"> |
187 | <n-select v-model:value="optionData.outputEncoding" size="small" :options="encodinghList"></n-select> | 189 | <n-select v-model:value="optionData.outputEncoding" size="small" :options="encodinghList"></n-select> |
188 | </SettingItem> | 190 | </SettingItem> |
189 | - <SettingItem name="是否清空场景"> | ||
190 | - <n-switch @change="handleChange" v-model:value="optionData.clearScene" size="small" /> | ||
191 | - </SettingItem> | ||
192 | </setting-item-box> | 191 | </setting-item-box> |
193 | </collapse-item> | 192 | </collapse-item> |
194 | </template> | 193 | </template> |
@@ -253,10 +252,6 @@ const encodinghList = [ | @@ -253,10 +252,6 @@ const encodinghList = [ | ||
253 | { label: 'sRGB ', value: 'sRGB ' } | 252 | { label: 'sRGB ', value: 'sRGB ' } |
254 | ] | 253 | ] |
255 | 254 | ||
256 | -const handleChange = (e: boolean) => { | ||
257 | - if (e) props.optionData.dataset = [''] | ||
258 | -} | ||
259 | - | ||
260 | const handleFileStaticUri = (value: UploadFileInfo[]) => { | 255 | const handleFileStaticUri = (value: UploadFileInfo[]) => { |
261 | props.optionData.dataset = value.map(item => item?.url)?.filter(Boolean) as any | 256 | props.optionData.dataset = value.map(item => item?.url)?.filter(Boolean) as any |
262 | if (Array.isArray(props.optionData.dataset) && props.optionData.dataset.length === 0) { | 257 | if (Array.isArray(props.optionData.dataset) && props.optionData.dataset.length === 0) { |
1 | <template> | 1 | <template> |
2 | - <div class="go-content-box" :style="{ border: !borderConfig.show ? 'none' : ''}"> | ||
3 | - <div v-if="useDetectWebGLContext()"> | 2 | + <div class="go-content-box" :style="{ border: !borderConfig.show ? 'none' : '' }"> |
3 | + <div> | ||
4 | <vue3dLoader | 4 | <vue3dLoader |
5 | ref="vue3dLoaderRef" | 5 | ref="vue3dLoaderRef" |
6 | :webGLRendererOptions="webGLRendererOptions" | 6 | :webGLRendererOptions="webGLRendererOptions" |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | @load="onLoad" | 20 | @load="onLoad" |
21 | :position="position" | 21 | :position="position" |
22 | :rotation="rotation" | 22 | :rotation="rotation" |
23 | - :lights="lights" | 23 | + :lights="[lights[lightInput]]" |
24 | :showFps="showFps" | 24 | :showFps="showFps" |
25 | :labels="labels" | 25 | :labels="labels" |
26 | /> | 26 | /> |
@@ -29,15 +29,13 @@ | @@ -29,15 +29,13 @@ | ||
29 | <n-progress type="line" :color="themeColor" :percentage="process" :indicator-placement="'inside'" processing /> | 29 | <n-progress type="line" :color="themeColor" :percentage="process" :indicator-placement="'inside'" processing /> |
30 | </div> | 30 | </div> |
31 | </div> | 31 | </div> |
32 | - <div v-else>您的浏览器不支持WebGL!</div> | ||
33 | </div> | 32 | </div> |
34 | </template> | 33 | </template> |
35 | <script setup lang="ts"> | 34 | <script setup lang="ts"> |
36 | -import { PropType, toRefs, ref, nextTick, computed, watch } from 'vue' | 35 | +import { PropType, toRefs, ref, nextTick, computed } from 'vue' |
37 | import { CreateComponentType } from '@/packages/index.d' | 36 | import { CreateComponentType } from '@/packages/index.d' |
38 | import { vue3dLoader } from 'vue-3d-loader' | 37 | import { vue3dLoader } from 'vue-3d-loader' |
39 | import { useDesignStore } from '@/store/modules/designStore/designStore' | 38 | import { useDesignStore } from '@/store/modules/designStore/designStore' |
40 | -import { useDetectWebGLContext } from '@/utils/external/useSupportWebGL' | ||
41 | 39 | ||
42 | const designStore = useDesignStore() | 40 | const designStore = useDesignStore() |
43 | 41 | ||
@@ -54,7 +52,6 @@ const themeColor = computed(() => { | @@ -54,7 +52,6 @@ const themeColor = computed(() => { | ||
54 | 52 | ||
55 | const vue3dLoaderRef = ref(null) | 53 | const vue3dLoaderRef = ref(null) |
56 | 54 | ||
57 | -//threejs配置 | ||
58 | const webGLRendererOptions = { | 55 | const webGLRendererOptions = { |
59 | alpha: true, // 透明 | 56 | alpha: true, // 透明 |
60 | antialias: true, // 抗锯齿 | 57 | antialias: true, // 抗锯齿 |
@@ -96,13 +93,9 @@ const { | @@ -96,13 +93,9 @@ const { | ||
96 | rotation, | 93 | rotation, |
97 | lights, | 94 | lights, |
98 | showFps, | 95 | showFps, |
99 | - labels | ||
100 | -} = toRefs(props.chartConfig.option) as any | ||
101 | - | ||
102 | -watch(dataset, (newData: string) => { | ||
103 | - //dateset为空则清除场景 | ||
104 | - if(!newData) clearScene.value=true | ||
105 | -}) | 96 | + labels, |
97 | + lightInput | ||
98 | +} = toRefs(props.chartConfig.option) as any | ||
106 | </script> | 99 | </script> |
107 | 100 | ||
108 | <style lang="scss" scoped> | 101 | <style lang="scss" scoped> |
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | <n-tree | 3 | <n-tree |
4 | + ref="nTreeRef" | ||
4 | :accordion="treeConfig.accordion" | 5 | :accordion="treeConfig.accordion" |
5 | :checkable="treeConfig.checkable" | 6 | :checkable="treeConfig.checkable" |
6 | :default-expand-all="treeConfig.defaultExpandAll" | 7 | :default-expand-all="treeConfig.defaultExpandAll" |
@@ -11,17 +12,20 @@ | @@ -11,17 +12,20 @@ | ||
11 | label-field="name" | 12 | label-field="name" |
12 | children-field="children" | 13 | children-field="children" |
13 | @update:selected-keys="onClick" | 14 | @update:selected-keys="onClick" |
15 | + @update:checked-keys="onClick" | ||
16 | + :checked-keys="checkedKeys" | ||
14 | /> | 17 | /> |
15 | </div> | 18 | </div> |
16 | </template> | 19 | </template> |
17 | 20 | ||
18 | <script setup lang="ts"> | 21 | <script setup lang="ts"> |
19 | -import { PropType, toRefs } from 'vue' | 22 | +import { PropType, toRefs, ref } from 'vue' |
20 | import { CreateComponentType } from '@/packages/index.d' | 23 | import { CreateComponentType } from '@/packages/index.d' |
21 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 24 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
22 | import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook' | 25 | import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook' |
23 | import { InteractEventOn } from '@/enums/eventEnum' | 26 | import { InteractEventOn } from '@/enums/eventEnum' |
24 | import { ComponentInteractParamsEnum } from './interact' | 27 | import { ComponentInteractParamsEnum } from './interact' |
28 | +import { NTree } from 'naive-ui' | ||
25 | 29 | ||
26 | const props = defineProps({ | 30 | const props = defineProps({ |
27 | chartConfig: { | 31 | chartConfig: { |
@@ -32,7 +36,16 @@ const props = defineProps({ | @@ -32,7 +36,16 @@ const props = defineProps({ | ||
32 | 36 | ||
33 | const { dataset, treeConfig } = toRefs(props.chartConfig.option) | 37 | const { dataset, treeConfig } = toRefs(props.chartConfig.option) |
34 | 38 | ||
39 | +const nTreeRef = ref<null | InstanceType<typeof NTree>>(null) | ||
40 | + | ||
41 | +const checkedKeys = ref([]) | ||
42 | + | ||
35 | const onClick = (v: string[]) => { | 43 | const onClick = (v: string[]) => { |
44 | + // nTreeRef.value?.selectedKeys(v) | ||
45 | + console.log(nTreeRef.value) | ||
46 | + console.log(v) | ||
47 | + // nTreeRef.value?.onUpdateCheckedKeys(v) | ||
48 | + if (Array.isArray(v) && v.length == 0) return | ||
36 | useChartInteract( | 49 | useChartInteract( |
37 | props.chartConfig, | 50 | props.chartConfig, |
38 | useChartEditStore, | 51 | useChartEditStore, |