cloud-web-corejs 1.0.54-dev.745 → 1.0.54-dev.747

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 (52) hide show
  1. package/package.json +194 -192
  2. package/src/App.vue +73 -71
  3. package/src/components/baseArea/index.vue +1628 -1628
  4. package/src/components/fileLibrary/categoryMoveDialog.vue +109 -109
  5. package/src/components/fileLibrary/fileObjAuthDialog.vue +297 -297
  6. package/src/components/fileLibrary/index.vue +1109 -1109
  7. package/src/components/fileLibrary/propertiesDialog.vue +190 -190
  8. package/src/components/fileLibrary/recycleBinDialog.vue +237 -237
  9. package/src/components/wf/mixins/setCandidateDialog.js +217 -217
  10. package/src/components/wf/mixins/setCandidateDialog2.js +252 -252
  11. package/src/components/xform/docs//345/257/271/346/257/224/345/212/237/350/203/275/350/220/275/345/234/260/346/226/271/346/241/210.md +986 -986
  12. package/src/components/xform/form-designer/form-widget/field-widget/area-select-widget.vue +272 -272
  13. package/src/components/xform/form-designer/form-widget/field-widget/baseAttachment-widget.vue +216 -216
  14. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +928 -928
  15. package/src/components/xform/form-designer/index.vue +195 -195
  16. package/src/components/xform/form-designer/indexMixin.js +848 -848
  17. package/src/components/xform/form-designer/setting-panel/index.vue +313 -313
  18. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/columnRenderDialog.vue +124 -124
  19. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +369 -369
  20. package/src/components/xform/form-designer/widget-panel/index.vue +389 -389
  21. package/src/components/xform/form-designer/widget-panel/indexMixin.js +343 -343
  22. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +4531 -4531
  23. package/src/components/xform/form-render/container-item/data-table-mixin.js +4748 -4576
  24. package/src/components/xform/form-render/container-item/tab-item.vue +125 -125
  25. package/src/components/xform/form-render/indexMixin.js +5061 -5078
  26. package/src/components/xform/lang/en-US.js +457 -457
  27. package/src/components/xform/lang/zh-CN.js +628 -628
  28. package/src/components/xform/utils/util.js +1585 -1554
  29. package/src/index.js +347 -230
  30. package/src/layout/components/AppMain.vue +122 -125
  31. package/src/layout/components/extractedCode/viewDialog.vue +207 -207
  32. package/src/layout/components/langTool.vue +128 -123
  33. package/src/layout/defaultLayout.vue +164 -158
  34. package/src/microRouter/index.js +389 -0
  35. package/src/permission.js +185 -135
  36. package/src/public-path.js +8 -0
  37. package/src/store/config/index.js +667 -669
  38. package/src/store/modules/micro.js +46 -0
  39. package/src/store/modules/permission.js +468 -373
  40. package/src/store/modules/user.js +419 -415
  41. package/src/utils/auth.js +27 -1
  42. package/src/utils/index.js +579 -6
  43. package/src/utils/keepAlive.js +4 -0
  44. package/src/utils/menuAdapter.js +183 -0
  45. package/src/utils/request.js +417 -28
  46. package/src/views/bd/setting/formVersion/ftHistoryDialog.vue +483 -483
  47. package/src/views/bd/setting/form_script/form_list.vue +174 -174
  48. package/src/views/bd/setting/form_script/mixins/form_list.js +330 -330
  49. package/src/views/bd/setting/form_template/formDesignerDialog.vue +171 -171
  50. package/src/views/bd/setting/form_template/wfObjConfigDialog.vue +253 -253
  51. package/src/views/user/menuFallback/index.vue +123 -0
  52. package/src/views/user/wf/wfReport/index.vue +625 -625
