openxiangda 1.0.145 → 1.0.147

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.
@@ -1,4 +1,4 @@
1
- import { F as FieldDefinition, a as FormRuntimeApi, R as RuntimeResponse, b as FormSchema } from './ProcessPreview-CUQFUDvw.mjs';
1
+ import { F as FieldDefinition, a as FormRuntimeApi, R as RuntimeResponse, b as FormSchema } from './ProcessPreview-BoblxCUt.mjs';
2
2
 
3
3
  type DataManagementConfigScope = 'global' | 'personal';
4
4
  type DataManagementDensity = 'compact' | 'middle' | 'loose';
@@ -1,4 +1,4 @@
1
- import { F as FieldDefinition, a as FormRuntimeApi, R as RuntimeResponse, b as FormSchema } from './ProcessPreview-CUQFUDvw.js';
1
+ import { F as FieldDefinition, a as FormRuntimeApi, R as RuntimeResponse, b as FormSchema } from './ProcessPreview-BoblxCUt.js';
2
2
 
3
3
  type DataManagementConfigScope = 'global' | 'personal';
4
4
  type DataManagementDensity = 'compact' | 'middle' | 'loose';
@@ -7686,6 +7686,30 @@ function createFormRuntimeApi(config) {
7686
7686
  });
7687
7687
  return response.data || response.result || [];
7688
7688
  },
