@cloudbase/weda-ui-mp 3.29.0 → 3.30.0

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.
@@ -0,0 +1,156 @@
1
+ import * as echarts from '../chart/common/lib/echarts.min';
2
+ import { commonCompBehavior } from '../../utils/common-behavior';
3
+ import equal from '../../utils/deepEqual';
4
+
5
+ Component({
6
+ options: {
7
+ virtualHost: true,
8
+ multipleSlots: true,
9
+ },
10
+ behaviors: [commonCompBehavior],
11
+ properties: {
12
+ id: {
13
+ type: String,
14
+ value: '',
15
+ },
16
+ className: {
17
+ type: String,
18
+ value: '',
19
+ },
20
+ style: {
21
+ type: String,
22
+ value: '',
23
+ },
24
+ option: {
25
+ type: Object,
26
+ value: {},
27
+ },
28
+ dark: {
29
+ type: Boolean,
30
+ value: false,
31
+ },
32
+ opts: {
33
+ type: Object,
34
+ value: {},
35
+ },
36
+ },
37
+ data: {
38
+ ec: {},
39
+ echarts: null,
40
+ _prevOption: null,
41
+ _prevDark: null,
42
+ _theme: null, // 通过 setTheme API 设置的主题,优先级高于 dark 属性
43
+ },
44
+ lifetimes: {
45
+ attached() {
46
+ // 在组件实例进入页面节点树时执行
47
+ this.initData();
48
+ this.updateWidgetAPI();
49
+ },
50
+ detached() {
51
+ // 在组件实例被从页面节点树移除时执行
52
+ },
53
+ },
54
+ methods: {
55
+ updateWidgetAPI() {
56
+ const that = this;
57
+ this.setReadonlyAttributes &&
58
+ this.setReadonlyAttributes({
59
+ setOption(params) {
60
+ if (that._chart && params) {
61
+ that._chart.setOption(params.option, params.opts);
62
+ }
63
+ },
64
+ setTheme(opts) {
65
+ // 切换主题需要 dispose 后重新 init
66
+ // theme 可能是 'dark'、'light' 等字符串,与 dark 属性是两种设置方式
67
+ if (opts?.theme !== undefined) {
68
+ that._setTheme(opts.theme);
69
+ }
70
+ },
71
+ echarts: that.data.echarts,
72
+ echartsInstance: that._chart,
73
+ });
74
+ },
75
+ initData() {
76
+ this.setData({
77
+ id: this.id,
78
+ ec: {
79
+ onInit: this.initChart.bind(this),
80
+ },
81
+ });
82
+ },
83
+ async initChart(canvas, width, height, dpr) {
84
+ // _theme 优先(通过 setTheme API 设置),否则根据 dark 属性判断
85
+ const theme = this.data._theme !== null ? this.data._theme : this.data.dark ? 'dark' : null;
86
+ const objEchart = echarts.init(canvas, theme, {
87
+ width,
88
+ height,
89
+ devicePixelRatio: dpr,
90
+ });
91
+ canvas.setChart(objEchart);
92
+ const options = this.data.option;
93
+ objEchart.setOption(options, true);
94
+ this._chart = objEchart;
95
+
96
+ this.setData({
97
+ echarts,
98
+ _prevDark: this.data.dark,
99
+ });
100
+
101
+ this.updateWidgetAPI();
102
+ this.triggerEvent('onReady', { echartsInstance: objEchart, echarts });
103
+
104
+ return objEchart;
105
+ },
106
+ // 通过 API 设置主题
107
+ _setTheme(theme) {
108
+ // 检查是否真正变化
109
+ if (this.data._theme === theme) {
110
+ return;
111
+ }
112
+ this.setData({ _theme: theme });
113
+ // 切换主题需要 dispose 后重新 init
114
+ if (this._chart) {
115
+ this._chart.dispose();
116
+ this._chart = null;
117
+ const canvas = this.selectComponent(`#canvas_${this.properties.id}`);
118
+ canvas?.init();
119
+ }
120
+ },
121
+ },
122
+ observers: {
123
+ // 当 option 变化时
124
+ option: async function (option) {
125
+ // 检查数据是否真正变化
126
+ const prevOption = this.data._prevOption;
127
+ if (prevOption && equal(option, prevOption)) {
128
+ return;
129
+ }
130
+ this.setData({ _prevOption: option });
131
+
132
+ const canvas = this.selectComponent(`#canvas_${this.properties.id}`);
133
+ canvas?.init();
134
+ this._chart && this._chart.setOption(option, true);
135
+ },
136
+ dark: function (dark) {
137
+ // 检查是否真正变化,避免初始化时重复触发
138
+ if (this.data._prevDark === dark) {
139
+ return;
140
+ }
141
+ this.setData({ _prevDark: dark });
142
+ // 如果已通过 setTheme API 设置主题,则 dark 属性不生效
143
+ if (this.data._theme !== null) {
144
+ return;
145
+ }
146
+ // 切换主题需要 dispose 后重新 init
147
+ if (this._chart) {
148
+ this._chart.dispose();
149
+ this._chart = null;
150
+ // 重新初始化
151
+ const canvas = this.selectComponent(`#canvas_${this.properties.id}`);
152
+ canvas?.init();
153
+ }
154
+ },
155
+ },
156
+ });
@@ -0,0 +1,6 @@
1
+ {
2
+ "component": true,
3
+ "usingComponents": {
4
+ "ec-canvas": "../chart/ec-canvas/ec-canvas"
5
+ }
6
+ }
@@ -0,0 +1 @@
1
+ <view wx:if="ec" class="{{className}} ec_container" style="{{style}}" id="{{id}}"> <ec-canvas id="{{'canvas_'+id}}" canvasId="{{'canvas_'+id}}" ec="{{ ec }}" /> </view>
@@ -0,0 +1,9 @@
1
+ /**index.wxss**/
2
+ ec-canvas {
3
+ width: 100%;
4
+ height: 100%;
5
+ }
6
+ .ec_container {
7
+ width: 100%;
8
+ height: 380px;
9
+ }
@@ -1,8 +1,36 @@
1
- import { callDataSource } from '../../../utils/tcb';
1
+ import { callDataSource, getOpenApi } from '../../../utils/tcb';
2
2
  import classNames from '../../../utils/classnames';
