sy-form-components 0.2.8 → 0.2.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/dist/index.js CHANGED
@@ -6893,6 +6893,38 @@ var normalizeField = (key, field, system = false) => ({
6893
6893
  width: field?.width,
6894
6894
  system
6895
6895
  });
6896
+ var SYSTEM_VALUE_ALIASES = {
6897
+ formInstanceId: ["formInstanceId", "formInstId", "form_instance_id", "processInstanceId"],
6898
+ instanceTitle: ["instanceTitle", "instance_title", "processInstanceTitle", "title"],
6899
+ createdBy: ["createdBy", "created_by", "originator"],
6900
+ createdByName: ["createdByName", "created_by_name", "originatorName", "creatorName"],
6901
+ createdByDepartmentId: ["createdByDepartmentId", "created_by_department_id", "originatorCorp"],
6902
+ createdByDepartmentName: [
6903
+ "createdByDepartmentName",
6904
+ "created_by_department_name",
6905
+ "originatorDepartmentName",
6906
+ "originatorCorpName"
6907
+ ],
6908
+ createdAt: ["createdAt", "created_at", "createTime", "gmtCreate"],
6909
+ updatedAt: ["updatedAt", "updated_at", "modifiedTime", "modifyTime", "gmtModified"]
6910
+ };
6911
+ var pickAliasValue = (record, aliases) => {
6912
+ for (const alias of aliases) {
6913
+ const value = record?.[alias];
6914
+ if (value !== void 0 && value !== null && value !== "") return value;
6915
+ }
6916
+ return void 0;
6917
+ };
6918
+ var normalizeDataManagementRecord = (record) => {
6919
+ if (!record || typeof record !== "object" || Array.isArray(record)) return record;
6920
+ const normalized = { ...record };
6921
+ Object.entries(SYSTEM_VALUE_ALIASES).forEach(([targetKey, aliases]) => {
6922
+ if (normalized[targetKey] !== void 0 && normalized[targetKey] !== null) return;
6923
+ const aliasValue = pickAliasValue(record, aliases);
6924
+ if (aliasValue !== void 0) normalized[targetKey] = aliasValue;
6925
+ });
6926
+ return normalized;
6927
+ };
6896
6928
  var PROCESS_INSTANCE_STATUS_OPTIONS = [
6897
6929
  { label: "\u5F85\u5904\u7406", value: "pending" },
6898
6930
  { label: "\u5BA1\u6279\u4E2D", value: "running" },
@@ -6947,15 +6979,29 @@ var PROCESS_SYSTEM_FIELDS = [
6947
6979
  )
6948
6980
  ];
6949
6981
  var BASE_SYSTEM_FIELDS = [
6950
- normalizeField("createTime", { label: "\u521B\u5EFA\u65F6\u95F4", componentName: "DateField", width: 170 }, true),
6951
6982
  normalizeField(
6952
- "modifiedTime",
6953
- { label: "\u66F4\u65B0\u65F6\u95F4", componentName: "DateField", width: 170 },
6983
+ "instanceTitle",
6984
+ { label: "\u5B9E\u4F8B\u6807\u9898", componentName: "TextField", width: 220, displayable: true },
6954
6985
  true
6955
6986
  ),
6956
6987
  normalizeField(
6957
- "originatorName",
6958
- { label: "\u521B\u5EFA\u4EBA", componentName: "TextField", width: 130 },
6988
+ "createdByName",
6989
+ { label: "\u521B\u5EFA\u4EBA", componentName: "TextField", width: 130, displayable: true },
6990
+ true
6991
+ ),
6992
+ normalizeField(
6993
+ "createdByDepartmentName",
6994
+ { label: "\u521B\u5EFA\u4EBA\u90E8\u95E8", componentName: "TextField", width: 150, displayable: true },
6995
+ true
6996
+ ),
6997
+ normalizeField(
6998
+ "createdAt",
6999
+ { label: "\u521B\u5EFA\u65F6\u95F4", componentName: "DateField", width: 170, displayable: true },
7000
+ true
7001
+ ),
7002
+ normalizeField(
7003
+ "updatedAt",
7004
+ { label: "\u66F4\u65B0\u65F6\u95F4", componentName: "DateField", width: 170, displayable: true },
6959
7005
  true
6960
7006
  )
6961
7007
  ];
@@ -6976,7 +7022,7 @@ var normalizeDataManagementList = (payload) => {
6976
7022
  const records = body?.data || body?.records || body?.list || body?.items || [];
6977
7023
  const total = body?.totalCount ?? body?.total ?? body?.count ?? records.length;
6978
7024
  return {
6979
- records: Array.isArray(records) ? records : [],
7025
+ records: Array.isArray(records) ? records.map(normalizeDataManagementRecord) : [],
6980
7026
  total: Number(total) || 0
6981
7027
  };
6982
7028
  };
