@cloudbase/lowcode-builder 1.8.106 → 1.8.108
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/lib/builder/config/dependencies.d.ts +10 -0
- package/lib/builder/config/dependencies.js +46 -0
- package/lib/builder/config/index.d.ts +1 -0
- package/lib/builder/config/index.js +5 -3
- package/lib/builder/core/index.d.ts +1 -1
- package/lib/builder/core/index.js +13 -13
- package/lib/builder/h5/generate.js +1 -0
- package/lib/builder/mp/BuildContext.d.ts +1 -0
- package/lib/builder/mp/index.d.ts +1 -2
- package/lib/builder/mp/index.js +13 -38
- package/lib/builder/mp/lowcode.js +5 -1
- package/lib/builder/mp/materials.d.ts +2 -3
- package/lib/builder/mp/materials.js +28 -26
- package/lib/builder/mp/mp_config.js +2 -1
- package/lib/builder/mp/util.d.ts +5 -2
- package/lib/builder/mp/util.js +14 -6
- package/lib/builder/mp/wxml.d.ts +3 -1
- package/lib/builder/mp/wxml.js +20 -7
- package/lib/builder.web.js +8 -8
- package/package.json +4 -4
- package/template/html/index.html.ejs +4 -2
- package/template/mp/app/common.js +0 -2
- package/template/mp/app/weapps-api.js +1 -20
- package/template/mp/common/info/index.js +4 -2
- package/template/mp/common/util.js +33 -774
- package/template/mp/common/weapp-page.js +12 -514
- package/template/mp/component/index.js +52 -19
- package/template/mp/component/index.json +1 -1
- package/template/mp/datasources/index.js.tpl +3 -99
- package/template/mp/package.json +4 -15
- package/template/mp/packages/$wd_system/pages/login/index.json +1 -1
- package/template/mp/packages/$wd_system/pages/login/methods/loginByWXPhone.js +6 -3
- package/template/mp/page/index.js +1 -2
- package/template/mp/common/constant.js +0 -1
- package/template/mp/common/data-patch-test.js +0 -60
- package/template/mp/common/data-patch.js +0 -66
- package/template/mp/common/event-emitter.js +0 -124
- package/template/mp/common/flow.js +0 -65
- package/template/mp/common/merge-renderer.js +0 -75
- package/template/mp/common/placeholder/index.js +0 -1
- package/template/mp/common/placeholder/index.json +0 -4
- package/template/mp/common/placeholder/index.wxml +0 -1
- package/template/mp/common/placeholder/index.wxss +0 -1
- package/template/mp/common/query.js +0 -300
- package/template/mp/common/style.js +0 -34
- package/template/mp/common/watch.js +0 -70
- package/template/mp/common/weapp-component.js +0 -289
- package/template/mp/common/widget.js +0 -872
|
@@ -1,511 +1,18 @@
|
|
|
1
1
|
/* eslint-disable no-restricted-syntax */
|
|
2
2
|
'use strict';
|
|
3
|
-
import { generateForContextOfWidget, generateWidgetAPIContext, getWidget } from './widget';
|
|
4
|
-
import { observable, untracked } from 'mobx';
|
|
5
3
|
import { auth } from '@cloudbase/weda-client';
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
import lodashSet from 'lodash.set';
|
|
4
|
+
const { checkAnonymous, __internal__ = {}} = auth;
|
|
5
|
+
const { getAuthConfig, redirectToLogin, getAccessPermission, findLoginPage } = __internal__
|
|
9
6
|
import { getWedaAPI } from '@cloudbase/weda-client'
|
|
10
7
|
|
|
11
8
|
let LOGIN_CONFIG = <%= customLoginConfig %>
|
|
12
9
|
|
|
13
|
-
/**
|
|
14
|
-
* Convert abcWordSnd -> abc-word-snd
|
|
15
|
-
*/
|
|
16
|
-
export function toDash(str) {
|
|
17
|
-
return str.replace(/[A-Z]/g, (upperLetter) => `-${upperLetter.toLowerCase()}`);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function createComputed(funcs, bindContext = null) {
|
|
21
|
-
const computed = {};
|
|
22
|
-
for (const name in funcs) {
|
|
23
|
-
Object.defineProperty(computed, name, {
|
|
24
|
-
get() {
|
|
25
|
-
try {
|
|
26
|
-
return bindContext ? funcs[name].call(bindContext) : funcs[name]();
|
|
27
|
-
} catch (e) {
|
|
28
|
-
console.error('Computed error', e);
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
enumerable: true,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
return computed;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function generateDataContext(widget) {
|
|
38
|
-
const dataContext = {};
|
|
39
|
-
while (widget?._scope) {
|
|
40
|
-
const current = widget;
|
|
41
|
-
// 此处采用代理的方式,是为了可以获取到最新的 _scope.dataContext 防止 dataContext 引用被重新赋值
|
|
42
|
-
if (current?._scope?.id) {
|
|
43
|
-
Object.defineProperty(dataContext, current._scope.id, {
|
|
44
|
-
get() {
|
|
45
|
-
return current?._scope?.dataContext;
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
widget = widget.parent;
|
|
50
|
-
}
|
|
51
|
-
return dataContext;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @param evtListeners
|
|
56
|
-
* @param [options]
|
|
57
|
-
*/
|
|
58
|
-
export function createEventHandlers(
|
|
59
|
-
evtListeners,
|
|
60
|
-
options = {
|
|
61
|
-
looseError: false,
|
|
62
|
-
isComposite: false,
|
|
63
|
-
syncCall: false,
|
|
64
|
-
},
|
|
65
|
-
) {
|
|
66
|
-
const { looseError = false, isComposite = false, syncCall = false } = options;
|
|
67
|
-
const evtHandlers = {};
|
|
68
|
-
function proxyWrapper(target, compareTarget, key) {
|
|
69
|
-
try {
|
|
70
|
-
return new Proxy(target, {
|
|
71
|
-
get(target, p) {
|
|
72
|
-
if (p !== 'id') {
|
|
73
|
-
if (
|
|
74
|
-
(key === 'currentTarget' || key === 'target') &&
|
|
75
|
-
p !== '_userWidget' &&
|
|
76
|
-
target[p] !== compareTarget?.[p]
|
|
77
|
-
) {
|
|
78
|
-
// console.log(`@deprecated event.${key}.${String(p)}`);
|
|
79
|
-
reportEvent(`event.${key}.${String(p)}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return target[p];
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
} catch (e) {
|
|
86
|
-
return target;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
for (const name in evtListeners) {
|
|
90
|
-
const listeners = evtListeners[name];
|
|
91
|
-
evtHandlers[name] = function (event = {}) {
|
|
92
|
-
const { app } = getWedaAPI();
|
|
93
|
-
const self = this;
|
|
94
|
-
const owner = this._getInstance();
|
|
95
|
-
const target = !!event?.target?.id ? getWidget(owner.widgets, event.target.id) : undefined;
|
|
96
|
-
const currentTarget = !!event?.currentTarget?.id ? getWidget(owner.widgets, event.currentTarget.id) : undefined;
|
|
97
|
-
event.target = proxyWrapper(target, target?._userWidget, 'target');
|
|
98
|
-
event.currentTarget = proxyWrapper(currentTarget, currentTarget?._userWidget, 'currentTarget');
|
|
99
|
-
const [prefix = '', trigger] = name.split('$');
|
|
100
|
-
// The page event handler
|
|
101
|
-
const forContext = (!!currentTarget && generateForContextOfWidget(currentTarget)) || {};
|
|
102
|
-
const dataContext = untracked(() => generateDataContext(currentTarget));
|
|
103
|
-
const $w = untracked(() => generateWidgetAPIContext(owner?.__internal__?.$w, currentTarget, forContext));
|
|
104
|
-
|
|
105
|
-
function checkPageActive(pageId, currentPageContext, listener) {
|
|
106
|
-
/**
|
|
107
|
-
* 复合组件自身不中断校验
|
|
108
|
-
*/
|
|
109
|
-
if (isComposite) {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
const { id, __internal__ } = currentPageContext || {};
|
|
113
|
-
if (pageId && id) {
|
|
114
|
-
/**
|
|
115
|
-
* TODO:
|
|
116
|
-
* IOS 设备跳转扫码成功回到当前页调度存在时序问题
|
|
117
|
-
* 成功响应时当前页非 active 状态
|
|
118
|
-
* 取消判断待兼容
|
|
119
|
-
*/
|
|
120
|
-
if (pageId !== id /* || (__internal__ && !__internal__.active)*/) {
|
|
121
|
-
if (!name?.includes?.('onDataChange')) {
|
|
122
|
-
console.error(`Action error: [${name}] 页面生命周期结束,链式调用中断`);
|
|
123
|
-
}
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async function processListener(l) {
|
|
131
|
-
/**
|
|
132
|
-
* 调用前置校验
|
|
133
|
-
* 是否仍可调用方法
|
|
134
|
-
*/
|
|
135
|
-
if (!checkPageActive(owner.id, app.__internal__?.activePage, l)) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
let { args = {}, argsBinds = {} } = l;
|
|
140
|
-
args = { ...args, params: args.params?.map?.(item => { return typeof item === 'object' && item !== null && !Array.isArray(item) ? { ...item } : item }) || [] };
|
|
141
|
-
const nextEventHandles = [
|
|
142
|
-
{
|
|
143
|
-
handlerName: '',
|
|
144
|
-
event: {
|
|
145
|
-
...event,
|
|
146
|
-
originEvent: undefined
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
];
|
|
150
|
-
let error = false;
|
|
151
|
-
const isIfAction = l.sourceKey === 'platform:utils.If';
|
|
152
|
-
const isShowModalAction = l.sourceKey === 'platform:showModal';
|
|
153
|
-
try {
|
|
154
|
-
const resolvedData = mergeDynamic2StaticData(args, argsBinds, {
|
|
155
|
-
$w,
|
|
156
|
-
forContext,
|
|
157
|
-
codeContext: {
|
|
158
|
-
instance: owner,
|
|
159
|
-
event,
|
|
160
|
-
},
|
|
161
|
-
dataContext,
|
|
162
|
-
});
|
|
163
|
-
let res = await l.handler.call(owner, { event, data: resolvedData.params?.[0], args: resolvedData.params || [], $w });
|
|
164
|
-
nextEventHandles[0].handlerName =
|
|
165
|
-
prefix && l.key ? `${prefix}$${l.key}${!isIfAction || res ? '_success' : '_fail'}` : '';
|
|
166
|
-
nextEventHandles[0].event.detail = isIfAction ? event.detail : res;
|
|
167
|
-
if (isShowModalAction) {
|
|
168
|
-
let handlerName = '';
|
|
169
|
-
|
|
170
|
-
if (res.cancel) {
|
|
171
|
-
handlerName = `${prefix}$${l.key}_cancel`;
|
|
172
|
-
} else if (res.confirm) {
|
|
173
|
-
handlerName = `${prefix}$${l.key}_confirm`;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (handlerName) {
|
|
177
|
-
nextEventHandles.push({
|
|
178
|
-
handlerName,
|
|
179
|
-
event: {
|
|
180
|
-
...event,
|
|
181
|
-
detail: res,
|
|
182
|
-
originEvent: undefined
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
} catch (e) {
|
|
188
|
-
if (e.message) {
|
|
189
|
-
e._target = `${currentTarget?.id ? `组件${currentTarget?.id}` : ''}[${trigger}事件,响应ID${l.key}]`;
|
|
190
|
-
}
|
|
191
|
-
nextEventHandles[0].handlerName = l.key ? `${prefix}$${l.key}_fail` : '';
|
|
192
|
-
nextEventHandles[0].event.detail = isIfAction ? event.detail : e;
|
|
193
|
-
error = e;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* 调用后置校验
|
|
198
|
-
* 是否触发后置事件
|
|
199
|
-
*/
|
|
200
|
-
if (checkPageActive(owner.id, app.__internal__?.activePage, l)) {
|
|
201
|
-
const nextHandler = nextEventHandles[0];
|
|
202
|
-
|
|
203
|
-
if (!self[nextHandler.handlerName] && error) {
|
|
204
|
-
const message = generateErrorDebugMessage(error) || error.errMsg || ''
|
|
205
|
-
console.error(`Action error:`, message, error?.stack);
|
|
206
|
-
if (!looseError && !/scanCode:fail cancel/.test(message)) {
|
|
207
|
-
if (app.__internal__?.env?.type !== 'production') {
|
|
208
|
-
app.showModal({
|
|
209
|
-
title: `事件响应失败`,
|
|
210
|
-
content: message,
|
|
211
|
-
showCancel: false,
|
|
212
|
-
});
|
|
213
|
-
} else {
|
|
214
|
-
app.showToast({
|
|
215
|
-
icon: 'error',
|
|
216
|
-
title: `事件响应失败`,
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
throw error;
|
|
221
|
-
} else {
|
|
222
|
-
const res = await Promise.all(
|
|
223
|
-
nextEventHandles
|
|
224
|
-
.filter((nextHandler) => self[nextHandler.handlerName])
|
|
225
|
-
.map(async (nextHandler) => {
|
|
226
|
-
return self[nextHandler.handlerName](nextHandler.event);
|
|
227
|
-
}),
|
|
228
|
-
);
|
|
229
|
-
return res.length ? res[res.length - 1] : nextEventHandles[nextEventHandles.length - 1]?.event?.detail;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const promise = Promise.all(
|
|
235
|
-
listeners.map((l) => {
|
|
236
|
-
return processListener(l).then(
|
|
237
|
-
(res) => ({ data: res, error: null }),
|
|
238
|
-
(error) => ({ data: null, error }),
|
|
239
|
-
);
|
|
240
|
-
}),
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
if (syncCall) {
|
|
244
|
-
return promise.then((listenerRes) => {
|
|
245
|
-
const res = [];
|
|
246
|
-
for (const item of listenerRes) {
|
|
247
|
-
if (item.error) {
|
|
248
|
-
throw item.error;
|
|
249
|
-
} else {
|
|
250
|
-
res.push(item.data);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
return res.length ? res[0] : event.detail;
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return evtHandlers;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function generateErrorDebugMessage(error) {
|
|
263
|
-
return `${error?._target ? `${error?._target}:` : ''}${error?.message || ''}`;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export function getDeep(target, key, keySeparator = '.') {
|
|
267
|
-
if (key == null) {
|
|
268
|
-
return target;
|
|
269
|
-
}
|
|
270
|
-
const keys = `${key}`.split(keySeparator);
|
|
271
|
-
while (keys.length > 0 && target != null && target !== undefined) {
|
|
272
|
-
target = target[keys.shift()];
|
|
273
|
-
}
|
|
274
|
-
return keys.length === 0 ? target : undefined;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Touch all props of given object deeply
|
|
279
|
-
*/
|
|
280
|
-
export function touchObj(obj) {
|
|
281
|
-
if (!obj) {
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
if (typeof obj === 'string') {
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
if (Array.isArray(obj)) {
|
|
288
|
-
obj.forEach(touchObj);
|
|
289
|
-
} else if (obj) {
|
|
290
|
-
Object.keys(obj).forEach((key) => touchObj(obj[key]));
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
export function throttle(fn, limit) {
|
|
295
|
-
let lastExecTime = 0;
|
|
296
|
-
let timer = null;
|
|
297
|
-
|
|
298
|
-
function invoke() {
|
|
299
|
-
lastExecTime = Date.now();
|
|
300
|
-
timer = null;
|
|
301
|
-
fn();
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const throttled = function () {
|
|
305
|
-
const idledDuration = Date.now() - lastExecTime;
|
|
306
|
-
if (idledDuration >= limit) {
|
|
307
|
-
if (timer) {
|
|
308
|
-
clearTimeout(timer);
|
|
309
|
-
timer = null;
|
|
310
|
-
}
|
|
311
|
-
invoke();
|
|
312
|
-
} else if (!timer) {
|
|
313
|
-
timer = setTimeout(invoke, limit - idledDuration);
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
|
-
return throttled;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
export function deepEqual(a, b) {
|
|
320
|
-
if (a === b) {
|
|
321
|
-
return true;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
325
|
-
if (a.length !== b.length) {
|
|
326
|
-
return false;
|
|
327
|
-
}
|
|
328
|
-
for (let i = 0; i < a.length; i++) {
|
|
329
|
-
if (!deepEqual(a[i], b[i])) {
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
if (a && b && typeof a === 'object' && typeof b === 'object') {
|
|
337
|
-
const aProps = Object.keys(a);
|
|
338
|
-
const bProps = Object.keys(b);
|
|
339
|
-
if (!deepEqual(aProps, bProps)) {
|
|
340
|
-
return false;
|
|
341
|
-
}
|
|
342
|
-
for (let i = 0; i < aProps.length; i++) {
|
|
343
|
-
const prop = aProps[i];
|
|
344
|
-
if (!deepEqual(a[prop], b[prop])) {
|
|
345
|
-
return false;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
return true;
|
|
349
|
-
}
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
function isObject(value) {
|
|
354
|
-
let type = typeof value;
|
|
355
|
-
return !!value && (type == 'object' || type == 'function');
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
function isIndex(value, length) {
|
|
359
|
-
length = length == null ? 9007199254740991 : length;
|
|
360
|
-
return (
|
|
361
|
-
!!length &&
|
|
362
|
-
(typeof value === 'number' || /^(?:0|[1-9]\d*)$/.test(value)) &&
|
|
363
|
-
value > -1 &&
|
|
364
|
-
value % 1 == 0 &&
|
|
365
|
-
value < length
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
function assignValue(object, key, value) {
|
|
370
|
-
let objValue = object[key];
|
|
371
|
-
if (
|
|
372
|
-
!(Object.hasOwnProperty.call(object, key) && (objValue === value || (objValue !== objValue && value !== value))) ||
|
|
373
|
-
(value === undefined && !(key in object))
|
|
374
|
-
) {
|
|
375
|
-
object[key] = value;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
export function set(object, path, value) {
|
|
380
|
-
if (!isObject(object)) {
|
|
381
|
-
return object;
|
|
382
|
-
}
|
|
383
|
-
path = path.split('.');
|
|
384
|
-
|
|
385
|
-
let index = -1;
|
|
386
|
-
let { length } = path;
|
|
387
|
-
let lastIndex = length - 1;
|
|
388
|
-
let nested = object;
|
|
389
|
-
|
|
390
|
-
while (nested != null && ++index < length) {
|
|
391
|
-
let key = path[index];
|
|
392
|
-
let newValue = value;
|
|
393
|
-
|
|
394
|
-
if (index != lastIndex) {
|
|
395
|
-
let objValue = nested[key];
|
|
396
|
-
newValue = undefined;
|
|
397
|
-
if (newValue === undefined) {
|
|
398
|
-
newValue = isObject(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {};
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
assignValue(nested, key, newValue);
|
|
402
|
-
nested = nested[key];
|
|
403
|
-
}
|
|
404
|
-
return object;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
export function findLoginPage() {
|
|
408
|
-
const { app } = getWedaAPI();
|
|
409
|
-
const { pages = [], loginConfigVersion } = app.__internal__.getConfig();
|
|
410
|
-
const custom = pages.find((item) => item.type === 'login')
|
|
411
|
-
if (loginConfigVersion) {
|
|
412
|
-
return custom || {
|
|
413
|
-
id: 'login',
|
|
414
|
-
packageName: '$wd_system',
|
|
415
|
-
uuid: '$wd_system/login',
|
|
416
|
-
type: 'login'
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
10
|
export function findStatusPage() {
|
|
422
11
|
const { app } = getWedaAPI();
|
|
423
12
|
const { pages = [] } = app.__internal__.getConfig();
|
|
424
13
|
return pages.find((item) => item.type === 'status');
|
|
425
14
|
}
|
|
426
15
|
|
|
427
|
-
let _AUTH_CONFIG_CACHE = null;
|
|
428
|
-
|
|
429
|
-
export async function getAuthConfig() {
|
|
430
|
-
const { app } = getWedaAPI();
|
|
431
|
-
if (_AUTH_CONFIG_CACHE) {
|
|
432
|
-
return _AUTH_CONFIG_CACHE;
|
|
433
|
-
}
|
|
434
|
-
try {
|
|
435
|
-
const res = await app.cloud.callWedaApi({
|
|
436
|
-
action: 'DescribeRuntimeResourceStrategy',
|
|
437
|
-
data: {
|
|
438
|
-
ResourceType: `<%= isAdminPortal? 'modelApp' : 'app'%>`,
|
|
439
|
-
ResourceId: app.id,
|
|
440
|
-
},
|
|
441
|
-
});
|
|
442
|
-
const settingData = {};
|
|
443
|
-
// 云api不支持map只能传字符串,需要转换
|
|
444
|
-
res.forEach((item) => {
|
|
445
|
-
settingData[item.Key] = ['AllowRegister', 'NeedLogin'].includes(item.Key) ? item.Value === '1' : item.Value;
|
|
446
|
-
});
|
|
447
|
-
_AUTH_CONFIG_CACHE = settingData;
|
|
448
|
-
return _AUTH_CONFIG_CACHE;
|
|
449
|
-
} catch (e) {
|
|
450
|
-
return {
|
|
451
|
-
NeedLogin: false,
|
|
452
|
-
RejectStrategy: 'show_warning',
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
let _AUTH_CACHE_MAP = {};
|
|
458
|
-
|
|
459
|
-
async function getAccessPermission(app, appId, packageName = "", pageId) {
|
|
460
|
-
let cacheKey = `${appId}-${pageId}`;
|
|
461
|
-
if (packageName) {
|
|
462
|
-
const matched = packageName.match(/packages\/(.*)$/);
|
|
463
|
-
const subKey = matched?.[1] || packageName
|
|
464
|
-
cacheKey = `${appId}-${subKey}-${pageId}`
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (_AUTH_CACHE_MAP[cacheKey] !== undefined) {
|
|
468
|
-
return _AUTH_CACHE_MAP[cacheKey];
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
const res = await app.cloud.callWedaApi({
|
|
472
|
-
action: 'DescribeResourcesPermission',
|
|
473
|
-
data: {
|
|
474
|
-
ResourceType: `<%= isAdminPortal? 'modelApp' : 'app'%>`,
|
|
475
|
-
ResourceIdList: [cacheKey],
|
|
476
|
-
AppResourceId: appId,
|
|
477
|
-
},
|
|
478
|
-
});
|
|
479
|
-
if (Array.isArray(res)) {
|
|
480
|
-
const resourceInfo = res.find((i) => i.ResourceId === cacheKey);
|
|
481
|
-
const isAccess = !!resourceInfo?.IsAccess;
|
|
482
|
-
|
|
483
|
-
_AUTH_CACHE_MAP[cacheKey] = {
|
|
484
|
-
isAccess,
|
|
485
|
-
roleId: resourceInfo?.RoleId,
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
return _AUTH_CACHE_MAP[cacheKey];
|
|
489
|
-
} else {
|
|
490
|
-
throw new Error(`鉴权接口返回参数不正确 - ${JSON.stringify(res)}`);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
export async function checkAnonymous() {
|
|
495
|
-
let isAnonymous = true;
|
|
496
|
-
try {
|
|
497
|
-
const { accessToken } = await getAccessToken();
|
|
498
|
-
isAnonymous = !accessToken;
|
|
499
|
-
const { app } = getWedaAPI();
|
|
500
|
-
// 私密链路有token则不是匿名; tcb链路会匿名登录需要多验证scope === 'anonymous'
|
|
501
|
-
if (accessToken && app.__internal__.getCloudSdkConfig('endpointType') === 'tcb-api') {
|
|
502
|
-
const scope = await loginScope();
|
|
503
|
-
isAnonymous = scope === 'anonymous';
|
|
504
|
-
}
|
|
505
|
-
} catch (e) {}
|
|
506
|
-
return isAnonymous;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
16
|
export function formatErrorMsg(e) {
|
|
510
17
|
let msg = e?.errMsg || e?.error_description || e?.message;
|
|
511
18
|
const uri = e?.error_uri;
|
|
@@ -528,11 +35,11 @@ export async function checkAuth(app, appId, $page) {
|
|
|
528
35
|
}
|
|
529
36
|
|
|
530
37
|
const loginConfig = await getLoginConfig();
|
|
531
|
-
|
|
532
|
-
const hasOpenIdLoginType = loginConfig?.miniprogram?.find(v => v.type === 'openid_login');
|
|
38
|
+
// openid 登录特殊处理,不在登录页登录,在原地静默登录
|
|
39
|
+
const hasOpenIdLoginType = loginConfig?.miniprogram?.find(v => v.type === 'openid_login')?.enable;
|
|
40
|
+
const hasUnionIdLoginType = loginConfig?.miniprogram?.find(v => v.type === 'unionid_login')?.enable;
|
|
533
41
|
|
|
534
42
|
const loginPage = findLoginPage(app);
|
|
535
|
-
const judgePhoneLogin = loginPage && hasPhoneLoginType;
|
|
536
43
|
const loginPageUUID = loginPage?.uuid || loginPage?.id
|
|
537
44
|
const currentUUID = $page.uuid || $page.id
|
|
538
45
|
if (loginPageUUID === currentUUID) {
|
|
@@ -543,10 +50,10 @@ export async function checkAuth(app, appId, $page) {
|
|
|
543
50
|
return true;
|
|
544
51
|
}
|
|
545
52
|
wx.showNavigationBarLoading();
|
|
546
|
-
const requestList = [getAccessPermission(
|
|
53
|
+
const requestList = [getAccessPermission(appId, $page.__internal__.packageName, $page.id, <%= !!isAdminPortal %>)];
|
|
547
54
|
// 暂时先认为有登录页则自定义登录功能开启且生效
|
|
548
|
-
if (
|
|
549
|
-
requestList.push(getAuthConfig(
|
|
55
|
+
if (loginPage || hasOpenIdLoginType || hasUnionIdLoginType) {
|
|
56
|
+
requestList.push(getAuthConfig(<%= !!isAdminPortal %>));
|
|
550
57
|
}
|
|
551
58
|
try {
|
|
552
59
|
const [accessData, authConfig] = await Promise.all(requestList);
|
|
@@ -556,12 +63,18 @@ export async function checkAuth(app, appId, $page) {
|
|
|
556
63
|
if (!accessData?.isAccess) {
|
|
557
64
|
// 当前匿名情况下,且需要登录后访问应用
|
|
558
65
|
if (isAnonymousUser && (authConfig?.NeedLogin || authConfig?.RejectStrategy == 'to_login')) {
|
|
559
|
-
|
|
560
|
-
if (judgePhoneLogin) {
|
|
561
|
-
redirectToLogin($page);
|
|
562
|
-
} else if (hasOpenIdLoginType){
|
|
66
|
+
if(hasOpenIdLoginType){
|
|
563
67
|
// 开启了openId静默登录,则进行openid登录
|
|
564
|
-
|
|
68
|
+
const result = await app.cloud.openIdLoginInWxApp();
|
|
69
|
+
return result
|
|
70
|
+
} else if (hasUnionIdLoginType) {
|
|
71
|
+
// 开启了unionId静默登录,则进行unionId登录
|
|
72
|
+
const result = await app.cloud.unionIdLoginInWxApp();
|
|
73
|
+
return result
|
|
74
|
+
}
|
|
75
|
+
else if (loginPage) {
|
|
76
|
+
// 开启了手机号授权登录,则判断是否跳转到登录页面
|
|
77
|
+
redirectToLogin($page);
|
|
565
78
|
}
|
|
566
79
|
} else {
|
|
567
80
|
app.showToast({
|
|
@@ -569,34 +82,32 @@ export async function checkAuth(app, appId, $page) {
|
|
|
569
82
|
icon: 'error',
|
|
570
83
|
});
|
|
571
84
|
}
|
|
572
|
-
} else if (authConfig?.NeedLogin) {
|
|
85
|
+
} else if (authConfig?.NeedLogin && isAnonymousUser) {
|
|
86
|
+
// 此分支逻辑本不应该前端判断是否登录,历史原因后端短期内搞不定,后续后端优化后删除
|
|
573
87
|
// 如果当前页面匿名用户有权限访问,且需要登录后访问应用,则按配置进行登录
|
|
574
|
-
if (
|
|
575
|
-
//
|
|
88
|
+
if (hasOpenIdLoginType) {
|
|
89
|
+
// openId静默登录
|
|
90
|
+
const result = await app.cloud.openIdLoginInWxApp();
|
|
91
|
+
return result
|
|
92
|
+
} else if (hasUnionIdLoginType) {
|
|
93
|
+
// 开启了unionId静默登录
|
|
94
|
+
const result = await app.cloud.unionIdLoginInWxApp();
|
|
95
|
+
return result
|
|
96
|
+
} else if (loginPage) {
|
|
576
97
|
try {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
return false;
|
|
580
|
-
}
|
|
98
|
+
redirectToLogin($page);
|
|
99
|
+
return false;
|
|
581
100
|
} catch (e) {
|
|
582
101
|
redirectToLogin($page);
|
|
583
102
|
return false;
|
|
584
103
|
}
|
|
585
|
-
} else if (hasOpenIdLoginType) {
|
|
586
|
-
// openId静默登录
|
|
587
|
-
return await app.cloud.openIdLoginInWxApp();;
|
|
588
104
|
}
|
|
589
105
|
}
|
|
590
106
|
|
|
591
107
|
return accessData?.isAccess;
|
|
592
108
|
} catch (e) {
|
|
593
|
-
if(app
|
|
109
|
+
if(app?.__internal__?.activePage?.id === $page.id) {
|
|
594
110
|
throw new Error(formatErrorMsg(e))
|
|
595
|
-
app.showModal({
|
|
596
|
-
title: '页面鉴权失败',
|
|
597
|
-
content: formatErrorMsg(e),
|
|
598
|
-
showCancel: false,
|
|
599
|
-
});
|
|
600
111
|
}
|
|
601
112
|
return false;
|
|
602
113
|
} finally {
|
|
@@ -604,219 +115,6 @@ export async function checkAuth(app, appId, $page) {
|
|
|
604
115
|
}
|
|
605
116
|
}
|
|
606
117
|
|
|
607
|
-
export function redirectToLogin(currentPage) {
|
|
608
|
-
// 去登录则清空权限缓存。
|
|
609
|
-
_AUTH_CACHE_MAP = {};
|
|
610
|
-
const { app } = getWedaAPI();
|
|
611
|
-
const loginPage = findLoginPage(app);
|
|
612
|
-
if (!currentPage) {
|
|
613
|
-
currentPage = app.utils.getCurrentPage() || {};
|
|
614
|
-
}
|
|
615
|
-
const loginPageUUID = loginPage?.uuid || loginPage?.id
|
|
616
|
-
const currentUUID = currentPage.uuid || currentPage.id
|
|
617
|
-
if (loginPageUUID === currentUUID) {
|
|
618
|
-
return true;
|
|
619
|
-
}
|
|
620
|
-
if (loginPage) {
|
|
621
|
-
app.redirectTo({
|
|
622
|
-
pageId: loginPage.id,
|
|
623
|
-
packageName: loginPage.packageName,
|
|
624
|
-
params: {
|
|
625
|
-
sourcePagePackageName: currentPage.__internal__.packageName || undefined,
|
|
626
|
-
sourcePageId: currentPage.id,
|
|
627
|
-
sourcePageParams: currentPage.params || currentPage.dataset?.params,
|
|
628
|
-
},
|
|
629
|
-
});
|
|
630
|
-
} else {
|
|
631
|
-
app.showToast({
|
|
632
|
-
title: '用户未登录',
|
|
633
|
-
icon: 'error',
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
let loading = {};
|
|
639
|
-
export let enumOptions = observable({});
|
|
640
|
-
|
|
641
|
-
export function formatEnum(path, optionname) {
|
|
642
|
-
// 判断是单选还是多选
|
|
643
|
-
let isSingle = Array.isArray(path);
|
|
644
|
-
// 获取到options
|
|
645
|
-
let parseOptions = getEnumOptions(optionname);
|
|
646
|
-
if (parseOptions === '') {
|
|
647
|
-
return !isSingle ? path : path.join(',');
|
|
648
|
-
}
|
|
649
|
-
let multiTmp = [];
|
|
650
|
-
let value = !isSingle
|
|
651
|
-
? JSON.parse(parseOptions)?.find((item) => item?.key === path)?.value
|
|
652
|
-
: JSON.parse(parseOptions)
|
|
653
|
-
?.filter((item) => path.some((pathValue) => item?.key === pathValue))
|
|
654
|
-
.map((item) => multiTmp.push(item?.value));
|
|
655
|
-
// 对多选或者单选有不同处理
|
|
656
|
-
return !isSingle ? value : multiTmp?.join(',');
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
function getEnumOptions(optionName) {
|
|
660
|
-
if (enumOptions[optionName]) {
|
|
661
|
-
return enumOptions[optionName];
|
|
662
|
-
}
|
|
663
|
-
if (!loading[optionName]) {
|
|
664
|
-
loading[optionName] = true;
|
|
665
|
-
getGeneralOptions(optionName).then((data) => {
|
|
666
|
-
enumOptions[optionName] = data?.Items[0]?.Config;
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
return '';
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
async function getGeneralOptions(optionName) {
|
|
673
|
-
const { app } = getWedaAPI();
|
|
674
|
-
return app.cloud.callWedaApi({
|
|
675
|
-
action: 'DescribeGeneralOptionsDetailList',
|
|
676
|
-
data: {
|
|
677
|
-
PageSize: 1,
|
|
678
|
-
PageIndex: 1,
|
|
679
|
-
OptNameList: [optionName],
|
|
680
|
-
},
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
export function getMpEventHandlerName(widgetId, evtName, modifier = {}) {
|
|
685
|
-
// Only builtin events have will bubble
|
|
686
|
-
return `on${widgetId}$${evtName.replace(/\./g, '_')}${modifier.isCapturePhase ? '$cap' : ''}${
|
|
687
|
-
modifier.noPropagation ? '$cat' : ''
|
|
688
|
-
}`;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
function isPlainObject(src) {
|
|
692
|
-
return Object.prototype.toString.call(src) === '[object Object]';
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
const isEmptyObj = (obj) => {
|
|
696
|
-
if (!isPlainObject(obj)) {
|
|
697
|
-
return false;
|
|
698
|
-
}
|
|
699
|
-
for (const i in obj) {
|
|
700
|
-
if (Object.prototype.hasOwnProperty.call(obj, i)) {
|
|
701
|
-
return false;
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
return true;
|
|
705
|
-
};
|
|
706
|
-
|
|
707
|
-
export function mergeDynamic2StaticData(
|
|
708
|
-
staticData,
|
|
709
|
-
dataBinds,
|
|
710
|
-
context /* : {
|
|
711
|
-
$w: any;
|
|
712
|
-
forContext?: {
|
|
713
|
-
lists: any[]
|
|
714
|
-
forItems: Record<string,any>
|
|
715
|
-
};
|
|
716
|
-
codeContext: {
|
|
717
|
-
instance: any
|
|
718
|
-
event?: Event;
|
|
719
|
-
};
|
|
720
|
-
dataContext?: Record<string,any>;
|
|
721
|
-
paramsContext?: Record<string,any>;
|
|
722
|
-
}*/,
|
|
723
|
-
combainErrors = false,
|
|
724
|
-
) {
|
|
725
|
-
const { forContext = {}, codeContext = {}, dataContext = {}, $w, paramsContext = {} } = context;
|
|
726
|
-
const { lists = [], forItems = {} } = forContext;
|
|
727
|
-
|
|
728
|
-
const resolvedData = {
|
|
729
|
-
...staticData,
|
|
730
|
-
};
|
|
731
|
-
let error = null;
|
|
732
|
-
|
|
733
|
-
for (const key in dataBinds) {
|
|
734
|
-
try {
|
|
735
|
-
set(
|
|
736
|
-
resolvedData,
|
|
737
|
-
key,
|
|
738
|
-
dataBinds[key].call(
|
|
739
|
-
codeContext.instance,
|
|
740
|
-
codeContext.instance,
|
|
741
|
-
lists,
|
|
742
|
-
forItems,
|
|
743
|
-
codeContext.event,
|
|
744
|
-
dataContext,
|
|
745
|
-
$w,
|
|
746
|
-
paramsContext,
|
|
747
|
-
),
|
|
748
|
-
);
|
|
749
|
-
} catch(e) {
|
|
750
|
-
if(combainErrors) {
|
|
751
|
-
error = e
|
|
752
|
-
} else {
|
|
753
|
-
throw e
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
if(error) {
|
|
758
|
-
throw error
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
return resolvedData;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
function replaceStaticResourceAttribute(obj, replacer, paths, index = 0) {
|
|
765
|
-
const path = paths[index];
|
|
766
|
-
const value = lodashGet(obj, path);
|
|
767
|
-
if (index === paths.length - 1) {
|
|
768
|
-
try {
|
|
769
|
-
if (value) {
|
|
770
|
-
lodashSet(obj, path, replacer(value));
|
|
771
|
-
}
|
|
772
|
-
} catch (e) {
|
|
773
|
-
console.error(e);
|
|
774
|
-
}
|
|
775
|
-
} else {
|
|
776
|
-
if (Array.isArray(value)) {
|
|
777
|
-
value.forEach((current) => {
|
|
778
|
-
replaceStaticResourceAttribute(current, replacer, paths, index + 1);
|
|
779
|
-
});
|
|
780
|
-
} else {
|
|
781
|
-
try {
|
|
782
|
-
Object.values(value).forEach((current) => {
|
|
783
|
-
replaceStaticResourceAttribute(current, replacer, paths, index + 1);
|
|
784
|
-
});
|
|
785
|
-
} catch (e) {}
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
export function processStaticResourceAttribute(data, replacer, property) {
|
|
791
|
-
const { app } = getWedaAPI();
|
|
792
|
-
const { __internal__ = {} } = app || {};
|
|
793
|
-
const { resolveStaticResourceUrl = (str) => str } = __internal__ || {};
|
|
794
|
-
if (!replacer) {
|
|
795
|
-
replacer = resolveStaticResourceUrl;
|
|
796
|
-
}
|
|
797
|
-
let segments = [property];
|
|
798
|
-
if (/\.\*\.?/.test(property)) {
|
|
799
|
-
segments = property
|
|
800
|
-
?.trim()
|
|
801
|
-
.split('.')
|
|
802
|
-
.reduce((segments, path) => {
|
|
803
|
-
const latest = segments.length ? segments.length - 1 : 0;
|
|
804
|
-
const current = segments[latest];
|
|
805
|
-
if (path === '*') {
|
|
806
|
-
segments.push('');
|
|
807
|
-
} else {
|
|
808
|
-
segments[latest] = current ? `${current}.${path}` : path;
|
|
809
|
-
}
|
|
810
|
-
return segments;
|
|
811
|
-
}, []);
|
|
812
|
-
}
|
|
813
|
-
try {
|
|
814
|
-
replaceStaticResourceAttribute(data, replacer, segments);
|
|
815
|
-
} catch (e) {
|
|
816
|
-
console.error('处理静态资源失败:', e);
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
|
|
820
118
|
<% if(expirationStartTimesnap){ %>
|
|
821
119
|
function formatLifecycle(time) {
|
|
822
120
|
let str = '';
|
|
@@ -874,45 +172,6 @@ export async function getExpiredMessage(createdTime = 0) {
|
|
|
874
172
|
<% } %>
|
|
875
173
|
}
|
|
876
174
|
|
|
877
|
-
|
|
878
|
-
export function patchWdigetPropsWithEvtListeners(widgetProps, evtListeners) {
|
|
879
|
-
const actionMap = Object.keys(evtListeners).reduce((map, evtKey = '') => {
|
|
880
|
-
const matched = evtKey.match(/^on(.*?)\$(.*)$/);
|
|
881
|
-
if (matched?.[1] && matched?.[2] && !/[._]/.test(matched?.[2])) {
|
|
882
|
-
if (!map[matched?.[1]]) {
|
|
883
|
-
map[matched?.[1]] = new Set([]);
|
|
884
|
-
}
|
|
885
|
-
map[matched?.[1]].add(matched?.[2]);
|
|
886
|
-
}
|
|
887
|
-
return map;
|
|
888
|
-
}, {});
|
|
889
|
-
for (let key in widgetProps) {
|
|
890
|
-
const props = widgetProps[key];
|
|
891
|
-
if (actionMap[key]) {
|
|
892
|
-
if (!props.classList) {
|
|
893
|
-
props.classList = [];
|
|
894
|
-
}
|
|
895
|
-
props.classList = Array.from(
|
|
896
|
-
new Set([...props.classList, ...Array.from(actionMap[key]).map((trigger) => `wd-event-${trigger}`)]),
|
|
897
|
-
);
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
return widgetProps;
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
export function reportEvent(tag) {
|
|
905
|
-
const { app } = getWedaAPI()
|
|
906
|
-
try {
|
|
907
|
-
const { envVersion } = app.__internal__?.getConfig?.() || {};
|
|
908
|
-
// console.log('>>>>>>reportevent:', tag);
|
|
909
|
-
getApp().globalData._aegis?.reportEvent?.({
|
|
910
|
-
name: tag,
|
|
911
|
-
ext2: envVersion,
|
|
912
|
-
});
|
|
913
|
-
} catch (e) {}
|
|
914
|
-
}
|
|
915
|
-
|
|
916
175
|
export async function getLoginConfig() {
|
|
917
176
|
const { app } = getWedaAPI()
|
|
918
177
|
<% if(loginConfigPathname){ %>
|