3
3
  import customInfo from '../../../utils/getCustomInfo';
4
4
  import { errorHandler } from '../../../utils/error';
5
5
 
6
+ /**
7
+ * 通过 APIs 连接器获取 API Key (qqmapV2)
8
+ * @param {string} userAPIsID - APIs 连接器 ID
9
+ * @returns {Promise<string>} API Key
10
+ */
11
+ function getApiKeyByOpenApi(userAPIsID) {
12
+ return getOpenApi({ userAPIsID, path: '/getApiKey' }, true).then((res) => {
13
+ if (!res?.result?.apiKey) {
14
+ throw new Error(JSON.stringify(res));
15
+ }
16
+ return res.result.apiKey;
17
+ });
18
+ }
19
+
20
+ /**
21
+ * 通过数据源获取 API Key
22
+ * @param {string} dataSourceName - 数据源名称
23
+ * @returns {Promise<string>} API Key
24
+ */
25
+ function getApiKeyByDataSource(dataSourceName) {
26
+ return callDataSource({ dataSourceName, methodName: 'getApiKey' }).then((res) => {
27
+ if (!res?.apiKey) {
28
+ throw new Error(JSON.stringify(res));
29
+ }
30
+ return res.apiKey;
31
+ });
32
+ }
33
+
6
34
  // eslint-disable-next-line @typescript-eslint/no-var-requires
7
35
  let QQMapWX = require('../../../utils/qqmap-wx-jssdk1.2/qqmap-wx-jssdk');
8
36
  let qqmapsdk;