@@ -6996,7 +7042,9 @@ var buildFilterPayload = (group) => {
6996
7042
  var normalizeColumnConfig = (cfg, fields) => {
6997
7043
  const allowed = new Set(fields.map((field) => field.fieldId));
6998
7044
  const configured = Array.isArray(cfg?.showFields) ? cfg.showFields.filter((fieldId) => allowed.has(fieldId)) : [];
6999
- const defaultShow = fields.filter((field) => !field.system || field.displayable).slice(0, 8).map((field) => field.fieldId);
7045
+ const defaultBusinessFields = fields.filter((field) => !field.system).slice(0, 8).map((field) => field.fieldId);
7046
+ const defaultSystemFields = fields.filter((field) => field.system && field.displayable).map((field) => field.fieldId);
7047
+ const defaultShow = [...defaultBusinessFields, ...defaultSystemFields];
7000
7048
  return {
7001
7049
  showFields: configured.length > 0 ? configured : defaultShow,
7002
7050
  widths: cfg?.widths || {},
@@ -7658,8 +7706,14 @@ var import_react49 = require("react");
7658
7706
  var FORM_INSTANCE_METADATA_KEYS = /* @__PURE__ */ new Set([
7659
7707
  "appType",
7660
7708
  "code",
7709
+ "createTime",
7710
+ "created_at",
7661
7711
  "createdAt",
7662
7712
  "createdBy",
7713
+ "created_by",
7714
+ "created_by_department_id",
7715
+ "created_by_department_name",
7716
+ "created_by_name",
7663
7717
  "createdByDepartmentId",
7664
7718
  "createdByDepartmentName",
7665
7719
  "createdByName",
@@ -7671,9 +7725,18 @@ var FORM_INSTANCE_METADATA_KEYS = /* @__PURE__ */ new Set([
7671
7725
  "formUuid",
7672
7726
  "instanceTitle",
7673
7727
  "message",
7728
+ "modifiedTime",
7729
+ "modifyTime",
7730
+ "originator",
7731
+ "originatorCorp",
7732
+ "originatorCorpName",
7733
+ "originatorDepartmentName",
7734
+ "originatorName",
7735
+ "processInstanceTitle",
7674
7736
  "result",
7675
7737
  "success",
7676
7738
  "title",
7739
+ "updated_at",
7677
7740
  "updatedAt"
7678
7741
  ]);
7679
7742
  var isPlainRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -7720,6 +7783,76 @@ var extractFormValues = (formInstance, fieldIds) => {
7720
7783
  const flatValues = pickKnownFields(formInstance, fieldIds);
7721
7784
  return Object.keys(flatValues).length > 0 ? flatValues : null;
7722
7785
  };
7786
+ var firstValue = (source, keys) => {
7787
+ for (const key of keys) {
7788
+ const value = source[key];
7789
+ if (value !== void 0 && value !== null && value !== "") return value;
7790
+ }
7791
+ return void 0;
7792
+ };
7793
+ var normalizeFormInstanceInfo = (formInstance, fallback) => {
7794
+ if (!isPlainRecord(formInstance)) return null;
7795
+ const creator = isPlainRecord(formInstance.creator) ? formInstance.creator : {};
7796
+ const formInstanceId = firstValue(formInstance, [
7797
+ "formInstanceId",
7798
+ "formInstId",
7799
+ "form_instance_id",
7800
+ "id"
7801
+ ]);
7802
+ const createdByName = firstValue(formInstance, [
7803
+ "createdByName",
7804
+ "created_by_name",
7805
+ "originatorName",
7806
+ "creatorName"
7807
+ ]);
7808
+ const createdByDepartmentName = firstValue(formInstance, [
7809
+ "createdByDepartmentName",
7810
+ "created_by_department_name",
7811
+ "originatorDepartmentName",
7812
+ "originatorCorpName"
7813
+ ]);
7814
+ return {
7815
+ ...formInstance,
7816
+ formInstanceId: formInstanceId || fallback?.formInstanceId || "",
7817
+ formUuid: formInstance.formUuid || fallback?.formUuid || "",
7818
+ appType: formInstance.appType || fallback?.appType || "",
7819
+ data: isPlainRecord(formInstance.data) ? formInstance.data : {},
7820
+ title: firstValue(formInstance, [
7821
+ "title",
7822
+ "instanceTitle",
7823
+ "instance_title",
7824
+ "processInstanceTitle"
7825
+ ]) || void 0,
7826
+ instanceTitle: firstValue(formInstance, [
7827
+ "instanceTitle",
7828
+ "instance_title",
7829
+ "processInstanceTitle",
7830
+ "title"
7831
+ ]) || void 0,
7832
+ creator: {
7833
+ userId: creator.userId || creator.id || formInstance.createdBy || formInstance.originator || "",
7834
+ name: creator.name || createdByName || "",
7835
+ avatar: creator.avatar,
7836
+ department: creator.department || createdByDepartmentName || ""
7837
+ },
7838
+ createdBy: firstValue(formInstance, ["createdBy", "created_by", "originator"]),
7839
+ createdByName,
7840
+ createdByDepartmentId: firstValue(formInstance, [
7841
+ "createdByDepartmentId",
7842
+ "created_by_department_id",
7843
+ "originatorCorp"
7844
+ ]),
7845
+ createdByDepartmentName,
7846
+ createdAt: firstValue(formInstance, ["createdAt", "created_at", "createTime", "gmtCreate"]) || "",
7847
+ updatedAt: firstValue(formInstance, [
7848
+ "updatedAt",
7849
+ "updated_at",
7850
+ "modifiedTime",
7851
+ "modifyTime",
7852
+ "gmtModified"
7853
+ ])
7854
+ };
7855
+ };
7723
7856
 
7724
7857
  // src/hooks/useFormDetail.ts
7725
7858
  function useFormDetail(options) {
@@ -7750,8 +7883,13 @@ function useFormDetail(options) {
7750
7883
  if (!permResult || !hasViewOperation(permResult.operations, "view")) {
7751
7884
  onPermissionDenied?.();
7752
7885
  }
7886
+ const normalizedInfo = normalizeFormInstanceInfo(formResult, {
7887
+ formUuid,
7888
+ appType,
7889
+ formInstanceId
7890
+ });
7753
7891
  setPermissions(permResult);
7754
- setInstanceInfo(formResult);
7892
+ setInstanceInfo(normalizedInfo);
7755
7893
  setFormData(extractFormValues(formResult, fieldIds));
7756
7894
  } catch (error) {
7757
7895
  console.error("[useFormDetail] Failed to load data:", error);
@@ -9731,8 +9869,8 @@ var SummaryPanel = ({
9731
9869
  )
9732
9870
  ] }),
9733
9871
  /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("h1", { className: "m-0 break-words text-2xl font-semibold leading-9 text-ant-text md:text-[28px]", children: title }),
9734
- items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "mt-5 grid grid-cols-1 gap-4 md:grid-cols-3", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
9735
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-gray-100 text-ant-text-secondary", children: item.icon }),
9872
+ items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "mt-5 grid grid-cols-1 gap-4 md:grid-cols-4", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
9873
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-gray-100 text-ant-text-secondary", children: item.icon }),
9736
9874
  /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { className: "min-w-0", children: [
9737
9875
  /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "block text-xs leading-5 text-ant-text-tertiary", children: item.label }),
9738
9876
  /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "block break-words text-sm font-medium leading-6 text-ant-text", children: item.value || "-" })
@@ -9847,6 +9985,7 @@ var ProcessPreview = ({
9847
9985
  // src/modules/DataManagementList.tsx
9848
9986
  var import_react61 = require("react");
9849
9987
  var import_antd32 = require("antd");
9988
+ var import_dayjs5 = __toESM(require("dayjs"));
9850
9989
  var import_icons11 = require("@ant-design/icons");
9851
9990
  var import_jsx_runtime89 = require("react/jsx-runtime");
9852
9991
  var createGroup = () => ({
@@ -9881,6 +10020,11 @@ var formatPrimitive = (value) => {
9881
10020
  return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "text-ant-color-text-quaternary", children: "--" });
9882
10021
  return String(value);
9883
10022
  };
10023
+ var formatDateTime = (value) => {
10024
+ if (value === void 0 || value === null || value === "") return formatPrimitive("");
10025
+ const parsed = (0, import_dayjs5.default)(value);
10026
+ return parsed.isValid() ? parsed.format("YYYY-MM-DD HH:mm:ss") : String(value);
10027
+ };
9884
10028
  var pickOptionLabel = (field, value) => {
9885
10029
  const options = field.options || field.optionList || field.option_list || field.componentProps?.options || [];
9886
10030
  const scalar = typeof value === "object" ? value?.value ?? value?.id ?? value?.label ?? value?.name : value;
@@ -9908,6 +10052,9 @@ var renderStatusTag = (value, fieldId) => {
9908
10052
  var renderCellValue = (value, field) => {
9909
10053
  const status = renderStatusTag(value, field.fieldId);
9910
10054
  if (status) return status;
10055
+ if (field.componentName === "DateField" || field.componentName === "DateTimeField") {
10056
+ return formatDateTime(value);
10057
+ }
9911
10058
  if (Array.isArray(value)) {
9912
10059
  if (value.length === 0) return formatPrimitive("");
9913
10060
  if (field.componentName === "ImageField") {
@@ -10086,6 +10233,54 @@ function FilterGroupEditor({
10086
10233
  }
10087
10234
  );
10088
10235
  }
10236
+ function ResizableColumnTitle({
10237
+ label,
10238
+ width,
10239
+ onResize,
10240
+ onResizeEnd
10241
+ }) {
10242
+ const dragRef = (0, import_react61.useRef)({ startX: 0, startWidth: width, latestWidth: width });
10243
+ const handleMouseDown = (event) => {
10244
+ event.preventDefault();
10245
+ event.stopPropagation();
10246
+ dragRef.current = {
10247
+ startX: event.clientX,
10248
+ startWidth: width,
10249
+ latestWidth: width
10250
+ };
10251
+ const handleMouseMove = (moveEvent) => {
10252
+ const nextWidth = Math.min(
10253
+ 520,
10254
+ Math.max(96, dragRef.current.startWidth + moveEvent.clientX - dragRef.current.startX)
10255
+ );
10256
+ dragRef.current.latestWidth = nextWidth;
10257
+ onResize(nextWidth);
10258
+ };
10259
+ const handleMouseUp = () => {
10260
+ document.removeEventListener("mousemove", handleMouseMove);
10261
+ document.removeEventListener("mouseup", handleMouseUp);
10262
+ onResizeEnd(dragRef.current.latestWidth);
10263
+ };
10264
+ document.addEventListener("mousemove", handleMouseMove);
10265
+ document.addEventListener("mouseup", handleMouseUp);
10266
+ };
10267
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("span", { className: "relative flex min-w-0 items-center pr-3", children: [
10268
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "min-w-0 truncate", children: label }),
10269
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10270
+ "span",
10271
+ {
10272
+ "aria-hidden": true,
10273
+ className: "absolute -right-2 top-1/2 h-5 w-2 -translate-y-1/2 cursor-col-resize rounded hover:bg-ant-color-primary",
10274
+ onClick: (event) => {
10275
+ event.preventDefault();
10276
+ event.stopPropagation();
10277
+ },
10278
+ onMouseDown: handleMouseDown,
10279
+ title: "\u62D6\u62FD\u8C03\u6574\u5217\u5BBD"
10280
+ }
10281
+ )
10282
+ ] });
10283
+ }
10089
10284
  var DataManagementList = ({
10090
10285
  appType,
10091
10286
  formUuid,
@@ -10095,6 +10290,7 @@ var DataManagementList = ({
10095
10290
  configScope = "global",
10096
10291
  title,
10097
10292
  detailRenderer,
10293
+ detailPageUrlBuilder,
10098
10294
  submitRenderer,
10099
10295
  requestOverride,
10100
10296
  rowActions = []
@@ -10108,9 +10304,11 @@ var DataManagementList = ({
10108
10304
  }, [requestOverride]);
10109
10305
  const [fields, setFields] = (0, import_react61.useState)([]);
10110
10306
  const [config, setConfig] = (0, import_react61.useState)({});
10307
+ const [formType, setFormType] = (0, import_react61.useState)("form");
10111
10308
  const [showFields, setShowFields] = (0, import_react61.useState)([]);
10112
10309
  const [lockFieldIds, setLockFieldIds] = (0, import_react61.useState)([]);
10113
10310
  const [widths, setWidths] = (0, import_react61.useState)({});
10311
+ const widthsRef = (0, import_react61.useRef)({});
10114
10312
  const [sort, setSort] = (0, import_react61.useState)([]);
10115
10313
  const [density, setDensity] = (0, import_react61.useState)("middle");
10116
10314
  const [detailOpenMode, setDetailOpenMode] = (0, import_react61.useState)("drawer");
@@ -10147,7 +10345,7 @@ var DataManagementList = ({
10147
10345
  const fetchStateRef = (0, import_react61.useRef)({});
10148
10346
  const request = api.request;
10149
10347
  const getPopupContainer = (0, import_react61.useCallback)(
10150
- (triggerNode) => triggerNode?.parentElement || rootRef.current || document.body,
10348
+ (triggerNode) => rootRef.current || triggerNode?.ownerDocument?.body || (typeof document !== "undefined" ? document.body : triggerNode?.parentElement),
10151
10349
  []
10152
10350
  );
10153
10351
  const confirmDanger = (0, import_react61.useCallback)((title2, content, onOk) => {
@@ -10157,6 +10355,9 @@ var DataManagementList = ({
10157
10355
  () => showFields.map((fieldId) => fields.find((field) => field.fieldId === fieldId)).filter(Boolean),
10158
10356
  [fields, showFields]
10159
10357
  );
10358
+ (0, import_react61.useEffect)(() => {
10359
+ widthsRef.current = widths;
10360
+ }, [widths]);
10160
10361
  (0, import_react61.useEffect)(() => {
10161
10362
  fetchStateRef.current = {
10162
10363
  current,
@@ -10224,16 +10425,18 @@ var DataManagementList = ({
10224
10425
  }).catch(() => void 0);
10225
10426
  if (!mounted) return;
10226
10427
  const resolved = normalizeColumnConfig(saved, allFields);
10428
+ const resolvedDetailOpenMode = detailPageUrlBuilder ? resolved.detailOpenMode : "drawer";
10227
10429
  const nextSearchKeyWord = saved?.filter?.searchKeyWord || "";
10228
10430
  const nextFilterGroup = hydrateFilterGroup(saved?.filter?.group);
10229
10431
  setFields(allFields);
10432
+ setFormType(schemaResult.formType || "form");
10230
10433
  setConfig(saved || {});
10231
10434
  setShowFields(resolved.showFields);
10232
10435
  setWidths(resolved.widths);
10233
10436
  setLockFieldIds(resolved.lockFieldIds);
10234
10437
  setSort(resolved.sort);
10235
10438
  setDensity(resolved.density);
10236
- setDetailOpenMode(resolved.detailOpenMode);
10439
+ setDetailOpenMode(resolvedDetailOpenMode);
10237
10440
  setPageSize(resolved.pageSize);
10238
10441
  setSearchKeyWord(nextSearchKeyWord);
10239
10442
  setFilterGroup(nextFilterGroup);
@@ -10255,7 +10458,7 @@ var DataManagementList = ({
10255
10458
  return () => {
10256
10459
  mounted = false;
10257
10460
  };
10258
- }, [appType, configScope, formUuid, loadData, menuFormUuid, request]);
10461
+ }, [appType, configScope, detailPageUrlBuilder, formUuid, loadData, menuFormUuid, request]);
10259
10462
  const persistConfig = (0, import_react61.useCallback)(
10260
10463
  async (patch) => {
10261
10464
  const nextConfig = { ...config, ...patch };
@@ -10279,22 +10482,62 @@ var DataManagementList = ({
10279
10482
  showFields,
10280
10483
  lockFieldIds,
10281
10484
  widths,
10485
+ sort,
10282
10486
  density,
10283
10487
  detailOpenMode,
10284
10488
  pageSize
10285
10489
  });
10490
+ await loadData({ current: 1, pageSize, sort });
10491
+ };
10492
+ const handleSortChange = (index, patch) => {
10493
+ setSort(
10494
+ (prev) => prev.map((item, itemIndex) => itemIndex === index ? { ...item, ...patch } : item)
10495
+ );
10286
10496
  };
10497
+ const handleAddSort = () => {
10498
+ const firstFieldId = showFields[0] || fields[0]?.fieldId;
10499
+ if (!firstFieldId) return;
10500
+ setSort((prev) => [...prev, { id: firstFieldId, isAsc: "y" }]);
10501
+ };
10502
+ const handleRemoveSort = (index) => {
10503
+ setSort((prev) => prev.filter((_, itemIndex) => itemIndex !== index));
10504
+ };
10505
+ const updateColumnWidth = (0, import_react61.useCallback)((fieldId, width) => {
10506
+ const nextWidth = Math.round(Math.max(96, Math.min(520, width)));
10507
+ widthsRef.current = { ...widthsRef.current, [fieldId]: nextWidth };
10508
+ setWidths(widthsRef.current);
10509
+ }, []);
10510
+ const commitColumnWidth = (0, import_react61.useCallback)(
10511
+ (fieldId, width) => {
10512
+ const nextWidth = Math.round(Math.max(96, Math.min(520, width)));
10513
+ const nextWidths = { ...widthsRef.current, [fieldId]: nextWidth };
10514
+ widthsRef.current = nextWidths;
10515
+ setWidths(nextWidths);
10516
+ void persistConfig({ widths: nextWidths });
10517
+ },
10518
+ [persistConfig]
10519
+ );
10287
10520
  const handleDetail = (0, import_react61.useCallback)(
10288
10521
  (record) => {
10289
10522
  const formInstanceId = getRecordId(record);
10290
- if (detailOpenMode === "newPage" && typeof window !== "undefined") {
10291
- window.open(`/${appType}/forms/${formUuid}/detail/${formInstanceId}`, "_blank");
10523
+ if (!formInstanceId) {
10524
+ import_antd32.message.warning("\u5F53\u524D\u8BB0\u5F55\u7F3A\u5C11\u5B9E\u4F8B ID\uFF0C\u65E0\u6CD5\u6253\u5F00\u8BE6\u60C5");
10292
10525
  return;
10293
10526
  }
10527
+ if (detailOpenMode === "newPage" && detailPageUrlBuilder && typeof window !== "undefined") {
10528
+ const detailUrl = detailPageUrlBuilder({ record, formInstanceId: String(formInstanceId) });
10529
+ if (detailUrl) {
10530
+ window.open(detailUrl, "_blank");
10531
+ return;
10532
+ }
10533
+ }
10534
+ if (detailOpenMode === "newPage" && !detailPageUrlBuilder) {
10535
+ setDetailOpenMode("drawer");
10536
+ }
10294
10537
  setActiveRecord(record);
10295
10538
  setDetailOpen(true);
10296
10539
  },
10297
- [appType, detailOpenMode, formUuid]
10540
+ [detailOpenMode, detailPageUrlBuilder]
10298
10541
  );
10299
10542
  const handleDelete = (0, import_react61.useCallback)(
10300
10543
  async (ids) => {
@@ -10410,22 +10653,33 @@ var DataManagementList = ({
10410
10653
  await loadData({ current: 1, pageSize });
10411
10654
  };
10412
10655
  const columns = (0, import_react61.useMemo)(() => {
10413
- const baseColumns = visibleFields.map((field) => ({
10414
- title: field.label,
10415
- dataIndex: field.fieldId,
10416
- key: field.fieldId,
10417
- width: widths[field.fieldId] || field.width || 160,
10418
- fixed: lockFieldIds.includes(field.fieldId) ? "left" : void 0,
10419
- ellipsis: true,
10420
- sorter: true,
10421
- render: (value) => renderCellValue(value, field)
10422
- })) || [];
10656
+ const baseColumns = visibleFields.map((field) => {
10657
+ const columnWidth = widths[field.fieldId] || field.width || 160;
10658
+ return {
10659
+ title: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10660
+ ResizableColumnTitle,
10661
+ {
10662
+ label: field.label,
10663
+ width: columnWidth,
10664
+ onResize: (width) => updateColumnWidth(field.fieldId, width),
10665
+ onResizeEnd: (width) => commitColumnWidth(field.fieldId, width)
10666
+ }
10667
+ ),
10668
+ dataIndex: field.fieldId,
10669
+ key: field.fieldId,
10670
+ width: columnWidth,
10671
+ fixed: lockFieldIds.includes(field.fieldId) ? "left" : void 0,
10672
+ ellipsis: true,
10673
+ sorter: true,
10674
+ render: (value) => renderCellValue(value, field)
10675
+ };
10676
+ }) || [];
10423
10677
  return [
10424
10678
  ...baseColumns,
10425
10679
  {
10426
10680
  title: "\u64CD\u4F5C",
10427
10681
  key: "__actions",
10428
- width: 148,
10682
+ width: 136,
10429
10683
  fixed: "right",
10430
10684
  render: (_, record) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_antd32.Space, { size: 4, children: [
10431
10685
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { type: "link", size: "small", onClick: () => handleDetail(record), children: "\u8BE6\u60C5" }),
@@ -10436,18 +10690,6 @@ var DataManagementList = ({
10436
10690
  getPopupContainer,
10437
10691
  menu: {
10438
10692
  items: [
10439
- ...rowActions.map((action) => ({
10440
- key: action.key,
10441
- label: action.label,
10442
- danger: action.danger,
10443
- onClick: () => action.onClick(record)
10444
- })),
10445
- {
10446
- key: "workflow",
10447
- label: "\u6D41\u7A0B\u65E5\u5FD7",
10448
- icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.HistoryOutlined, {}),
10449
- onClick: () => import_antd32.message.info("\u8BF7\u901A\u8FC7 detailRenderer \u63A5\u5165\u6D41\u7A0B\u65E5\u5FD7\u6216\u6D41\u7A0B\u56FE\u5165\u53E3")
10450
- },
10451
10693
  ...!readonly ? [
10452
10694
  {
10453
10695
  key: "delete",
@@ -10460,6 +10702,20 @@ var DataManagementList = ({
10460
10702
  () => handleDelete([String(getRecordId(record))])
10461
10703
  )
10462
10704
  }
10705
+ ] : [],
10706
+ ...rowActions.map((action) => ({
10707
+ key: action.key,
10708
+ label: action.label,
10709
+ danger: action.danger,
10710
+ onClick: () => action.onClick(record)
10711
+ })),
10712
+ ...formType === "process" ? [
10713
+ {
10714
+ key: "workflow",
10715
+ label: "\u6D41\u7A0B\u65E5\u5FD7",
10716
+ icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.HistoryOutlined, {}),
10717
+ onClick: () => import_antd32.message.info("\u8BF7\u901A\u8FC7 detailRenderer \u63A5\u5165\u6D41\u7A0B\u65E5\u5FD7\u6216\u6D41\u7A0B\u56FE\u5165\u53E3")
10718
+ }
10463
10719
  ] : []
10464
10720
  ]
10465
10721
  },
@@ -10471,16 +10727,23 @@ var DataManagementList = ({
10471
10727
  ];
10472
10728
  }, [
10473
10729
  confirmDanger,
10730
+ commitColumnWidth,
10731
+ formType,
10474
10732
  getPopupContainer,
10475
10733
  handleDelete,
10476
10734
  handleDetail,
10477
10735
  lockFieldIds,
10478
10736
  readonly,
10479
10737
  rowActions,
10738
+ updateColumnWidth,
10480
10739
  visibleFields,
10481
10740
  widths
10482
10741
  ]);
10483
10742
  const tableSize = density === "compact" ? "small" : density === "loose" ? "large" : "middle";
10743
+ const tableScrollX = Math.max(
10744
+ 900,
10745
+ visibleFields.reduce((sum, field) => sum + (widths[field.fieldId] || field.width || 160), 136)
10746
+ );
10484
10747
  const importPreviewColumns = (0, import_react61.useMemo)(() => {
10485
10748
  const keys = Array.from(
10486
10749
  new Set(importPreview.flatMap((record) => Object.keys(record || {})))
@@ -10497,450 +10760,525 @@ var DataManagementList = ({
10497
10760
  };
10498
10761
  });
10499
10762
  }, [fields, importPreview]);
10500
- return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.ConfigProvider, { getPopupContainer, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { ref: rootRef, className: `${fullHeight ? "h-full min-h-full" : ""} bg-ant-bg-layout`, children: [
10501
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mx-auto flex h-full max-w-[1440px] flex-col px-4 py-4 md:px-6", children: [
10502
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mb-4 flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
10503
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10504
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("h1", { className: "text-xl font-semibold text-ant-color-text", children: title || "\u6570\u636E\u7BA1\u7406" }),
10505
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("p", { className: "mt-1 text-sm text-ant-color-text-secondary", children: [
10506
- "\u5171 ",
10507
- total,
10508
- " \u6761\u6570\u636E\uFF0C\u5DF2\u9009\u62E9 ",
10509
- selectedRowKeys.length,
10510
- " \u6761"
10511
- ] })
10512
- ] }),
10513
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_antd32.Space, { wrap: true, children: [
10514
- !readonly && submitRenderer && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.PlusOutlined, {}), type: "primary", onClick: () => setSubmitOpen(true), children: "\u65B0\u589E" }),
10515
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10516
- import_antd32.Input.Search,
10763
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.ConfigProvider, { getPopupContainer, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
10764
+ "div",
10765
+ {
10766
+ ref: rootRef,
10767
+ className: `relative w-full bg-ant-bg-layout ${fullHeight ? "flex h-[calc(100vh-88px)] min-h-[560px] overflow-hidden" : ""}`,
10768
+ children: [
10769
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mx-auto flex min-h-0 w-full max-w-[1440px] flex-col px-4 py-4 md:px-6", children: [
10770
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mb-4 flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
10771
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10772
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("h1", { className: "text-xl font-semibold text-ant-color-text", children: title || "\u6570\u636E\u7BA1\u7406" }),
10773
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("p", { className: "mt-1 text-sm text-ant-color-text-secondary", children: [
10774
+ "\u5171 ",
10775
+ total,
10776
+ " \u6761\u6570\u636E\uFF0C\u5DF2\u9009\u62E9 ",
10777
+ selectedRowKeys.length,
10778
+ " \u6761"
10779
+ ] })
10780
+ ] }),
10781
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_antd32.Space, { wrap: true, children: [
10782
+ !readonly && submitRenderer && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.PlusOutlined, {}), type: "primary", onClick: () => setSubmitOpen(true), children: "\u65B0\u589E" }),
10783
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10784
+ import_antd32.Input.Search,
10785
+ {
10786
+ allowClear: true,
10787
+ className: "w-[260px]",
10788
+ placeholder: "\u641C\u7D22\u5173\u952E\u5B57",
10789
+ value: searchKeyWord,
10790
+ onChange: (event) => setSearchKeyWord(event.target.value),
10791
+ onSearch: (value) => {
10792
+ const nextSearchKeyWord = String(value || "");
10793
+ setSearchKeyWord(nextSearchKeyWord);
10794
+ persistConfig({
10795
+ filter: { searchKeyWord: nextSearchKeyWord, group: filterGroup }
10796
+ });
10797
+ loadData({
10798
+ current: 1,
10799
+ pageSize,
10800
+ searchKeyWord: nextSearchKeyWord,
10801
+ filterGroup
10802
+ });
10803
+ }
10804
+ }
10805
+ ),
10806
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.FilterOutlined, {}), onClick: () => setFilterOpen(true), children: "\u7B5B\u9009" }),
10807
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.SettingOutlined, {}), onClick: () => setColumnOpen(true), children: "\u5217\u8BBE\u7F6E" }),
10808
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10809
+ import_antd32.Dropdown,
10810
+ {
10811
+ getPopupContainer,
10812
+ menu: {
10813
+ items: [
10814
+ {
10815
+ key: "selected",
10816
+ label: "\u5BFC\u51FA\u9009\u4E2D",
10817
+ disabled: selectedRowKeys.length === 0,
10818
+ onClick: () => {
10819
+ setExportScope("selected");
10820
+ setExportFields(showFields);
10821
+ setExportOpen(true);
10822
+ }
10823
+ },
10824
+ {
10825
+ key: "all",
10826
+ label: "\u5BFC\u51FA\u5168\u90E8",
10827
+ onClick: () => {
10828
+ setExportScope("all");
10829
+ setExportFields(showFields);
10830
+ setExportOpen(true);
10831
+ }
10832
+ },
10833
+ {
10834
+ key: "records",
10835
+ label: "\u5BFC\u51FA\u8BB0\u5F55",
10836
+ onClick: () => loadTransferRecords("export")
10837
+ }
10838
+ ]
10839
+ },
10840
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.DownloadOutlined, {}), children: "\u5BFC\u51FA" })
10841
+ }
10842
+ ),
10843
+ !readonly && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10844
+ import_antd32.Dropdown,
10845
+ {
10846
+ getPopupContainer,
10847
+ menu: {
10848
+ items: [
10849
+ { key: "import", label: "\u5BFC\u5165\u6570\u636E", onClick: () => setImportOpen(true) },
10850
+ {
10851
+ key: "records",
10852
+ label: "\u5BFC\u5165\u8BB0\u5F55",
10853
+ onClick: () => loadTransferRecords("import")
10854
+ }
10855
+ ]
10856
+ },
10857
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.ImportOutlined, {}), children: "\u5BFC\u5165" })
10858
+ }
10859
+ ),
10860
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.ReloadOutlined, {}), onClick: () => loadData({ current, pageSize }) })
10861
+ ] })
10862
+ ] }),
10863
+ selectedRowKeys.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-ant-border-secondary bg-ant-bg-container px-4 py-3 shadow-sm", children: [
10864
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("span", { className: "text-sm text-ant-color-text-secondary", children: [
10865
+ "\u5DF2\u9009 ",
10866
+ selectedRowKeys.length,
10867
+ " \u6761"
10868
+ ] }),
10869
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_antd32.Space, { wrap: true, children: [
10870
+ !readonly && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.SwapOutlined, {}), onClick: handleBatchApprove, children: "\u6279\u91CF\u5BA1\u6279" }),
10871
+ !readonly && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10872
+ import_antd32.Button,
10873
+ {
10874
+ danger: true,
10875
+ icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.DeleteOutlined, {}),
10876
+ onClick: () => confirmDanger(
10877
+ "\u786E\u8BA4\u6279\u91CF\u5220\u9664",
10878
+ `\u5C06\u5220\u9664 ${selectedRowKeys.length} \u6761\u6570\u636E\uFF0C\u786E\u8BA4\u7EE7\u7EED\u5417\uFF1F`,
10879
+ () => handleDelete(selectedRowKeys.map(String))
10880
+ ),
10881
+ children: "\u6279\u91CF\u5220\u9664"
10882
+ }
10883
+ ),
10884
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { type: "link", onClick: () => setSelectedRowKeys([]), children: "\u53D6\u6D88\u9009\u62E9" })
10885
+ ] })
10886
+ ] }),
10887
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "relative flex-1 overflow-hidden rounded-lg border border-ant-border-secondary bg-ant-bg-container", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10888
+ import_antd32.Table,
10517
10889
  {
10518
- allowClear: true,
10519
- className: "w-[260px]",
10520
- placeholder: "\u641C\u7D22\u5173\u952E\u5B57",
10521
- value: searchKeyWord,
10522
- onChange: (event) => setSearchKeyWord(event.target.value),
10523
- onSearch: (value) => {
10524
- const nextSearchKeyWord = String(value || "");
10525
- setSearchKeyWord(nextSearchKeyWord);
10526
- persistConfig({
10527
- filter: { searchKeyWord: nextSearchKeyWord, group: filterGroup }
10528
- });
10890
+ rowKey: (record) => String(getRecordId(record)),
10891
+ loading: loading || schemaLoading,
10892
+ columns,
10893
+ dataSource,
10894
+ size: tableSize,
10895
+ scroll: {
10896
+ x: tableScrollX,
10897
+ y: fullHeight ? selectedRowKeys.length > 0 ? "calc(100vh - 360px)" : "calc(100vh - 300px)" : void 0
10898
+ },
10899
+ rowSelection: {
10900
+ selectedRowKeys,
10901
+ onChange: setSelectedRowKeys
10902
+ },
10903
+ pagination: {
10904
+ current,
10905
+ pageSize,
10906
+ total,
10907
+ showSizeChanger: true,
10908
+ showTotal: (count) => `\u5171 ${count} \u6761`
10909
+ },
10910
+ onChange: (pagination, _filters, sorter) => {
10911
+ const sorters = Array.isArray(sorter) ? sorter : [sorter];
10912
+ const nextSort = sorters.filter((item) => item?.field && item?.order).map((item) => ({
10913
+ id: String(item.field),
10914
+ isAsc: item.order === "ascend" ? "y" : "n"
10915
+ }));
10916
+ setSort(nextSort);
10917
+ persistConfig({ sort: nextSort });
10529
10918
  loadData({
10530
- current: 1,
10531
- pageSize,
10532
- searchKeyWord: nextSearchKeyWord,
10533
- filterGroup
10919
+ current: pagination.current || 1,
10920
+ pageSize: pagination.pageSize || pageSize,
10921
+ sort: nextSort
10534
10922
  });
10535
10923
  }
10536
10924
  }
10537
- ),
10538
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.FilterOutlined, {}), onClick: () => setFilterOpen(true), children: "\u7B5B\u9009" }),
10539
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.SettingOutlined, {}), onClick: () => setColumnOpen(true), children: "\u5217\u8BBE\u7F6E" }),
10540
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10541
- import_antd32.Dropdown,
10542
- {
10543
- getPopupContainer,
10544
- menu: {
10545
- items: [
10546
- {
10547
- key: "selected",
10548
- label: "\u5BFC\u51FA\u9009\u4E2D",
10549
- disabled: selectedRowKeys.length === 0,
10550
- onClick: () => {
10551
- setExportScope("selected");
10552
- setExportFields(showFields);
10553
- setExportOpen(true);
10554
- }
10555
- },
10556
- {
10557
- key: "all",
10558
- label: "\u5BFC\u51FA\u5168\u90E8",
10559
- onClick: () => {
10560
- setExportScope("all");
10561
- setExportFields(showFields);
10562
- setExportOpen(true);
10563
- }
10564
- },
10925
+ ) })
10926
+ ] }),
10927
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10928
+ import_antd32.Modal,
10929
+ {
10930
+ getContainer: false,
10931
+ title: "\u9AD8\u7EA7\u7B5B\u9009",
10932
+ open: filterOpen,
10933
+ width: 760,
10934
+ onCancel: () => setFilterOpen(false),
10935
+ onOk: () => {
10936
+ setFilterOpen(false);
10937
+ persistConfig({ filter: { searchKeyWord, group: filterGroup } });
10938
+ loadData({ current: 1, pageSize, searchKeyWord, filterGroup });
10939
+ },
10940
+ okText: "\u5E94\u7528\u7B5B\u9009",
10941
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(FilterGroupEditor, { group: filterGroup, fields, onChange: setFilterGroup })
10942
+ }
10943
+ ),
10944
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10945
+ import_antd32.Modal,
10946
+ {
10947
+ getContainer: false,
10948
+ title: "\u5217\u8BBE\u7F6E",
10949
+ open: columnOpen,
10950
+ width: 920,
10951
+ onCancel: () => setColumnOpen(false),
10952
+ onOk: handleColumnCommit,
10953
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "space-y-5", children: [
10954
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10955
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u663E\u793A\u5217" }),
10956
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10957
+ import_antd32.Checkbox.Group,
10565
10958
  {
10566
- key: "records",
10567
- label: "\u5BFC\u51FA\u8BB0\u5F55",
10568
- onClick: () => loadTransferRecords("export")
10959
+ className: "grid grid-cols-2 gap-2 md:grid-cols-3",
10960
+ value: showFields,
10961
+ options: fields.map((field) => ({ label: field.label, value: field.fieldId })),
10962
+ onChange: (values) => setShowFields(values.map(String))
10569
10963
  }
10570
- ]
10571
- },
10572
- children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.DownloadOutlined, {}), children: "\u5BFC\u51FA" })
10573
- }
10574
- ),
10575
- !readonly && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10576
- import_antd32.Dropdown,
10577
- {
10578
- getPopupContainer,
10579
- menu: {
10580
- items: [
10581
- { key: "import", label: "\u5BFC\u5165\u6570\u636E", onClick: () => setImportOpen(true) },
10964
+ )
10965
+ ] }),
10966
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10967
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u5217\u5BBD" }),
10968
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "grid max-h-56 gap-2 overflow-auto rounded-lg border border-ant-border-secondary p-3 md:grid-cols-2", children: showFields.map((fieldId) => {
10969
+ const field = fields.find((item) => item.fieldId === fieldId);
10970
+ const width = widths[fieldId] || field?.width || 160;
10971
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
10972
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "min-w-0 truncate text-sm text-ant-color-text-secondary", children: field?.label || fieldId }),
10973
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10974
+ import_antd32.InputNumber,
10975
+ {
10976
+ min: 96,
10977
+ max: 520,
10978
+ value: width,
10979
+ addonAfter: "px",
10980
+ onChange: (value) => updateColumnWidth(fieldId, Number(value || 160)),
10981
+ onBlur: () => commitColumnWidth(fieldId, widthsRef.current[fieldId] || width)
10982
+ }
10983
+ )
10984
+ ] }, fieldId);
10985
+ }) })
10986
+ ] }),
10987
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10988
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u51BB\u7ED3\u5217" }),
10989
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10990
+ import_antd32.Select,
10582
10991
  {
10583
- key: "records",
10584
- label: "\u5BFC\u5165\u8BB0\u5F55",
10585
- onClick: () => loadTransferRecords("import")
10992
+ mode: "multiple",
10993
+ className: "w-full",
10994
+ value: lockFieldIds,
10995
+ options: showFields.map((fieldId) => {
10996
+ const field = fields.find((item) => item.fieldId === fieldId);
10997
+ return { label: field?.label || fieldId, value: fieldId };
10998
+ }),
10999
+ onChange: setLockFieldIds
10586
11000
  }
