openxiangda 1.0.136 → 1.0.138

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 (28) hide show
  1. package/lib/cli.js +687 -5
  2. package/lib/design-gates.js +16 -3
  3. package/openxiangda-skills/references/best-practices.md +18 -7
  4. package/openxiangda-skills/references/component-guide.md +7 -1
  5. package/openxiangda-skills/references/permission-design-patterns.md +95 -5
  6. package/openxiangda-skills/references/permissions-settings.md +165 -0
  7. package/openxiangda-skills/references/resource-manifest-cheatsheet.md +87 -0
  8. package/package.json +1 -1
  9. package/packages/sdk/dist/{ProcessPreview-Ci8_UsbN.d.mts → ProcessPreview-CZJP8n3e.d.mts} +6 -0
  10. package/packages/sdk/dist/{ProcessPreview-Ci8_UsbN.d.ts → ProcessPreview-CZJP8n3e.d.ts} +6 -0
  11. package/packages/sdk/dist/components/index.cjs +143 -16
  12. package/packages/sdk/dist/components/index.cjs.map +1 -1
  13. package/packages/sdk/dist/components/index.d.mts +8 -2
  14. package/packages/sdk/dist/components/index.d.ts +8 -2
  15. package/packages/sdk/dist/components/index.mjs +143 -16
  16. package/packages/sdk/dist/components/index.mjs.map +1 -1
  17. package/packages/sdk/dist/runtime/index.cjs +169 -25
  18. package/packages/sdk/dist/runtime/index.cjs.map +1 -1
  19. package/packages/sdk/dist/runtime/index.d.mts +1 -1
  20. package/packages/sdk/dist/runtime/index.d.ts +1 -1
  21. package/packages/sdk/dist/runtime/index.mjs +169 -25
  22. package/packages/sdk/dist/runtime/index.mjs.map +1 -1
  23. package/packages/sdk/dist/runtime/react.cjs +26 -9
  24. package/packages/sdk/dist/runtime/react.cjs.map +1 -1
  25. package/packages/sdk/dist/runtime/react.d.mts +13 -3
  26. package/packages/sdk/dist/runtime/react.d.ts +13 -3
  27. package/packages/sdk/dist/runtime/react.mjs +26 -9
  28. package/packages/sdk/dist/runtime/react.mjs.map +1 -1
@@ -12414,6 +12414,16 @@ async function getViewPermission(request, params) {
12414
12414
  }
12415
12415
 
12416
12416
  // packages/sdk/src/components/core/dataManagementApi.ts
