openxiangda 1.0.8 → 1.0.9

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/cli.js CHANGED
@@ -743,6 +743,8 @@ async function menu(args) {
743
743
  fail('用法: openxiangda menu create <menuCode> --name <text>');
744
744
  }
745
745
  const target = getWorkspaceTarget(config, profileName, flags);
746
+ const formUuid = flags['form-uuid'] || resolveOptionalFormUuid(target.bound, flags['form-code']);
747
+ const pageId = flags['page-id'] || resolveOptionalPageId(target.bound, flags['page-code']);
746
748
  const data = await requestWithAuth(
747
749
  config,
748
750
  target.profileName,
@@ -752,14 +754,21 @@ async function menu(args) {
752
754
  body: {
753
755
  name,
754
756
  type: flags.type || 'nav',
755
- formUuid: flags['form-uuid'] || resolveOptionalFormUuid(target.bound, flags['form-code']),
756
- pageId: flags['page-id'] || resolveOptionalPageId(target.bound, flags['page-code']),
757
+ formUuid,
758
+ pageId,
757
759
  parentId: flags['parent-id'] || null,
758
760
  icon: flags.icon || null,
759
761
  },
760
762
  }
761
763
  );
762
- if (data?.id) saveMenuResource(target, menuCode, data.id, { name });
764
+ if (data?.id) {
765
+ saveMenuResource(target, menuCode, data.id, {
766
+ name,
767
+ type: flags.type || 'nav',
768
+ ...(formUuid ? { formUuid } : {}),
769
+ ...(pageId ? { pageId } : {}),
770
+ });
771
+ }
763
772
  if (flags.json) return writeJson(data);
764
773
  print(JSON.stringify(data, null, 2));
765
774
  return;