10587
- ]
10588
- },
10589
- children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.ImportOutlined, {}), children: "\u5BFC\u5165" })
10590
- }
10591
- ),
10592
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.ReloadOutlined, {}), onClick: () => loadData({ current, pageSize }) })
10593
- ] })
10594
- ] }),
10595
- selectedRowKeys.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-ant-border-secondary bg-ant-bg-container px-4 py-3 shadow-sm", children: [
10596
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("span", { className: "text-sm text-ant-color-text-secondary", children: [
10597
- "\u5DF2\u9009 ",
10598
- selectedRowKeys.length,
10599
- " \u6761"
10600
- ] }),
10601
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_antd32.Space, { wrap: true, children: [
10602
- !readonly && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.SwapOutlined, {}), onClick: handleBatchApprove, children: "\u6279\u91CF\u5BA1\u6279" }),
10603
- !readonly && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10604
- import_antd32.Button,
10605
- {
10606
- danger: true,
10607
- icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.DeleteOutlined, {}),
10608
- onClick: () => confirmDanger(
10609
- "\u786E\u8BA4\u6279\u91CF\u5220\u9664",
10610
- `\u5C06\u5220\u9664 ${selectedRowKeys.length} \u6761\u6570\u636E\uFF0C\u786E\u8BA4\u7EE7\u7EED\u5417\uFF1F`,
10611
- () => handleDelete(selectedRowKeys.map(String))
10612
- ),
10613
- children: "\u6279\u91CF\u5220\u9664"
10614
- }
10615
- ),
10616
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { type: "link", onClick: () => setSelectedRowKeys([]), children: "\u53D6\u6D88\u9009\u62E9" })
10617
- ] })
10618
- ] }),
10619
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "relative flex-1 overflow-hidden rounded-lg border border-ant-border-secondary bg-ant-bg-container", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10620
- import_antd32.Table,
10621
- {
10622
- rowKey: (record) => String(getRecordId(record)),
10623
- loading: loading || schemaLoading,
10624
- columns,
10625
- dataSource,
10626
- size: tableSize,
10627
- scroll: {
10628
- x: Math.max(900, visibleFields.length * 160),
10629
- y: fullHeight ? selectedRowKeys.length > 0 ? "calc(100vh - 320px)" : "calc(100vh - 260px)" : void 0
10630
- },
10631
- rowSelection: {
10632
- selectedRowKeys,
10633
- onChange: setSelectedRowKeys
10634
- },
10635
- pagination: {
10636
- current,
10637
- pageSize,
10638
- total,
10639
- showSizeChanger: true,
10640
- showTotal: (count) => `\u5171 ${count} \u6761`
10641
- },
10642
- onChange: (pagination, _filters, sorter) => {
10643
- const sorters = Array.isArray(sorter) ? sorter : [sorter];
10644
- const nextSort = sorters.filter((item) => item?.field && item?.order).map((item) => ({
10645
- id: String(item.field),
10646
- isAsc: item.order === "ascend" ? "y" : "n"
10647
- }));
10648
- setSort(nextSort);
10649
- persistConfig({ sort: nextSort });
10650
- loadData({
10651
- current: pagination.current || 1,
10652
- pageSize: pagination.pageSize || pageSize,
10653
- sort: nextSort
10654
- });
11001
+ )
11002
+ ] }),
11003
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Divider, { className: "my-1" }),
11004
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
11005
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
11006
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "text-sm font-medium text-ant-color-text", children: "\u6392\u5E8F\u89C4\u5219" }),
11007
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { size: "small", onClick: handleAddSort, disabled: fields.length === 0, children: "\u6DFB\u52A0\u6392\u5E8F" })
11008
+ ] }),
11009
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "space-y-2", children: sort.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "rounded-lg border border-dashed border-ant-border-secondary px-3 py-4 text-center text-sm text-ant-color-text-tertiary", children: "\u6682\u65E0\u6392\u5E8F\u89C4\u5219" }) : sort.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "flex items-center gap-2", children: [
11010
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11011
+ import_antd32.Select,
11012
+ {
11013
+ className: "min-w-0 flex-1",
11014
+ value: item.id,
11015
+ options: fields.map((field) => ({
11016
+ label: field.label,
11017
+ value: field.fieldId
11018
+ })),
11019
+ onChange: (value) => handleSortChange(index, { id: value })
11020
+ }
11021
+ ),
11022
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11023
+ import_antd32.Segmented,
11024
+ {
11025
+ value: item.isAsc,
11026
+ options: [
11027
+ { label: "\u5347\u5E8F", value: "y" },
11028
+ { label: "\u964D\u5E8F", value: "n" }
11029
+ ],
11030
+ onChange: (value) => handleSortChange(index, { isAsc: value })
11031
+ }
11032
+ ),
11033
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11034
+ import_antd32.Button,
11035
+ {
11036
+ danger: true,
11037
+ type: "text",
11038
+ icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_icons11.DeleteOutlined, {}),
11039
+ onClick: () => handleRemoveSort(index)
11040
+ }
11041
+ )
11042
+ ] }, `${item.id}_${index}`)) })
11043
+ ] }),
11044
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "grid gap-4 md:grid-cols-3", children: [
11045
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
11046
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u8868\u683C\u5BC6\u5EA6" }),
11047
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11048
+ import_antd32.Segmented,
11049
+ {
11050
+ block: true,
11051
+ value: density,
11052
+ options: [
11053
+ { label: "\u7D27\u51D1", value: "compact" },
11054
+ { label: "\u6807\u51C6", value: "middle" },
11055
+ { label: "\u5BBD\u677E", value: "loose" }
11056
+ ],
11057
+ onChange: (value) => setDensity(value)
11058
+ }
11059
+ )
11060
+ ] }),
11061
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
11062
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u8BE6\u60C5\u6253\u5F00\u65B9\u5F0F" }),
11063
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11064
+ import_antd32.Segmented,
11065
+ {
11066
+ block: true,
11067
+ value: detailOpenMode,
11068
+ options: detailPageUrlBuilder ? [
11069
+ { label: "\u62BD\u5C49", value: "drawer" },
11070
+ { label: "\u65B0\u9875", value: "newPage" }
11071
+ ] : [{ label: "\u62BD\u5C49", value: "drawer" }],
11072
+ onChange: (value) => setDetailOpenMode(value)
11073
+ }
11074
+ )
11075
+ ] }),
11076
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
11077
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u9875\u5927\u5C0F" }),
11078
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11079
+ import_antd32.Select,
11080
+ {
11081
+ className: "w-full",
11082
+ value: pageSize,
11083
+ options: [10, 20, 50, 100].map((value) => ({ label: `${value} \u6761`, value })),
11084
+ onChange: setPageSize
11085
+ }
11086
+ )
11087
+ ] })
11088
+ ] })
11089
+ ] })
10655
11090
  }
