@tianyr/schema-antd 0.1.0 → 0.2.0
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/README.md +57 -12
- package/dist/SchemaField.d.ts +1 -1
- package/dist/biz-select/BizMultiSelect.d.ts +3 -0
- package/dist/biz-select/BizMultiSelect.d.ts.map +1 -0
- package/dist/biz-select/BizMultiSelect.js +120 -0
- package/dist/biz-select/BizMultiSelect.js.map +1 -0
- package/dist/biz-select/BizMultiSelectDisplay.d.ts +3 -0
- package/dist/biz-select/BizMultiSelectDisplay.d.ts.map +1 -0
- package/dist/biz-select/BizMultiSelectDisplay.js +59 -0
- package/dist/biz-select/BizMultiSelectDisplay.js.map +1 -0
- package/dist/biz-select/BizSelect.d.ts +3 -0
- package/dist/biz-select/BizSelect.d.ts.map +1 -0
- package/dist/biz-select/BizSelect.js +87 -0
- package/dist/biz-select/BizSelect.js.map +1 -0
- package/dist/biz-select/BizSelectDisplay.d.ts +3 -0
- package/dist/biz-select/BizSelectDisplay.d.ts.map +1 -0
- package/dist/biz-select/BizSelectDisplay.js +58 -0
- package/dist/biz-select/BizSelectDisplay.js.map +1 -0
- package/dist/biz-select/cache.d.ts +23 -0
- package/dist/biz-select/cache.d.ts.map +1 -0
- package/dist/biz-select/cache.js +141 -0
- package/dist/biz-select/cache.js.map +1 -0
- package/dist/biz-select/compile.d.ts +36 -0
- package/dist/biz-select/compile.d.ts.map +1 -0
- package/dist/biz-select/compile.js +103 -0
- package/dist/biz-select/compile.js.map +1 -0
- package/dist/biz-select/factories.d.ts +32 -0
- package/dist/biz-select/factories.d.ts.map +1 -0
- package/dist/biz-select/factories.js +67 -0
- package/dist/biz-select/factories.js.map +1 -0
- package/dist/biz-select/format.d.ts +66 -0
- package/dist/biz-select/format.d.ts.map +1 -0
- package/dist/biz-select/format.js +175 -0
- package/dist/biz-select/format.js.map +1 -0
- package/dist/biz-select/index.d.ts +28 -0
- package/dist/biz-select/index.d.ts.map +1 -0
- package/dist/biz-select/index.js +26 -0
- package/dist/biz-select/index.js.map +1 -0
- package/dist/biz-select/key.d.ts +25 -0
- package/dist/biz-select/key.d.ts.map +1 -0
- package/dist/biz-select/key.js +83 -0
- package/dist/biz-select/key.js.map +1 -0
- package/dist/biz-select/normalize.d.ts +43 -0
- package/dist/biz-select/normalize.d.ts.map +1 -0
- package/dist/biz-select/normalize.js +49 -0
- package/dist/biz-select/normalize.js.map +1 -0
- package/dist/biz-select/registry.d.ts +15 -0
- package/dist/biz-select/registry.d.ts.map +1 -0
- package/dist/biz-select/registry.js +81 -0
- package/dist/biz-select/registry.js.map +1 -0
- package/dist/biz-select/resolveBatch.d.ts +34 -0
- package/dist/biz-select/resolveBatch.d.ts.map +1 -0
- package/dist/biz-select/resolveBatch.js +124 -0
- package/dist/biz-select/resolveBatch.js.map +1 -0
- package/dist/biz-select/schema.d.ts +5 -0
- package/dist/biz-select/schema.d.ts.map +1 -0
- package/dist/biz-select/schema.js +28 -0
- package/dist/biz-select/schema.js.map +1 -0
- package/dist/biz-select/source-id.d.ts +8 -0
- package/dist/biz-select/source-id.d.ts.map +1 -0
- package/dist/biz-select/source-id.js +10 -0
- package/dist/biz-select/source-id.js.map +1 -0
- package/dist/biz-select/types.d.ts +160 -0
- package/dist/biz-select/types.d.ts.map +1 -0
- package/dist/{app-select → biz-select}/types.js.map +1 -1
- package/dist/biz-select/useCandidates.d.ts +40 -0
- package/dist/biz-select/useCandidates.d.ts.map +1 -0
- package/dist/biz-select/useCandidates.js +292 -0
- package/dist/biz-select/useCandidates.js.map +1 -0
- package/dist/biz-select/useResolvedLabels.d.ts +28 -0
- package/dist/biz-select/useResolvedLabels.d.ts.map +1 -0
- package/dist/biz-select/useResolvedLabels.js +151 -0
- package/dist/biz-select/useResolvedLabels.js.map +1 -0
- package/dist/biz-select/useSelectedLabel.d.ts +18 -0
- package/dist/biz-select/useSelectedLabel.d.ts.map +1 -0
- package/dist/biz-select/useSelectedLabel.js +156 -0
- package/dist/biz-select/useSelectedLabel.js.map +1 -0
- package/dist/biz-select/useSelectedLabels.d.ts +26 -0
- package/dist/biz-select/useSelectedLabels.d.ts.map +1 -0
- package/dist/biz-select/useSelectedLabels.js +88 -0
- package/dist/biz-select/useSelectedLabels.js.map +1 -0
- package/dist/biz-select/useStableSourceKey.d.ts +3 -0
- package/dist/biz-select/useStableSourceKey.d.ts.map +1 -0
- package/dist/biz-select/useStableSourceKey.js +48 -0
- package/dist/biz-select/useStableSourceKey.js.map +1 -0
- package/dist/flat.d.ts +43 -0
- package/dist/flat.d.ts.map +1 -0
- package/dist/flat.js +91 -0
- package/dist/flat.js.map +1 -0
- package/dist/form/SchemaFormField.d.ts.map +1 -1
- package/dist/form/SchemaFormField.js +4 -3
- package/dist/form/SchemaFormField.js.map +1 -1
- package/dist/form/derive.d.ts +3 -8
- package/dist/form/derive.d.ts.map +1 -1
- package/dist/form/derive.js +28 -0
- package/dist/form/derive.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/registry.d.ts +6 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js.map +1 -1
- package/dist/types.d.ts +7 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/app-select/AppSelect.d.ts +0 -3
- package/dist/app-select/AppSelect.d.ts.map +0 -1
- package/dist/app-select/AppSelect.js +0 -56
- package/dist/app-select/AppSelect.js.map +0 -1
- package/dist/app-select/AppSelectDisplay.d.ts +0 -3
- package/dist/app-select/AppSelectDisplay.d.ts.map +0 -1
- package/dist/app-select/AppSelectDisplay.js +0 -39
- package/dist/app-select/AppSelectDisplay.js.map +0 -1
- package/dist/app-select/cache.d.ts +0 -26
- package/dist/app-select/cache.d.ts.map +0 -1
- package/dist/app-select/cache.js +0 -82
- package/dist/app-select/cache.js.map +0 -1
- package/dist/app-select/hooks.d.ts +0 -56
- package/dist/app-select/hooks.d.ts.map +0 -1
- package/dist/app-select/hooks.js +0 -322
- package/dist/app-select/hooks.js.map +0 -1
- package/dist/app-select/index.d.ts +0 -7
- package/dist/app-select/index.d.ts.map +0 -1
- package/dist/app-select/index.js +0 -6
- package/dist/app-select/index.js.map +0 -1
- package/dist/app-select/register.d.ts +0 -2
- package/dist/app-select/register.d.ts.map +0 -1
- package/dist/app-select/register.js +0 -10
- package/dist/app-select/register.js.map +0 -1
- package/dist/app-select/sources.d.ts +0 -20
- package/dist/app-select/sources.d.ts.map +0 -1
- package/dist/app-select/sources.js +0 -59
- package/dist/app-select/sources.js.map +0 -1
- package/dist/app-select/types.d.ts +0 -68
- package/dist/app-select/types.d.ts.map +0 -1
- package/dist/app-select/utils.d.ts +0 -30
- package/dist/app-select/utils.d.ts.map +0 -1
- package/dist/app-select/utils.js +0 -76
- package/dist/app-select/utils.js.map +0 -1
- /package/dist/{app-select → biz-select}/types.js +0 -0
package/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# schema-antd
|
|
2
2
|
|
|
3
|
-
基于 antd v5 的 Schema
|
|
3
|
+
基于 antd v5 的 Schema 驱动表单、可编辑表格与业务下拉。一份扁平的字段配置,同时用于普通表单、
|
|
4
4
|
单活动行编辑表格和全行常驻编辑表格,字段的显隐、禁用、校验、选项和联动都由配置描述。
|
|
5
5
|
|
|
6
6
|
- **不内置 antd**:`antd` / `react` 全部是 peer 依赖,产物只有 ESM 与类型声明
|
|
7
7
|
- **一份绑定层**:普通表单和两种表格的行复用同一个字段绑定,联动语义完全一致
|
|
8
8
|
- **可编辑列三态**:`true` 编辑、`'read'` 只读但跟随本行 Form(能看到联动带出的值)、`false` 直接读行记录
|
|
9
|
+
- **业务下拉**:`BizSelect` 把候选来源、名称回显、级联接入收进一个组件,值默认存标量;选项契约 `{ value, label }`
|
|
9
10
|
|
|
10
11
|
## 安装
|
|
11
12
|
|
|
@@ -117,26 +118,68 @@ const columns: EditableColumn<OrderRow>[] = [
|
|
|
117
118
|
/>
|
|
118
119
|
```
|
|
119
120
|
|
|
120
|
-
##
|
|
121
|
+
## BizSelect
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
业务下拉:候选从哪来、只有一个编码时名称怎么还原、切换上级后旧候选怎么办。
|
|
124
|
+
值默认是标量编码(`valueMode="object"` 可存对象),字段类型由使用方显式注册。
|
|
123
125
|
|
|
124
126
|
```ts
|
|
125
|
-
import {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
import { defineSelectSources, loaded, remote, staticList } from '@tianyr/schema-antd'
|
|
128
|
+
|
|
129
|
+
defineSelectSources({
|
|
130
|
+
province: staticList(PROVINCES), // 前端常量,不发请求
|
|
131
|
+
currency: loaded(api.listCurrency), // 一次拉全量,之后前端过滤
|
|
132
|
+
material: remote({ // 关键词交给后端,另配编码精确回显
|
|
133
|
+
recordFields: { value: 'code', label: 'name' }, // 后端记录字段名 → 契约 { value, label }
|
|
134
|
+
search: (keyword, params, signal) => api.pageMaterial({ keyword, ...params }, signal),
|
|
135
|
+
resolve: (code, params, signal) => api.getMaterial(code, params, signal),
|
|
136
|
+
requiredParams: ['warehouseCode'], // 缺参数不发请求,避免查到别家数据
|
|
137
|
+
}),
|
|
132
138
|
})
|
|
133
139
|
```
|
|
134
140
|
|
|
135
141
|
```tsx
|
|
136
|
-
|
|
142
|
+
// 独立使用:受控,value / onChange 必配
|
|
143
|
+
<BizSelect source="currency" value={currency} onChange={setCurrency} />
|
|
144
|
+
|
|
145
|
+
// 只读:同一套名称解析,不挂 Select
|
|
146
|
+
<BizSelectDisplay source="material" params={{ warehouseCode }} value={materialCode} />
|
|
147
|
+
|
|
148
|
+
// 多选:独立组件,值是编码数组(schema 里的类型名是 'BizMultiSelect')
|
|
149
|
+
<BizMultiSelect source="material" params={{ warehouseCode }} value={codes} onChange={setCodes} />
|
|
137
150
|
```
|
|
138
151
|
|
|
139
|
-
|
|
152
|
+
多选刻意不做成 `mode` 属性:值类型属于 API 面,合并会把 `BizSelectProps.value` 拓宽成联合。
|
|
153
|
+
候选、搜索、展示转换、批量解析与单选完全共用;清空时输出 `undefined`(不是 `[]`),
|
|
154
|
+
这样 `required` 规则天然生效。
|
|
155
|
+
|
|
156
|
+
在 schema 里用,级联一行配完(先调一次 `registerBizSelectField()` 注册类型):
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
{
|
|
160
|
+
type: 'BizSelect',
|
|
161
|
+
name: 'materialCode',
|
|
162
|
+
label: '物料',
|
|
163
|
+
source: 'material',
|
|
164
|
+
paramsFrom: { warehouseCode: 'warehouseCode' }, // 参数名 ← 字段名
|
|
165
|
+
blockedText: '请先选择仓库',
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
约定:
|
|
170
|
+
|
|
171
|
+
- 选项契约是 `{ value, label }`,和 antd 同词汇;后端 `{ code, name }`、`{ userId, userName }` 在源的
|
|
172
|
+
`recordFields` 上映射一次(`staticList(list, recordFields)`,`loaded(load, { recordFields })`,`remote({ recordFields })`)。
|
|
173
|
+
没声明就视为已经是 `{ value, label }`,不做自动嗅探。
|
|
174
|
+
- 行为由源的能力推导:`options` 前端常量、`load` 一次拉全量后前端过滤、`search` 后端搜索,三者可组合。
|
|
175
|
+
- `resolve(value)` 专用于按值精确回显,不要用模糊搜索冒充。
|
|
176
|
+
- `requiredParams` 不齐时进入 `blocked`:候选为空、不发请求。
|
|
177
|
+
- `invalidateSelectSource(name)` 让已挂载的实例重新取数;`useCandidates` 可把同一份候选给树、弹窗复用。
|
|
178
|
+
- 表格列只有 id 时用 `useResolvedLabels` 批量解析:源声明了 `resolveMany` 才会合并成一次请求,
|
|
179
|
+
没声明就逐条(开发态告警一次)。有限枚举的列应该用 `load` 型源一次拉全量,不必逐条解析。
|
|
180
|
+
- 内联源要跨实例共享缓存,就传导入的函数或显式 `cacheKey`;内联箭头每次渲染都换键,缓存命中不了。
|
|
181
|
+
- 已经是 `{ value, label }` 形状的本地枚举(数据字典、常量表)直接 `staticList` 即可,不必再写 `recordFields`;
|
|
182
|
+
分组选项和树形选项不在范围内(契约是扁平结构)。详见 `src/biz-select/README.md` §4。
|
|
140
183
|
|
|
141
184
|
## 其他导出
|
|
142
185
|
|
|
@@ -154,6 +197,8 @@ registerAppSelectSource('product', {
|
|
|
154
197
|
不影响功能,只是少几条开发提示。
|
|
155
198
|
- `virtual` 不开放:虚拟滚动会卸载离屏行,全行常驻表格的行 Form 会随之销毁、输入丢失。
|
|
156
199
|
|
|
200
|
+
版本变更见 [CHANGELOG.md](./CHANGELOG.md)。
|
|
201
|
+
|
|
157
202
|
## License
|
|
158
203
|
|
|
159
204
|
MIT
|
package/dist/SchemaField.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AnyFieldSchema, FieldMode } from './types.js';
|
|
|
2
2
|
export interface SchemaFieldProps<TValue = unknown> {
|
|
3
3
|
schema: AnyFieldSchema<TValue>;
|
|
4
4
|
value?: TValue;
|
|
5
|
-
/** 统一为 (value, ...meta);Select/
|
|
5
|
+
/** 统一为 (value, ...meta);Select/BizSelect 的 meta[0] 即选中项 */
|
|
6
6
|
onChange?: (value: TValue, ...meta: unknown[]) => void;
|
|
7
7
|
/** 高于 schema.mode */
|
|
8
8
|
mode?: FieldMode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizMultiSelect.d.ts","sourceRoot":"","sources":["../../src/biz-select/BizMultiSelect.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,mBAAmB,EAAqC,MAAM,SAAS,CAAC;AAetF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,+BAsIxD"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* BizMultiSelect:业务下拉的多选态。
|
|
4
|
+
*
|
|
5
|
+
* 和 `BizSelect` 共用候选、展示转换和批量解析,差别只在值:
|
|
6
|
+
* 一个是标量/对象,一个是它们的数组。刻意做成独立组件而不是 `mode` 属性,
|
|
7
|
+
* 因为值类型属于 API 面——合并会把 `BizSelectProps.value` 拓宽成联合,
|
|
8
|
+
* 所有存量调用点跟着变宽,而我们没有任何地方需要这种兼容。
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect, useMemo } from 'react';
|
|
11
|
+
import { Select } from 'antd';
|
|
12
|
+
import { normalizeSource } from './normalize.js';
|
|
13
|
+
import { resolveSelectSource } from './registry.js';
|
|
14
|
+
import { useCandidates } from './useCandidates.js';
|
|
15
|
+
import { useSelectedLabels } from './useSelectedLabels.js';
|
|
16
|
+
import { buildObjectValues, defaultSearchFields, readObjectLabels, readValues, toAntOption, } from './format.js';
|
|
17
|
+
const DEFAULT_BLOCKED_TEXT = '请先选择上级';
|
|
18
|
+
/** antd 在多选下回传的是已选项数组;单选偶发单个对象,两种都接住 */
|
|
19
|
+
function pickedOptions(antOption) {
|
|
20
|
+
const list = Array.isArray(antOption) ? antOption : antOption ? [antOption] : [];
|
|
21
|
+
const picked = [];
|
|
22
|
+
for (const item of list) {
|
|
23
|
+
const raw = item?.raw;
|
|
24
|
+
if (raw)
|
|
25
|
+
picked.push(raw);
|
|
26
|
+
}
|
|
27
|
+
return picked;
|
|
28
|
+
}
|
|
29
|
+
export function BizMultiSelect(props) {
|
|
30
|
+
const { source, params, displayMode = 'L', searchFields, seedOptions, debounceMs, cacheKey, blockedText = DEFAULT_BLOCKED_TEXT, valueMode = 'primitive', valueFields, value, onChange, disabled, placeholder, ...rest } = props;
|
|
31
|
+
const codes = readValues(value, valueMode, valueFields);
|
|
32
|
+
const valueNames = readObjectLabels(value, valueMode, valueFields);
|
|
33
|
+
const sourceObj = resolveSelectSource(source);
|
|
34
|
+
const candidates = useCandidates({
|
|
35
|
+
source,
|
|
36
|
+
cacheKey,
|
|
37
|
+
params,
|
|
38
|
+
searchFields: searchFields ?? defaultSearchFields(displayMode),
|
|
39
|
+
debounceMs,
|
|
40
|
+
});
|
|
41
|
+
const { sourceKey } = candidates;
|
|
42
|
+
const selected = useSelectedLabels({
|
|
43
|
+
source,
|
|
44
|
+
cacheKey,
|
|
45
|
+
sourceKey,
|
|
46
|
+
codes,
|
|
47
|
+
valueNames,
|
|
48
|
+
seedOptions,
|
|
49
|
+
// 回显查未过滤全集,否则输入关键词后已选项会被筛掉、名称退回编码
|
|
50
|
+
candidates: candidates.echoOptions,
|
|
51
|
+
params,
|
|
52
|
+
});
|
|
53
|
+
// load 型没有 resolve,名称只能从全集里找:只要有编码说不清名字就先拉一次
|
|
54
|
+
const needEchoLoad = selected.status === 'missing' && normalizeSource(sourceObj).candidateMode === 'load';
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (needEchoLoad)
|
|
57
|
+
candidates.open();
|
|
58
|
+
}, [needEchoLoad, sourceKey, candidates.open]);
|
|
59
|
+
const byCode = useMemo(() => {
|
|
60
|
+
const map = new Map();
|
|
61
|
+
for (const option of candidates.options)
|
|
62
|
+
map.set(String(option.value), option);
|
|
63
|
+
for (const option of selected.options)
|
|
64
|
+
map.set(String(option.value), option);
|
|
65
|
+
return map;
|
|
66
|
+
}, [candidates.options, selected.options]);
|
|
67
|
+
/**
|
|
68
|
+
* 已选项始终补回候选。
|
|
69
|
+
*
|
|
70
|
+
* 单选在搜索态会跳过补回(避免结果里混进一条不匹配的记录),多选不能这么做:
|
|
71
|
+
* antd 的 tag 文本是从候选里查的,候选里没有就退化成裸编码,搜索时整排 tag 一起变编码,
|
|
72
|
+
* 比多一行已选项难看得多。
|
|
73
|
+
*/
|
|
74
|
+
const antOptions = useMemo(() => {
|
|
75
|
+
const list = candidates.options.map((item) => toAntOption(item, displayMode));
|
|
76
|
+
const present = new Set(list.map((item) => String(item.value)));
|
|
77
|
+
for (const option of selected.options) {
|
|
78
|
+
const key = String(option.value);
|
|
79
|
+
if (present.has(key))
|
|
80
|
+
continue;
|
|
81
|
+
present.add(key);
|
|
82
|
+
list.push(toAntOption(option, displayMode));
|
|
83
|
+
}
|
|
84
|
+
return list;
|
|
85
|
+
}, [candidates.options, selected.options, displayMode]);
|
|
86
|
+
const handleChange = (next, antOption) => {
|
|
87
|
+
const list = (Array.isArray(next) ? next : []).filter((item) => item !== undefined && item !== null && item !== '');
|
|
88
|
+
const emit = onChange;
|
|
89
|
+
// 清空给 undefined 而不是 []:与 ctx.clear() 一致,也让 required 规则天然生效
|
|
90
|
+
if (!list.length) {
|
|
91
|
+
emit?.(undefined, []);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// 刚选中/刚取消的项 antd 会给回来:以它为准,再退回候选和已解析结果
|
|
95
|
+
const picked = new Map();
|
|
96
|
+
for (const option of pickedOptions(antOption))
|
|
97
|
+
picked.set(String(option.value), option);
|
|
98
|
+
const lookup = (code) => picked.get(String(code)) ?? byCode.get(String(code));
|
|
99
|
+
const options = list.map((code) => lookup(code) ?? { value: code });
|
|
100
|
+
if (valueMode === 'object') {
|
|
101
|
+
const objectMap = new Map();
|
|
102
|
+
for (const option of options)
|
|
103
|
+
objectMap.set(String(option.value), option);
|
|
104
|
+
emit?.(buildObjectValues(list, objectMap, valueFields), options);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
emit?.(list, options);
|
|
108
|
+
};
|
|
109
|
+
return (_jsx(Select, { ...rest, mode: "multiple",
|
|
110
|
+
// 候选由数据源决定,一律关掉 antd 自带过滤:本地过滤已在 hook 里做
|
|
111
|
+
filterOption: false, showSearch: true, options: antOptions, value: codes, loading: candidates.loading || selected.status === 'loading' || rest.loading, disabled: disabled || candidates.blocked, placeholder: candidates.blocked ? blockedText : placeholder, notFoundContent: candidates.blocked ? (blockedText) : candidates.error ? (
|
|
112
|
+
// 失败得能重试:静默给一个空列表等于让用户以为「确实没有」
|
|
113
|
+
_jsx("a", { onClick: () => candidates.reload(), children: "\u52A0\u8F7D\u5931\u8D25\uFF0C\u70B9\u51FB\u91CD\u8BD5" })) : (rest.notFoundContent), onSearch: candidates.search, onChange: handleChange, onDropdownVisibleChange: (opened) => {
|
|
114
|
+
if (opened)
|
|
115
|
+
candidates.open();
|
|
116
|
+
else
|
|
117
|
+
candidates.resetKeyword();
|
|
118
|
+
} }));
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=BizMultiSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizMultiSelect.js","sourceRoot":"","sources":["../../src/biz-select/BizMultiSelect.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizMultiSelectDisplay.d.ts","sourceRoot":"","sources":["../../src/biz-select/BizMultiSelectDisplay.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAa1D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,+BAkDtE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* BizMultiSelect 的只读态。
|
|
4
|
+
*
|
|
5
|
+
* 与 `BizSelectDisplay` 对称:复用同一套名称解析,不挂载 Select。
|
|
6
|
+
* 解析不出的编码原样显示——宁可露出「查不到」,也不要编一个名字出来。
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect } from 'react';
|
|
9
|
+
import { EMPTY, defaultSearchFields, formatLabel, readObjectLabels, readValues } from './format.js';
|
|
10
|
+
import { normalizeSource } from './normalize.js';
|
|
11
|
+
import { resolveSelectSource } from './registry.js';
|
|
12
|
+
import { useCandidates } from './useCandidates.js';
|
|
13
|
+
import { useSelectedLabels } from './useSelectedLabels.js';
|
|
14
|
+
/** 与 read.tsx 的 MULTI_SEPARATOR 保持一致 */
|
|
15
|
+
const DEFAULT_SEPARATOR = '、';
|
|
16
|
+
/** 状态说明挂在 title 上:不能把「没查到」误认为「业务值为空」 */
|
|
17
|
+
const STATUS_TITLE = {
|
|
18
|
+
loading: '正在解析名称',
|
|
19
|
+
missing: '部分名称未找到,显示原始值',
|
|
20
|
+
blocked: '缺少必需参数,未解析名称',
|
|
21
|
+
error: '名称解析失败,显示原始值',
|
|
22
|
+
};
|
|
23
|
+
export function BizMultiSelectDisplay(props) {
|
|
24
|
+
const { source, params, displayMode = 'L', seedOptions, cacheKey, emptyText = EMPTY, valueMode = 'primitive', valueFields, value, separator = DEFAULT_SEPARATOR, } = props;
|
|
25
|
+
const sourceObj = resolveSelectSource(source);
|
|
26
|
+
const codes = readValues(value, valueMode, valueFields);
|
|
27
|
+
const valueNames = readObjectLabels(value, valueMode, valueFields);
|
|
28
|
+
// 只有 load 型需要为回显拉一次全集:它没有 resolve,名称只能从全集里找
|
|
29
|
+
const candidates = useCandidates({
|
|
30
|
+
source,
|
|
31
|
+
cacheKey,
|
|
32
|
+
params,
|
|
33
|
+
searchFields: defaultSearchFields(displayMode),
|
|
34
|
+
});
|
|
35
|
+
const { sourceKey } = candidates;
|
|
36
|
+
const selected = useSelectedLabels({
|
|
37
|
+
source,
|
|
38
|
+
cacheKey,
|
|
39
|
+
sourceKey,
|
|
40
|
+
codes,
|
|
41
|
+
valueNames,
|
|
42
|
+
seedOptions,
|
|
43
|
+
candidates: candidates.echoOptions,
|
|
44
|
+
params,
|
|
45
|
+
});
|
|
46
|
+
const needEchoLoad = selected.status === 'missing' && normalizeSource(sourceObj).candidateMode === 'load';
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (needEchoLoad)
|
|
49
|
+
candidates.open();
|
|
50
|
+
}, [needEchoLoad, sourceKey, candidates.open]);
|
|
51
|
+
if (!codes.length)
|
|
52
|
+
return _jsx(_Fragment, { children: emptyText });
|
|
53
|
+
// 只返回内容本身:外层 schema-field-read 由 SchemaField 统一包,
|
|
54
|
+
// 这里再套一层会得到双层 span。title 只在解析异常时挂。
|
|
55
|
+
const text = selected.options.map((option) => formatLabel(option, displayMode)).join(separator);
|
|
56
|
+
const title = STATUS_TITLE[selected.status];
|
|
57
|
+
return title ? _jsx("span", { title: title, children: text }) : _jsx(_Fragment, { children: text });
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=BizMultiSelectDisplay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizMultiSelectDisplay.js","sourceRoot":"","sources":["../../src/biz-select/BizMultiSelectDisplay.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAIxD,wCAAwC;AACxC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B,wCAAwC;AACxC,MAAM,YAAY,GAA4C;IAC5D,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,eAAe;IACxB,OAAO,EAAE,cAAc;IACvB,KAAK,EAAE,cAAc;CACtB,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,KAAiC;IACrE,MAAM,EACJ,MAAM,EACN,MAAM,EACN,WAAW,GAAG,GAAG,EACjB,WAAW,EACX,QAAQ,EACR,SAAS,GAAG,KAAK,EACjB,SAAS,GAAG,WAAW,EACvB,WAAW,EACX,KAAK,EACL,SAAS,GAAG,iBAAiB,GAC9B,GAAG,KAAK,CAAC;IAEV,MAAM,SAAS,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAEnE,4CAA4C;IAC5C,MAAM,UAAU,GAAG,aAAa,CAAC;QAC/B,MAAM;QACN,QAAQ;QACR,MAAM;QACN,YAAY,EAAE,mBAAmB,CAAC,WAAW,CAAC;KAC/C,CAAC,CAAC;IACH,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IAEjC,MAAM,QAAQ,GAAG,iBAAiB,CAAC;QACjC,MAAM;QACN,QAAQ;QACR,SAAS;QACT,KAAK;QACL,UAAU;QACV,WAAW;QACX,UAAU,EAAE,UAAU,CAAC,WAAW;QAClC,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,eAAe,CAAC,SAAS,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC;IAC1G,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,YAAY;YAAE,UAAU,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAE/C,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,4BAAG,SAAS,GAAI,CAAC;IAE3C,kDAAkD;IAClD,mCAAmC;IACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChG,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC,CAAC,CAAC,eAAM,KAAK,EAAE,KAAK,YAAG,IAAI,GAAQ,CAAC,CAAC,CAAC,4BAAG,IAAI,GAAI,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizSelect.d.ts","sourceRoot":"","sources":["../../src/biz-select/BizSelect.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAa,cAAc,EAA0B,MAAM,SAAS,CAAC;AAIjF,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,+BAmH9C"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* BizSelect:业务下拉的可编辑态。
|
|
4
|
+
*
|
|
5
|
+
* 渲染层只吃「候选列表 + 已选名称 + 展示模式」,不认识 load / search / resolve。
|
|
6
|
+
* 所有取数与解析都在 hook 里完成。
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect, useMemo } from 'react';
|
|
9
|
+
import { Select } from 'antd';
|
|
10
|
+
import { normalizeSource } from './normalize.js';
|
|
11
|
+
import { resolveSelectSource } from './registry.js';
|
|
12
|
+
import { useCandidates } from './useCandidates.js';
|
|
13
|
+
import { useSelectedLabel } from './useSelectedLabel.js';
|
|
14
|
+
import { buildObjectValue, defaultSearchFields, readObjectLabel, readValue, toAntOption, } from './format.js';
|
|
15
|
+
const DEFAULT_BLOCKED_TEXT = '请先选择上级';
|
|
16
|
+
export function BizSelect(props) {
|
|
17
|
+
const { source, params, displayMode = 'L', searchFields, seedOptions, debounceMs, cacheKey, blockedText = DEFAULT_BLOCKED_TEXT, valueMode = 'primitive', valueFields, value, onChange, disabled, placeholder, ...rest } = props;
|
|
18
|
+
const sourceObj = resolveSelectSource(source);
|
|
19
|
+
const fields = searchFields ?? defaultSearchFields(displayMode);
|
|
20
|
+
const code = readValue(value, valueMode, valueFields);
|
|
21
|
+
const valueName = readObjectLabel(value, valueMode, valueFields);
|
|
22
|
+
// 源直接交给 Hook:解析与来源键(含版本订阅)都在里面,组件不再自己算一份
|
|
23
|
+
const candidates = useCandidates({
|
|
24
|
+
source,
|
|
25
|
+
cacheKey,
|
|
26
|
+
params,
|
|
27
|
+
searchFields: fields,
|
|
28
|
+
debounceMs,
|
|
29
|
+
});
|
|
30
|
+
const { sourceKey } = candidates;
|
|
31
|
+
const selected = useSelectedLabel({
|
|
32
|
+
source: sourceObj,
|
|
33
|
+
sourceKey,
|
|
34
|
+
code,
|
|
35
|
+
valueName,
|
|
36
|
+
seedOptions,
|
|
37
|
+
// 回显查的是未过滤全集,否则输入关键词后已选项会被筛掉、名称退回编码
|
|
38
|
+
candidates: candidates.echoOptions,
|
|
39
|
+
params,
|
|
40
|
+
});
|
|
41
|
+
// 只有 load 型需要为了回显提前拉一次全集:它没有 resolve,名称只能从全集里找。
|
|
42
|
+
// 对象值自带名称、seed 已命中时不用拉。
|
|
43
|
+
const hasKnownName = Boolean(valueName) || Boolean(seedOptions?.some((item) => item.value === code));
|
|
44
|
+
const needEchoLoad = code !== undefined && !hasKnownName && normalizeSource(sourceObj).candidateMode === 'load';
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (needEchoLoad)
|
|
47
|
+
candidates.open();
|
|
48
|
+
}, [needEchoLoad, sourceKey, candidates.open]);
|
|
49
|
+
// 搜索中不要补回已选项:否则结果里会混进一条不匹配的记录。
|
|
50
|
+
// 关闭下拉后 keyword 归零,已选项会重新补回,闭合态照常显示名称。
|
|
51
|
+
// 取数失败时也不补:补上一条会让列表非空,antd 就不渲染 notFoundContent,
|
|
52
|
+
// 重试入口跟着被藏起来,用户只看到孤零零一条已选项。
|
|
53
|
+
const searching = candidates.keyword.trim().length > 0;
|
|
54
|
+
const antOptions = useMemo(() => {
|
|
55
|
+
const list = candidates.options.map((item) => toAntOption(item, displayMode));
|
|
56
|
+
if (searching || candidates.error)
|
|
57
|
+
return list;
|
|
58
|
+
const selectedOption = selected.option;
|
|
59
|
+
if (selectedOption && !list.some((item) => item.value === selectedOption.value)) {
|
|
60
|
+
list.unshift(toAntOption(selectedOption, displayMode));
|
|
61
|
+
}
|
|
62
|
+
return list;
|
|
63
|
+
}, [candidates.options, candidates.error, displayMode, selected.option, searching]);
|
|
64
|
+
const handleChange = (next, antOption) => {
|
|
65
|
+
const picked = antOption?.raw ??
|
|
66
|
+
antOptions.find((item) => item.value === next)?.raw;
|
|
67
|
+
const emit = onChange;
|
|
68
|
+
if (valueMode === 'object') {
|
|
69
|
+
emit?.(next === undefined || next === null ? undefined : buildObjectValue(next, picked, valueFields), picked);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
emit?.(next ?? undefined, picked);
|
|
73
|
+
};
|
|
74
|
+
return (_jsx(Select, { ...rest,
|
|
75
|
+
// 候选由数据源决定,一律关掉 antd 自带过滤:本地过滤已在 hook 里做
|
|
76
|
+
filterOption: false, showSearch: true, options: antOptions, value: code, loading: candidates.loading || selected.status === 'loading' || rest.loading, disabled: disabled || candidates.blocked, placeholder: candidates.blocked ? blockedText : placeholder, notFoundContent: candidates.blocked ? (blockedText) : candidates.error ? (
|
|
77
|
+
// 失败得能重试:静默给一个空列表等于让用户以为「确实没有」
|
|
78
|
+
_jsx("a", { onClick: () => candidates.reload(), children: "\u52A0\u8F7D\u5931\u8D25\uFF0C\u70B9\u51FB\u91CD\u8BD5" })) : (rest.notFoundContent), onSearch: candidates.search, onChange: handleChange, onDropdownVisibleChange: (opened) => {
|
|
79
|
+
// 只有展开时才取默认候选,避免挂载即发请求
|
|
80
|
+
if (opened)
|
|
81
|
+
candidates.open();
|
|
82
|
+
else
|
|
83
|
+
candidates.resetKeyword();
|
|
84
|
+
rest.onDropdownVisibleChange?.(opened);
|
|
85
|
+
} }));
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=BizSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizSelect.js","sourceRoot":"","sources":["../../src/biz-select/BizSelect.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizSelectDisplay.d.ts","sourceRoot":"","sources":["../../src/biz-select/BizSelectDisplay.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAUrD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,+BAmD5D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* BizSelect 的只读态。
|
|
4
|
+
*
|
|
5
|
+
* 复用同一套名称解析,但不挂载 Select:只读列表里成百上千个单元格
|
|
6
|
+
* 不该为了显示一个名称付出一个交互组件的代价。
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect } from 'react';
|
|
9
|
+
import { EMPTY, defaultSearchFields, formatLabel, readObjectLabel, readValue } from './format.js';
|
|
10
|
+
import { normalizeSource } from './normalize.js';
|
|
11
|
+
import { resolveSelectSource } from './registry.js';
|
|
12
|
+
import { useCandidates } from './useCandidates.js';
|
|
13
|
+
import { useSelectedLabel } from './useSelectedLabel.js';
|
|
14
|
+
/** 状态说明挂在 title 上:用户不能把「没查到」误认为「业务值为空」 */
|
|
15
|
+
const STATUS_TITLE = {
|
|
16
|
+
loading: '正在解析名称',
|
|
17
|
+
missing: '未找到对应名称,显示原始值',
|
|
18
|
+
blocked: '缺少必需参数,未解析名称',
|
|
19
|
+
error: '名称解析失败,显示原始值',
|
|
20
|
+
};
|
|
21
|
+
export function BizSelectDisplay(props) {
|
|
22
|
+
const { source, params, displayMode = 'L', seedOptions, cacheKey, emptyText = EMPTY, valueMode = 'primitive', valueFields, value, } = props;
|
|
23
|
+
const sourceObj = resolveSelectSource(source);
|
|
24
|
+
const code = readValue(value, valueMode, valueFields);
|
|
25
|
+
const valueName = readObjectLabel(value, valueMode, valueFields);
|
|
26
|
+
// 只有 load 型需要为回显拉一次全集:它没有 resolve,名称只能从全集里找
|
|
27
|
+
const candidates = useCandidates({
|
|
28
|
+
source,
|
|
29
|
+
cacheKey,
|
|
30
|
+
params,
|
|
31
|
+
searchFields: defaultSearchFields(displayMode),
|
|
32
|
+
});
|
|
33
|
+
const { sourceKey } = candidates;
|
|
34
|
+
// 对象值自带名称、seed 已命中时不用为了回显拉全集
|
|
35
|
+
const hasKnownName = Boolean(valueName) || Boolean(seedOptions?.some((item) => item.value === code));
|
|
36
|
+
const needEchoLoad = code !== undefined && !hasKnownName && normalizeSource(sourceObj).candidateMode === 'load';
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (needEchoLoad)
|
|
39
|
+
candidates.open();
|
|
40
|
+
}, [needEchoLoad, sourceKey, candidates.open]);
|
|
41
|
+
const { option, status } = useSelectedLabel({
|
|
42
|
+
source: sourceObj,
|
|
43
|
+
sourceKey,
|
|
44
|
+
code,
|
|
45
|
+
valueName,
|
|
46
|
+
seedOptions,
|
|
47
|
+
candidates: candidates.echoOptions,
|
|
48
|
+
params,
|
|
49
|
+
});
|
|
50
|
+
if (status === 'empty' || !option)
|
|
51
|
+
return _jsx(_Fragment, { children: emptyText });
|
|
52
|
+
// 只返回内容本身:外层 schema-field-read 由 SchemaField 统一包,
|
|
53
|
+
// 这里再套一层会得到双层 span。title 只在解析异常时挂,正常态不产生额外节点。
|
|
54
|
+
const text = formatLabel(option, displayMode);
|
|
55
|
+
const title = STATUS_TITLE[status];
|
|
56
|
+
return title ? _jsx("span", { title: title, children: text }) : _jsx(_Fragment, { children: text });
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=BizSelectDisplay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BizSelectDisplay.js","sourceRoot":"","sources":["../../src/biz-select/BizSelectDisplay.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD,0CAA0C;AAC1C,MAAM,YAAY,GAA4C;IAC5D,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,eAAe;IACxB,OAAO,EAAE,cAAc;IACvB,KAAK,EAAE,cAAc;CACtB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC3D,MAAM,EACJ,MAAM,EACN,MAAM,EACN,WAAW,GAAG,GAAG,EACjB,WAAW,EACX,QAAQ,EACR,SAAS,GAAG,KAAK,EACjB,SAAS,GAAG,WAAW,EACvB,WAAW,EACX,KAAK,GACN,GAAG,KAAK,CAAC;IAEV,MAAM,SAAS,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAEjE,4CAA4C;IAC5C,MAAM,UAAU,GAAG,aAAa,CAAC;QAC/B,MAAM;QACN,QAAQ;QACR,MAAM;QACN,YAAY,EAAE,mBAAmB,CAAC,WAAW,CAAC;KAC/C,CAAC,CAAC;IACH,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IACjC,6BAA6B;IAC7B,MAAM,YAAY,GAChB,OAAO,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC;IAClF,MAAM,YAAY,GAChB,IAAI,KAAK,SAAS,IAAI,CAAC,YAAY,IAAI,eAAe,CAAC,SAAS,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC;IAC7F,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,YAAY;YAAE,UAAU,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAE/C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC;QAC1C,MAAM,EAAE,SAAS;QACjB,SAAS;QACT,IAAI;QACJ,SAAS;QACT,WAAW;QACX,UAAU,EAAE,UAAU,CAAC,WAAW;QAClC,MAAM;KACP,CAAC,CAAC;IAEH,IAAI,MAAM,KAAK,OAAO,IAAI,CAAC,MAAM;QAAE,OAAO,4BAAG,SAAS,GAAI,CAAC;IAE3D,kDAAkD;IAClD,8CAA8C;IAC9C,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,CAAC,CAAC,eAAM,KAAK,EAAE,KAAK,YAAG,IAAI,GAAQ,CAAC,CAAC,CAAC,4BAAG,IAAI,GAAI,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 候选与解析的共享缓存。
|
|
3
|
+
*
|
|
4
|
+
* 表格式页面里同一列的几十个单元格会各调一次源,因此在**来源键**这一层共享:
|
|
5
|
+
* 同键并发只发一次请求,失败不缓存。
|
|
6
|
+
* 调用方各自的取消只影响自己的状态更新,不打断共享中的请求。
|
|
7
|
+
*/
|
|
8
|
+
import type { BizOption } from './types.js';
|
|
9
|
+
export declare function loadCandidatesWithCache(key: string, loader: () => Promise<BizOption[]>): Promise<BizOption[]>;
|
|
10
|
+
/** 丢掉单条候选缓存:reload() 要真正重取,不能又命中同一份 */
|
|
11
|
+
export declare function dropCandidateCache(key: string): void;
|
|
12
|
+
/**
|
|
13
|
+
* 只看缓存、不发起请求:批量解析用它先把已命中的挑出来,
|
|
14
|
+
* 免得已经查过的编码还被塞进批量请求里占位。
|
|
15
|
+
*/
|
|
16
|
+
export declare function peekResolved(key: string): Promise<BizOption | null> | undefined;
|
|
17
|
+
/** 丢掉单条解析缓存:`reload()` 要真正重查,不能又命中同一份 */
|
|
18
|
+
export declare function dropResolvedCache(key: string): void;
|
|
19
|
+
export declare function resolveCodeWithCache(key: string, loader: () => Promise<BizOption | null>): Promise<BizOption | null>;
|
|
20
|
+
export declare function clearSelectCacheOfSource(sourceKey: string): void;
|
|
21
|
+
export declare function clearSelectCache(): void;
|
|
22
|
+
export declare function getSelectCacheSize(): number;
|
|
23
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/biz-select/cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA2FzC,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,GACjC,OAAO,CAAC,SAAS,EAAE,CAAC,CA2BtB;AAED,uCAAuC;AACvC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,SAAS,CAE/E;AAED,yCAAyC;AACzC,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GACtC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAgB3B;AAOD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAQhE;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
|