7689
+ searchDepartments: async (params) => {
7690
+ const page = params?.page ?? 1;
7691
+ const pageSize = params?.pageSize ?? 50;
7692
+ const response = await request({
7693
+ url: "/department/search",
7694
+ method: "get",
7695
+ params: {
7696
+ keyword: params?.keyword,
7697
+ page,
7698
+ pageSize,
7699
+ includePath: params?.includePath ?? true
7700
+ }
7701
+ });
7702
+ const data = response.data || response.result;
7703
+ if (Array.isArray(data)) {
7704
+ return { items: data, total: data.length, page, pageSize };
7705
+ }
7706
+ return {
7707
+ items: data?.items || data?.list || [],
7708
+ total: Number(data?.total ?? data?.count ?? data?.items?.length ?? 0),
7709
+ page: Number(data?.page ?? page),
7710
+ pageSize: Number(data?.pageSize ?? pageSize)
7711
+ };
7712
+ },
7689
7713
  getDepartmentParentDepartments: async (id) => {
7690
7714
  const response = await request({
7691
7715
  url: `/department/${id}/parentDepartments`,
@@ -13218,6 +13242,21 @@ var import_react53 = require("react");
13218
13242
  var import_react50 = require("react");
13219
13243
  var import_antd22 = require("antd");
13220
13244
 
13245
+ // packages/sdk/src/components/fields/shared/departmentSearch.ts
13246
+ function canSearchAllDepartments(api, configuredTreeData) {
13247
+ return !configuredTreeData?.length && typeof api.searchDepartments === "function";
13248
+ }
13249
+ function normalizeDepartmentSearchItems(result) {
13250
+ const data = result?.data || result?.result || result;
13251
+ const source = Array.isArray(data) ? data : data?.items || data?.list || [];
13252
+ return source.map((item) => normalizeDepartmentNode(item)).filter((item) => item.id);
13253
+ }
13254
+ function getDepartmentPathText(department, separator = "/") {
13255
+ const path = Array.isArray(department?.path) ? department.path : [];
13256
+ const pathText = path.map((item) => item?.name).filter(Boolean).join(separator);
13257
+ return pathText || String(department?.fullPath || getDepartmentName(department) || "");
13258
+ }
13259
+
13221
13260
  // packages/sdk/src/components/fields/shared/DepartmentPicker.tsx
13222
13261
  var import_react49 = require("react");
13223
13262
  var import_antd21 = require("antd");
@@ -13232,7 +13271,11 @@ var getMobileComponent2 = (name) => {
13232
13271
  }
13233
13272
  };
13234
13273
  function normalizeSelection(items) {
13235
- return items.map((item) => ({ id: String(item.id || ""), name: String(item.name || item.id || "") })).filter((item) => item.id);
13274
+ return items.map((item) => ({
13275
+ id: String(item.id || ""),
13276
+ name: String(item.name || item.id || ""),
13277
+ fullPath: item.fullPath
13278
+ })).filter((item) => item.id);
13236
13279
  }
13237
13280
  function matchSearch(nodes, keyword) {
13238
13281
  if (!keyword) return nodes;
@@ -13253,7 +13296,12 @@ function DepartmentPickerPanel({
13253
13296
  treeData,
13254
13297
  onConfirm,
13255
13298
  onCancel,
13256
- mobile = false
13299
+ mobile = false,
13300
+ showSearch = true,
13301
+ searchScope = "loaded",
13302
+ showFullPath = false,
13303
+ searchMinLength = 1,
13304
+ searchDebounceMs = 300
13257
13305
  }) {
13258
13306
  const {
13259
13307
  treeData: loadedTreeData,
@@ -13267,11 +13315,53 @@ function DepartmentPickerPanel({
13267
13315
  const [selected, setSelected] = (0, import_react49.useState)(() => normalizeSelection(value));
13268
13316
  const [expandedKeys, setExpandedKeys] = (0, import_react49.useState)([]);
13269
13317
  const [currentDeptId, setCurrentDeptId] = (0, import_react49.useState)(null);
13318
+ const [remoteSearchResults, setRemoteSearchResults] = (0, import_react49.useState)([]);
13319
+ const [remoteSearchLoading, setRemoteSearchLoading] = (0, import_react49.useState)(false);
13320
+ const [remoteSearchError, setRemoteSearchError] = (0, import_react49.useState)("");
13321
+ const searchSeqRef = (0, import_react49.useRef)(0);
13270
13322
  const selectedIds = selected.map((item) => item.id);
13271
13323
  const MobileSearchBar = getMobileComponent2("SearchBar");
13324
+ const trimmedKeyword = keyword.trim();
13325
+ const canRemoteSearch = showSearch && searchScope === "all" && trimmedKeyword.length >= searchMinLength && canSearchAllDepartments(api, treeData);
13326
+ const spinning = treeLoading || remoteSearchLoading;
13327
+ (0, import_react49.useEffect)(() => {
13328
+ if (!canRemoteSearch) {
13329
+ searchSeqRef.current += 1;
13330
+ setRemoteSearchResults([]);
13331
+ setRemoteSearchLoading(false);
13332
+ setRemoteSearchError("");
13333
+ return;
13334
+ }
13335
+ const seq = searchSeqRef.current + 1;
13336
+ searchSeqRef.current = seq;
13337
+ setRemoteSearchLoading(true);
13338
+ setRemoteSearchError("");
13339
+ const timer = window.setTimeout(() => {
13340
+ api.searchDepartments?.({
13341
+ keyword: trimmedKeyword,
13342
+ page: 1,
13343
+ pageSize: 50,
13344
+ includePath: true
13345
+ }).then((result) => {
13346
+ if (searchSeqRef.current !== seq) return;
13347
+ setRemoteSearchResults(normalizeDepartmentSearchItems(result));
13348
+ }).catch((error) => {
13349
+ if (searchSeqRef.current !== seq) return;
13350
+ setRemoteSearchResults([]);
13351
+ setRemoteSearchError(error?.message || "\u641C\u7D22\u5931\u8D25");
13352
+ }).finally(() => {
13353
+ if (searchSeqRef.current === seq) {
13354
+ setRemoteSearchLoading(false);
13355
+ }
13356
+ });
13357
+ }, searchDebounceMs);
13358
+ return () => {
13359
+ window.clearTimeout(timer);
13360
+ };
13361
+ }, [api, canRemoteSearch, searchDebounceMs, trimmedKeyword]);
13272
13362
  const filteredTreeData = (0, import_react49.useMemo)(
13273
- () => matchSearch(loadedTreeData, keyword.trim()),
13274
- [keyword, loadedTreeData]
13363
+ () => showSearch ? matchSearch(loadedTreeData, trimmedKeyword) : loadedTreeData,
13364
+ [loadedTreeData, showSearch, trimmedKeyword]
13275
13365
  );
13276
13366
  const currentPath = (0, import_react49.useMemo)(() => {
13277
13367
  if (!currentDeptId) return [];
@@ -13286,13 +13376,36 @@ function DepartmentPickerPanel({
13286
13376
  return path;
13287
13377
  }, [currentDeptId, nodeMap, parentMap]);
13288
13378
  const mobileList = (0, import_react49.useMemo)(() => {
13289
- if (keyword.trim()) {
13290
- const lower = keyword.trim().toLowerCase();
13379
+ if (canRemoteSearch) {
13380
+ return remoteSearchResults;
13381
+ }
13382
+ if (showSearch && trimmedKeyword) {
13383
+ const lower = trimmedKeyword.toLowerCase();
13291
13384
  return flatNodes.filter((item) => item.name.toLowerCase().includes(lower)).map((item) => item.node);
13292
13385
  }
13293
13386
  if (!currentDeptId) return loadedTreeData;
13294
13387
  return nodeMap.get(currentDeptId)?.children || [];
13295
- }, [currentDeptId, flatNodes, keyword, loadedTreeData, nodeMap]);
13388
+ }, [
13389
+ canRemoteSearch,
13390
+ currentDeptId,
13391
+ flatNodes,
13392
+ loadedTreeData,
13393
+ nodeMap,
13394
+ remoteSearchResults,
13395
+ showSearch,
13396
+ trimmedKeyword
13397
+ ]);
13398
+ const getNodeValue = (node) => {
13399
+ const id = getDepartmentId(node);
13400
+ const name = getDepartmentName(node);
13401
+ const fullPath = getDepartmentPathText(node);
13402
+ return {
13403
+ id,
13404
+ name,
13405
+ ...fullPath && fullPath !== name ? { fullPath } : {}
13406
+ };
13407
+ };
13408
+ const getSelectedLabel = (item) => showFullPath ? item.fullPath || item.name : item.name;
13296
13409
  const upsertSelected = (department, checked) => {
13297
13410
  if (multiple) {
13298
13411
  setSelected((prev) => {
@@ -13309,14 +13422,14 @@ function DepartmentPickerPanel({
13309
13422
  const checkedKeys = Array.isArray(keys) ? keys : keys.checked;
13310
13423
  const next = checkedKeys.map((key) => {
13311
13424
  const node = nodeMap.get(String(key));
13312
- return node ? { id: getDepartmentId(node), name: getDepartmentName(node) } : void 0;
13425
+ return node ? getNodeValue(node) : void 0;
13313
13426
  }).filter(Boolean);
13314
13427
  setSelected(next);
13315
13428
  };
13316
13429
  const handleTreeSelect = (keys) => {
13317
13430
  const id = String(keys[0] || "");
13318
13431
  const node = id ? nodeMap.get(id) : void 0;
13319
- setSelected(node ? [{ id, name: getDepartmentName(node) }] : []);
13432
+ setSelected(node ? [getNodeValue(node)] : []);
13320
13433
  };
13321
13434
  const renderSelected = () => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker-selected", children: [
13322
13435
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker-selected-head", children: [
@@ -13326,8 +13439,51 @@ function DepartmentPickerPanel({
13326
13439
  ] }),
13327
13440
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { type: "button", onClick: () => setSelected([]), disabled: !selected.length, children: "\u6E05\u7A7A" })
13328
13441
  ] }),
13329
- selected.length ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "sy-org-picker-tags", children: selected.map((item) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Tag, { closable: true, onClose: () => upsertSelected(item, false), children: item.name }, item.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Empty, { image: import_antd21.Empty.PRESENTED_IMAGE_SIMPLE, description: "\u6682\u65E0\u9009\u62E9" })
13442
+ selected.length ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "sy-org-picker-tags", children: selected.map((item) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Tag, { closable: true, onClose: () => upsertSelected(item, false), children: getSelectedLabel(item) }, item.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Empty, { image: import_antd21.Empty.PRESENTED_IMAGE_SIMPLE, description: "\u6682\u65E0\u9009\u62E9" })
13330
13443
  ] });
13444
+ const renderRemoteSearchResults = () => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13445
+ import_antd21.List,
13446
+ {
13447
+ dataSource: remoteSearchResults,
13448
+ locale: { emptyText: remoteSearchError || "\u6682\u65E0\u90E8\u95E8" },
13449
+ renderItem: (node) => {
13450
+ const id = getDepartmentId(node);
13451
+ const name = getDepartmentName(node);
13452
+ const selectedNow = selectedIds.includes(id);
13453
+ const pathText = getDepartmentPathText(node);
13454
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13455
+ import_antd21.List.Item,
13456
+ {
13457
+ onClick: () => upsertSelected(getNodeValue(node), true),
13458
+ actions: [
13459
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13460
+ import_antd21.Checkbox,
13461
+ {
13462
+ checked: selectedNow,
13463
+ onChange: (event) => upsertSelected(getNodeValue(node), event.target.checked)
13464
+ },
13465
+ "select"
13466
+ )
13467
+ ],
13468
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13469
+ import_antd21.List.Item.Meta,
13470
+ {
13471
+ avatar: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_icons9.ApartmentOutlined, {}),
13472
+ title: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { children: [
13473
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { children: name }),
13474
+ showFullPath && pathText && pathText !== name ? /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { className: "sy-org-picker-path", children: [
13475
+ " ",
13476
+ pathText
13477
+ ] }) : null
13478
+ ] })
13479
+ }
13480
+ )
13481
+ },
13482
+ id
13483
+ );
13484
+ }
13485
+ }
13486
+ );
13331
13487
  if (mobile) {
13332
13488
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker sy-org-picker-mobile", children: [
13333
13489
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker-mobile-head", children: [
@@ -13335,7 +13491,7 @@ function DepartmentPickerPanel({
13335
13491
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("strong", { children: "\u9009\u62E9\u90E8\u95E8" }),
13336
13492
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { type: "button", onClick: () => onConfirm(selected), children: "\u786E\u5B9A" })
13337
13493
  ] }),
