af-mobile-client-vue3 1.3.88 → 1.3.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/core/ImageUploader/index.vue +11 -4
- package/src/components/data/XCellList/index.vue +1 -1
- package/src/components/data/XOlMap/index.vue +190 -0
- package/src/components/data/XOlMap/types.ts +42 -0
- package/src/router/routes.ts +421 -421
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/views/component/XCellListView/index.vue +48 -21
- package/src/views/component/XFormGroupView/index.vue +82 -78
- package/src/views/component/XFormView/index.vue +42 -41
- package/src/views/component/XOlMapView/index.vue +37 -1
- package/src/views/component/XOlMapView/testData.ts +77 -0
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@ import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
|
|
|
5
5
|
import { formatNow } from '@af-mobile-client-vue3/utils/timeUtil'
|
|
6
6
|
import {
|
|
7
7
|
ActionSheet,
|
|
8
|
+
showToast,
|
|
8
9
|
Icon as VanIcon,
|
|
9
10
|
Uploader as vanUploader,
|
|
10
11
|
} from 'vant'
|
|
@@ -171,8 +172,11 @@ function triggerCamera() {
|
|
|
171
172
|
handlePhotoUpload(result.data)
|
|
172
173
|
}
|
|
173
174
|
else {
|
|
174
|
-
|
|
175
|
-
|
|
175
|
+
if (props.isAsyncUpload)
|
|
176
|
+
showToast('此处不允许浏览器上传,请在移动端操作')
|
|
177
|
+
else
|
|
178
|
+
// 浏览器模式:打开文件选择
|
|
179
|
+
openBrowserFilePicker()
|
|
176
180
|
}
|
|
177
181
|
},
|
|
178
182
|
})
|
|
@@ -392,8 +396,11 @@ function handleActionSelect(option: any) {
|
|
|
392
396
|
})
|
|
393
397
|
}
|
|
394
398
|
else {
|
|
395
|
-
|
|
396
|
-
|
|
399
|
+
if (props.isAsyncUpload)
|
|
400
|
+
showToast('此处不允许浏览器上传,请在移动端操作')
|
|
401
|
+
else
|
|
402
|
+
// 浏览器模式:打开文件选择
|
|
403
|
+
openBrowserFilePicker()
|
|
397
404
|
}
|
|
398
405
|
},
|
|
399
406
|
})
|
|
@@ -1308,7 +1308,7 @@ function handleCheckboxChange(item: any, checked: boolean) {
|
|
|
1308
1308
|
min-width: 76px;
|
|
1309
1309
|
height: 40px;
|
|
1310
1310
|
border-radius: 10px;
|
|
1311
|
-
padding: 0
|
|
1311
|
+
padding: 0 10px;
|
|
1312
1312
|
// font-size: var(--van-font-size-md);
|
|
1313
1313
|
transition: all 0.2s ease;
|
|
1314
1314
|
&:active {
|
|
@@ -12,6 +12,8 @@ import type {
|
|
|
12
12
|
PhoneLocationStatus,
|
|
13
13
|
PointData,
|
|
14
14
|
PointLayerConfig,
|
|
15
|
+
PolygonData,
|
|
16
|
+
PolygonLayerConfig,
|
|
15
17
|
TrackData,
|
|
16
18
|
WebGLPointOptions,
|
|
17
19
|
WMSLayerConfig,
|
|
@@ -25,6 +27,7 @@ import { defaults as defaultControls, ScaleLine } from 'ol/control'
|
|
|
25
27
|
import Feature from 'ol/Feature'
|
|
26
28
|
import LineString from 'ol/geom/LineString'
|
|
27
29
|
import Point from 'ol/geom/Point'
|
|
30
|
+
import Polygon from 'ol/geom/Polygon'
|
|
28
31
|
import { defaults as defaultInteractions } from 'ol/interaction'
|
|
29
32
|
import { Image as ImageLayer, Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
|
|
30
33
|
import { fromLonLat, toLonLat } from 'ol/proj'
|
|
@@ -91,6 +94,10 @@ let locationLayer: VectorLayer<VectorSource> | null = null
|
|
|
91
94
|
const trackLayers: Record<number, VectorLayer<VectorSource>> = {}
|
|
92
95
|
const trackLayerStatus = ref<TrackData[]>([])
|
|
93
96
|
|
|
97
|
+
/** 存储多边形图层 */
|
|
98
|
+
const polygonLayers: Record<number, VectorLayer<VectorSource>> = {}
|
|
99
|
+
const polygonLayerStatus = ref<PolygonLayerConfig[]>([])
|
|
100
|
+
|
|
94
101
|
/**
|
|
95
102
|
* 创建位置图标图层
|
|
96
103
|
*/
|
|
@@ -564,6 +571,46 @@ function createPointFeature(point: PointData, icon: string, iconAnchor: [number,
|
|
|
564
571
|
return feature
|
|
565
572
|
}
|
|
566
573
|
|
|
574
|
+
/**
|
|
575
|
+
* 创建多边形要素
|
|
576
|
+
* @param polygon - 多边形数据
|
|
577
|
+
* @returns 返回要素实例
|
|
578
|
+
*/
|
|
579
|
+
function createPolygonFeature(polygon: PolygonData): Feature {
|
|
580
|
+
// 将经纬度坐标转换为地图坐标
|
|
581
|
+
const coordinates = polygon.coordinates.map(coord => fromLonLat(coord))
|
|
582
|
+
|
|
583
|
+
const feature = new Feature({
|
|
584
|
+
geometry: new Polygon([coordinates]),
|
|
585
|
+
properties: polygon,
|
|
586
|
+
})
|
|
587
|
+
|
|
588
|
+
// 设置多边形样式
|
|
589
|
+
const style = new Style({
|
|
590
|
+
fill: new Fill({
|
|
591
|
+
color: polygon.fillColor || 'rgba(255, 0, 0, 0.3)',
|
|
592
|
+
}),
|
|
593
|
+
stroke: new Stroke({
|
|
594
|
+
color: polygon.strokeColor || '#ff0000',
|
|
595
|
+
width: polygon.strokeWidth || 2,
|
|
596
|
+
}),
|
|
597
|
+
text: new Text({
|
|
598
|
+
text: polygon.name || '',
|
|
599
|
+
font: '12px sans-serif',
|
|
600
|
+
fill: new Fill({
|
|
601
|
+
color: '#333',
|
|
602
|
+
}),
|
|
603
|
+
stroke: new Stroke({
|
|
604
|
+
color: '#fff',
|
|
605
|
+
width: 2,
|
|
606
|
+
}),
|
|
607
|
+
}),
|
|
608
|
+
})
|
|
609
|
+
|
|
610
|
+
feature.setStyle(style)
|
|
611
|
+
return feature
|
|
612
|
+
}
|
|
613
|
+
|
|
567
614
|
/**
|
|
568
615
|
* 创建点位图层
|
|
569
616
|
* @param config - 图层配置
|
|
@@ -911,6 +958,102 @@ function navigationHandleLocation() {
|
|
|
911
958
|
}
|
|
912
959
|
}
|
|
913
960
|
|
|
961
|
+
/**
|
|
962
|
+
* 创建多边形图层
|
|
963
|
+
* @param config - 图层配置
|
|
964
|
+
* @returns 返回图层实例
|
|
965
|
+
*/
|
|
966
|
+
function createPolygonLayer(config: PolygonLayerConfig): VectorLayer<VectorSource> {
|
|
967
|
+
const vectorSource = new VectorSource()
|
|
968
|
+
const vectorLayer = new VectorLayer({
|
|
969
|
+
source: vectorSource,
|
|
970
|
+
visible: config.show,
|
|
971
|
+
zIndex: config.id === undefined ? 1 : 4, // 多边形图层层级稍高
|
|
972
|
+
})
|
|
973
|
+
|
|
974
|
+
// 添加多边形要素
|
|
975
|
+
const addFeatures = (data: PolygonData[]) => {
|
|
976
|
+
// 清除现有要素
|
|
977
|
+
vectorSource.clear()
|
|
978
|
+
// 添加新的多边形要素
|
|
979
|
+
data.forEach((polygon) => {
|
|
980
|
+
const feature = createPolygonFeature(polygon)
|
|
981
|
+
vectorSource.addFeature(feature)
|
|
982
|
+
})
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// 添加点击事件处理
|
|
986
|
+
if (config.onClick) {
|
|
987
|
+
map?.on('click', (event) => {
|
|
988
|
+
const feature = map.forEachFeatureAtPixel(event.pixel, feature => feature, {
|
|
989
|
+
layerFilter: layer => layer === vectorLayer,
|
|
990
|
+
})
|
|
991
|
+
if (feature) {
|
|
992
|
+
const properties = feature.getProperties()
|
|
993
|
+
const { geometry, ...polygonData } = properties
|
|
994
|
+
config.onClick(polygonData as PolygonData, event)
|
|
995
|
+
}
|
|
996
|
+
})
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// 监听图层可见性变化
|
|
1000
|
+
vectorLayer.on('change:visible', async () => {
|
|
1001
|
+
if (vectorLayer.getVisible() && config.dataProvider) {
|
|
1002
|
+
try {
|
|
1003
|
+
const data = await config.dataProvider()
|
|
1004
|
+
addFeatures(data)
|
|
1005
|
+
}
|
|
1006
|
+
catch (error) {
|
|
1007
|
+
console.error('获取多边形数据失败:', error)
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
})
|
|
1011
|
+
|
|
1012
|
+
// 初始加载数据
|
|
1013
|
+
if (config.show && config.dataProvider) {
|
|
1014
|
+
const result = config.dataProvider()
|
|
1015
|
+
if (result instanceof Promise) {
|
|
1016
|
+
result.then((data) => {
|
|
1017
|
+
addFeatures(data)
|
|
1018
|
+
}).catch((error) => {
|
|
1019
|
+
console.error('获取初始多边形数据失败:', error)
|
|
1020
|
+
})
|
|
1021
|
+
}
|
|
1022
|
+
else {
|
|
1023
|
+
addFeatures(result)
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
return vectorLayer
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* 添加多边形图层
|
|
1032
|
+
* @param config - 图层配置
|
|
1033
|
+
* @returns 返回图层实例
|
|
1034
|
+
*/
|
|
1035
|
+
function addPolygonLayer(config: PolygonLayerConfig): VectorLayer<VectorSource> | null {
|
|
1036
|
+
if (!map)
|
|
1037
|
+
return null
|
|
1038
|
+
|
|
1039
|
+
const vectorLayer = createPolygonLayer(config)
|
|
1040
|
+
map.addLayer(vectorLayer)
|
|
1041
|
+
polygonLayers[config.id] = vectorLayer
|
|
1042
|
+
|
|
1043
|
+
// 更新图层状态
|
|
1044
|
+
if (config.showInControl !== false) {
|
|
1045
|
+
const existingIndex = polygonLayerStatus.value.findIndex(layer => layer.id === config.id)
|
|
1046
|
+
if (existingIndex === -1) {
|
|
1047
|
+
polygonLayerStatus.value.push(config)
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
polygonLayerStatus.value[existingIndex] = config
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
return vectorLayer
|
|
1055
|
+
}
|
|
1056
|
+
|
|
914
1057
|
/**
|
|
915
1058
|
* 添加轨迹图层
|
|
916
1059
|
* @param trackData - 轨迹数据
|
|
@@ -1044,6 +1187,31 @@ function handleToggleTrackLayer(track: TrackData): void {
|
|
|
1044
1187
|
setTrackLayerVisible(track.id, track.show)
|
|
1045
1188
|
}
|
|
1046
1189
|
|
|
1190
|
+
/**
|
|
1191
|
+
* 控制多边形图层显示/隐藏
|
|
1192
|
+
* @param layerId - 图层ID
|
|
1193
|
+
* @param visible - 是否显示
|
|
1194
|
+
*/
|
|
1195
|
+
function setPolygonLayerVisible(layerId: number, visible: boolean): void {
|
|
1196
|
+
const layer = polygonLayers[layerId]
|
|
1197
|
+
if (layer) {
|
|
1198
|
+
layer.setVisible(visible)
|
|
1199
|
+
// 更新图层状态
|
|
1200
|
+
const layerIndex = polygonLayerStatus.value.findIndex(layer => layer.id === layerId)
|
|
1201
|
+
if (layerIndex !== -1) {
|
|
1202
|
+
polygonLayerStatus.value[layerIndex].show = visible
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* 切换多边形图层显示状态
|
|
1209
|
+
*/
|
|
1210
|
+
function handleTogglePolygonLayer(layer: PolygonLayerConfig): void {
|
|
1211
|
+
layer.show = !layer.show
|
|
1212
|
+
setPolygonLayerVisible(layer.id, layer.show)
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1047
1215
|
// 暴露方法给父组件
|
|
1048
1216
|
defineExpose({
|
|
1049
1217
|
updateLocationMarker,
|
|
@@ -1067,6 +1235,9 @@ defineExpose({
|
|
|
1067
1235
|
addTrackLayer,
|
|
1068
1236
|
setTrackLayerVisible,
|
|
1069
1237
|
handleToggleTrackLayer,
|
|
1238
|
+
addPolygonLayer,
|
|
1239
|
+
setPolygonLayerVisible,
|
|
1240
|
+
handleTogglePolygonLayer,
|
|
1070
1241
|
})
|
|
1071
1242
|
|
|
1072
1243
|
// 组件卸载时清理地图实例
|
|
@@ -1185,6 +1356,25 @@ onUnmounted(() => {
|
|
|
1185
1356
|
</div>
|
|
1186
1357
|
</div>
|
|
1187
1358
|
</div>
|
|
1359
|
+
|
|
1360
|
+
<!-- 多边形图层 -->
|
|
1361
|
+
<div v-if="polygonLayerStatus.length > 0" class="control-panel layer-control">
|
|
1362
|
+
<div class="control-title">
|
|
1363
|
+
<i class="van-icon van-icon-map-marked" /> 多边形图层
|
|
1364
|
+
</div>
|
|
1365
|
+
<div class="layer-list">
|
|
1366
|
+
<div
|
|
1367
|
+
v-for="layer in polygonLayerStatus"
|
|
1368
|
+
:key="layer.id"
|
|
1369
|
+
class="layer-item"
|
|
1370
|
+
:class="{ active: layer.show }"
|
|
1371
|
+
@click="handleTogglePolygonLayer(layer)"
|
|
1372
|
+
>
|
|
1373
|
+
<i class="van-icon" :class="layer.show ? 'van-icon-eye' : 'van-icon-closed-eye'" />
|
|
1374
|
+
<span>{{ layer.value }}</span>
|
|
1375
|
+
</div>
|
|
1376
|
+
</div>
|
|
1377
|
+
</div>
|
|
1188
1378
|
</div>
|
|
1189
1379
|
</div>
|
|
1190
1380
|
</div>
|
|
@@ -147,3 +147,45 @@ export interface TrackData {
|
|
|
147
147
|
color: string
|
|
148
148
|
show?: boolean // 是否显示
|
|
149
149
|
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 多边形数据接口
|
|
153
|
+
*/
|
|
154
|
+
export interface PolygonData {
|
|
155
|
+
/** 多边形ID */
|
|
156
|
+
id: number
|
|
157
|
+
/** 多边形名称 */
|
|
158
|
+
name: string
|
|
159
|
+
/** 多边形坐标点数组 [经度, 纬度][] */
|
|
160
|
+
coordinates: [number, number][]
|
|
161
|
+
/** 填充颜色 */
|
|
162
|
+
fillColor?: string
|
|
163
|
+
/** 边框颜色 */
|
|
164
|
+
strokeColor?: string
|
|
165
|
+
/** 边框宽度 */
|
|
166
|
+
strokeWidth?: number
|
|
167
|
+
/** 透明度 */
|
|
168
|
+
opacity?: number
|
|
169
|
+
/** 是否显示 */
|
|
170
|
+
show?: boolean
|
|
171
|
+
/** 自定义数据 */
|
|
172
|
+
extData?: Record<string, any>
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 多边形图层配置接口
|
|
177
|
+
*/
|
|
178
|
+
export interface PolygonLayerConfig {
|
|
179
|
+
/** 图层ID */
|
|
180
|
+
id: number
|
|
181
|
+
/** 图层名称 */
|
|
182
|
+
value: string
|
|
183
|
+
/** 是否显示 */
|
|
184
|
+
show: boolean
|
|
185
|
+
/** 是否在控制面板显示 */
|
|
186
|
+
showInControl?: boolean
|
|
187
|
+
/** 点击事件处理函数 */
|
|
188
|
+
onClick?: (polygon: PolygonData, event: any) => void
|
|
189
|
+
/** 多边形数据提供者 */
|
|
190
|
+
dataProvider?: () => PolygonData[] | Promise<PolygonData[]>
|
|
191
|
+
}
|