xt-element-ui 1.2.8 → 1.3.1

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.
Files changed (47) hide show
  1. package/docs/components/base/xt-map.md +331 -0
  2. package/docs/components/base/xt-step-price.md +103 -217
  3. package/lib/index.common.js +2218 -87
  4. package/lib/index.css +1 -1
  5. package/lib/index.umd.js +2218 -87
  6. package/lib/index.umd.min.js +5 -5
  7. package/package.json +4 -3
  8. package/src/components/ex-button/index.js +8 -2
  9. package/src/components/ex-chart/index.js +6 -0
  10. package/src/components/ex-date-picker/index.js +8 -2
  11. package/src/components/ex-icon/index.js +6 -0
  12. package/src/components/ex-page/index.js +8 -2
  13. package/src/components/ex-select-tree/index.js +8 -2
  14. package/src/components/ex-table/index.js +6 -0
  15. package/src/components/ex-upload/index.js +6 -0
  16. package/src/components/xt-button/index.js +8 -2
  17. package/src/components/xt-button/index.vue +53 -10
  18. package/src/components/xt-button/style/index.scss +147 -43
  19. package/src/components/xt-card/index.js +8 -2
  20. package/src/components/xt-card-item/index.js +8 -2
  21. package/src/components/xt-config-provider/index.js +6 -0
  22. package/src/components/xt-flex-box/index.js +8 -2
  23. package/src/components/xt-flex-box/style/index.scss +0 -9
  24. package/src/components/xt-grid-box/index.js +8 -2
  25. package/src/components/xt-grid-item/index.js +7 -1
  26. package/src/components/xt-input/index.js +8 -2
  27. package/src/components/xt-input/index.vue +66 -37
  28. package/src/components/xt-input/style/index.scss +70 -13
  29. package/src/components/xt-map/adapters/amap.js +235 -0
  30. package/src/components/xt-map/adapters/baidu.js +254 -0
  31. package/src/components/xt-map/adapters/base.js +267 -0
  32. package/src/components/xt-map/adapters/index.js +29 -0
  33. package/src/components/xt-map/adapters/tianditu.js +242 -0
  34. package/src/components/xt-map/config/xt-map-config.js +197 -0
  35. package/src/components/xt-map/index.js +22 -0
  36. package/src/components/xt-map/index.vue +351 -0
  37. package/src/components/xt-map/loaders/script-loader.js +114 -0
  38. package/src/components/xt-map/provider.vue +200 -0
  39. package/src/components/xt-map/style/index.scss +77 -0
  40. package/src/components/xt-step-price/index.js +9 -0
  41. package/src/components/xt-step-price/index.vue +12 -10
  42. package/src/components/xt-step-price/style/index.scss +32 -24
  43. package/src/components/xt-step-price-item/index.js +6 -0
  44. package/src/components/xt-step-price-item/index.vue +13 -9
  45. package/src/components/xt-text/index.js +8 -2
  46. package/src/components/xt-time/index.js +6 -0
  47. package/src/index.js +6 -0
