@cloudbase/framework-plugin-low-code 0.7.1 → 0.7.2

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 (79) hide show
  1. package/lib/builder/config/common.js +1 -1
  2. package/lib/builder/config/index.js +2 -2
  3. package/lib/builder/config/mp.js +1 -1
  4. package/lib/builder/core/copy.js +3 -3
  5. package/lib/builder/core/generate.js +13 -13
  6. package/lib/builder/core/index.js +13 -13
  7. package/lib/builder/core/material.js +6 -6
  8. package/lib/builder/core/plugin.js +3 -3
  9. package/lib/builder/core/prepare.js +2 -2
  10. package/lib/builder/core/webpack.js +5 -5
  11. package/lib/builder/mp/index.d.ts.map +1 -1
  12. package/lib/builder/mp/index.js +50 -49
  13. package/lib/builder/mp/lowcode.js +4 -4
  14. package/lib/builder/mp/materials.js +16 -16
  15. package/lib/builder/mp/mixMode.js +12 -12
  16. package/lib/builder/mp/mp_config.js +11 -11
  17. package/lib/builder/mp/util.d.ts.map +1 -1
  18. package/lib/builder/mp/util.js +12 -9
  19. package/lib/builder/mp/wxml.d.ts.map +1 -1
  20. package/lib/builder/mp/wxml.js +7 -6
  21. package/lib/builder/service/builder/copy.js +11 -11
  22. package/lib/builder/service/builder/generate.js +58 -54
  23. package/lib/builder/service/builder/index.js +2 -2
  24. package/lib/builder/service/builder/plugin.js +2 -2
  25. package/lib/builder/service/builder/webpack.js +24 -23
  26. package/lib/builder/types/common.js +1 -0
  27. package/lib/builder/util/common.d.ts.map +1 -1
  28. package/lib/builder/util/common.js +8 -6
  29. package/lib/builder/util/console.js +1 -1
  30. package/lib/builder/util/generateFiles.js +2 -2
  31. package/lib/builder/util/index.js +1 -1
  32. package/lib/builder/util/junk.js +4 -2
  33. package/lib/builder/util/mp.js +1 -1
  34. package/lib/builder/util/net.js +1 -1
  35. package/lib/builder/util/style.js +1 -1
  36. package/lib/builder/util/weapp.js +1 -1
  37. package/lib/generate.js +2 -2
  38. package/lib/generator/config/index.js +2 -2
  39. package/lib/generator/core/generate.js +36 -34
  40. package/lib/generator/core/index.js +4 -4
  41. package/lib/generator/core/material.js +14 -14
  42. package/lib/generator/types/common.js +6 -3
  43. package/lib/generator/util/common.d.ts.map +1 -1
  44. package/lib/generator/util/common.js +1 -1
  45. package/lib/generator/util/index.js +1 -1
  46. package/lib/generator/util/style.js +2 -2
  47. package/lib/index.d.ts.map +1 -1
  48. package/lib/index.js +104 -66
  49. package/lib/utils/common.d.ts +1 -1
  50. package/lib/utils/common.d.ts.map +1 -1
  51. package/lib/utils/common.js +2 -2
  52. package/lib/utils/dataSource.d.ts.map +1 -1
  53. package/lib/utils/dataSource.js +4 -11
  54. package/lib/utils/index.js +1 -1
  55. package/lib/utils/postProcess.js +3 -3
  56. package/lib/weapps-core/config/index.js +1 -1
  57. package/lib/weapps-core/index.js +2 -2
  58. package/lib/weapps-core/types/index.js +1 -1
  59. package/lib/weapps-core/utils/appbuild.js +6 -3
  60. package/lib/weapps-core/utils/common.js +3 -2
  61. package/lib/weapps-core/utils/formily.js +37 -37
  62. package/lib/weapps-core/utils/index.js +1 -1
  63. package/lib/weapps-core/utils/style.js +15 -15
  64. package/package.json +1 -1
  65. package/template/mp/app/weapps-api.js +16 -5
  66. package/template/mp/app.js +59 -48
  67. package/template/mp/common/util.js +9 -4
  68. package/template/mp/common/weapp-component.js +26 -7
  69. package/template/mp/common/weapp-page.js +45 -2
  70. package/template/mp/common/widget.js +1 -0
  71. package/template/mp/package.json +1 -1
  72. package/template/package.json +2 -2
  73. package/template/src/app/global-api.js +37 -3
  74. package/template/src/handlers/FieldMiddleware/renderer.jsx +12 -0
  75. package/template/src/handlers/actionHandler/utils.js +1 -3
  76. package/template/src/handlers/utils/common.js +27 -21
  77. package/template/src/handlers/utils/widgets.js +16 -4
  78. package/template/src/index.jsx +3 -2
  79. package/template/src/pages/composite.tpl +25 -7