12417
+ var FORM_ACTION_PERMISSIONS = [
12418
+ "view",
12419
+ "create",
12420
+ "edit",
12421
+ "delete",
12422
+ "export",
12423
+ "import",
12424
+ "change_records",
12425
+ "workflow"
12426
+ ];
12417
12427
  var unwrap = (response) => {
12418
12428
  if (response instanceof Blob) return response;
12419
12429
  if (response?.data?.result !== void 0) return response.data.result;
@@ -12422,6 +12432,24 @@ var unwrap = (response) => {
12422
12432
  return response;
12423
12433
  };
12424
12434
  var pickData = (value) => value?.data ?? value?.result ?? value;
12435
+ var normalizeActionSummary = (value) => {
12436
+ const raw = pickData(value) || {};
12437
+ const actions = Array.from(
12438
+ /* @__PURE__ */ new Set([...raw.actions || [], ...raw.operations || []])
12439
+ ).filter(
12440
+ (action) => FORM_ACTION_PERMISSIONS.includes(action)
12441
+ );
12442
+ const can = FORM_ACTION_PERMISSIONS.reduce((result, action) => {
12443
+ result[action] = Boolean(raw.can?.[action] ?? actions.includes(action));
12444
+ return result;
12445
+ }, {});
12446
+ return {
12447
+ ...raw,
12448
+ actions,
12449
+ operations: actions,
12450
+ can
12451
+ };
12452
+ };
12425
12453
  var normalizeComponentName = (field) => field?.componentName || field?.component_name || field?.component_type || field?.componentType || field?.type || "TextField";
12426
12454
  var normalizeField = (key, field, system = false) => ({
12427
12455
  ...field,
@@ -12673,6 +12701,14 @@ async function getDataManagementConfig(request, options) {
12673
12701
  });
12674
12702
  return unwrap(response);
12675
12703
  }
12704
+ async function getDataManagementActionSummary(request, params) {
12705
+ const response = await request({
12706
+ url: "/permission/form-group/view-permissions",
12707
+ method: "get",
12708
+ params
12709
+ });
12710
+ return normalizeActionSummary(response);
12711
+ }
12676
12712
  async function saveDataManagementConfig(request, options) {
12677
12713
  const targetFormUuid = options.menuFormUuid || options.formUuid;
12678
12714
  const personal = options.scope === "personal";
@@ -18487,7 +18523,9 @@ var DataManagementList = ({
18487
18523
  requestOverride,
18488
18524
  allowSchemaFallback = false,
18489
18525
  rowActions = [],
18490
- maxVisibleRowActions
18526
+ maxVisibleRowActions,
18527
+ permissionMode = "auto",
18528
+ actionOverrides
18491
18529
  }) => {
18492
18530
  const rootRef = (0, import_react79.useRef)(null);
18493
18531
  const api = (0, import_react79.useMemo)(() => {
@@ -18538,6 +18576,9 @@ var DataManagementList = ({
18538
18576
  const [activeRecord, setActiveRecord] = (0, import_react79.useState)(null);
18539
18577
  const [detailOpen, setDetailOpen] = (0, import_react79.useState)(false);
18540
18578
  const [submitOpen, setSubmitOpen] = (0, import_react79.useState)(false);
18579
+ const [actionSummary, setActionSummary] = (0, import_react79.useState)(null);
18580
+ const [permissionLoading, setPermissionLoading] = (0, import_react79.useState)(permissionMode === "auto");
18581
+ const [permissionError, setPermissionError] = (0, import_react79.useState)(null);
18541
18582
  const fetchStateRef = (0, import_react79.useRef)({});
18542
18583
  const isProcessForm = isProcessFormType(formType);
18543
18584
  const request = api.request;
@@ -18553,6 +18594,67 @@ var DataManagementList = ({
18553
18594
  const confirmDanger = (0, import_react79.useCallback)((title2, content, onOk) => {
18554
18595
  if (confirmAction(title2, content)) onOk();
18555
18596
  }, []);
18597
+ (0, import_react79.useEffect)(() => {
18598
+ let mounted = true;
18599
+ if (permissionMode !== "auto") {
18600
+ setActionSummary(null);
18601
+ setPermissionLoading(false);
18602
+ setPermissionError(null);
18603
+ return () => {
18604
+ mounted = false;
18605
+ };
18606
+ }
18607
+ if (!appType || !formUuid) return void 0;
18608
+ setPermissionLoading(true);
18609
+ setPermissionError(null);
18610
+ getDataManagementActionSummary(request, { appType, formUuid }).then((summary) => {
18611
+ if (!mounted) return;
18612
+ setActionSummary(summary);
18613
+ }).catch((error) => {
18614
+ if (!mounted) return;
18615
+ setActionSummary(null);
18616
+ setPermissionError(error instanceof Error ? error : new Error(String(error)));
18617
+ }).finally(() => {
18618
+ if (mounted) setPermissionLoading(false);
18619
+ });
18620
+ return () => {
18621
+ mounted = false;
18622
+ };
18623
+ }, [appType, formUuid, permissionMode, request]);
18624
+ const baseActionCan = (0, import_react79.useMemo)(() => {
18625
+ if (permissionMode === "auto") {
18626
+ return FORM_ACTION_PERMISSIONS.reduce((result, action) => {
18627
+ result[action] = Boolean(actionSummary?.can?.[action]);
18628
+ return result;
18629
+ }, {});
18630
+ }
18631
+ return FORM_ACTION_PERMISSIONS.reduce((result, action) => {
18632
+ result[action] = true;
18633
+ return result;
18634
+ }, {});
18635
+ }, [actionSummary?.can, permissionMode]);
18636
+ const canAction = (0, import_react79.useCallback)(
18637
+ (action) => {
18638
+ if (permissionLoading && permissionMode === "auto") return false;
18639
+ if (permissionError && permissionMode === "auto") return action === "view";
18640
+ let allowed = permissionMode === "off" ? true : Boolean(baseActionCan[action]);
18641
+ if (permissionMode === "auto") {
18642
+ allowed = allowed && actionOverrides?.[action] !== false;
18643
+ } else if (actionOverrides?.[action] === false) {
18644
+ allowed = false;
18645
+ }
18646
+ if (readonly && ["create", "edit", "delete", "import"].includes(action)) {
18647
+ return false;
18648
+ }
18649
+ return allowed;
18650
+ },
18651
+ [actionOverrides, baseActionCan, permissionError, permissionLoading, permissionMode, readonly]
18652
+ );
18653
+ const canCreate = canAction("create");
18654
+ const canDelete = canAction("delete");
18655
+ const canExport = canAction("export");
18656
+ const canImport = canAction("import");
18657
+ const canWorkflow = canAction("workflow");
18556
18658
  const visibleFields = (0, import_react79.useMemo)(
18557
18659
  () => showFields.map((fieldId) => fields.find((field) => field.fieldId === fieldId)).filter(Boolean),
18558
18660
  [fields, showFields]
@@ -18796,11 +18898,15 @@ var DataManagementList = ({
18796
18898
  const handleDelete = (0, import_react79.useCallback)(
18797
18899
  async (ids) => {
18798
18900
  if (ids.length === 0) return;
18901
+ if (!canDelete) {
18902
+ import_antd39.message.error("\u65E0\u6743\u9650\u5220\u9664\u6570\u636E");
18903
+ return;
18904
+ }
18799
18905
  await deleteDataManagementRows(request, { appType, formUuid, formInstanceIds: ids });
18800
18906
  setSelectedRowKeys([]);
18801
18907
  await loadData({ current, pageSize });
18802
18908
  },
18803
- [appType, current, formUuid, loadData, pageSize, request]
18909
+ [appType, canDelete, current, formUuid, loadData, pageSize, request]
18804
18910
  );
18805
18911
  const getSelectedRecordIds = (0, import_react79.useCallback)(
18806
18912
  () => selectedRowKeys.map((key) => {
@@ -18840,6 +18946,10 @@ var DataManagementList = ({
18840
18946
  }
18841
18947
  };
18842
18948
  const handleExport = async (scope) => {
18949
+ if (!canExport) {
18950
+ import_antd39.message.error("\u65E0\u6743\u9650\u5BFC\u51FA\u6570\u636E");
18951
+ return;
18952
+ }
18843
18953
  const selectedIds = scope === "selected" ? getSelectedRecordIds() : [];
18844
18954
  if (scope === "selected" && selectedIds.length === 0) {
18845
18955
  import_antd39.message.warning("\u8BF7\u5148\u9009\u62E9\u8981\u5BFC\u51FA\u7684\u8BB0\u5F55");
@@ -18878,6 +18988,10 @@ var DataManagementList = ({
18878
18988
  }
18879
18989
  };
18880
18990
  const handleDownloadTemplate = async () => {
18991
+ if (!canImport) {
18992
+ import_antd39.message.error("\u65E0\u6743\u9650\u5BFC\u5165\u6570\u636E");
18993
+ return;
18994
+ }
18881
18995
  setTemplateDownloading(true);
18882
18996
  try {
18883
18997
  const response = await downloadDataManagementImportTemplate(request, { appType, formUuid });
@@ -18891,6 +19005,8 @@ var DataManagementList = ({
18891
19005
  }
18892
19006
  };
18893
19007
  const loadTransferRecords = async (type) => {
19008
+ if (type === "import" && !canImport) return;
19009
+ if (type === "export" && !canExport) return;
18894
19010
  setRecordTab(type);
18895
19011
  setRecordsOpen(true);
18896
19012
  const result = await getDataManagementTransferRecords(request, {
@@ -18903,6 +19019,10 @@ var DataManagementList = ({
18903
19019
  setTransferRecords(result.records);
18904
19020
  };
18905
19021
  const handleImportPreview = async (file) => {
19022
+ if (!canImport) {
19023
+ import_antd39.message.error("\u65E0\u6743\u9650\u5BFC\u5165\u6570\u636E");
19024
+ return import_antd39.Upload.LIST_IGNORE;
19025
+ }
18906
19026
  const base64 = await fileToBase64(file);
18907
19027
  setImportBase64(base64);
18908
19028
  const result = await importPreviewDataManagementRows(request, {
@@ -18916,6 +19036,10 @@ var DataManagementList = ({
18916
19036
  };
18917
19037
  const handleImportConfirm = async () => {
18918
19038
  if (!importBase64) return;
19039
+ if (!canImport) {
19040
+ import_antd39.message.error("\u65E0\u6743\u9650\u5BFC\u5165\u6570\u636E");
19041
+ return;
19042
+ }
18919
19043
  await importDataManagementRows(request, { appType, formUuid, fileBase64: importBase64 });
18920
19044
  import_antd39.message.success("\u5BFC\u5165\u4EFB\u52A1\u5DF2\u521B\u5EFA");
18921
19045
  setImportOpen(false);
@@ -18924,7 +19048,7 @@ var DataManagementList = ({
18924
19048
  await loadData({ current: 1, pageSize });
18925
19049
  };
18926
19050
  const visibleRowActionLimit = normalizeMaxVisibleRowActions(maxVisibleRowActions);
18927
- const rowActionCount = 1 + rowActions.length + (readonly ? 0 : 1) + (isProcessForm ? 1 : 0);
19051
+ const rowActionCount = 1 + rowActions.filter((action) => !action.requiredAction || canAction(action.requiredAction)).length + (canDelete ? 1 : 0) + (isProcessForm && canWorkflow ? 1 : 0);
18928
19052
  const actionColumnWidth = Math.max(
18929
19053
  ACTION_COLUMN_MIN_WIDTH,
18930
19054
  Math.min(rowActionCount, visibleRowActionLimit) * ACTION_BUTTON_ESTIMATED_WIDTH + (rowActionCount > visibleRowActionLimit ? ACTION_MORE_BUTTON_WIDTH : 0) + ACTION_COLUMN_HORIZONTAL_PADDING
@@ -18964,13 +19088,13 @@ var DataManagementList = ({
18964
19088
  label: "\u8BE6\u60C5",
18965
19089
  onClick: () => handleDetail(record)
18966
19090
  },
18967
- ...rowActions.map((action) => ({
19091
+ ...rowActions.filter((action) => !action.requiredAction || canAction(action.requiredAction)).map((action) => ({
18968
19092
  key: action.key,
18969
19093
  label: action.label,
18970
19094
  danger: action.danger,
18971
19095
  onClick: () => action.onClick(record)
18972
19096
  })),
18973
- ...!readonly ? [
19097
+ ...canDelete ? [
18974
19098
  {
18975
19099
  key: "delete",
18976
19100
  label: "\u5220\u9664",
@@ -18983,7 +19107,7 @@ var DataManagementList = ({
18983
19107
  )
18984
19108
  }
18985
19109
  ] : [],
18986
- ...isProcessForm ? [
19110
+ ...isProcessForm && canWorkflow ? [
18987
19111
  {
18988
19112
  key: "workflow",
18989
19113
  label: "\u6D41\u7A0B\u65E5\u5FD7",
@@ -19044,7 +19168,9 @@ var DataManagementList = ({
19044
19168
  handleDetail,
19045
19169
  isProcessForm,
19046
19170
  lockFieldIds,
19047
- readonly,
19171
+ canAction,
19172
+ canDelete,
19173
+ canWorkflow,
19048
19174
  rowActions,
19049
19175
  updateColumnWidth,
19050
19176
  visibleRowActionLimit,
@@ -19084,7 +19210,7 @@ var DataManagementList = ({
19084
19210
  /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "mx-auto flex min-h-0 w-full max-w-[1440px] flex-col px-4 py-4 md:px-6", children: [
19085
19211
  title && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("h2", { className: "m-0 text-xl font-semibold text-ant-color-text", children: title }) }),
19086
19212
  /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "mb-4 flex flex-col gap-3 md:flex-row md:items-center", children: /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_antd39.Space, { wrap: true, children: [
19087
- !readonly && (submitRenderer || runtimeFormSchema) && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd39.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.PlusOutlined, {}), type: "primary", onClick: () => setSubmitOpen(true), children: "\u65B0\u589E" }),
19213
+ canCreate && (submitRenderer || runtimeFormSchema) && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd39.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.PlusOutlined, {}), type: "primary", onClick: () => setSubmitOpen(true), children: "\u65B0\u589E" }),
19088
19214
  /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19089
19215
  import_antd39.Input.Search,
19090
19216
  {
@@ -19110,7 +19236,7 @@ var DataManagementList = ({
19110
19236
  ),
19111
19237
  /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd39.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.FilterOutlined, {}), onClick: () => setFilterOpen(true), children: "\u7B5B\u9009" }),
19112
19238
  /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd39.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.SettingOutlined, {}), onClick: () => setColumnOpen(true), children: "\u5217\u8BBE\u7F6E" }),
19113
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19239
+ canExport && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19114
19240
  import_antd39.Dropdown,
19115
19241
  {
19116
19242
  getPopupContainer,
@@ -19135,7 +19261,7 @@ var DataManagementList = ({
19135
19261
  children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd39.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.DownloadOutlined, {}), children: "\u5BFC\u51FA" })
19136
19262
  }
19137
19263
  ),
19138
- !readonly && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19264
+ canImport && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19139
19265
  import_antd39.Dropdown,
19140
19266
  {
19141
19267
  getPopupContainer,
@@ -19161,7 +19287,7 @@ var DataManagementList = ({
19161
19287
  " \u6761"
19162
19288
  ] }),
19163
19289
  /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_antd39.Space, { wrap: true, children: [
19164
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19290
+ canExport && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19165
19291
  import_antd39.Button,
19166
19292
  {
19167
19293
  icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.DownloadOutlined, {}),
@@ -19173,8 +19299,8 @@ var DataManagementList = ({
19173
19299
  children: "\u5BFC\u51FA\u9009\u4E2D"
19174
19300
  }
19175
19301
  ),
19176
- !readonly && isProcessForm && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd39.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.SwapOutlined, {}), onClick: handleBatchApprove, children: "\u6279\u91CF\u5BA1\u6279" }),
19177
- !readonly && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19302
+ isProcessForm && canWorkflow && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd39.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.SwapOutlined, {}), onClick: handleBatchApprove, children: "\u6279\u91CF\u5BA1\u6279" }),
19303
+ canDelete && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
19178
19304
  import_antd39.Button,
19179
19305
  {
19180
19306
  danger: true,
@@ -19479,7 +19605,7 @@ var DataManagementList = ({
19479
19605
  width: 720,
19480
19606
  onCancel: () => setImportOpen(false),
19481
19607
  onOk: handleImportConfirm,
19482
- okButtonProps: { disabled: !importBase64 },
19608
+ okButtonProps: { disabled: !importBase64 || !canImport },
19483
19609
  okText: "\u786E\u8BA4\u5BFC\u5165",
19484
19610
  children: [
19485
19611
  /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "mb-3 flex flex-col gap-3 rounded-lg border border-ant-border-secondary bg-ant-bg-container px-4 py-3 md:flex-row md:items-center md:justify-between", children: [
@@ -19492,6 +19618,7 @@ var DataManagementList = ({
19492
19618
  {
19493
19619
  icon: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_icons16.DownloadOutlined, {}),
19494
19620
  loading: templateDownloading,
19621
+ disabled: !canImport,
19495
19622
  onClick: handleDownloadTemplate,
19496
19623
  children: "\u4E0B\u8F7D\u5BFC\u5165\u6A21\u677F"
19497
19624
  }
@@ -19542,8 +19669,8 @@ var DataManagementList = ({
19542
19669
  {
19543
19670
  value: recordTab,
19544
19671
  options: [
19545
- { label: "\u5BFC\u5165\u8BB0\u5F55", value: "import" },
19546
- { label: "\u5BFC\u51FA\u8BB0\u5F55", value: "export" }
19672
+ ...canImport ? [{ label: "\u5BFC\u5165\u8BB0\u5F55", value: "import" }] : [],
19673
+ ...canExport ? [{ label: "\u5BFC\u51FA\u8BB0\u5F55", value: "export" }] : []
19547
19674
  ],
19548
19675
  onChange: (value) => loadTransferRecords(value)
19549
19676
  }