10656
- }
10657
- ) })
10658
- ] }),
10659
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10660
- import_antd32.Modal,
10661
- {
10662
- getContainer: false,
10663
- title: "\u9AD8\u7EA7\u7B5B\u9009",
10664
- open: filterOpen,
10665
- width: 760,
10666
- onCancel: () => setFilterOpen(false),
10667
- onOk: () => {
10668
- setFilterOpen(false);
10669
- persistConfig({ filter: { searchKeyWord, group: filterGroup } });
10670
- loadData({ current: 1, pageSize, searchKeyWord, filterGroup });
10671
- },
10672
- okText: "\u5E94\u7528\u7B5B\u9009",
10673
- children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(FilterGroupEditor, { group: filterGroup, fields, onChange: setFilterGroup })
10674
- }
10675
- ),
10676
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10677
- import_antd32.Modal,
10678
- {
10679
- getContainer: false,
10680
- title: "\u5217\u8BBE\u7F6E",
10681
- open: columnOpen,
10682
- width: 720,
10683
- onCancel: () => setColumnOpen(false),
10684
- onOk: handleColumnCommit,
10685
- children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "space-y-5", children: [
10686
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10687
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u663E\u793A\u5217" }),
10688
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11091
+ ),
11092
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11093
+ import_antd32.Modal,
11094
+ {
11095
+ getContainer: false,
11096
+ title: exportScope === "selected" ? "\u5BFC\u51FA\u9009\u4E2D\u6570\u636E" : "\u5BFC\u51FA\u5168\u90E8\u6570\u636E",
11097
+ open: exportOpen,
11098
+ onCancel: () => setExportOpen(false),
11099
+ footer: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_antd32.Space, { children: [
11100
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { onClick: () => setExportOpen(false), children: "\u53D6\u6D88" }),
11101
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11102
+ import_antd32.Button,
11103
+ {
11104
+ type: "primary",
11105
+ loading: exporting,
11106
+ disabled: exportScope === "selected" && selectedRowKeys.length === 0,
11107
+ onClick: () => handleExport(exportScope),
11108
+ children: exportScope === "selected" ? `\u5BFC\u51FA\u9009\u4E2D (${selectedRowKeys.length})` : "\u5BFC\u51FA\u5168\u90E8"
11109
+ }
11110
+ )
11111
+ ] }),
11112
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10689
11113
  import_antd32.Checkbox.Group,