@@ -377,4 +377,5 @@ function mountBuiltinWigetsAPI(widget, owner) {
377
377
  })
378
378
  }
379
379
 
380
+ widget._methods = {}
380
381
  }
@@ -3,7 +3,7 @@
3
3
  "version": "1.0.0",
4
4
  "scripts": {},
5
5
  "dependencies": {
6
- "@cloudbase/weda-cloud-sdk": "1.0.8-alpha.12",
6
+ "@cloudbase/weda-cloud-sdk": "1.0.8",
7
7
  "@cloudbase/oauth": "0.1.1-alpha.2",
8
8
  "mobx": "^5.15.4",
9
9
  "lodash.get": "^4.4.2",
@@ -5,8 +5,8 @@
5
5
  "build-web": "webpack --config ./webpack/webpack.web.prod.js"
6
6
  },
7
7
  "dependencies": {
8
- "@cloudbase/js-sdk": "1.5.3-alpha.0",
9
- "@cloudbase/weda-cloud-sdk": "1.0.8-alpha.12",
8
+ "@cloudbase/js-sdk": "2.4.0-alpha.0",
9
+ "@cloudbase/weda-cloud-sdk": "1.0.8",
10
10
  "@tcwd/weapps-core": "2.2.6",
11
11
  "@tcwd/weapps-sdk": "1.2.9",
12
12
  "@zxing/library": "^0.18.6",
@@ -9,6 +9,7 @@ import { formatEnum, enumOptions } from '../utils/formatEnum';
9
9
  import { getter, setter, _isMobile } from '../utils';
10
10
  import actionMap from './material-actions';
11
11
  import { scanCodeApi } from '../utils/scan-code-action';
12
+ import { get as lodashGet } from 'lodash'
12
13
 
13
14
  const mainAppKey = '__weappsMainApp';
14
15
  const appGlobal = process.env.isMiniprogram ? getApp() : window;
@@ -17,6 +18,9 @@ export const app = createGlboalApi();
17
18
  export const $page = createPageApi();
18
19
 
19
20
  export function setCurrentPage(pageCtx) {
21
+ try {
22
+ app.__internal__.activePage = pageCtx
23
+ } catch(e) { }
20
24
  Object.assign($page, pageCtx);
21
25
  }
22
26
 
@@ -25,6 +29,12 @@ function createGlboalApi() {
25
29
  id: '<%= appId %>',
26
30
  domain: '<%= domain %>',
27
31
  platform: 'WEB',
32
+ __internal__: {
33
+ activePage: null,
34
+ getConfig: function () {
35
+ return <%= appConfig %>;
36
+ },
37
+ },
28
38
  formActions: {},
29
39
  pages: {},
30
40
  session: {
@@ -38,20 +48,26 @@ function createGlboalApi() {
38
48
  common,
39
49
  dataSources: DS_SDK,
40
50
  relaunchHome: function () {
41
- const { pages = [] } = globalAPI.utils._getConfig();
51
+ const { pages = [] } = globalAPI.__internal__.getConfig();
42
52
  if (pages[0]) {
43
53
  globalAPI.reLaunch({
44
54
  pageId: pages[0].id,
45
55
  });
46
56
  }
47
57
  },
58
+ invoke(params) {
59
+ return $page.invokeComponentMethod(params)
60
+ },
48
61
  utils: {
49
62
  formatDate,
50
63
  formatEnum,
51
64
  get: getter,
52
65
  set: setter,
53
- _getConfig: function () {
54
- return <%= appConfig %>;
66
+ /**
67
+ * @deprecated
68
+ */
69
+ _getConfig(){
70
+ return globalAPI.__internal__.getConfig()
55
71
  },
56
72
  getWXContext: function () {
57
73
  return Promise.resolve({})
@@ -117,6 +133,24 @@ function createPageApi() {
117
133
  // 页面数据源变量存储位置
118
134
  dataVar: {},
119
135
  };
136
+ $page.invokeComponentMethod = ({ component, method, params }) => {
137
+ const widgetData = lodashGet($page.widgets, component);
138
+ if (Array.isArray(widgetData)) {
139
+ throw new Error('调用方法失败:id为'+component+'的组件拥有多个实例')
140
+ // widgetData.forEach(widget => {
141
+ // if(!widget._methods[method]) {
142
+ // throw new Error('NOT_FOUND')
143
+ // } else {
144
+ // actions.push(widget._methods[method])
145
+ // }
146
+ // })
147
+ } else {
148
+ if(!widgetData._methods[method] || typeof widgetData._methods[method]!= 'function') {
149
+ throw new Error('调用方法失败:未找到id为'+component+'下的方法'+method)
150
+ }
151
+ return widgetData._methods[method](params)
152
+ }
153
+ }
120
154
  return $page;
121
155
  }
122
156
 
@@ -188,6 +188,7 @@ function FieldWrapper({
188
188
  const injectContext = {};
189
189
  const indexRef = React.useRef();
190
190
  const typeRef = React.useRef();
191
+ const instanceRef = React.useRef();
191
192
  const { 'x-props': xProps } = componentSchema;
192
193
  let { staticResourceAttribute = [], listenerInstances = [] } = xProps;
193
194
 
@@ -250,6 +251,16 @@ function FieldWrapper({
250
251
  ? get(widgetsData, forIndexes)
251
252
  : widgetsData;
252
253
 
254
+ React.useLayoutEffect(() => {
255
+ return () => {
256
+ instanceRef.current = undefined;
257
+ };
258
+ }, []);
259
+
260
+ React.useLayoutEffect(() => {
261
+ currentWidget._getInstanceRef = () => instanceRef;
262
+ }, [currentWidget, instanceRef]);
263
+
253
264
  if (!Array.isArray(staticResourceAttribute)) {
254
265
  staticResourceAttribute = [];
255
266
  }
@@ -264,6 +275,7 @@ function FieldWrapper({
264
275
 
265
276
  return (
266
277
  <Field
278
+ ref={instanceRef}
267
279
  data={{
268
280
  ...data,
269
281
  _selectableBlockEvents: {
@@ -39,11 +39,9 @@ export function emitEvent(
39
39
  ? {
40
40
  /**
41
41
  * @deprecated 历史bug
42
- * value,origin,isCapturePhase
42
+ * value
43
43
  */
44
44
  value: res,
45
- origin: args.event,
46
- isCapturePhase: !!args.event?.isCapturePhase,
47
45
  ...res,
48
46
  }
49
47
  : res,
@@ -150,12 +150,12 @@ export function getStaticResourceAttribute(staticUrl) {
150
150
  }
151
151
 
152
152
  export function findLoginPage(app = window.app) {
153
- const { pages = [] } = app.utils._getConfig();
153
+ const { pages = [] } = app.__internal__.getConfig();
154
154
  return pages.find(item => item.type === 'login');
155
155
  }
156
156
 
157
157
  let _AUTH_CONFIG_CACHE = null;
158
- async function getAuthConfig(app = window.app) {
158
+ export async function getAuthConfig(app = window.app) {
159
159
  if (_AUTH_CONFIG_CACHE) {
160
160
  return _AUTH_CONFIG_CACHE;
161
161
  }
@@ -209,6 +209,19 @@ async function getAccessPermission(app, appId, pageId) {
209
209
  return isAccess
210
210
  }
211
211
 
212
+ export async function checkAnonymous() {
213
+ // 用户是否非匿名登录前端判断条件:有accessToken且scope不为anonymous
214
+ // 此分支逻辑本不应该前端判断是否登录,历史原因后端短期内搞不定,后续后端优化后删除
215
+ let isAnonymous = true;
216
+ try {
217
+ const [scope, { accessToken }] = await Promise.all([loginScope(), getAccessToken()]);
218
+ if (accessToken && scope !== 'anonymous') {
219
+ isAnonymous = false;
220
+ }
221
+ } catch (e) { }
222
+ return isAnonymous;
223
+ }
224
+
212
225
  /**
213
226
  * 检查页面权限
214
227
  **/
@@ -223,31 +236,24 @@ export async function checkAuth(app, appId, $page) {
223
236
  // 暂时先认为有登录页则自定义登录功能开启且生效
224
237
  if (loginPage) {
225
238
  requestList.push(getAuthConfig(app));
239
+ requestList.push(checkAnonymous());
226
240
  }
227
- const [isAccess, authConfig] = await Promise.all(requestList);
241
+ const [isAccess, authConfig, isAnonymous] = await Promise.all(requestList);
228
242
  app.hideNavigationBarLoading();
229
243
 
230
- if (!isAccess) {
231
- if (loginPage && (authConfig.NeedLogin || authConfig.RejectStrategy == 'to_login')) {
232
- redirectToLogin($page);
233
- } else {
234
- app.showToast({
235
- title: '页面无访问权限',
236
- icon: 'error',
237
- });
238
- }
239
- } else if (loginPage && authConfig.NeedLogin) {
240
- // 此分支逻辑本不应该前端判断是否登录,历史原因后端短期内搞不定,后续后端优化后删除
241
- try {
242
- const [scope, { accessToken }] = await Promise.all([loginScope(), getAccessToken()]);
243
- if (!accessToken || scope === 'anonymous') {
244
- redirectToLogin($page);
245
- }
246
- } catch (e) {
247
- console.error('获取身份失败', e);
244
+ if (loginPage && isAnonymous) {
245
+ if (authConfig.NeedLogin || (!isAccess && authConfig.RejectStrategy === 'to_login')) {
248
246
  redirectToLogin($page);
247
+ return isAccess;
249
248
  }
250
249
  }
250
+
251
+ if (!isAccess) {
252
+ app.showToast({
253
+ title: '页面无访问权限',
254
+ icon: 'error',
255
+ });
256
+ }
251
257
  return isAccess;
252
258
  }
253
259
 
@@ -94,7 +94,12 @@ export function retryDataBinds(tryTime = 10) {
94
94
  retryDataBinds(tryTime - 1);
95
95
  }, 0);
96
96
  }
97
- export function createWidgets(widgetProps, dataBinds, scopeContext = {}, context = {}) {
97
+ export function createWidgets(
98
+ widgetProps,
99
+ dataBinds,
100
+ scopeContext = {},
101
+ context = {}
102
+ ) {
98
103
  const nodeTree = createWidgetTree(widgetProps, dataBinds);
99
104
  const widgets = runFor(nodeTree, {}, null, null, scopeContext, context);
100
105
  return widgets;
@@ -115,7 +120,7 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}, context
115
120
  parentLevelWidgets,
116
121
  parentWidget,
117
122
  scopeContext,
118
- context,
123
+ context
119
124
  ) {
120
125
  const nodeId = curForNode.id;
121
126
  if (!curForNode.value) {
@@ -180,6 +185,13 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}, context
180
185
  includeInvisibleDescendants
181
186
  );
182
187
  w.getOwnerWidget = () => null; // 寻找父widget,默认返回null, 后续会覆写
188
+ w._getInstanceRef = () => null; // 默认初始值
189
+ Object.defineProperty(w, '_methods', {
190
+ get() {
191
+ const instance = this._getInstanceRef();
192
+ return instance?.current?.methods;
193
+ },
194
+ });
183
195
  // 提供一个给 Node 挂载 API 的方式
184
196
  untracked(() => {
185
197
  w.extends = (name, fnOrData) =>
@@ -213,7 +225,7 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}, context
213
225
  subForItems,
214
226
  undefined,
215
227
  context,
216
- scopeContext,
228
+ scopeContext
217
229
  );
218
230
  disposeError = false;
219
231
  } catch (e) {
@@ -251,7 +263,7 @@ export function createWidgets(widgetProps, dataBinds, scopeContext = {}, context
251
263
  widgets,
252
264
  node.parent && widgets[node.parent.id],
253
265
  scopeContext,
254
- context,
266
+ context
255
267
  );
256
268
  curForNode.id && widgets[curForNode.id]._disposers.push(dispose);
257
269
  }
@@ -12,7 +12,7 @@ import attachFastClick from 'fastclick'
12
12
  import { initWebConfig } from 'handlers/lifecycle'
13
13
  const AppConfig = require('../webpack/miniprogram.config')
14
14
  import { app } from './app/global-api'
15
- import { redirectToLogin, findLoginPage, getAuthConfig } from './handlers/utils'
15
+ import { redirectToLogin, findLoginPage, getAuthConfig, checkAnonymous } from './handlers/utils'
16
16
  // app 中注册配置页面以及app的全局配置miniprogram.config,h5里分app以及web页分别处理,使用process.env.isApp 区分判断
17
17
  if (process.env.isApp) {
18
18
  initWebConfig(app, AppConfig);
@@ -63,7 +63,8 @@ setConfig({
63
63
  const loginPage = findLoginPage();
64
64
  if (loginPage) {
65
65
  const authConfig = await getAuthConfig();
66
- if (authConfig.NeedLogin || authConfig.RejectStrategy == 'to_login') {
66
+ const isAnonymous = await checkAnonymous();
67
+ if (isAnonymous && authConfig.RejectStrategy == 'to_login') {
67
68
  redirectToLogin();
68
69
  } else if (authConfig.RejectStrategy == 'show_warning') {
69
70
  app.showToast({
@@ -51,7 +51,7 @@ class CompositeCompWrapper extends React.Component {
51
51
  this.compConfig = <%= JSON.stringify(compConfig, null, 2) %>
52
52
  this.virtualFields = Object.assign({}, props.pageVirtualFields || {}, {
53
53
  <% useComponents.forEach(compItem => {%>
54
- "<%= compItem.key %>": <% if(compItem.isPlainProps) {%> (props) => <<%= compItem.var %> {...resolveComponentProps(props, 1)} /> <% } else {%> (props) => <<%= compItem.var %>{...resolveComponentProps(props, 0)} /> <% }%>,
54
+ "<%= compItem.key %>": React.forwardRef((props,ref) => <<%= compItem.var %> {...resolveComponentProps(props, <%= compItem.isPlainProps? 1:0 %>)} ref={ref}/>),
55
55
  <%}) %>
56
56
  });
57
57
  this.events = (<%= emitEvents %>).reduce((obj, trigger) => {
@@ -107,6 +107,7 @@ class CompositeCompWrapper extends React.Component {
107
107
  }
108
108
 
109
109
  createCompAPI(compThis) {
110
+ const { forwardRef, ...restProps } = compThis.props || {};
110
111
  compThis.$WEAPPS_COMP = {
111
112
  compConfig: compThis.compConfig,
112
113
  widgets: compThis.widgets,
@@ -114,7 +115,7 @@ class CompositeCompWrapper extends React.Component {
114
115
  handler: compThis.handler,
115
116
  lib: { const: constObj, tools: toolsObj },
116
117
  get props() {
117
- return {...compThis.props, events: compThis.events, data: compThis.propsData }
118
+ return {...restProps, events: compThis.events, data: compThis.propsData }
118
119
  },
119
120
  get state() {
120
121
  return compThis.state
@@ -122,16 +123,32 @@ class CompositeCompWrapper extends React.Component {
122
123
  get computed() {
123
124
  return compThis.computed
124
125
  },
126
+ get _instanceRef() {
127
+ return forwardRef
128
+ },
129
+ get methods() {
130
+ return forwardRef.current?.methods
131
+ },
132
+ set methods(value) {
133
+ if(!forwardRef.current) {
134
+ forwardRef.current = {}
135
+ }
136
+ forwardRef.current.methods = value
137
+ return value
138
+ }
125
139
  };
126
140
  }
127
141
 
128
142
  componentDidMount() {
129
- lifecycle.onAttached && lifecycle.onAttached.bind(this)()
130
- lifecycle.onReady && lifecycle.onReady.bind(this)()
143
+ const onAttached = lifecycle.onAttached && lifecycle.onAttached.bind(this)
144
+ Promise.resolve(onAttached()).then(()=>{
145
+ lifecycle.onReady && lifecycle.onReady.bind(this)()
146
+ })
131
147
  }
132
148
 
133
149
  componentWillUnmount() {
134
150
  lifecycle.onDetached && lifecycle.onDetached.bind(this)()
151
+ this.$WEAPPS_COMP._instanceRef.current = undefined
135
152
  }
136
153
 
137
154
  render() {
@@ -148,6 +165,7 @@ class CompositeCompWrapper extends React.Component {
148
165
  }
149
166
  }
150
167
 
151
- export default observer((props) => (
152
- <CompositeCompWrapper {...props}></CompositeCompWrapper>
153
- ));
168
+ export default observer((props, _ref) => (
169
+ <CompositeCompWrapper {...props} forwardRef={_ref}></CompositeCompWrapper>
170
+ ), { forwardRef: true });
171
+