@tplc/business 0.5.46 → 0.5.49
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/CHANGELOG.md +30 -0
- package/components/lcb-block/lcb-block.vue +1 -3
- package/components/lcb-block/types.ts +4 -0
- package/components/lcb-light-map/api.ts +35 -0
- package/components/lcb-light-map/lcb-light-map.vue +243 -0
- package/components/lcb-light-map/types.ts +73 -0
- package/components/lcb-light-map/util.ts +79 -0
- package/components/lcb-render-view/lcb-render-view.vue +1 -0
- package/global.d.ts +1 -0
- package/package.json +1 -1
- package/types/components/lcb-block/types.d.ts +4 -0
- package/types/components/lcb-image/lcb-image.vue.d.ts +1 -1
- package/types/components/lcb-light-map/api.d.ts +10 -0
- package/types/components/lcb-light-map/lcb-light-map.vue.d.ts +59 -0
- package/types/components/lcb-light-map/types.d.ts +69 -0
- package/types/components/lcb-light-map/util.d.ts +40 -0
- package/types/components/lcb-list/lcb-list.vue.d.ts +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.5.49](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.5.48...v0.5.49) (2025-11-15)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ✨ Features | 新功能
|
|
9
|
+
|
|
10
|
+
* 新增lcb-light-map ([b18d767](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/b18d767059fccadf5f55400d5fc34e352fa4c55d))
|
|
11
|
+
|
|
12
|
+
### [0.5.48](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.5.47...v0.5.48) (2025-11-14)
|
|
13
|
+
|
|
14
|
+
### [0.5.47](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v1.0.2...v0.5.47) (2025-11-14)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### 🚀 Chore | 构建/工程依赖/工具
|
|
18
|
+
|
|
19
|
+
* **release:** 0.5.46 ([41a92a1](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/41a92a19794b409587e3e349dabd87beab6376a3))
|
|
20
|
+
* **release:** 1.0.3 ([e8e02e2](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/e8e02e28480097a9e2bc68e7017198382eb956e4))
|
|
21
|
+
* **release:** 1.0.4 ([a45ebc8](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/a45ebc8d8b7de3c31b084e14022c4dda6707a761))
|
|
22
|
+
* **release:** 1.0.5 ([bd6ed33](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/bd6ed332cb17cc13458d50ca86daa7b64996dc36))
|
|
23
|
+
* **release:** 1.0.6 ([c75540a](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/c75540a368a11693f59ca4811274f35f7d301add))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### ✨ Features | 新功能
|
|
27
|
+
|
|
28
|
+
* home search tabs允许为空 ([9678a10](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/9678a10bb5f4a8b5c5948410d5db4482d8589bcc))
|
|
29
|
+
* 优化动画 ([5f25096](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/5f25096abaea90f07141f7213fac04997686bd80))
|
|
30
|
+
* 变更fit ([096456a](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/096456a09c6daa730e42c0733f476f8d3c6493fc))
|
|
31
|
+
* 变更图片默认值 ([966bdcc](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/966bdcc897209edf09d2469ba151118f856c5f53))
|
|
32
|
+
* 改回mfit ([901781e](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/901781ea64d44fcf23b6587a479f1321243ce3f4))
|
|
33
|
+
* 调整预览 ([ed2baed](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/commit/ed2baedafa3b05a54803aec024c190185c76902e))
|
|
34
|
+
|
|
5
35
|
### [0.5.46](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v1.0.6...v0.5.46) (2025-11-12)
|
|
6
36
|
|
|
7
37
|
### [0.5.45](https://gitlab888.30jia.com.cn/tourism-front/zero-code-pro/compare/v0.5.44...v0.5.45) (2025-11-10)
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
<view
|
|
3
3
|
:style="{
|
|
4
4
|
width: position === 'absolute' ? '100%' : '',
|
|
5
|
-
marginTop: transformValueUnit(-(floatUp || 0)),
|
|
6
|
-
marginLeft: transformValueUnit(marginHorizontal || 0),
|
|
7
|
-
marginRight: transformValueUnit(marginHorizontal || 0),
|
|
8
5
|
padding: `${transformValueUnit(paddingTop || paddingVertical || 0)} ${transformValueUnit(paddingRight || paddingHorizontal || 0)} ${transformValueUnit(paddingBottom || paddingVertical || 0)} ${transformValueUnit(paddingLeft || paddingHorizontal || 0)}`,
|
|
9
6
|
borderRadius: `${transformValueUnit(topRadius || radius)} ${transformValueUnit(topRadius || radius)} ${transformValueUnit(bottomRadius || radius)} ${transformValueUnit(bottomRadius || radius)}`,
|
|
10
7
|
color,
|
|
@@ -18,6 +15,7 @@
|
|
|
18
15
|
boxShadow:
|
|
19
16
|
shadowColor && shadowSize ? `0px 0px ${blurSize}px ${shadowSize}px ${shadowColor}` : '',
|
|
20
17
|
textAlign,
|
|
18
|
+
margin: `${transformValueUnit(marginTop || -(floatUp || 0))} ${transformValueUnit(marginRight || marginHorizontal || 0)} ${transformValueUnit(marginBottom || 0)} ${transformValueUnit(marginLeft || marginHorizontal || 0)}`,
|
|
21
19
|
...customStyle,
|
|
22
20
|
...getFlexStyle(align),
|
|
23
21
|
}"
|
|
@@ -25,6 +25,10 @@ export interface LcbBlockProps {
|
|
|
25
25
|
paddingBottom?: number
|
|
26
26
|
paddingLeft?: number
|
|
27
27
|
paddingRight?: number
|
|
28
|
+
marginTop?: number
|
|
29
|
+
marginBottom?: number
|
|
30
|
+
marginLeft?: number
|
|
31
|
+
marginRight?: number
|
|
28
32
|
zIndex?: number
|
|
29
33
|
position?: 'relative' | 'absolute'
|
|
30
34
|
color?: string
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { IResData } from 'action'
|
|
2
|
+
import type { LightMapConfig, MapDetail } from './types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 获取地图配置列表
|
|
6
|
+
*/
|
|
7
|
+
export const getMapConfigListApi = async () => {
|
|
8
|
+
const { data } = (await uni.$lcb.http.post('/clockLightConfig/list', {}, true)) as IResData<
|
|
9
|
+
LightMapConfig[]
|
|
10
|
+
>
|
|
11
|
+
|
|
12
|
+
const list = data.map(
|
|
13
|
+
(item) =>
|
|
14
|
+
({
|
|
15
|
+
...item,
|
|
16
|
+
mapConfig: JSON.parse(`${item.mapConfig}`),
|
|
17
|
+
}) as LightMapConfig,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
return list
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 获取地图详细信息
|
|
25
|
+
* @param clockLightConfigId 地图配置ID
|
|
26
|
+
*/
|
|
27
|
+
export const getMapDetailApi = async (clockLightConfigId: string) => {
|
|
28
|
+
const { data } = (await uni.$lcb.http.post(
|
|
29
|
+
'/clockLightUser/detail',
|
|
30
|
+
{ clockLightConfigId },
|
|
31
|
+
true,
|
|
32
|
+
)) as IResData<MapDetail>
|
|
33
|
+
|
|
34
|
+
return data
|
|
35
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<lcb-block v-bind="$props">
|
|
3
|
+
<view class="light-map-container relative">
|
|
4
|
+
<!-- 地图标题 -->
|
|
5
|
+
<view v-if="currentMapConfig" class="map-header text-center mb-20rpx">
|
|
6
|
+
<view class="text-4 font-500" v-if="currentMapConfig.title">
|
|
7
|
+
{{ currentMapConfig.title }}
|
|
8
|
+
</view>
|
|
9
|
+
<view v-if="currentMapConfig.subTitle" class="text-3 text-hint mt-1">
|
|
10
|
+
{{ currentMapConfig.subTitle }}
|
|
11
|
+
</view>
|
|
12
|
+
</view>
|
|
13
|
+
|
|
14
|
+
<!-- 地图切换区域 -->
|
|
15
|
+
<view class="map-wrapper relative">
|
|
16
|
+
<!-- 单个地图容器 -->
|
|
17
|
+
<view
|
|
18
|
+
v-if="currentMapConfig"
|
|
19
|
+
class="light-map m-auto relative overflow-hidden"
|
|
20
|
+
:style="{
|
|
21
|
+
width: props.width + 'rpx',
|
|
22
|
+
height: props.height + 'rpx',
|
|
23
|
+
backgroundImage: `url(${getBackgroundImage(currentMapConfig)})`,
|
|
24
|
+
backgroundSize: 'cover',
|
|
25
|
+
backgroundPosition: 'center',
|
|
26
|
+
}"
|
|
27
|
+
>
|
|
28
|
+
<!-- 位置点 -->
|
|
29
|
+
<view
|
|
30
|
+
v-for="(item, idx) in currentDetailInfo?.clockLightUserRecordList"
|
|
31
|
+
:key="idx"
|
|
32
|
+
class="dot absolute rounded-full"
|
|
33
|
+
:style="getDotStyle(item, currentMapConfig)"
|
|
34
|
+
/>
|
|
35
|
+
</view>
|
|
36
|
+
|
|
37
|
+
<!-- 左侧箭头按钮 -->
|
|
38
|
+
<view
|
|
39
|
+
v-if="currentIndex > 0"
|
|
40
|
+
class="arrow-btn arrow-btn-left absolute z-10"
|
|
41
|
+
@click="handlePrev"
|
|
42
|
+
>
|
|
43
|
+
<wd-icon name="arrow-left" size="40rpx" color="#ffffff" />
|
|
44
|
+
</view>
|
|
45
|
+
|
|
46
|
+
<!-- 右侧箭头按钮 -->
|
|
47
|
+
<view
|
|
48
|
+
v-if="currentIndex < mapConfigList.length - 1"
|
|
49
|
+
class="arrow-btn arrow-btn-right absolute z-10"
|
|
50
|
+
@click="handleNext"
|
|
51
|
+
>
|
|
52
|
+
<wd-icon name="arrow-right" size="40rpx" color="#ffffff" />
|
|
53
|
+
</view>
|
|
54
|
+
</view>
|
|
55
|
+
|
|
56
|
+
<!-- 加载状态 -->
|
|
57
|
+
<view v-if="loading" class="flex-center p-40rpx">
|
|
58
|
+
<wd-loading />
|
|
59
|
+
</view>
|
|
60
|
+
|
|
61
|
+
<!-- 空状态 -->
|
|
62
|
+
<view v-if="!loading && mapConfigList.length === 0" class="flex-center p-40rpx text-gray-400">
|
|
63
|
+
暂无地图数据
|
|
64
|
+
</view>
|
|
65
|
+
</view>
|
|
66
|
+
</lcb-block>
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
<script setup lang="ts">
|
|
70
|
+
import { computed, ref } from 'vue'
|
|
71
|
+
import type { LightMapConfig, MapDetail, LcbLightMapProps } from './types'
|
|
72
|
+
import { getMapConfigListApi, getMapDetailApi } from './api'
|
|
73
|
+
import { getDotStyle } from './util'
|
|
74
|
+
defineOptions({
|
|
75
|
+
name: 'LcbLightMap',
|
|
76
|
+
options: {
|
|
77
|
+
addGlobalClass: true,
|
|
78
|
+
virtualHost: true,
|
|
79
|
+
styleIsolation: 'shared',
|
|
80
|
+
},
|
|
81
|
+
})
|
|
82
|
+
const props = withDefaults(defineProps<LcbLightMapProps>(), { width: 650, height: 848 })
|
|
83
|
+
|
|
84
|
+
const currentDetailInfo = ref<MapDetail>()
|
|
85
|
+
// 状态
|
|
86
|
+
const mapConfigList = ref<LightMapConfig[]>([])
|
|
87
|
+
const currentIndex = ref(0)
|
|
88
|
+
const loading = ref(true)
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 当前地图配置
|
|
92
|
+
*/
|
|
93
|
+
const currentMapConfig = computed(() => {
|
|
94
|
+
return mapConfigList.value[currentIndex.value] || null
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 根据点亮率获取对应的背景图
|
|
99
|
+
*/
|
|
100
|
+
const getBackgroundImage = (mapConfig: LightMapConfig) => {
|
|
101
|
+
const clockLightProductCountRate = currentDetailInfo.value?.clockLightProductCountRate || 0
|
|
102
|
+
const { backgroundImages } = mapConfig.mapConfig
|
|
103
|
+
|
|
104
|
+
if (clockLightProductCountRate < 31) {
|
|
105
|
+
return backgroundImages.default
|
|
106
|
+
} else if (clockLightProductCountRate < 61) {
|
|
107
|
+
return backgroundImages.p30
|
|
108
|
+
} else if (clockLightProductCountRate < 81) {
|
|
109
|
+
return backgroundImages.p60
|
|
110
|
+
} else if (clockLightProductCountRate < 100) {
|
|
111
|
+
return backgroundImages.p80
|
|
112
|
+
} else {
|
|
113
|
+
return backgroundImages.p100
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 切换到上一个地图
|
|
119
|
+
*/
|
|
120
|
+
const handlePrev = async () => {
|
|
121
|
+
if (currentIndex.value > 0) {
|
|
122
|
+
currentIndex.value--
|
|
123
|
+
const targetConfig = mapConfigList.value[currentIndex.value]
|
|
124
|
+
if (targetConfig) {
|
|
125
|
+
await getMapInfo(targetConfig.clockLightConfigId)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 切换到下一个地图
|
|
132
|
+
*/
|
|
133
|
+
const handleNext = async () => {
|
|
134
|
+
if (currentIndex.value < mapConfigList.value.length - 1) {
|
|
135
|
+
currentIndex.value++
|
|
136
|
+
const targetConfig = mapConfigList.value[currentIndex.value]
|
|
137
|
+
if (targetConfig) {
|
|
138
|
+
await getMapInfo(targetConfig.clockLightConfigId)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 获取地图配置列表
|
|
145
|
+
*/
|
|
146
|
+
const getMapConfigList = async () => {
|
|
147
|
+
try {
|
|
148
|
+
const list = await getMapConfigListApi()
|
|
149
|
+
mapConfigList.value = list
|
|
150
|
+
return list
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error('获取地图配置列表失败:', error)
|
|
153
|
+
return []
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 获取地图详细信息
|
|
159
|
+
* @param clockLightConfigId 地图配置ID
|
|
160
|
+
*/
|
|
161
|
+
const getMapInfo = async (clockLightConfigId: string) => {
|
|
162
|
+
try {
|
|
163
|
+
loading.value = true
|
|
164
|
+
const data = await getMapDetailApi(clockLightConfigId)
|
|
165
|
+
currentDetailInfo.value = data
|
|
166
|
+
} finally {
|
|
167
|
+
loading.value = false
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* 初始化
|
|
173
|
+
*/
|
|
174
|
+
const init = async () => {
|
|
175
|
+
loading.value = true
|
|
176
|
+
try {
|
|
177
|
+
// 先获取地图配置列表
|
|
178
|
+
const list = await getMapConfigList()
|
|
179
|
+
|
|
180
|
+
// 如果有地图配置,加载第一个地图的详细信息
|
|
181
|
+
if (list.length > 0) {
|
|
182
|
+
await getMapInfo(list[0].clockLightConfigId)
|
|
183
|
+
}
|
|
184
|
+
} finally {
|
|
185
|
+
loading.value = false
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 初始化
|
|
190
|
+
init()
|
|
191
|
+
</script>
|
|
192
|
+
|
|
193
|
+
<style lang="scss" scoped>
|
|
194
|
+
.light-map-container {
|
|
195
|
+
width: 100%;
|
|
196
|
+
|
|
197
|
+
.map-header {
|
|
198
|
+
padding: 20rpx 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.map-wrapper {
|
|
202
|
+
width: 100%;
|
|
203
|
+
position: relative;
|
|
204
|
+
|
|
205
|
+
// 箭头按钮
|
|
206
|
+
.arrow-btn {
|
|
207
|
+
top: 50%;
|
|
208
|
+
display: flex;
|
|
209
|
+
align-items: center;
|
|
210
|
+
justify-content: center;
|
|
211
|
+
width: 60rpx;
|
|
212
|
+
height: 60rpx;
|
|
213
|
+
cursor: pointer;
|
|
214
|
+
background: rgba(0, 0, 0, 0.4);
|
|
215
|
+
border-radius: 50%;
|
|
216
|
+
transition: all 0.3s;
|
|
217
|
+
transform: translateY(-50%);
|
|
218
|
+
|
|
219
|
+
&:active {
|
|
220
|
+
opacity: 0.8;
|
|
221
|
+
transform: translateY(-50%) scale(0.9);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
&.arrow-btn-left {
|
|
225
|
+
left: 10rpx;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
&.arrow-btn-right {
|
|
229
|
+
right: 10rpx;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.light-map {
|
|
235
|
+
background-repeat: no-repeat;
|
|
236
|
+
|
|
237
|
+
.dot {
|
|
238
|
+
box-shadow: 0 2rpx 4rpx rgba(231, 163, 83, 0.4);
|
|
239
|
+
transform-origin: center;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
</style>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { LcbBlockProps } from '../lcb-block/types'
|
|
2
|
+
|
|
3
|
+
export interface LcbLightMapProps extends LcbBlockProps {
|
|
4
|
+
width: number
|
|
5
|
+
height: number
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 位置记录接口
|
|
9
|
+
*/
|
|
10
|
+
export interface LocationRecord {
|
|
11
|
+
latitude: number
|
|
12
|
+
longitude: number
|
|
13
|
+
[key: string]: any
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 地图详细配置接口
|
|
18
|
+
*/
|
|
19
|
+
export interface MapDetailConfig {
|
|
20
|
+
boundaries: {
|
|
21
|
+
southwest: {
|
|
22
|
+
latitude: number
|
|
23
|
+
longitude: number
|
|
24
|
+
}
|
|
25
|
+
northeast: {
|
|
26
|
+
latitude: number
|
|
27
|
+
longitude: number
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
physicalSize: {
|
|
31
|
+
xSize: number // X轴总距离(米)
|
|
32
|
+
ySize: number // Y轴总距离(米)
|
|
33
|
+
}
|
|
34
|
+
backgroundImages: {
|
|
35
|
+
default: string
|
|
36
|
+
p30: string
|
|
37
|
+
p60: string
|
|
38
|
+
p80: string
|
|
39
|
+
p100: string
|
|
40
|
+
}
|
|
41
|
+
displaySize?: {
|
|
42
|
+
normal?: {
|
|
43
|
+
width: number
|
|
44
|
+
height: number
|
|
45
|
+
}
|
|
46
|
+
index?: {
|
|
47
|
+
width: number
|
|
48
|
+
height: number
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
dotStyle: {
|
|
52
|
+
width: number
|
|
53
|
+
height: number
|
|
54
|
+
backgroundColor: string
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 地图配置接口
|
|
60
|
+
*/
|
|
61
|
+
export interface LightMapConfig {
|
|
62
|
+
clockLightConfigId: string
|
|
63
|
+
subTitle: string
|
|
64
|
+
title: string
|
|
65
|
+
mapConfig: MapDetailConfig
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface MapDetail {
|
|
69
|
+
clockLightConfigId: string
|
|
70
|
+
clockLightProductCountRate: number
|
|
71
|
+
clockLightUserRecordList: LocationRecord[]
|
|
72
|
+
clockLightConfigList: LightMapConfig[]
|
|
73
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { LightMapConfig, LocationRecord } from './types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 使用 Haversine 公式计算两个经纬度坐标之间的距离
|
|
5
|
+
* @param lat1 起点纬度
|
|
6
|
+
* @param lng1 起点经度
|
|
7
|
+
* @param lat2 终点纬度
|
|
8
|
+
* @param lng2 终点经度
|
|
9
|
+
* @returns 距离(单位:米)
|
|
10
|
+
*/
|
|
11
|
+
export const getDistanceByLoc = (
|
|
12
|
+
lat1: number = 0,
|
|
13
|
+
lng1: number = 0,
|
|
14
|
+
lat2: number = 0,
|
|
15
|
+
lng2: number = 0,
|
|
16
|
+
): number => {
|
|
17
|
+
const rad1 = (lat1 * Math.PI) / 180.0
|
|
18
|
+
const rad2 = (lat2 * Math.PI) / 180.0
|
|
19
|
+
const a = rad1 - rad2
|
|
20
|
+
const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
|
|
21
|
+
const r = 6378140 // 地球半径(米)
|
|
22
|
+
|
|
23
|
+
const distance =
|
|
24
|
+
r *
|
|
25
|
+
2 *
|
|
26
|
+
Math.asin(
|
|
27
|
+
Math.sqrt(
|
|
28
|
+
Math.pow(Math.sin(a / 2), 2) +
|
|
29
|
+
Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2),
|
|
30
|
+
),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
return distance
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 获取指定地图配置的点样式
|
|
37
|
+
*/
|
|
38
|
+
const getDotStyleConfig = (mapConfig: LightMapConfig) => {
|
|
39
|
+
return mapConfig.mapConfig.dotStyle
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 计算位置点相对于地图的百分比位置
|
|
44
|
+
*/
|
|
45
|
+
export const getPosition = (item: LocationRecord, mapConfig: LightMapConfig) => {
|
|
46
|
+
const { latitude, longitude } = item
|
|
47
|
+
const { boundaries, physicalSize } = mapConfig.mapConfig
|
|
48
|
+
const { southwest } = boundaries
|
|
49
|
+
const { xSize, ySize } = physicalSize
|
|
50
|
+
|
|
51
|
+
// 计算该点到西南角的X轴距离(保持纬度不变,只改变经度)
|
|
52
|
+
const x = getDistanceByLoc(southwest.latitude, southwest.longitude, southwest.latitude, longitude)
|
|
53
|
+
|
|
54
|
+
// 计算该点到西南角的Y轴距离(保持经度不变,只改变纬度)
|
|
55
|
+
const y = getDistanceByLoc(southwest.latitude, southwest.longitude, latitude, southwest.longitude)
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
left: (x / xSize) * 100,
|
|
59
|
+
bottom: (y / ySize) * 100,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 获取点的完整样式
|
|
65
|
+
*/
|
|
66
|
+
export const getDotStyle = (item: LocationRecord, mapConfig: LightMapConfig) => {
|
|
67
|
+
const position = getPosition(item, mapConfig)
|
|
68
|
+
const style = getDotStyleConfig(mapConfig)
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
left: `${position.left}%`,
|
|
72
|
+
bottom: `${position.bottom}%`,
|
|
73
|
+
width: `${style.width}rpx`,
|
|
74
|
+
height: `${style.height}rpx`,
|
|
75
|
+
backgroundColor: style.backgroundColor,
|
|
76
|
+
marginLeft: `-${style.width / 2}rpx`,
|
|
77
|
+
marginBottom: `-${style.height / 2}rpx`,
|
|
78
|
+
}
|
|
79
|
+
}
|
package/global.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ declare module 'vue' {
|
|
|
26
26
|
'lcb-icon': (typeof import('@tplc/business/components/lcb-icon/lcb-icon.vue'))['default']
|
|
27
27
|
'lcb-image': (typeof import('@tplc/business/components/lcb-image/lcb-image.vue'))['default']
|
|
28
28
|
'lcb-img-nav': (typeof import('@tplc/business/components/lcb-img-nav/lcb-img-nav.vue'))['default']
|
|
29
|
+
'lcb-light-map': (typeof import('@tplc/business/components/lcb-light-map/lcb-light-map.vue'))['default']
|
|
29
30
|
'lcb-list': (typeof import('@tplc/business/components/lcb-list/lcb-list.vue'))['default']
|
|
30
31
|
'lcb-map': (typeof import('@tplc/business/components/lcb-map/lcb-map.vue'))['default']
|
|
31
32
|
'lcb-nav': (typeof import('@tplc/business/components/lcb-nav/lcb-nav.vue'))['default']
|
package/package.json
CHANGED
|
@@ -23,6 +23,10 @@ export interface LcbBlockProps {
|
|
|
23
23
|
paddingBottom?: number
|
|
24
24
|
paddingLeft?: number
|
|
25
25
|
paddingRight?: number
|
|
26
|
+
marginTop?: number
|
|
27
|
+
marginBottom?: number
|
|
28
|
+
marginLeft?: number
|
|
29
|
+
marginRight?: number
|
|
26
30
|
zIndex?: number
|
|
27
31
|
position?: 'relative' | 'absolute'
|
|
28
32
|
color?: string
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LightMapConfig, MapDetail } from './types'
|
|
2
|
+
/**
|
|
3
|
+
* 获取地图配置列表
|
|
4
|
+
*/
|
|
5
|
+
export declare const getMapConfigListApi: () => Promise<LightMapConfig[]>
|
|
6
|
+
/**
|
|
7
|
+
* 获取地图详细信息
|
|
8
|
+
* @param clockLightConfigId 地图配置ID
|
|
9
|
+
*/
|
|
10
|
+
export declare const getMapDetailApi: (clockLightConfigId: string) => Promise<MapDetail>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { LcbLightMapProps } from './types'
|
|
2
|
+
declare const _default: import('vue').DefineComponent<
|
|
3
|
+
__VLS_WithDefaults<
|
|
4
|
+
__VLS_TypePropsToOption<LcbLightMapProps>,
|
|
5
|
+
{
|
|
6
|
+
width: number
|
|
7
|
+
height: number
|
|
8
|
+
}
|
|
9
|
+
>,
|
|
10
|
+
{},
|
|
11
|
+
unknown,
|
|
12
|
+
{},
|
|
13
|
+
{},
|
|
14
|
+
import('vue').ComponentOptionsMixin,
|
|
15
|
+
import('vue').ComponentOptionsMixin,
|
|
16
|
+
{},
|
|
17
|
+
string,
|
|
18
|
+
import('vue').PublicProps,
|
|
19
|
+
Readonly<
|
|
20
|
+
import('vue').ExtractPropTypes<
|
|
21
|
+
__VLS_WithDefaults<
|
|
22
|
+
__VLS_TypePropsToOption<LcbLightMapProps>,
|
|
23
|
+
{
|
|
24
|
+
width: number
|
|
25
|
+
height: number
|
|
26
|
+
}
|
|
27
|
+
>
|
|
28
|
+
>
|
|
29
|
+
>,
|
|
30
|
+
{
|
|
31
|
+
width: number
|
|
32
|
+
height: number
|
|
33
|
+
},
|
|
34
|
+
{}
|
|
35
|
+
>
|
|
36
|
+
export default _default
|
|
37
|
+
type __VLS_WithDefaults<P, D> = {
|
|
38
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D
|
|
39
|
+
? __VLS_Prettify<
|
|
40
|
+
P[K] & {
|
|
41
|
+
default: D[K]
|
|
42
|
+
}
|
|
43
|
+
>
|
|
44
|
+
: P[K]
|
|
45
|
+
}
|
|
46
|
+
type __VLS_Prettify<T> = {
|
|
47
|
+
[K in keyof T]: T[K]
|
|
48
|
+
} & {}
|
|
49
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T
|
|
50
|
+
type __VLS_TypePropsToOption<T> = {
|
|
51
|
+
[K in keyof T]-?: {} extends Pick<T, K>
|
|
52
|
+
? {
|
|
53
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>
|
|
54
|
+
}
|
|
55
|
+
: {
|
|
56
|
+
type: import('vue').PropType<T[K]>
|
|
57
|
+
required: true
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { LcbBlockProps } from '../lcb-block/types'
|
|
2
|
+
export interface LcbLightMapProps extends LcbBlockProps {
|
|
3
|
+
width: number
|
|
4
|
+
height: number
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 位置记录接口
|
|
8
|
+
*/
|
|
9
|
+
export interface LocationRecord {
|
|
10
|
+
latitude: number
|
|
11
|
+
longitude: number
|
|
12
|
+
[key: string]: any
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 地图详细配置接口
|
|
16
|
+
*/
|
|
17
|
+
export interface MapDetailConfig {
|
|
18
|
+
boundaries: {
|
|
19
|
+
southwest: {
|
|
20
|
+
latitude: number
|
|
21
|
+
longitude: number
|
|
22
|
+
}
|
|
23
|
+
northeast: {
|
|
24
|
+
latitude: number
|
|
25
|
+
longitude: number
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
physicalSize: {
|
|
29
|
+
xSize: number
|
|
30
|
+
ySize: number
|
|
31
|
+
}
|
|
32
|
+
backgroundImages: {
|
|
33
|
+
default: string
|
|
34
|
+
p30: string
|
|
35
|
+
p60: string
|
|
36
|
+
p80: string
|
|
37
|
+
p100: string
|
|
38
|
+
}
|
|
39
|
+
displaySize?: {
|
|
40
|
+
normal?: {
|
|
41
|
+
width: number
|
|
42
|
+
height: number
|
|
43
|
+
}
|
|
44
|
+
index?: {
|
|
45
|
+
width: number
|
|
46
|
+
height: number
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
dotStyle: {
|
|
50
|
+
width: number
|
|
51
|
+
height: number
|
|
52
|
+
backgroundColor: string
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 地图配置接口
|
|
57
|
+
*/
|
|
58
|
+
export interface LightMapConfig {
|
|
59
|
+
clockLightConfigId: string
|
|
60
|
+
subTitle: string
|
|
61
|
+
title: string
|
|
62
|
+
mapConfig: MapDetailConfig
|
|
63
|
+
}
|
|
64
|
+
export interface MapDetail {
|
|
65
|
+
clockLightConfigId: string
|
|
66
|
+
clockLightProductCountRate: number
|
|
67
|
+
clockLightUserRecordList: LocationRecord[]
|
|
68
|
+
clockLightConfigList: LightMapConfig[]
|
|
69
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { LightMapConfig, LocationRecord } from './types'
|
|
2
|
+
/**
|
|
3
|
+
* 使用 Haversine 公式计算两个经纬度坐标之间的距离
|
|
4
|
+
* @param lat1 起点纬度
|
|
5
|
+
* @param lng1 起点经度
|
|
6
|
+
* @param lat2 终点纬度
|
|
7
|
+
* @param lng2 终点经度
|
|
8
|
+
* @returns 距离(单位:米)
|
|
9
|
+
*/
|
|
10
|
+
export declare const getDistanceByLoc: (
|
|
11
|
+
lat1?: number,
|
|
12
|
+
lng1?: number,
|
|
13
|
+
lat2?: number,
|
|
14
|
+
lng2?: number,
|
|
15
|
+
) => number
|
|
16
|
+
/**
|
|
17
|
+
* 计算位置点相对于地图的百分比位置
|
|
18
|
+
*/
|
|
19
|
+
export declare const getPosition: (
|
|
20
|
+
item: LocationRecord,
|
|
21
|
+
mapConfig: LightMapConfig,
|
|
22
|
+
) => {
|
|
23
|
+
left: number
|
|
24
|
+
bottom: number
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 获取点的完整样式
|
|
28
|
+
*/
|
|
29
|
+
export declare const getDotStyle: (
|
|
30
|
+
item: LocationRecord,
|
|
31
|
+
mapConfig: LightMapConfig,
|
|
32
|
+
) => {
|
|
33
|
+
left: string
|
|
34
|
+
bottom: string
|
|
35
|
+
width: string
|
|
36
|
+
height: string
|
|
37
|
+
backgroundColor: string
|
|
38
|
+
marginLeft: string
|
|
39
|
+
marginBottom: string
|
|
40
|
+
}
|
|
@@ -41,6 +41,10 @@ declare const __VLS_component: import('vue').DefineComponent<
|
|
|
41
41
|
paddingBottom: number
|
|
42
42
|
paddingLeft: number
|
|
43
43
|
paddingRight: number
|
|
44
|
+
marginTop: number
|
|
45
|
+
marginBottom: number
|
|
46
|
+
marginLeft: number
|
|
47
|
+
marginRight: number
|
|
44
48
|
fontSize: number
|
|
45
49
|
fontWeight: number
|
|
46
50
|
topRadius: number
|