10690
11114
  {
10691
- className: "grid grid-cols-2 gap-2 md:grid-cols-3",
10692
- value: showFields,
11115
+ className: "grid grid-cols-2 gap-2",
11116
+ value: exportFields,
10693
11117
  options: fields.map((field) => ({ label: field.label, value: field.fieldId })),
10694
- onChange: (values) => setShowFields(values.map(String))
10695
- }
10696
- )
10697
- ] }),
10698
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10699
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u51BB\u7ED3\u5217" }),
10700
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10701
- import_antd32.Select,
10702
- {
10703
- mode: "multiple",
10704
- className: "w-full",
10705
- value: lockFieldIds,
10706
- options: showFields.map((fieldId) => {
10707
- const field = fields.find((item) => item.fieldId === fieldId);
10708
- return { label: field?.label || fieldId, value: fieldId };
10709
- }),
10710
- onChange: setLockFieldIds
11118
+ onChange: (values) => setExportFields(values.map(String))
10711
11119
  }
10712
11120
  )
10713
- ] }),
10714
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "grid gap-4 md:grid-cols-3", children: [
10715
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10716
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u8868\u683C\u5BC6\u5EA6" }),
11121
+ }
11122
+ ),
11123
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11124
+ import_antd32.Modal,
11125
+ {
11126
+ getContainer: false,
11127
+ title: "\u6279\u91CF\u5BA1\u6279",
11128
+ open: batchApprovalOpen,
11129
+ onCancel: () => setBatchApprovalOpen(false),
11130
+ onOk: handleBatchApprovalConfirm,
11131
+ okText: batchApprovalAction === "approved" ? "\u786E\u8BA4\u901A\u8FC7" : "\u786E\u8BA4\u62D2\u7EDD",
11132
+ confirmLoading: batchApproving,
11133
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "space-y-4", children: [
11134
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "text-sm text-ant-color-text-secondary", children: [
11135
+ "\u5DF2\u9009\u62E9 ",
11136
+ selectedRowKeys.length,
11137
+ " \u6761\u8BB0\u5F55"
11138
+ ] }),
10717
11139
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10718
11140
  import_antd32.Segmented,