13338
- MobileSearchBar ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(MobileSearchBar, { placeholder: "\u641C\u7D22\u90E8\u95E8", value: keyword, onChange: setKeyword }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("input", { value: keyword, onChange: (event) => setKeyword(event.target.value) }),
13494
+ showSearch ? MobileSearchBar ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(MobileSearchBar, { placeholder: "\u641C\u7D22\u90E8\u95E8", value: keyword, onChange: setKeyword }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("input", { value: keyword, onChange: (event) => setKeyword(event.target.value) }) : null,
13339
13495
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker-breadcrumb", children: [
13340
13496
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { type: "button", onClick: () => setCurrentDeptId(null), children: "\u90E8\u95E8" }),
13341
13497
  currentPath.map((item) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("button", { type: "button", onClick: () => setCurrentDeptId(item.id), children: [
@@ -13343,16 +13499,17 @@ function DepartmentPickerPanel({
13343
13499
  item.name
13344
13500
  ] }, item.id))
13345
13501
  ] }),
13346
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Spin, { spinning: treeLoading, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13502
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Spin, { spinning, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13347
13503
  import_antd21.List,
13348
13504
  {
13349
13505
  dataSource: mobileList,
13350
- locale: { emptyText: "\u6682\u65E0\u90E8\u95E8" },
13506
+ locale: { emptyText: remoteSearchError || "\u6682\u65E0\u90E8\u95E8" },
13351
13507
  renderItem: (node) => {
13352
13508
  const id = getDepartmentId(node);
13353
13509
  const name = getDepartmentName(node);
13354
13510
  const selectedNow = selectedIds.includes(id);
13355
- const hasChildren = Boolean(node.hasChildren && !node.isLeaf);
13511
+ const hasChildren = !canRemoteSearch && Boolean(node.hasChildren && !node.isLeaf);
13512
+ const pathText = getDepartmentPathText(node);
13356
13513
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13357
13514
  import_antd21.List.Item,
13358
13515
  {
@@ -13361,7 +13518,7 @@ function DepartmentPickerPanel({
13361
13518
  import_antd21.Checkbox,
13362
13519
  {
13363
13520
  checked: selectedNow,
13364
- onChange: (event) => upsertSelected({ id, name }, event.target.checked)
13521
+ onChange: (event) => upsertSelected(getNodeValue(node), event.target.checked)
13365
13522
  },
13366
13523
  "select"
13367
13524
  ),
@@ -13379,7 +13536,19 @@ function DepartmentPickerPanel({
13379
13536
  "children"
13380
13537
  ) : null
13381
13538
  ],
13382
- children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.List.Item.Meta, { avatar: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_icons9.ApartmentOutlined, {}), title: name })
13539
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13540
+ import_antd21.List.Item.Meta,
13541
+ {
13542
+ avatar: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_icons9.ApartmentOutlined, {}),
13543
+ title: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { children: [
13544
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { children: name }),
13545
+ showFullPath && pathText && pathText !== name ? /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { className: "sy-org-picker-path", children: [
13546
+ " ",
13547
+ pathText
13548
+ ] }) : null
13549
+ ] })
13550
+ }
13551
+ )
13383
13552
  },