@@ -1,37 +1,66 @@
1
- <template>
2
- <div class="xt-input">
3
- <el-input
4
- :value="value"
5
- :placeholder="placeholder"
6
- :style="inputStyle"
7
- @input="$emit('input', $event)"
8
- />
9
- </div>
10
- </template>
11
-
12
- <script>
13
- export default {
14
- name: 'XtInput',
15
- props: {
16
- value: [String, Number],
17
- placeholder: {
18
- type: String,
19
- default: '请输入内容'
20
- },
21
- color: {
22
- type: String,
23
- default: ''
24
- }
25
- },
26
- computed: {
27
- inputStyle() {
28
- if (this.color) {
29
- return {
30
- '--xt-input-focus-color': this.color
31
- }
32
- }
33
- return {}
34
- }
35
- }
36
- }
37
- </script>
1
+ <template>
2
+ <div
3
+ class="xt-input"
4
+ :class="[
5
+ size ? 'xt-input--' + size : '',
6
+ { 'is-disabled': disabled }
7
+ ]"
8
+ >
9
+ <el-input
10
+ :value="value"
11
+ :placeholder="placeholder"
12
+ :type="type"
13
+ :size="size"
14
+ :disabled="disabled"
15
+ :readonly="readonly"
16
+ :style="inputStyle"
17
+ @input="$emit('input', $event)"
18
+ @change="$emit('change', $event)"
19
+ @focus="$emit('focus', $event)"
20
+ @blur="$emit('blur', $event)"
21
+ />
22
+ </div>
23
+ </template>
24
+
25
+ <script>
26
+ export default {
27
+ name: 'XtInput',
28
+ props: {
29
+ value: [String, Number],
30
+ placeholder: {
31
+ type: String,
32
+ default: '请输入内容'
33
+ },
34
+ type: {
35
+ type: String,
36
+ default: 'text'
37
+ },
38
+ size: {
39
+ type: String,
40
+ default: ''
41
+ },
42
+ disabled: {
43
+ type: Boolean,
44
+ default: false
45
+ },
46
+ readonly: {
47
+ type: Boolean,
48
+ default: false
49
+ },
50
+ color: {
51
+ type: String,
52
+ default: ''
53
+ }
54
+ },
55
+ computed: {
56
+ inputStyle() {
57
+ if (this.color) {
58
+ return {
59
+ '--xt-input-focus-color': this.color
60
+ }
61
+ }
62
+ return {}
63
+ }
64
+ }
65
+ }
66
+ </script>
@@ -1,27 +1,84 @@
1
1
  @import '../../../styles/variables.scss';
2
2
 