@@ -0,0 +1,389 @@
1
+ /**
2
+ * qiankun 主应用侧:应用注册表驱动的子应用注册。
3
+ * 注册表载体为逻辑参数 micro_app_registry(JSON 数组),
4
+ * 协议见 docs/qiankun微前端改造-实现方案.md 3.2 / 3.4。
5
+ * 由 permission store 在登录后菜单生成流程中调用(settings.microMainEnabled 门控)。
6
+ */
7
+ import { loadMicroApp } from "qiankun";
8
+ import { getLogicParamValue } from "@base/api/user";
9
+ import {
10
+ getAccessPath,
11
+ validateRegistry,
12
+ resolveEntry,
13
+ } from "@base/utils/menuAdapter";
14
+ import { getToken } from "@base/utils/auth";
15
+ import router from "@base/router";
16
+ import settings from "@/settings";
17
+
18
+ export const REGISTRY_PARAM_CODE = "micro_app_registry";
19
+ export const DEBUG_STORAGE_KEY = "micro_app_debug";
20
+
21
+ const REGISTRY_TIMEOUT = 8000;
22
+ const CONTAINER_WRAPPER_ID = "Appmicro";
23
+ const DEBUG_APP_CODE_REG = /^[A-Za-z][A-Za-z0-9_-]*$/;
24
+
25
+ // 保活管理:appCode → { instance, el };离开子应用路由只隐藏容器不卸载,
26
+ // 切回直接显示并经 update 生命周期同步路由,页面状态(页签/表格/表单)得以保留
27
+ let microAppConfigs = {};
28
+ let aliveApps = {};
29
+ let routeHookInstalled = false;
30
+
31
+ /**
32
+ * 读应用注册表(第一阶段载体:逻辑参数)。
33
+ * 非法条目由 validateRegistry 跳过并在控制台显式报错;
34
+ * 参数缺失 / 请求失败 / 超时一律回落空数组,不阻塞登录流程。
35
+ */
36
+ export function getAppRegistry() {
37
+ const fetchPromise = new Promise((resolve) => {
38
+ getLogicParamValue({
39
+ data: { paramCode: REGISTRY_PARAM_CODE },
40
+ failMsg: false,
41
+ errorMsg: false,
42
+ modal: false,
43
+ success: (res) => {
44
+ const raw = res && res.objx;
45
+ if (!raw) {
46
+ resolve([]);
47
+ return;
48
+ }
49
+ const { apps, errors } = validateRegistry(raw);
50
+ if (errors.length) {
51
+ console.error(
52
+ "[microRouter] 应用注册表存在非法条目(已跳过):",
53
+ errors
54
+ );
55
+ }
56
+ resolve(apps);
57
+ },
58
+ }).catch(() => resolve([]));
59
+ });
60
+ const timeoutPromise = new Promise((resolve) => {
61
+ setTimeout(() => {
62
+ resolve([]);
63
+ }, REGISTRY_TIMEOUT);
64
+ });
65
+ return Promise.race([fetchPromise, timeoutPromise]).then((apps) =>
66
+ applyDebugOverrides(apps)
67
+ );
68
+ }
69
+
70
+ /**
71
+ * 本机调试覆盖:localStorage.micro_app_debug 仅在当前浏览器生效,
72
+ * 用于"发布环境主应用 + 本机子应用"的联调,不影响其他用户。四档写法:
73
+ * "1" → settings.microDebugAppCode + microDebugEntry
74
+ * "appB" → appB + 默认调试入口
75
+ * "appB=http://localhost:9530/" → 指定入口;多个用逗号分隔,可混写
76
+ * '[{"appCode":"..","entry":".."}]' → 完整条目数组
77
+ * 与注册表按 appCode 合并:已存在的条目覆盖 entry 并强制 enabled,不存在的追加。
78
+ */
79
+ function getDebugOverrides() {
80
+ let raw = null;
81
+ try {
82
+ raw = window.localStorage.getItem(DEBUG_STORAGE_KEY);
83
+ } catch (e) {
84
+ return [];
85
+ }
86
+ if (!raw || !(raw = raw.trim())) return [];
87
+ const defaults = {
88
+ appCode: settings.microDebugAppCode || "",
89
+ entry: settings.microDebugEntry || "",
90
+ };
91
+ let items = [];
92
+ if (raw.charAt(0) === "[") {
93
+ try {
94
+ const list = JSON.parse(raw);
95
+ items = (Array.isArray(list) ? list : []).map((item) => ({
96
+ appCode: (item && item.appCode) || "",
97
+ entry: (item && item.entry) || defaults.entry,
98
+ }));
99
+ } catch (e) {
100
+ console.error(
101
+ "[microRouter] micro_app_debug JSON 解析失败,已忽略:",
102
+ e.message
103
+ );
104
+ return [];
105
+ }
106
+ } else if (raw === "1" || raw === "true") {
107
+ items = [defaults];
108
+ } else {
109
+ items = raw.split(",").map((part) => {
110
+ const idx = part.indexOf("=");
111
+ const code = (idx > -1 ? part.slice(0, idx) : part).trim();
112
+ const entry = idx > -1 ? part.slice(idx + 1).trim() : defaults.entry;
113
+ return { appCode: code, entry };
114
+ });
115
+ }
116
+ return items.filter((item) => {
117
+ if (!DEBUG_APP_CODE_REG.test(item.appCode || "") || !item.entry) {
118
+ console.error(
119
+ "[microRouter] micro_app_debug 非法条目已跳过:",
120
+ JSON.stringify(item)
121
+ );
122
+ return false;
123
+ }
124
+ return true;
125
+ });
126
+ }
127
+
128
+ function applyDebugOverrides(apps) {
129
+ const overrides = getDebugOverrides();
130
+ if (!overrides.length) return apps || [];
131
+ const result = (apps || []).slice();
132
+ overrides.forEach((override) => {
133
+ const existing = result.find((app) => app.appCode === override.appCode);
134
+ if (existing) {
135
+ existing.entry = override.entry;
136
+ existing.enabled = true;
137
+ } else {
138
+ result.push({
139
+ appCode: override.appCode,
140
+ appName: override.appCode + "(本地调试)",
141
+ entry: override.entry,
142
+ hasCorejs: true,
143
+ enabled: true,
144
+ });
145
+ }
146
+ console.warn(
147
+ "[microRouter] ⚠ 本地调试覆盖生效:" +
148
+ override.appCode +
149
+ " → " +
150
+ override.entry +
151
+ "(删除 localStorage." +
152
+ DEBUG_STORAGE_KEY +
153
+ " 后刷新恢复)"
154
+ );
155
+ });
156
+ return result;
157
+ }
158
+
159
+ /**
160
+ * activeRule 由 appCode 推导:hash 首段即归属首段,与菜单访问路径天然一致。
161
+ */
162
+ export function buildActiveRule(appCode) {
163
+ const prefix = "#/" + appCode;
164
+ return (location) => {
165
+ const hash = location.hash || "";
166
+ return (
167
+ hash === prefix ||
168
+ hash.indexOf(prefix + "/") === 0 ||
169
+ hash.indexOf(prefix + "?") === 0
170
+ );
171
+ };
172
+ }
173
+
174
+ /**
175
+ * 登记子应用(保活模式):不再走 registerMicroApps/start 的 activeRule 自动装卸,
176
+ * 改为路由钩子驱动的 loadMicroApp 手动装载——首次进入装载,离开只隐藏,切回显示并同步路由。
177
+ * options.subAppMenus 为 menuAdapter.dispatchMenus 的切分结果。
178
+ */
179
+ export function registerSubApps(apps, options = {}) {
180
+ const env = process.env.NODE_ENV || "development";
181
+ const subAppMenus = options.subAppMenus || {};
182
+ const mainAdapter = options.mainAdapter || createDefaultMainAdapter();
183
+ const userInfo = options.userInfo || null;
184
+ microAppConfigs = {};
185
+ (apps || []).forEach((app) => {
186
+ const entry = resolveEntry(app.entry, env);
187
+ if (!entry) {
188
+ console.error(
189
+ "[microRouter] 子应用缺少当前环境 entry,已跳过:" + app.appCode
190
+ );
191
+ return;
192
+ }
193
+ microAppConfigs[app.appCode] = {
194
+ name: app.appCode,
195
+ entry,
196
+ props: {
197
+ appCode: app.appCode,
198
+ menus: subAppMenus[app.appCode] || [],
199
+ token: getToken(),
200
+ lang: localStorage.getItem("i18n-lang") || "",
201
+ userInfo,
202
+ mainAdapter,
203
+ },
204
+ };
205
+ });
206
+ installRouteHook();
207
+ return Object.keys(microAppConfigs);
208
+ }
209
+
210
+ // 当前应处于激活态的子应用(等待容器期间用户可能又切走,异步续体据此丢弃过期操作)
211
+ let currentActiveAppCode = null;
212
+
213
+ function installRouteHook() {
214
+ if (routeHookInstalled) return;
215
+ routeHookInstalled = true;
216
+ router.afterEach((to) => {
217
+ const appCode =
218
+ to.meta && to.meta.isMicroApp && microAppConfigs[to.meta.appCode]
219
+ ? to.meta.appCode
220
+ : null;
221
+ currentActiveAppCode = appCode;
222
+ Object.keys(aliveApps).forEach((code) => {
223
+ if (code !== appCode) {
224
+ deactivateMicroApp(code);
225
+ }
226
+ });
227
+ if (appCode) {
228
+ activateMicroApp(appCode);
229
+ }
230
+ });
231
+ }
232
+
233
+ // 刷新直接落在子应用路由时,afterEach 早于布局渲染(AppMain 懒加载 + showAppMain 延迟),
234
+ // 容器尚未进 DOM——轮询等待,超时显式报错
235
+ const WRAPPER_WAIT_INTERVAL = 100;
236
+ const WRAPPER_WAIT_MAX_TRIES = 100;
237
+
238
+ function waitForWrapper(tryCount = 0) {
239
+ const wrapper = document.getElementById(CONTAINER_WRAPPER_ID);
240
+ if (wrapper) return Promise.resolve(wrapper);
241
+ if (tryCount >= WRAPPER_WAIT_MAX_TRIES) {
242
+ console.error(
243
+ "[microRouter] 等待子应用容器 #" + CONTAINER_WRAPPER_ID + " 超时"
244
+ );
245
+ return Promise.resolve(null);
246
+ }
247
+ return new Promise((resolve) => {
248
+ setTimeout(() => {
249
+ resolve(waitForWrapper(tryCount + 1));
250
+ }, WRAPPER_WAIT_INTERVAL);
251
+ });
252
+ }
253
+
254
+ function getContainerEl(wrapper, appCode) {
255
+ const id = CONTAINER_WRAPPER_ID + "-" + appCode;
256
+ let el = document.getElementById(id);
257
+ if (!el) {
258
+ el = document.createElement("div");
259
+ el.id = id;
260
+ el.style.height = "100%";
261
+ wrapper.appendChild(el);
262
+ }
263
+ return el;
264
+ }
265
+
266
+ function activateMicroApp(appCode) {
267
+ const config = microAppConfigs[appCode];
268
+ if (!config) return;
269
+ waitForWrapper().then((wrapper) => {
270
+ if (!wrapper) return;
271
+ if (currentActiveAppCode !== appCode) return; // 等待期间已切走
272
+ const el = getContainerEl(wrapper, appCode);
273
+ el.style.display = "";
274
+ const alive = aliveApps[appCode];
275
+ if (!alive) {
276
+ aliveApps[appCode] = {
277
+ el,
278
+ instance: loadMicroApp({
279
+ name: config.name,
280
+ entry: config.entry,
281
+ container: el,
282
+ props: config.props,
283
+ }),
284
+ };
285
+ return;
286
+ }
287
+ // 已保活:显示容器并通知子应用恢复路由监听、同步当前 hash(含"切到本应用另一菜单"的深导航)
288
+ notifyMicroApp(alive.instance, { microActive: true });
289
+ });
290
+ }
291
+
292
+ function deactivateMicroApp(appCode) {
293
+ const alive = aliveApps[appCode];
294
+ if (!alive) return;
295
+ alive.el.style.display = "none";
296
+ // 暂停子应用路由监听,防止隐藏期间对主应用的 URL 变化做出反应(回写 URL 互相打架)
297
+ notifyMicroApp(alive.instance, { microActive: false });
298
+ }
299
+
300
+ function notifyMicroApp(instance, props) {
301
+ if (!instance || typeof instance.update !== "function") return;
302
+ const mountPromise = instance.mountPromise || Promise.resolve();
303
+ mountPromise
304
+ .then(() => instance.update(props))
305
+ .catch((e) => {
306
+ console.error("[microRouter] 子应用 update 通知失败:", e);
307
+ });
308
+ }
309
+
310
+ /** 真正卸载全部子应用(登出等场景按需调用;常规页签切换不卸载) */
311
+ export function unmountAllMicroApps() {
312
+ Object.keys(aliveApps).forEach((code) => {
313
+ const alive = aliveApps[code];
314
+ if (alive && alive.instance) {
315
+ alive.instance.unmount().catch(() => {});
316
+ }
317
+ if (alive && alive.el && alive.el.parentNode) {
318
+ alive.el.parentNode.removeChild(alive.el);
319
+ }
320
+ });
321
+ aliveApps = {};
322
+ }
323
+
324
+ /**
325
+ * 每个子应用先按菜单生成精确路由以携带菜单标题等元数据,再追加通配兜底。
326
+ * 路由均不挂组件,内容由 qiankun 挂进 AppMain 的 #Appmicro 容器。
327
+ */
328
+ export function buildSubAppRoutes(apps, subAppMenus = {}) {
329
+ const routes = [];
330
+ (apps || []).forEach((app) => {
331
+ const seenPaths = {};
332
+ (subAppMenus[app.appCode] || []).forEach((menu, index) => {
333
+ let path = getAccessPath(menu).split("?")[0];
334
+ if (!path) return;
335
+ if (!path.startsWith("/")) {
336
+ path = "/" + path;
337
+ }
338
+ if (seenPaths[path]) return;
339
+ seenPaths[path] = true;
340
+ routes.push({
341
+ path,
342
+ name: `micro-${app.appCode}-menu-${menu.id || menu.menuCode || index}`,
343
+ meta: {
344
+ title: menu.menuName || app.appName,
345
+ enTitle: menu.menuEnName || null,
346
+ treePathName: menu.treePathName,
347
+ repeatOpen: menu.repeatOpen,
348
+ isMicroApp: true,
349
+ appCode: app.appCode,
350
+ },
351
+ });
352
+ });
353
+ routes.push({
354
+ path: "/" + app.appCode + "/*",
355
+ name: "micro-" + app.appCode,
356
+ meta: {
357
+ title: app.appName,
358
+ isMicroApp: true,
359
+ appCode: app.appCode,
360
+ },
361
+ });
362
+ });
363
+ return routes;
364
+ }
365
+
366
+ // 子应用表单脚本跳主应用路由必须走该回调,不得直接摸主应用 router
367
+ function createDefaultMainAdapter() {
368
+ return {
369
+ navigate(path) {
370
+ const vueRoot = window.$vueRoot;
371
+ if (vueRoot && vueRoot.$router) {
372
+ vueRoot.$router.push(path).catch(() => {});
373
+ }
374
+ },
375
+ openTab(path) {
376
+ this.navigate(path);
377
+ },
378
+ closeTab(view) {
379
+ const vueRoot = window.$vueRoot;
380
+ if (vueRoot && vueRoot.$store) {
381
+ return vueRoot.$store.dispatch(
382
+ "tagsView/delView",
383
+ view || vueRoot.$route
384
+ );
385
+ }
386
+ return Promise.resolve();
387
+ },
388
+ };
389
+ }