10719
11141
  {
10720
11142
  block: true,
10721
- value: density,
11143
+ value: batchApprovalAction,
10722
11144
  options: [
10723
- { label: "\u7D27\u51D1", value: "compact" },
10724
- { label: "\u6807\u51C6", value: "middle" },
10725
- { label: "\u5BBD\u677E", value: "loose" }
11145
+ { label: "\u540C\u610F", value: "approved" },
11146
+ { label: "\u62D2\u7EDD", value: "rejected" }
10726
11147
  ],
10727
- onChange: (value) => setDensity(value)
11148
+ onChange: (value) => setBatchApprovalAction(value)
11149
+ }
11150
+ ),
11151
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11152
+ import_antd32.Input.TextArea,
11153
+ {
11154
+ value: batchApprovalComments,
11155
+ rows: 4,
11156
+ maxLength: 500,
11157
+ showCount: true,
11158
+ placeholder: "\u586B\u5199\u5BA1\u6279\u610F\u89C1",
11159
+ onChange: (event) => setBatchApprovalComments(event.target.value)
10728
11160
  }
10729
11161
  )
10730
- ] }),
10731
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10732
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u8BE6\u60C5\u6253\u5F00\u65B9\u5F0F" }),
11162
+ ] })
11163
+ }
11164
+ ),
11165
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
11166
+ import_antd32.Modal,
11167
+ {
11168
+ getContainer: false,
11169
+ title: "\u5BFC\u5165\u6570\u636E",
11170
+ open: importOpen,
11171
+ width: 720,
11172
+ onCancel: () => setImportOpen(false),
11173
+ onOk: handleImportConfirm,
11174
+ okButtonProps: { disabled: !importBase64 },
11175
+ okText: "\u786E\u8BA4\u5BFC\u5165",
11176
+ children: [
11177
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11178
+ import_antd32.Upload.Dragger,
11179
+ {
11180
+ accept: ".xlsx,.xls",
11181
+ maxCount: 1,
11182
+ beforeUpload: handleImportPreview,
11183
+ onRemove: () => {
11184
+ setImportBase64("");
11185
+ setImportPreview([]);
11186
+ },
11187
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "text-ant-color-text-secondary", children: "\u62D6\u62FD Excel \u6587\u4EF6\u5230\u6B64\u5904\uFF0C\u6216\u70B9\u51FB\u9009\u62E9\u6587\u4EF6" })
11188
+ }
11189
+ ),
11190
+ importPreview.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mt-4", children: [
11191
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u5BFC\u5165\u9884\u89C8" }),
11192
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11193
+ import_antd32.Table,
11194
+ {
11195
+ size: "small",
11196
+ dataSource: importPreview,
11197
+ columns: importPreviewColumns,
11198
+ scroll: { x: Math.max(600, (importPreviewColumns?.length || 0) * 150) },
11199
+ pagination: false,
11200
+ rowKey: (_, index) => String(index)
11201
+ }
11202
+ )
11203
+ ] })
11204
+ ]
11205
+ }
11206
+ ),
11207
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
11208
+ import_antd32.Drawer,
11209
+ {
11210
+ getContainer: false,
11211
+ rootStyle: { position: "absolute" },
11212
+ styles: { body: { padding: 24, overflow: "auto" } },
11213
+ title: recordTab === "import" ? "\u5BFC\u5165\u8BB0\u5F55" : "\u5BFC\u51FA\u8BB0\u5F55",
11214
+ open: recordsOpen,
11215
+ width: 720,
11216
+ onClose: () => setRecordsOpen(false),
11217
+ children: [
10733
11218
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10734
11219
  import_antd32.Segmented,
10735
11220
  {
10736
- block: true,
10737
- value: detailOpenMode,
11221
+ value: recordTab,
10738
11222
  options: [
10739
- { label: "\u62BD\u5C49", value: "drawer" },
10740
- { label: "\u65B0\u9875", value: "newPage" }
11223
+ { label: "\u5BFC\u5165\u8BB0\u5F55", value: "import" },
11224
+ { label: "\u5BFC\u51FA\u8BB0\u5F55", value: "export" }
10741
11225
  ],
10742
- onChange: (value) => setDetailOpenMode(value)
11226
+ onChange: (value) => loadTransferRecords(value)
10743
11227
  }
10744
- )
10745
- ] }),
10746
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
10747
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u9875\u5927\u5C0F" }),
11228
+ ),
10748
11229
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10749
- import_antd32.Select,
11230
+ import_antd32.Table,
10750
11231
  {
10751
- className: "w-full",
10752
- value: pageSize,
10753
- options: [10, 20, 50, 100].map((value) => ({ label: `${value} \u6761`, value })),
10754
- onChange: setPageSize
11232
+ className: "mt-4",
11233
+ size: "small",
11234
+ dataSource: transferRecords,
11235
+ rowKey: (record) => record.id || record.recordId
10755
11236
  }