3
- .xt-input .el-input__inner {
3
+ // 基础变量定义 - 通过组件顶层设置统一的 CSS 变量
4
+ .xt-input {
5
+ --xt-input-bg-color: var(--xt-fill-color-blank, #ffffff);
6
+ --xt-input-text-color: var(--xt-text-color-regular, #606266);
7
+ --xt-input-border-color: var(--xt-border-color, #dcdfe6);
8
+ --xt-input-border-color-hover: var(--xt-border-color-dark, #c0c4cc);
9
+ --xt-input-border-color-focus: var(--xt-color-primary, #1890ff);
10
+ --xt-input-placeholder-color: var(--xt-text-color-placeholder, #c0c4cc);
11
+ --xt-input-disabled-bg-color: var(--xt-fill-color-light, #f5f7fa);
12
+ --xt-input-disabled-text-color: var(--xt-text-color-placeholder, #c0c4cc);
13
+ --xt-input-disabled-border-color: var(--xt-border-color-light, #e4e7ed);
4
14
  --xt-input-focus-color: var(--xt-color-primary, #1890ff);
5
-
6
- background-color: var(--xt-input-bg-color, #ffffff);
7
- border-color: var(--xt-input-border-color, #DCDFE6);
8
- color: var(--xt-input-text-color, #303133);
9
- font-size: var(--xt-font-size-base, 14px);
15
+ --xt-input-border-radius: var(--xt-border-radius-base, 4px);
16
+ --xt-input-font-size: var(--xt-font-size-base, 14px);
17
+ --xt-input-height: 32px;
18
+ --xt-input-padding-x: 15px;
19
+ }
20
+
21
+ // 尺寸:small
22
+ .xt-input--small {
23
+ --xt-input-height: 28px;
24
+ --xt-input-font-size: var(--xt-font-size-small, 12px);
25
+ --xt-input-padding-x: 10px;
26
+ }
27
+
28
+ // 尺寸:medium(默认,无需单独覆盖)
29
+ .xt-input--medium {
30
+ --xt-input-height: 32px;
31
+ --xt-input-font-size: var(--xt-font-size-base, 14px);
32
+ --xt-input-padding-x: 15px;
33
+ }
34
+
35
+ // 尺寸:large
36
+ .xt-input--large {
37
+ --xt-input-height: 40px;
38
+ --xt-input-font-size: var(--xt-font-size-large, 16px);
39
+ --xt-input-padding-x: 16px;
40
+ }
41
+
42
+ // 内部结构样式(Element UI 2.x 结构)
43
+ .xt-input .el-input {
44
+ height: var(--xt-input-height);
45
+ }
46
+
47
+ .xt-input .el-input__inner {
48
+ background-color: var(--xt-input-bg-color);
49
+ border-color: var(--xt-input-border-color);
50
+ color: var(--xt-input-text-color);
51
+ font-size: var(--xt-input-font-size);
52
+ border-radius: var(--xt-input-border-radius);
53
+ height: var(--xt-input-height);
54
+ line-height: var(--xt-input-height);
55
+ padding: 0 var(--xt-input-padding-x);
56
+ transition: border-color var(--xt-transition-duration-fast, 0.2s) ease;
10
57
  }
11
58
 
12
59
  .xt-input .el-input__inner::placeholder {
13
- color: var(--xt-input-placeholder-color, #C0C4CC);
60
+ color: var(--xt-input-placeholder-color);
14
61
  }
15
62
 
63
+ // hover 状态
64
+ .xt-input .el-input__inner:hover {
65
+ border-color: var(--xt-input-border-color-hover);
66
+ }
67
+
68
+ // focus 状态
16
69
  .xt-input .el-input__inner:focus {
17
- border-color: var(--xt-input-focus-color);
70
+ border-color: var(--xt-input-border-color-focus);
18
71
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--xt-input-focus-color) 20%, transparent);
19
72
  }
20
73
 
21
- .xt-input .el-input {
22
- height: var(--xt-input-height, 32px);
74
+ // disabled 状态
75
+ .xt-input.is-disabled .el-input__inner {
76
+ background-color: var(--xt-input-disabled-bg-color);
77
+ border-color: var(--xt-input-disabled-border-color);
78
+ color: var(--xt-input-disabled-text-color);
79
+ cursor: not-allowed;
23
80
  }
24
81
 
25
- .xt-input .el-input .el-input__wrapper {
26
- padding: 0 var(--xt-input-padding-x, 15px);
27
- }
82
+ .xt-input.is-disabled .el-input__inner::placeholder {
83
+ color: var(--xt-input-disabled-text-color);
84
+ }
@@ -0,0 +1,235 @@
1
+ /**
2
+ * 高德地图适配器 (AMap)
3
+ * 以高德为基准,所有 xt-map 枚举直接映射
4
+ */
5
+
6
+ import { MapAdapterBase } from './base'
7
+ import { hasGlobal } from '../loaders/script-loader'
8
+
9
+ const A_MAP_MAP_TYPES = {
10
+ standard: 'amap', // 标准/矢量
11
+ satellite: 'satellite', // 卫星
12
+ hybrid: 'satellite', // 混合(卫星+路网,用卫星+路网图层组合实现)
13
+ traffic: 'traffic' // 实时路况(叠加在 standard 上)
14
+ }
15
+
16
+ // 高德地图样式 ID(主题映射)
17
+ const A_MAP_STYLES = {
18
+ light: 'amap://styles/normal',
19
+ dark: 'amap://styles/dark'
20
+ }
21
+
22
+ export class AMapAdapter extends MapAdapterBase {
23
+ constructor(container, options = {}) {
24
+ super(container, options)
25
+ this._mapTypeMap = { ...A_MAP_MAP_TYPES }
26
+ this._trafficLayer = null // 路况图层引用
27
+ this._satelliteLayer = null // 卫星图层
28
+ this._roadnetLayer = null // 路网图层(用于 hybrid)
29
+ this._currentLayers = [] // 当前叠加图层
30
+ }
31
+
32
+ getScriptUrl() {
33
+ if (this.apiUrl) return this.apiUrl
34
+ if (!this.apiKey) {
35
+ console.warn('[XtMap] 高德地图需要配置 apiKey')
36
+ return ''
37
+ }
38
+ // 高德 2.0 Web API
39
+ return `https://webapi.amap.com/maps?v=2.0&key=${encodeURIComponent(this.apiKey)}&plugin=AMap.Scale,AMap.ToolBar`
40
+ }
41
+
42
+ /**
43
+ * 脚本加载前设置高德 2.0 安全密钥
44
+ */
45
+ beforeLoadScript() {
46
+ const securityJsCode = this.options.securityJsCode || (typeof window !== 'undefined' && window._AMapSecurityConfig && window._AMapSecurityConfig.securityJsCode) || ''
47
+ if (securityJsCode && typeof window !== 'undefined') {
48
+ window._AMapSecurityConfig = {
49
+ securityJsCode: securityJsCode
50
+ }
51
+ }
52
+ }
53
+
54
+ isSdkLoaded() {
55
+ return hasGlobal('AMap') && typeof window.AMap === 'function'
56
+ }
57
+
58
+ async createMap() {
59
+ const AMap = window.AMap
60
+ if (!AMap) throw new Error('[XtMap] 高德地图 SDK 未加载')
61
+
62
+ const mapOptions = {
63
+ center: this.center,
64
+ zoom: this.zoom,
65
+ mapStyle: A_MAP_STYLES[this.theme] || A_MAP_STYLES.light,
66
+ viewMode: '2D',
67
+ resizeEnable: true
68
+ }
69
+
70
+ this.mapInstance = new AMap.Map(this.container, mapOptions)
71
+
72
+ // 应用地图类型
73
+ this._applyMapType(this.mapType)
74
+
75
+ // 绑定事件(延迟到地图就绪后)
76
+ await new Promise((resolve) => {
77
+ this.mapInstance.on('complete', () => resolve())
78
+ // 兜底:1秒后强制 resolve
79
+ setTimeout(resolve, 1500)
80
+ })
81
+
82
+ // 重新绑定已注册事件
83
+ for (const [eventName, handler] of this.eventHandlers.entries()) {
84
+ this._bindEvent(eventName, handler)
85
+ }
86
+ }
87
+
88
+ _applyMapType(type) {
89
+ if (!this.mapInstance) return
90
+ const AMap = window.AMap
91
+ if (!AMap) return
92
+
93
+ // 清除所有叠加图层
94
+ this._clearLayers()
95
+
96
+ try {
97
+ // 设置底图样式
98
+ this.mapInstance.setMapStyle(A_MAP_STYLES[this.theme] || A_MAP_STYLES.light)
99
+
100
+ if (type === 'satellite') {
101
+ this._satelliteLayer = new AMap.TileLayer.Satellite()
102
+ this.mapInstance.add(this._satelliteLayer)
103
+ this._currentLayers.push(this._satelliteLayer)
104
+ } else if (type === 'hybrid') {
105
+ // 卫星 + 路网
106
+ this._satelliteLayer = new AMap.TileLayer.Satellite()
107
+ this._roadnetLayer = new AMap.TileLayer.RoadNet()
108
+ this.mapInstance.add([this._satelliteLayer, this._roadnetLayer])
109
+ this._currentLayers.push(this._satelliteLayer, this._roadnetLayer)
110
+ } else if (type === 'traffic') {
111
+ // 路况图层叠加在 standard 上
112
+ this._trafficLayer = new AMap.TileLayer.Traffic({
113
+ autoRefresh: true,
114
+ interval: 180
115
+ })
116
+ this.mapInstance.add(this._trafficLayer)
117
+ this._currentLayers.push(this._trafficLayer)
118
+ }
119
+ } catch (e) {
120
+ console.warn('[XtMap] 设置地图类型失败:', e)
121
+ }
122
+ }
123
+
124
+ _clearLayers() {
125
+ if (!this.mapInstance) return
126
+ try {
127
+ if (this._currentLayers.length > 0) {
128
+ this.mapInstance.remove(this._currentLayers)
129
+ }
130
+ } catch (e) {
131
+ // 忽略
132
+ }
133
+ this._currentLayers = []
134
+ this._trafficLayer = null
135
+ this._satelliteLayer = null
136
+ this._roadnetLayer = null
137
+ }
138
+
139
+ _applyTheme(theme) {
140
+ if (!this.mapInstance) return
141
+ try {
142
+ this.mapInstance.setMapStyle(A_MAP_STYLES[theme] || A_MAP_STYLES.light)
143
+ // 主题变更可能影响图层显示,重新应用地图类型
144
+ this._applyMapType(this.mapType)
145
+ } catch (e) {
146
+ console.warn('[XtMap] 设置主题失败:', e)
147
+ }
148
+ }
149
+
150
+ _applyCenter(center) {
151
+ if (!this.mapInstance) return
152
+ try {
153
+ this.mapInstance.setCenter(center)
154
+ } catch (e) {
155
+ // 忽略
156
+ }
157
+ }
158
+
159
+ _applyZoom(zoom) {
160
+ if (!this.mapInstance) return
161
+ try {
162
+ this.mapInstance.setZoom(zoom)
163
+ } catch (e) {
164
+ // 忽略
165
+ }
166
+ }
167
+
168
+ getCenter() {
169
+ if (this.mapInstance && this.mapInstance.getCenter) {
170
+ const c = this.mapInstance.getCenter()
171
+ return [c.lng, c.lat]
172
+ }
173
+ return this.center
174
+ }
175
+
176
+ getZoom() {
177
+ if (this.mapInstance && this.mapInstance.getZoom) {
178
+ return this.mapInstance.getZoom()
179
+ }
180
+ return this.zoom
181
+ }
182
+
183
+ _bindEvent(eventName, handler) {
184
+ if (!this.mapInstance) return
185
+ try {
186
+ // 统一事件名映射
187
+ const eventMap = {
188
+ click: 'click',
189
+ moveend: 'moveend',
190
+ zoomend: 'zoomend',
191
+ zoomchange: 'zoomchange',
192
+ mapmove: 'mapmove',
193
+ complete: 'complete',
194
+ resize: 'resize'
195
+ }
196
+ const nativeEvent = eventMap[eventName] || eventName
197
+ this.mapInstance.on(nativeEvent, (e) => {
198
+ // 统一事件参数格式
199
+ const normalized = {
200
+ originalEvent: e,
201
+ lnglat: e && e.lnglat ? [e.lnglat.lng, e.lnglat.lat] : null
202
+ }
203
+ handler(normalized)
204
+ })
205
+ } catch (err) {
206
+ console.warn('[XtMap] 事件绑定失败:', eventName, err)
207
+ }
208
+ }
209
+
210
+ _unbindEvent(eventName, handler) {
211
+ if (!this.mapInstance) return
212
+ try {
213
+ this.mapInstance.off(eventName, handler)
214
+ } catch (e) {
215
+ // 忽略
216
+ }
217
+ }
218
+
219
+ _applyResize() {
220
+ if (this.mapInstance && this.mapInstance.resize) {
221
+ try {
222
+ this.mapInstance.resize()
223
+ } catch (e) {
224
+ // 忽略
225
+ }
226
+ }
227
+ }
228
+
229
+ destroy() {
230
+ this._clearLayers()
231
+ super.destroy()
232
+ }
233
+ }
234
+
235
+ export default AMapAdapter
@@ -0,0 +1,254 @@
1
+ /**
2
+ * 百度地图适配器 (BMap / Baidu)
3
+ * 百度地图 JS API 3.0 支持自定义样式
4
+ */
5
+
6
+ import { MapAdapterBase } from './base'
7
+ import { hasGlobal } from '../loaders/script-loader'
8
+
9
+ // 百度地图类型映射
10
+ const BAIDU_MAP_TYPES = {
11
+ standard: 'BMAP_NORMAL_MAP',
12
+ satellite: 'BMAP_SATELLITE_MAP',
13
+ hybrid: 'BMAP_HYBRID_MAP',
14
+ traffic: 'BMAP_NORMAL_MAP' // 路况通过图层叠加
15
+ }
16
+
17
+ // 百度地图自定义样式 ID(主题)
18
+ // light: 官方 normal 样式
19
+ // dark: 午夜蓝 dark 样式
20
+ const BAIDU_STYLES = {
21
+ light: { style: 'normal' },
22
+ dark: { style: 'dark' }
23
+ }
24
+
25
+ export class BaiduAdapter extends MapAdapterBase {
26
+ constructor(container, options = {}) {
27
+ super(container, options)
28
+ this._mapTypeMap = { ...BAIDU_MAP_TYPES }
29
+ this._coordType = options.baiduCoordType || 'bd09ll'
30
+ this._trafficLayer = null
31
+ this._callbackName = null
32
+ }
33
+
34
+ getScriptUrl() {
35
+ if (this.apiUrl) return this.apiUrl
36
+ if (!this.apiKey) {
37
+ console.warn('[XtMap] 百度地图需要配置 apiKey (ak)')
38
+ return ''
39
+ }
40
+ // 注意:_callbackName 在 beforeLoadScript 中已注册
41
+ return `https://api.map.baidu.com/api?v=3.0&ak=${encodeURIComponent(this.apiKey)}&callback=${this._callbackName}`
42
+ }
43
+
44
+ /**
45
+ * 脚本加载前注册百度 SDK 回调函数
46
+ */
47
+ beforeLoadScript() {
48
+ // 生成唯一 callback 名称,支持多实例
49
+ this._callbackName = `__xt_map_baidu_${Date.now()}_${Math.floor(Math.random() * 100000)}`
50
+ // 注册全局 callback(百度地图 SDK 加载完成后调用)
51
+ if (typeof window !== 'undefined') {
52
+ window[this._callbackName] = () => {
53
+ // 空实现,仅用于触发 Promise resolve
54
+ }
55
+ }
56
+ }
57
+
58
+ isSdkLoaded() {
59
+ return hasGlobal('BMap') && typeof window.BMap === 'function'
60
+ }
61
+
62
+ async createMap() {
63
+ const BMap = window.BMap
64
+ if (!BMap) throw new Error('[XtMap] 百度地图 SDK 未加载')
65
+
66
+ const mapOptions = {
67
+ enableMapClick: false
68
+ }
69
+
70
+ this.mapInstance = new BMap.Map(this.container, mapOptions)
71
+ this.mapInstance.centerAndZoom(new BMap.Point(this.center[0], this.center[1]), this.zoom)
72
+ this.mapInstance.enableScrollWheelZoom(true)
73
+
74
+ // 应用地图类型
75
+ this._applyMapType(this.mapType)
76
+
77
+ // 应用主题
78
+ this._applyTheme(this.theme)
79
+
80
+ // 等待地图就绪
81
+ await new Promise((resolve) => setTimeout(resolve, 500))
82
+
83
+ for (const [eventName, handler] of this.eventHandlers.entries()) {
84
+ this._bindEvent(eventName, handler)
85
+ }
86
+ }
87
+
88
+ _applyMapType(type) {
89
+ if (!this.mapInstance || !window.BMap) return
90
+
91
+ try {
92
+ // 清除路况图层
93
+ if (this._trafficLayer) {
94
+ try {
95
+ this.mapInstance.removeTileLayer(this._trafficLayer)
96
+ } catch (e) {}
97
+ this._trafficLayer = null
98
+ }
99
+
100
+ if (type === 'satellite') {
101
+ this.mapInstance.setMapType(window.BMAP_SATELLITE_MAP || 1)
102
+ } else if (type === 'hybrid') {
103
+ this.mapInstance.setMapType(window.BMAP_HYBRID_MAP || 2)
104
+ } else if (type === 'traffic') {
105
+ this.mapInstance.setMapType(window.BMAP_NORMAL_MAP || 0)
106
+ // 叠加路况图层
107
+ try {
108
+ const BMap = window.BMap
109
+ this._trafficLayer = new BMap.TrafficLayer()
110
+ this.mapInstance.addTileLayer(this._trafficLayer)
111
+ } catch (e) {
112
+ console.warn('[XtMap] 百度地图加载路况图层失败:', e)
113
+ }
114
+ } else {
115
+ this.mapInstance.setMapType(window.BMAP_NORMAL_MAP || 0)
116
+ }
117
+ } catch (e) {
118
+ console.warn('[XtMap] 百度地图切换地图类型失败:', e)
119
+ }
120
+ }
121
+
122
+ _applyTheme(theme) {
123
+ if (!this.mapInstance || !window.BMap) return
124
+ try {
125
+ // 百度 3.0 通过 setMapStyle 设置主题样式
126
+ const styleConfig = BAIDU_STYLES[theme] || BAIDU_STYLES.light
127
+ if (this.mapInstance.setMapStyleV2) {
128
+ // 新版 API
129
+ this.mapInstance.setMapStyleV2({ styleId: styleConfig.style === 'dark' ? 'midnight' : '' })
130
+ } else if (this.mapInstance.setMapStyle) {
131
+ // 旧版 API
132
+ const styleJson = theme === 'dark' ? this._getDarkStyleJson() : null
133
+ if (styleJson) {
134
+ this.mapInstance.setMapStyle({ styleJson: styleJson })
135
+ }
136
+ }
137
+ } catch (e) {
138
+ console.warn('[XtMap] 百度地图设置主题失败:', e)
139
+ }
140
+ }
141
+
142
+ /**
143
+ * 简易百度地图 dark 样式 JSON 配置
144
+ */
145
+ _getDarkStyleJson() {
146
+ return [
147
+ { featureType: 'land', elementType: 'geometry', stylers: { color: '#1a1a1a' } },
148
+ { featureType: 'water', elementType: 'geometry', stylers: { color: '#0a1a2a' } },
149
+ { featureType: 'green', elementType: 'geometry', stylers: { color: '#0a2a1a' } },
150
+ { featureType: 'building', elementType: 'geometry', stylers: { color: '#2a2a2a' } },
151
+ { featureType: 'highway', elementType: 'geometry', stylers: { color: '#3a3a3a' } },
152
+ { featureType: 'highway', elementType: 'geometry.stroke', stylers: { color: '#4a4a4a' } },
153
+ { featureType: 'arterial', elementType: 'geometry', stylers: { color: '#333333' } },
154
+ { featureType: 'arterial', elementType: 'geometry.stroke', stylers: { color: '#3d3d3d' } },
155
+ { featureType: 'local', elementType: 'geometry', stylers: { color: '#2a2a2a' } },
156
+ { featureType: 'railway', elementType: 'geometry', stylers: { color: '#3a3a3a' } },
157
+ { featureType: 'subway', elementType: 'geometry', stylers: { color: '#3a3a3a' } },
158
+ { featureType: 'boundary', elementType: 'geometry', stylers: { color: '#666666' } },
159
+ { featureType: 'district', elementType: 'labels.text.fill', stylers: { color: '#888888' } },
160
+ { featureType: 'poi', elementType: 'labels', stylers: { visibility: 'off' } }
161
+ ]
162
+ }
163
+
164
+ _applyCenter(center) {
165
+ if (!this.mapInstance || !window.BMap) return
166
+ try {
167
+ this.mapInstance.centerAndZoom(new window.BMap.Point(center[0], center[1]), this.zoom)
168
+ } catch (e) {
169
+ // 忽略
170
+ }
171
+ }
172
+
173
+ _applyZoom(zoom) {
174
+ if (!this.mapInstance) return
175
+ try {
176
+ this.mapInstance.setZoom(zoom)
177
+ } catch (e) {
178
+ // 忽略
179
+ }
180
+ }
181
+
182
+ getCenter() {
183
+ if (this.mapInstance && this.mapInstance.getCenter) {
184
+ const c = this.mapInstance.getCenter()
185
+ if (c) return [c.lng, c.lat]
186
+ }
187
+ return this.center
188
+ }
189
+
190
+ getZoom() {
191
+ if (this.mapInstance && this.mapInstance.getZoom) {
192
+ return this.mapInstance.getZoom()
193
+ }
194
+ return this.zoom
195
+ }
196
+
197
+ _bindEvent(eventName, handler) {
198
+ if (!this.mapInstance) return
199
+ try {
200
+ const eventMap = {
201
+ click: 'click',
202
+ moveend: 'moveend',
203
+ zoomend: 'zoomend',
204
+ zoomchange: 'zoomend',
205
+ mapmove: 'movestart'
206
+ }
207
+ const nativeEvent = eventMap[eventName] || eventName
208
+ this.mapInstance.addEventListener(nativeEvent, (e) => {
209
+ const normalized = {
210
+ originalEvent: e,
211
+ lnglat: e && e.point ? [e.point.lng, e.point.lat] : null
212
+ }
213
+ handler(normalized)
214
+ })
215
+ } catch (err) {
216
+ console.warn('[XtMap] 百度地图事件绑定失败:', eventName, err)
217
+ }
218
+ }
219
+
220
+ _unbindEvent(eventName, handler) {
221
+ if (!this.mapInstance) return
222
+ try {
223
+ this.mapInstance.removeEventListener(eventName, handler)
224
+ } catch (e) {
225
+ // 忽略
226
+ }
227
+ }
228
+
229
+ _applyResize() {
230
+ if (this.mapInstance && this.mapInstance.enableResize) {
231
+ try {
232
+ // 百度地图默认启用 resize,无需手动调用
233
+ if (typeof this.mapInstance.checkResize === 'function') {
234
+ this.mapInstance.checkResize()
235
+ }
236
+ } catch (e) {
237
+ // 忽略
238
+ }
239
+ }
240
+ }
241
+
242
+ destroy() {
243
+ if (this._callbackName && typeof window !== 'undefined') {
244
+ try {
245
+ delete window[this._callbackName]
246
+ } catch (e) {
247
+ // 忽略
248
+ }
249
+ }
250
+ super.destroy()
251
+ }
252
+ }
253
+
254
+ export default BaiduAdapter