13384
13553
  id
13385
13554
  );
@@ -13392,7 +13561,7 @@ function DepartmentPickerPanel({
13392
13561
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker", children: [
13393
13562
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker-main", children: [
13394
13563
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "sy-org-picker-tree", children: [
13395
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13564
+ showSearch ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13396
13565
  import_antd21.Input,
13397
13566
  {
13398
13567
  allowClear: true,
@@ -13401,8 +13570,8 @@ function DepartmentPickerPanel({
13401
13570
  value: keyword,
13402
13571
  onChange: (event) => setKeyword(event.target.value)
13403
13572
  }
13404
- ),
13405
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Spin, { spinning: treeLoading, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13573
+ ) : null,
13574
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_antd21.Spin, { spinning, children: canRemoteSearch ? renderRemoteSearchResults() : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
13406
13575
  import_antd21.Tree,
13407
13576
  {
13408
13577
  checkable: multiple,
@@ -13492,6 +13661,17 @@ function convertTreeData(nodes) {
13492
13661
  children: node.children ? convertTreeData(node.children) : void 0
13493
13662
  }));
13494
13663
  }
13664
+ function convertSearchTreeData(nodes, showFullPath) {
13665
+ return nodes.map((node) => {
13666
+ const name = getDepartmentName(node);
13667
+ const pathText = getDepartmentPathText(node);
13668
+ return {
13669
+ value: getDepartmentId(node),
13670
+ title: showFullPath && pathText ? pathText : name,
13671
+ isLeaf: true
13672
+ };
13673
+ });
13674
+ }
13495
13675
  function DepartmentSelectFieldPC({
13496
13676
  fieldId,
13497
13677
  behavior,
@@ -13501,6 +13681,11 @@ function DepartmentSelectFieldPC({
13501
13681
  treeData,
13502
13682
  allowClear = true,
13503
13683
  maxCount,
13684
+ notFoundContent,
13685
+ showSearch = true,
13686
+ searchScope = "loaded",
13687
+ searchMinLength = 1,
13688
+ searchDebounceMs = 300,
13504
13689
  showFullPath,
13505
13690
  scopeType,
13506
13691
  specifiedDepts,
@@ -13514,6 +13699,11 @@ function DepartmentSelectFieldPC({
13514
13699
  const remoteLoadedRef = (0, import_react50.useRef)(false);
13515
13700
  const [loadedTreeData, setLoadedTreeData] = (0, import_react50.useState)(configuredTreeData);
13516
13701
  const [pickerOpen, setPickerOpen] = (0, import_react50.useState)(false);
13702
+ const [searchKeyword, setSearchKeyword] = (0, import_react50.useState)("");
13703
+ const [remoteSearchResults, setRemoteSearchResults] = (0, import_react50.useState)([]);
13704
+ const [remoteSearchLoading, setRemoteSearchLoading] = (0, import_react50.useState)(false);
13705
+ const [selectedPathMap, setSelectedPathMap] = (0, import_react50.useState)({});
13706
+ const searchSeqRef = (0, import_react50.useRef)(0);
13517
13707
  (0, import_react50.useEffect)(() => {
13518
13708
  if (configuredTreeData.length) {
13519
13709
  setLoadedTreeData(configuredTreeData.map(normalizeDepartmentNode));
@@ -13525,22 +13715,87 @@ function DepartmentSelectFieldPC({
13525
13715
  (nodes) => setLoadedTreeData(nodes.map(normalizeDepartmentNode))
13526
13716
  );
13527
13717
  }, [api, configuredTreeData]);
13718
+ const trimmedSearchKeyword = searchKeyword.trim();
13719
+ const canRemoteSearch = showSearch && searchScope === "all" && trimmedSearchKeyword.length >= searchMinLength && canSearchAllDepartments(api, configuredTreeData);
13720
+ (0, import_react50.useEffect)(() => {
13721
+ if (!canRemoteSearch) {
13722
+ searchSeqRef.current += 1;
13723
+ setRemoteSearchResults([]);
13724
+ setRemoteSearchLoading(false);
13725
+ return;
13726
+ }
13727
+ const seq = searchSeqRef.current + 1;
13728
+ searchSeqRef.current = seq;
13729
+ setRemoteSearchLoading(true);
13730
+ const timer = window.setTimeout(() => {
13731
+ api.searchDepartments?.({
13732
+ keyword: trimmedSearchKeyword,
13733
+ page: 1,
13734
+ pageSize: 50,
13735
+ includePath: true
13736
+ }).then((result) => {
13737
+ if (searchSeqRef.current !== seq) return;
13738
+ setRemoteSearchResults(normalizeDepartmentSearchItems(result));
13739
+ }).catch(() => {
13740
+ if (searchSeqRef.current !== seq) return;
13741
+ setRemoteSearchResults([]);
13742
+ }).finally(() => {
13743
+ if (searchSeqRef.current === seq) {
13744
+ setRemoteSearchLoading(false);
13745
+ }
13746
+ });
13747
+ }, searchDebounceMs);
13748
+ return () => {
13749
+ window.clearTimeout(timer);
13750
+ };
13751
+ }, [api, canRemoteSearch, searchDebounceMs, trimmedSearchKeyword]);
13528
13752
  const scopedTreeData = filterTreeByScope(loadedTreeData, scopeType, specifiedDepts);
13529
13753
  const allDepts = flattenDepartments(scopedTreeData);
13754
+ const scopedRemoteSearchResults = (0, import_react50.useMemo)(() => {
13755
+ if (scopeType !== "specified" || !specifiedDepts?.length) {
13756
+ return remoteSearchResults;
13757
+ }
13758
+ const specifiedSet = new Set(specifiedDepts);
13759
+ return remoteSearchResults.filter((node) => {
13760
+ const id = getDepartmentId(node);
13761
+ if (specifiedSet.has(id)) return true;
13762
+ return node.path?.some((item) => specifiedSet.has(item.id));
13763
+ });
13764
+ }, [remoteSearchResults, scopeType, specifiedDepts]);
13765
+ const remoteDeptMap = (0, import_react50.useMemo)(() => {
13766
+ const map = /* @__PURE__ */ new Map();
13767
+ scopedRemoteSearchResults.forEach((node) => map.set(getDepartmentId(node), node));
13768
+ return map;
13769
+ }, [scopedRemoteSearchResults]);
13530
13770
  const handleChange = (selectedValue) => {
13531
13771
  const selectedValues = Array.isArray(selectedValue) ? selectedValue : selectedValue ? [selectedValue] : [];
13772
+ const nextPathMap = { ...selectedPathMap };
13532
13773
  const selected = selectedValues.map((item) => {
13533
13774
  const id = String(item?.value ?? item);
13534
13775
  const label = item?.label;
13535
- const matched = allDepts.find((dept) => dept.id === id) ?? value.find((dept) => getDepartmentId(dept) === id);
13776
+ const remoteDept = remoteDeptMap.get(id);
13777
+ const matched = remoteDept ?? allDepts.find((dept) => dept.id === id)?.node ?? value.find((dept) => getDepartmentId(dept) === id);
13778
+ if (remoteDept) {
13779
+ nextPathMap[id] = getDepartmentPathText(remoteDept);
13780
+ }
13536
13781
  const labelText = typeof label === "string" || typeof label === "number" ? String(label) : void 0;
13537
- return { id, name: labelText || matched?.name || id };
13782
+ return { id, name: getDepartmentName(matched) || labelText || id };
13538
13783
  }).filter((item) => item.id);
13539
13784
  const result = (multiple ? selected.slice(0, maxCount ?? selected.length) : selected.slice(0, 1)).map(toDepartmentValue);
13785
+ setSelectedPathMap(nextPathMap);
13540
13786
  setFieldValue(fieldId, result);
13541
13787
  onChange?.(result);
13542
13788
  };
13543
13789
  const handlePickerConfirm = (items) => {
13790
+ setSelectedPathMap((current) => {
13791
+ const next = { ...current };
13792
+ items.forEach((item) => {
13793
+ if (item.fullPath) {
13794
+ next[item.id] = String(item.fullPath);
13795
+ }
13796
+ });
13797
+ return next;
13798
+ });
13544
13799
  const result = (multiple ? items.slice(0, maxCount ?? items.length) : items.slice(0, 1)).map(
13545
13800
  toDepartmentValue
13546
13801
  );
@@ -13548,12 +13803,19 @@ function DepartmentSelectFieldPC({
13548
13803
  onChange?.(result);
13549
13804
  };
13550
13805
  const treeDataConverted = convertTreeData(scopedTreeData);
13806
+ const searchTreeDataConverted = convertSearchTreeData(scopedRemoteSearchResults, showFullPath);
13807
+ const renderedTreeData = canRemoteSearch ? searchTreeDataConverted : treeDataConverted;
13808
+ const getDisplayLabel2 = (dept) => {
13809
+ const id = getDepartmentId(dept);
13810
+ if (!showFullPath) return getDepartmentName(dept);
13811
+ return getDepartmentFullPath(id, scopedTreeData) || selectedPathMap[id] || (remoteDeptMap.has(id) ? getDepartmentPathText(remoteDeptMap.get(id)) : "") || getDepartmentName(dept);
13812
+ };
13551
13813
  const selectValue = multiple ? value.map((d) => ({
13552
13814
  value: getDepartmentId(d),
13553
- label: showFullPath ? getDepartmentFullPath(getDepartmentId(d), scopedTreeData) || getDepartmentName(d) : getDepartmentName(d)
13815
+ label: getDisplayLabel2(d)
13554
13816
  })) : value[0] ? {
13555
13817
  value: getDepartmentId(value[0]),
13556
- label: showFullPath ? getDepartmentFullPath(getDepartmentId(value[0]), scopedTreeData) || getDepartmentName(value[0]) : getDepartmentName(value[0])
13818
+ label: getDisplayLabel2(value[0])
13557
13819
  } : void 0;
13558
13820
  return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "sy-select-with-picker", children: [
13559
13821
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
@@ -13565,9 +13827,14 @@ function DepartmentSelectFieldPC({
13565
13827
  maxCount,
13566
13828
  allowClear,
13567
13829
  labelInValue: true,
13568
- treeData: treeDataConverted,
13830
+ showSearch,
13831
+ searchValue: searchKeyword,
13832
+ onSearch: setSearchKeyword,
13833
+ filterTreeNode: canRemoteSearch ? false : void 0,
13834
+ treeData: renderedTreeData,
13569
13835
  value: selectValue,
13570
13836
  placeholder,
13837
+ notFoundContent: remoteSearchLoading ? "\u641C\u7D22\u4E2D..." : notFoundContent || "\u6682\u65E0\u90E8\u95E8",
13571
13838
  disabled,
13572
13839
  onChange: handleChange,
13573
13840
  loadData: async (node) => {
@@ -13611,6 +13878,11 @@ function DepartmentSelectFieldPC({
13611
13878
  multiple,
13612
13879
  value,
13613
13880
  treeData,
13881
+ showSearch,
13882
+ searchScope,
13883
+ showFullPath,
13884
+ searchMinLength,
13885
+ searchDebounceMs,
13614
13886
  onConfirm: handlePickerConfirm,
13615
13887
  onCancel: () => void 0
13616
13888
  }
@@ -13643,6 +13915,10 @@ function DepartmentSelectFieldMobile({
13643
13915
  treeData,
13644
13916
  allowClear = true,
13645
13917
  maxCount,
13918
+ showSearch = true,
13919
+ searchScope = "loaded",
13920
+ searchMinLength = 1,
13921
+ searchDebounceMs = 300,
13646
13922
  showFullPath,
13647
13923
  scopeType,
13648
13924
  specifiedDepts,
@@ -13730,6 +14006,11 @@ function DepartmentSelectFieldMobile({
13730
14006
  multiple,
13731
14007
  value,
13732
14008
  treeData,
14009
+ showSearch,
14010
+ searchScope,
14011
+ showFullPath,
14012
+ searchMinLength,
14013
+ searchDebounceMs,
13733
14014
  onConfirm: handleConfirm,
13734
14015
  onCancel: () => setShowPicker(false)
13735
14016
  }