10756
11237
  )
10757
- ] })
10758
- ] })
10759
- ] })
10760
- }
10761
- ),
10762
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10763
- import_antd32.Modal,
10764
- {
10765
- getContainer: false,
10766
- title: exportScope === "selected" ? "\u5BFC\u51FA\u9009\u4E2D\u6570\u636E" : "\u5BFC\u51FA\u5168\u90E8\u6570\u636E",
10767
- open: exportOpen,
10768
- onCancel: () => setExportOpen(false),
10769
- footer: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_antd32.Space, { children: [
10770
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Button, { onClick: () => setExportOpen(false), children: "\u53D6\u6D88" }),
10771
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10772
- import_antd32.Button,
10773
- {
10774
- type: "primary",
10775
- loading: exporting,
10776
- disabled: exportScope === "selected" && selectedRowKeys.length === 0,
10777
- onClick: () => handleExport(exportScope),
10778
- children: exportScope === "selected" ? `\u5BFC\u51FA\u9009\u4E2D (${selectedRowKeys.length})` : "\u5BFC\u51FA\u5168\u90E8"
10779
- }
10780
- )
10781
- ] }),
10782
- children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10783
- import_antd32.Checkbox.Group,
11238
+ ]
11239
+ }
11240
+ ),
11241
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11242
+ import_antd32.Drawer,
10784
11243
  {
10785
- className: "grid grid-cols-2 gap-2",
10786
- value: exportFields,
10787
- options: fields.map((field) => ({ label: field.label, value: field.fieldId })),
10788
- onChange: (values) => setExportFields(values.map(String))
11244
+ getContainer: false,
11245
+ rootStyle: { position: "absolute" },
11246
+ styles: { body: { padding: 0, overflow: "auto" } },
11247
+ title: "\u8BE6\u60C5",
11248
+ open: detailOpen,
11249
+ width: 720,
11250
+ onClose: () => setDetailOpen(false),
11251
+ destroyOnClose: true,
11252
+ children: activeRecord && detailRenderer ? detailRenderer({
11253
+ record: activeRecord,
11254
+ formInstanceId: String(getRecordId(activeRecord)),
11255
+ onClose: () => setDetailOpen(false)
11256
+ }) : /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Empty, { description: "\u8BF7\u901A\u8FC7 detailRenderer \u63A5\u5165\u8BE6\u60C5\u6A21\u677F" })
10789
11257
  }
10790
- )
10791
- }
10792
- ),
10793
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10794
- import_antd32.Modal,
10795
- {
10796
- getContainer: false,
10797
- title: "\u6279\u91CF\u5BA1\u6279",
10798
- open: batchApprovalOpen,
10799
- onCancel: () => setBatchApprovalOpen(false),
10800
- onOk: handleBatchApprovalConfirm,
10801
- okText: batchApprovalAction === "approved" ? "\u786E\u8BA4\u901A\u8FC7" : "\u786E\u8BA4\u62D2\u7EDD",
10802
- confirmLoading: batchApproving,
10803
- children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "space-y-4", children: [
10804
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "text-sm text-ant-color-text-secondary", children: [
10805
- "\u5DF2\u9009\u62E9 ",
10806
- selectedRowKeys.length,
10807
- " \u6761\u8BB0\u5F55"
10808
- ] }),
10809
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10810
- import_antd32.Segmented,
10811
- {
10812
- block: true,
10813
- value: batchApprovalAction,
10814
- options: [
10815
- { label: "\u540C\u610F", value: "approved" },
10816
- { label: "\u62D2\u7EDD", value: "rejected" }
10817
- ],
10818
- onChange: (value) => setBatchApprovalAction(value)
10819
- }
10820
- ),
10821
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10822
- import_antd32.Input.TextArea,
10823
- {
10824
- value: batchApprovalComments,
10825
- rows: 4,
10826
- maxLength: 500,
10827
- showCount: true,
10828
- placeholder: "\u586B\u5199\u5BA1\u6279\u610F\u89C1",
10829
- onChange: (event) => setBatchApprovalComments(event.target.value)
10830
- }
10831
- )
10832
- ] })
10833
- }
10834
- ),
10835
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
10836
- import_antd32.Modal,
10837
- {
10838
- getContainer: false,
10839
- title: "\u5BFC\u5165\u6570\u636E",
10840
- open: importOpen,
10841
- width: 720,
10842
- onCancel: () => setImportOpen(false),
10843
- onOk: handleImportConfirm,
10844
- okButtonProps: { disabled: !importBase64 },
10845
- okText: "\u786E\u8BA4\u5BFC\u5165",
10846
- children: [
10847
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10848
- import_antd32.Upload.Dragger,
10849
- {
10850
- accept: ".xlsx,.xls",
10851
- maxCount: 1,
10852
- beforeUpload: handleImportPreview,
10853
- onRemove: () => {
10854
- setImportBase64("");
10855
- setImportPreview([]);
10856
- },
10857
- children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "text-ant-color-text-secondary", children: "\u62D6\u62FD Excel \u6587\u4EF6\u5230\u6B64\u5904\uFF0C\u6216\u70B9\u51FB\u9009\u62E9\u6587\u4EF6" })
10858
- }
10859
- ),
10860
- importPreview.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "mt-4", children: [
10861
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u5BFC\u5165\u9884\u89C8" }),
10862
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10863
- import_antd32.Table,
10864
- {
10865
- size: "small",
10866
- dataSource: importPreview,
10867
- columns: importPreviewColumns,
10868
- scroll: { x: Math.max(600, (importPreviewColumns?.length || 0) * 150) },
10869
- pagination: false,
10870
- rowKey: (_, index) => String(index)
11258
+ ),
11259
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
11260
+ import_antd32.Drawer,
11261
+ {
11262
+ getContainer: false,
11263
+ rootStyle: { position: "absolute" },
11264
+ styles: { body: { padding: 0, overflow: "auto" } },
11265
+ title: "\u65B0\u589E\u6570\u636E",
11266
+ open: submitOpen,
11267
+ width: 720,
11268
+ onClose: () => setSubmitOpen(false),
11269
+ destroyOnClose: true,
11270
+ children: submitRenderer ? submitRenderer({
11271
+ onClose: () => setSubmitOpen(false),
11272
+ onSubmitted: () => {
11273
+ setSubmitOpen(false);
11274
+ loadData({ current: 1, pageSize });
10871
11275
  }
10872
- )
10873
- ] })
10874
- ]
10875
- }
10876
- ),
10877
- /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
10878
- import_antd32.Drawer,
10879
- {
10880
- getContainer: false,
10881
- title: recordTab === "import" ? "\u5BFC\u5165\u8BB0\u5F55" : "\u5BFC\u51FA\u8BB0\u5F55",
10882
- open: recordsOpen,
10883
- width: 720,
10884
- onClose: () => setRecordsOpen(false),
10885
- children: [
10886
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10887
- import_antd32.Segmented,
10888
- {
10889
- value: recordTab,
10890
- options: [
10891
- { label: "\u5BFC\u5165\u8BB0\u5F55", value: "import" },
10892
- { label: "\u5BFC\u51FA\u8BB0\u5F55", value: "export" }
10893
- ],
10894
- onChange: (value) => loadTransferRecords(value)
10895
- }
10896
- ),
10897
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10898
- import_antd32.Table,
10899
- {
10900
- className: "mt-4",
10901
- size: "small",
10902
- dataSource: transferRecords,
10903
- rowKey: (record) => record.id || record.recordId
10904
- }
10905
- )
10906
- ]
10907
- }
10908
- ),
10909
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10910
- import_antd32.Drawer,
10911
- {
10912
- getContainer: false,
10913
- title: "\u8BE6\u60C5",
10914
- open: detailOpen,
10915
- width: 720,
10916
- onClose: () => setDetailOpen(false),
10917
- destroyOnClose: true,
10918
- children: activeRecord && detailRenderer ? detailRenderer({
10919
- record: activeRecord,
10920
- formInstanceId: String(getRecordId(activeRecord)),
10921
- onClose: () => setDetailOpen(false)
10922
- }) : /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Empty, { description: "\u8BF7\u901A\u8FC7 detailRenderer \u63A5\u5165\u8BE6\u60C5\u6A21\u677F" })
10923
- }
10924
- ),
10925
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
10926
- import_antd32.Drawer,
10927
- {
10928
- getContainer: false,
10929
- title: "\u65B0\u589E\u6570\u636E",
10930
- open: submitOpen,
10931
- width: 720,
10932
- onClose: () => setSubmitOpen(false),
10933
- destroyOnClose: true,
10934
- children: submitRenderer ? submitRenderer({
10935
- onClose: () => setSubmitOpen(false),
10936
- onSubmitted: () => {
10937
- setSubmitOpen(false);
10938
- loadData({ current: 1, pageSize });
11276
+ }) : /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Empty, { description: "\u8BF7\u901A\u8FC7 submitRenderer \u63A5\u5165\u63D0\u4EA4\u6A21\u677F" })
10939
11277
  }