@@ -107,7 +135,7 @@ Component({
107
135
  const { locationType, dataSource } = this.properties;
108
136
  const getReverseGeocoder = async (location) => {
109
137
  const { isApikeyStatus } = this.data;
110
- let key = isApikeyStatus.apiKey ? isApikeyStatus.apiKey : await this.getApikey(dataSource.name, 'get');
138
+ let key = isApikeyStatus.apiKey ? isApikeyStatus.apiKey : await this.getApikey(dataSource, 'get');
111
139
  if (key) {
112
140
  qqmapsdk = new QQMapWX({
113
141
  key: key,
@@ -262,7 +290,7 @@ Component({
262
290
  }
263
291
  // 获取腾讯地图apikey
264
292
  if (dataSource?.name) {
265
- this.getApikey(dataSource.name);
293
+ this.getApikey(dataSource);
266
294
  } else {
267
295
  this.setData({
268
296
  isApikeyStatus: {
@@ -311,9 +339,9 @@ Component({
311
339
  * 组件的方法列表
312
340
  */
313
341
  methods: {
314
- async getApikey(dataSourceName, type) {
342
+ async getApikey(dataSource, type) {
315
343
  try {
316
- if (!dataSourceName) {
344
+ if (!dataSource?.name) {
317
345
  this.setData({
318
346
  isApikeyStatus: {
319
347
  status: false,
@@ -323,19 +351,21 @@ Component({
323
351
  });
324
352
  return;
325
353
  }
326
- const res = await callDataSource({
327
- dataSourceName: dataSourceName,
328
- methodName: 'getApiKey',
329
- });
330
- if (res.apiKey) {
354
+
355
+ const apiKey =
356
+ dataSource.templateCode === 'qqmapV2'
357
+ ? await getApiKeyByOpenApi(dataSource.name)
358
+ : await getApiKeyByDataSource(dataSource.name);
359
+
360
+ if (apiKey) {
331
361
  if (type === 'get') {
332
- return res.apiKey;
362
+ return apiKey;
333
363
  }
334
364
  this.setData({
335
365
  isApikeyStatus: {
336
366
  status: true,
337
367
  message: '',
338
- apiKey: res.apiKey,
368
+ apiKey: apiKey,
339
369
  },
340
370
  });
341
371
  }
@@ -445,9 +475,9 @@ Component({
445
475
  wx.openLocation({
446
476
  latitude: e.detail.latitude,
447
477
  longitude: e.detail.longitude,
448
- scale: 18
478
+ scale: 18,
449
479
  });
450
- }
480
+ },
451
481
  },
452
482
  observers: {
453
483
  value: function (value) {
@@ -456,7 +486,7 @@ Component({
456
486
  this.setData({
457
487
  currentLocations: {},
458
488
  location: {},
459
- isAddrShow: false
489
+ isAddrShow: false,
460
490
  });
461
491
  return;
462
492
  }
@@ -106,13 +106,14 @@ Component({
106
106
  const counter = typeof currentInputValue === 'string' ? currentInputValue.length : 0;
107
107
  this.setData({ _hasClearIcon, counter });
108
108
  },
109
- 'disabled,size,classRoot,wrapClassName,before,after': function (
109
+ 'disabled,size,classRoot,wrapClassName,before,after,isFocus': function (
110
110
  disabled,
111
111
  size,
112
112
  classRoot,
113
113
  wrapClassName,
114
114
  before,
115
115
  after,
116
+ isFocus,
116
117
  ) {
117
118
  const _size = convertSize(size);
118
119
  const iconSize = convertIconSize(_size);
@@ -132,6 +133,7 @@ Component({
132
133
  [`${inputWrap}--no-radius-left`]: before,
133
134
  [`${inputWrap}--no-radius-right`]: after,
134
135
  [`${inputWrap}--no-radius`]: before && after,
136
+ 'is-focused': isFocus,
135
137
  },
136
138
  );
137
139
  const countCls = `${classPrefix}-input__limit-number`;
@@ -209,8 +209,8 @@
209
209
  }
210
210
 
211
211
  .weda-modal-new {
212
- padding-bottom: constant(safe-area-inset-bottom);
212
+ padding-bottom: max(constant(safe-area-inset-bottom, 0px), 48rpx);
213
213
  /* 兼容 iOS < 11.2 */
214
- padding-bottom: env(safe-area-inset-bottom);
214
+ padding-bottom: max(env(safe-area-inset-bottom, 0px), 48rpx);
215
215
  /* 兼容 iOS >= 11.2 */
216
216
  }
package/index.json CHANGED
@@ -126,7 +126,8 @@
126
126
  "WdUploadFile": "components/wd-upload-file/index",
127
127
  "WdCalendar": "components/wd-calendar/index",
128
128
  "WdTag": "components/wd-tag/index",
129
- "WdTagSelect": "components/wd-tag-select/index"
129
+ "WdTagSelect": "components/wd-tag-select/index",
130
+ "ECharts": "components/echart/index"
130
131
  },
131
132
  "actions": {
132
133
  "showToast": "actions/showToast/index",
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "miniprogram": "./",
4
4
  "packageManager": "yarn@3.0.2",
5
5
  "dependencies": {},
6
- "version": "3.29.0",
6
+ "version": "3.30.0",
7
7
  "main": "./",
8
8
  "publishConfig": {
9
9
  "access": "public"
package/utils/tcb.js CHANGED
@@ -184,3 +184,36 @@ export const getDefaultUploadPath = async (uploadPath) => {
184
184
  const _uploadPath = WeAppName ? `${uploadPath}/${WeAppName}` : uploadPath;
185
185
  return _uploadPath;
186
186
  };
187
+
188
+ /**
189
+ * 开放APIs 查询 (apis v2)
190
+ * @param param.userAPIsID - APIs 连接器 ID
191
+ * @param param.path - 请求路径
192
+ * @param param.method - 请求方法,默认 'get'
193
+ * @param param.data - 请求数据(可选)
194
+ * @param param.headers - 请求头(可选)
195
+ * @param throwError - 是否抛出错误,默认 false
196
+ */
197
+ export async function getOpenApi(param, throwError = false) {
198
+ const { userAPIsID, path, method = 'get', data, headers } = param;
199
+
200
+ try {
201
+ const app = await getCloudInstance();
202
+ if (!app?.apis?.[userAPIsID]) {
203
+ throw new Error(`APIs connector "${userAPIsID}" not found`);
204
+ }
205
+
206
+ const result = await app.apis[userAPIsID].request({
207
+ method,
208
+ path,
209
+ ...(data && { data }),
210
+ ...(headers && { headers }),
211
+ });
212
+
213
+ return result;
214
+ } catch (error) {
215
+ errorHandler({ code: 'GetOpenApi', error });
216
+ if (throwError) throw error;
217
+ return {};
218
+ }
219
+ }