@@ -1308,7 +1317,7 @@ async function permission(args) {
1308
1317
  const [groupCode] = positional;
1309
1318
  const name = flags.name || positional.slice(1).join(' ') || groupCode;
1310
1319
  if (!groupCode || !name) {
1311
- fail('用法: openxiangda permission page-group-create <groupCode> --name <text>');
1320
+ fail('用法: openxiangda permission page-group-create <groupCode> --name <text> [--menu-codes <menuCode...>|--page-codes <pageCode...>|--form-codes <formCode...>|--menu-ids <id...>]');
1312
1321
  }
1313
1322
  const target = getWorkspaceTarget(config, profileName, flags);
1314
1323
  const data = await requestWithAuth(
@@ -1320,7 +1329,7 @@ async function permission(args) {
1320
1329
  body: {
1321
1330
  name,
1322
1331
  roles: splitList(flags.roles),
1323
- menuFormUuids: resolveFormUuidList(target.bound, flags['menu-form-uuids'], flags['form-codes']),
1332
+ menuFormUuids: resolvePagePermissionMenuTargets(target.bound, flags),
1324
1333
  },
1325
1334
  }
1326
1335
  );
@@ -1891,10 +1900,29 @@ function resolveRoleId(bound, roleKey, flags = {}) {
1891
1900
  return mapped || roleKey;
1892
1901
  }
1893
1902
 
1894
- function resolveFormUuidList(bound, rawFormUuids, rawFormCodes) {
1895
- const direct = splitList(rawFormUuids);
1896
- const fromCodes = splitList(rawFormCodes).map(code => resolveOptionalFormUuid(bound, code));
1897
- return [...direct, ...fromCodes].filter(Boolean);
1903
+ function resolvePagePermissionMenuTargets(bound, flags = {}) {
1904
+ const direct = [
1905
+ ...splitList(flags['menu-form-uuids']),
1906
+ ...splitList(flags['menu-ids']),
1907
+ ];
1908
+ const fromMenuCodes = splitList(flags['menu-codes']).map(code => resolveMenuId(bound, code));
1909
+ const fromFormCodes = splitList(flags['form-codes']).map(code => resolveOptionalFormUuid(bound, code));
1910
+ const fromPageCodes = splitList(flags['page-codes']).map(code => resolvePageMenuTarget(bound, code));
1911
+ return unique([...direct, ...fromMenuCodes, ...fromFormCodes, ...fromPageCodes].filter(Boolean));
1912
+ }
1913
+
1914
+ function resolvePageMenuTarget(bound, pageCode) {
1915
+ const pageId = resolveOptionalPageId(bound, pageCode);
1916
+ const menuEntry = findMenuEntry(bound, entry => {
1917
+ if (!entry) return false;
1918
+ return entry.pageId === pageId || entry.pageCode === pageCode || entry.routeKey === pageCode;
1919
+ });
1920
+ if (menuEntry?.menuId) return menuEntry.menuId;
1921
+ fail(`页面 ${pageCode} 未找到已绑定菜单。请先发布/创建菜单,或直接传 --menu-codes/--menu-ids。`);
1922
+ }
1923
+
1924
+ function findMenuEntry(bound, predicate) {
1925
+ return Object.values(bound.resources?.menus || {}).find(predicate);
1898
1926
  }
1899
1927
 
1900
1928
  function resolveSettingsFormUuid(bound, formKey, flags = {}) {
@@ -2249,6 +2277,10 @@ function splitList(value) {
2249
2277
  .filter(Boolean);
2250
2278
  }
2251
2279
 
2280
+ function unique(values) {
2281
+ return [...new Set(values)];
2282
+ }
2283
+
2252
2284
  function renderTerminalQr(text) {
2253
2285
  try {
2254
2286
  require('qrcode-terminal').generate(text, { small: true });
@@ -369,11 +369,11 @@ Body:
369
369
  {
370
370
  "name": "销售可见页面",
371
371
  "roles": ["sales"],
372
- "menuFormUuids": ["FORM_XXX"]
372
+ "menuFormUuids": ["FORM_XXX", "MENU_ID_FOR_CODE_PAGE"]
373
373
  }
374
374
  ```
375
375
 
376
- An empty `menuFormUuids` array means all menus/pages are visible to the matched roles.
376
+ An empty `menuFormUuids` array means all menus/pages are visible to the matched roles. For form menus this field can contain form UUIDs; for custom code page menus use the actual menu ID returned by `/apps/:appType/menus`, not the code page `PAGE_...` legacy form UUID.
377
377
 
378
378
  ### GET `/apps/:appType/page-permission-groups/:groupId`
379
379
 
@@ -24,7 +24,7 @@ Page permission groups map role codes to visible menu `formUuid` values:
24
24
  {
25
25
  "name": "销售页面",
26
26
  "roles": ["sales"],
27
- "menuFormUuids": ["FORM_CUSTOMER", "FORM_ORDER"]
27
+ "menuFormUuids": ["FORM_CUSTOMER", "FORM_ORDER", "MENU_ID_FOR_CODE_PAGE"]
28
28
  }
29
29
  ```
30
30
 
@@ -32,7 +32,8 @@ Rules:
32
32
 
33
33
  - `roles: []` means all roles can match.
34
34
  - `menuFormUuids: []` means all menus/pages are visible to matched roles.
35
- - Prefer `--form-codes` in CLI so each profile resolves its own form UUIDs.
35
+ - Prefer `--form-codes` in CLI for form menus so each profile resolves its own form UUIDs.
36
+ - Prefer `--page-codes` or `--menu-codes` in CLI for custom code page menus so each profile resolves to real menu IDs.
36
37
 
37
38
  ## Form Permission Groups
38
39
 
@@ -40,9 +40,10 @@ Page permission groups control menu/page visibility:
40
40
 
41
41
  ```bash
42
42
  openxiangda permission page-group-create sales_pages --name "销售页面" --roles sales --form-codes customer,orders --profile dev
43
+ openxiangda permission page-group-create portal_pages --name "门户页面" --page-codes portal_pc,portal_mobile --profile dev
43
44
  ```
44
45
 
45
- Empty `--form-codes` and `--menu-form-uuids` means all menus/pages are visible to matched roles.
46
+ Use `--page-codes` or `--menu-codes` for custom code page menus; the CLI resolves code pages to their published menu IDs. Use `--form-codes` for form menus; the CLI resolves forms to profile-local form UUIDs. Empty target lists mean all menus/pages are visible to matched roles.
46
47
 
47
48
  ## Form Permission Groups
48
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
5
5
  "private": false,
6
6
  "bin": {