10940
- }) : /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_antd32.Empty, { description: "\u8BF7\u901A\u8FC7 submitRenderer \u63A5\u5165\u63D0\u4EA4\u6A21\u677F" })
10941
- }
10942
- )
10943
- ] }) });
11278
+ )
11279
+ ]
11280
+ }
11281
+ ) });
10944
11282
  };
10945
11283
 
10946
11284
  // src/templates/FormSubmitTemplate.tsx
@@ -11198,52 +11536,66 @@ var InnerFormContent = ({
11198
11536
  actions,
11199
11537
  inDrawer,
11200
11538
  position: "inline",
11201
- className: "mt-6 -mx-5 -mb-5 rounded-b-lg md:-mx-6 md:-mb-6"
11539
+ className: inDrawer ? "mt-5 -mx-4 -mb-4 rounded-b-lg md:-mx-5 md:-mb-5" : "mt-6 -mx-5 -mb-5 rounded-b-lg md:-mx-6 md:-mb-6"
11202
11540
  }
11203
11541
  ) : null;
11204
- return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(RuntimePageShell, { inDrawer, children: [
11205
- /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "space-y-6", children: [
11206
- header,
11207
- enableDraft && hasDraft && !submitted && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
11208
- DraftManager,
11209
- {
11210
- hasDraft,
11211
- draftTimestamp,
11212
- onRestore: handleRestoreDraft,
11213
- onDiscard: clearDraft
11214
- }
11215
- ) }),
11216
- !submitted ? /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: [
11217
- departmentSelector,
11218
- beforeForm,
11219
- renderForm ? renderForm({ schema, config }) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(FormRenderer, { columns: 2 }),
11220
- afterForm,
11221
- actionsNode
11222
- ] }) : successInfo && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
11223
- SubmitSuccessCard,
11224
- {
11225
- info: successInfo,
11226
- mode: submitSuccessMode,
11227
- isRedirecting,
11228
- countdown,
11229
- onContinue: handleContinue,
11230
- onViewDetail: handleViewDetail,
11231
- renderSuccess
11232
- }
11233
- ),
11234
- footer
11235
- ] }),
11236
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
11237
- ProcessPreview,
11238
- {
11239
- open: previewOpen,
11240
- routes: previewRoutes,
11241
- loading: previewLoading,
11242
- onClose: () => setPreviewOpen(false),
11243
- onConfirm: handlePreviewConfirm
11244
- }
11245
- )
11246
- ] });
11542
+ return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
11543
+ RuntimePageShell,
11544
+ {
11545
+ inDrawer,
11546
+ maxWidth: inDrawer ? "100%" : 1240,
11547
+ contentClassName: inDrawer ? "px-4 py-4 md:px-5" : "py-4 md:py-6",
11548
+ children: [
11549
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "space-y-6", children: [
11550
+ header,
11551
+ enableDraft && hasDraft && !submitted && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
11552
+ DraftManager,
11553
+ {
11554
+ hasDraft,
11555
+ draftTimestamp,
11556
+ onRestore: handleRestoreDraft,
11557
+ onDiscard: clearDraft
11558
+ }
11559
+ ) }),
11560
+ !submitted ? /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
11561
+ "div",
11562
+ {
11563
+ className: `rounded-lg border border-ant-border-secondary bg-ant-bg-container ${inDrawer ? "p-4 md:p-5" : "p-5 shadow-sm md:p-6"}`,
11564
+ children: [
11565
+ departmentSelector,
11566
+ beforeForm,
11567
+ renderForm ? renderForm({ schema, config }) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(FormRenderer, { columns: 2 }),
11568
+ afterForm,
11569
+ actionsNode
11570
+ ]
11571
+ }
11572
+ ) : successInfo && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
11573
+ SubmitSuccessCard,
11574
+ {
11575
+ info: successInfo,
11576
+ mode: submitSuccessMode,
11577
+ isRedirecting,
11578
+ countdown,
11579
+ onContinue: handleContinue,
11580
+ onViewDetail: handleViewDetail,
11581
+ renderSuccess
11582
+ }
11583
+ ),
11584
+ footer
11585
+ ] }),
11586
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
11587
+ ProcessPreview,
11588
+ {
11589
+ open: previewOpen,
11590
+ routes: previewRoutes,
11591
+ loading: previewLoading,
11592
+ onClose: () => setPreviewOpen(false),
11593
+ onConfirm: handlePreviewConfirm
11594
+ }
11595
+ )
11596
+ ]
11597
+ }
11598
+ );
11247
11599
  };
11248
11600
  var FormSubmitTemplate = ({
11249
11601
  schema,
@@ -11290,6 +11642,7 @@ var FormSubmitTemplate = ({
11290
11642
 
11291
11643
  // src/templates/FormDetailTemplate.tsx
11292
11644
  var import_react63 = require("react");
11645
+ var import_dayjs6 = __toESM(require("dayjs"));
11293
11646
 
11294
11647
  // src/templates/PageSkeleton.tsx
11295
11648
  var import_antd34 = require("antd");
@@ -11361,6 +11714,11 @@ function FormDataBridge({
11361
11714
  formDataRef.current = getFormData2;
11362
11715
  return null;
11363
11716
  }
11717
+ var formatDateTime2 = (value) => {
11718
+ if (!value || typeof value !== "string") return value || "-";
11719
+ const parsed = (0, import_dayjs6.default)(value);
11720
+ return parsed.isValid() ? parsed.format("YYYY-MM-DD HH:mm:ss") : value;
11721
+ };
11364
11722
  var InnerDetailContent = ({
11365
11723
  schema,
11366
11724
  formUuid,
@@ -11471,14 +11829,36 @@ var InnerDetailContent = ({
11471
11829
  renderSummary && instanceInfo ? renderSummary(instanceInfo) : /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
11472
11830
  SummaryPanel,
11473
11831
  {
11474
- title: instanceInfo?.title || formData?.instanceTitle || schema.formMeta.title,
11832
+ title: instanceInfo?.title || instanceInfo?.instanceTitle || schema.formMeta.title,
11475
11833
  eyebrow: `\u6570\u636E\u5B9E\u4F8B ${formInstanceId?.slice(0, 8) || "-"}`,
11476
- creator: instanceInfo?.creator ? {
11477
- name: instanceInfo.creator.name,
11478
- avatar: instanceInfo.creator.avatar,
11479
- department: instanceInfo.creator.department
11834
+ creator: instanceInfo?.creator || instanceInfo?.createdByName ? {
11835
+ name: instanceInfo?.creator?.name || instanceInfo?.createdByName,
11836
+ avatar: instanceInfo?.creator?.avatar,
11837
+ department: instanceInfo?.creator?.department || instanceInfo?.createdByDepartmentName
11480
11838
  } : void 0,
11481
- createdAt: instanceInfo?.createdAt,
11839
+ createdAt: formatDateTime2(instanceInfo?.createdAt),
11840
+ metaItems: [
11841
+ {
11842
+ key: "creator",
11843
+ label: "\u521B\u5EFA\u4EBA",
11844
+ value: instanceInfo?.creator?.name || instanceInfo?.createdByName || "\u672A\u77E5\u7528\u6237"
11845
+ },
11846
+ {
11847
+ key: "department",
11848
+ label: "\u521B\u5EFA\u4EBA\u90E8\u95E8",
11849
+ value: instanceInfo?.creator?.department || instanceInfo?.createdByDepartmentName || "-"
11850
+ },
11851
+ {
11852
+ key: "createdAt",
11853
+ label: "\u521B\u5EFA\u65F6\u95F4",
11854
+ value: formatDateTime2(instanceInfo?.createdAt)
11855
+ },
11856
+ {
11857
+ key: "updatedAt",
11858
+ label: "\u66F4\u65B0\u65F6\u95F4",
11859
+ value: formatDateTime2(instanceInfo?.updatedAt)
11860
+ }
11861
+ ],
11482
11862
  status: mode === "edit" ? { label: "\u7F16\u8F91\u4E2D", tone: "brand" } : void 0
11483
11863
  }
11484
11864
  ),