crud-page-react 0.0.1
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 +200 -0
- package/dist/components/CrudPage.d.ts +9 -0
- package/dist/components/DynamicFilter.d.ts +8 -0
- package/dist/components/DynamicForm.d.ts +12 -0
- package/dist/components/DynamicTable.d.ts +18 -0
- package/dist/index.d.ts +270 -0
- package/dist/index.esm.js +2492 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2526 -0
- package/dist/index.js.map +1 -0
- package/dist/types/schema.d.ts +191 -0
- package/dist/types/validationRules.d.ts +32 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# CRUD Page React
|
|
2
|
+
|
|
3
|
+
一个基于 React + Ant Design 的动态 CRUD 组件库,支持通过 JSON Schema 配置生成完整的增删改查界面。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🚀 **零代码配置** - 通过 JSON Schema 配置即可生成完整 CRUD 界面
|
|
8
|
+
- 📝 **丰富的表单组件** - 支持 15+ 种表单控件类型
|
|
9
|
+
- 🔍 **智能筛选** - 自动生成筛选器,支持范围查询
|
|
10
|
+
- 📊 **灵活表格** - 可配置列宽、排序、固定列等
|
|
11
|
+
- 🎨 **Raw JSON 模式** - 支持原始 JSON 编辑和查看
|
|
12
|
+
- 🔌 **自定义 API** - 支持自定义 API 请求函数
|
|
13
|
+
- 📱 **响应式设计** - 适配移动端和桌面端
|
|
14
|
+
- 🎯 **TypeScript 支持** - 完整的类型定义
|
|
15
|
+
|
|
16
|
+
## 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install crud-page-react
|
|
20
|
+
# 或
|
|
21
|
+
yarn add crud-page-react
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 依赖要求
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"react": ">=16.8.0",
|
|
29
|
+
"react-dom": ">=16.8.0",
|
|
30
|
+
"antd": ">=5.0.0",
|
|
31
|
+
"dayjs": ">=1.11.0"
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 快速开始
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import React from 'react';
|
|
39
|
+
import { CrudPage } from 'crud-page-react';
|
|
40
|
+
import type { CrudPageSchema } from 'crud-page-react';
|
|
41
|
+
|
|
42
|
+
const schema: CrudPageSchema = {
|
|
43
|
+
id: 'users',
|
|
44
|
+
title: '用户管理',
|
|
45
|
+
api: {
|
|
46
|
+
list: '/api/users',
|
|
47
|
+
create: '/api/users',
|
|
48
|
+
update: '/api/users/:id',
|
|
49
|
+
delete: '/api/users/:id',
|
|
50
|
+
},
|
|
51
|
+
fields: [
|
|
52
|
+
{
|
|
53
|
+
key: 'id',
|
|
54
|
+
label: 'ID',
|
|
55
|
+
type: 'number',
|
|
56
|
+
table: { width: 80 },
|
|
57
|
+
form: false,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: 'name',
|
|
61
|
+
label: '姓名',
|
|
62
|
+
type: 'string',
|
|
63
|
+
filter: true,
|
|
64
|
+
table: true,
|
|
65
|
+
form: { required: true },
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
key: 'email',
|
|
69
|
+
label: '邮箱',
|
|
70
|
+
type: 'string',
|
|
71
|
+
filter: true,
|
|
72
|
+
table: true,
|
|
73
|
+
form: { required: true },
|
|
74
|
+
rules: ['email'],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: 'status',
|
|
78
|
+
label: '状态',
|
|
79
|
+
type: 'string',
|
|
80
|
+
widget: 'select',
|
|
81
|
+
config: {
|
|
82
|
+
options: [
|
|
83
|
+
{ label: '启用', value: 'active' },
|
|
84
|
+
{ label: '禁用', value: 'inactive' },
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
filter: true,
|
|
88
|
+
table: true,
|
|
89
|
+
form: true,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
rowKey: 'id',
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
function App() {
|
|
96
|
+
return (
|
|
97
|
+
<div>
|
|
98
|
+
<CrudPage schema={schema} />
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default App;
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 自定义 API 请求
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { CrudPage, ApiRequest } from 'crud-page-react';
|
|
110
|
+
|
|
111
|
+
// 自定义 API 请求函数
|
|
112
|
+
const customApiRequest: ApiRequest = async (url, options) => {
|
|
113
|
+
const token = localStorage.getItem('token');
|
|
114
|
+
const response = await fetch(url, {
|
|
115
|
+
headers: {
|
|
116
|
+
'Content-Type': 'application/json',
|
|
117
|
+
'Authorization': token ? `Bearer ${token}` : '',
|
|
118
|
+
...options?.headers,
|
|
119
|
+
},
|
|
120
|
+
...options,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return response.json();
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// 使用自定义 API 请求
|
|
131
|
+
<CrudPage
|
|
132
|
+
schema={schema}
|
|
133
|
+
apiRequest={customApiRequest}
|
|
134
|
+
/>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API 文档
|
|
138
|
+
|
|
139
|
+
### CrudPageProps
|
|
140
|
+
|
|
141
|
+
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|
|
142
|
+
|------|------|------|--------|------|
|
|
143
|
+
| schema | CrudPageSchema | ✓ | - | 页面配置 schema |
|
|
144
|
+
| initialData | Record<string, unknown>[] | ✗ | [] | 初始数据,API 失败时作为降级数据 |
|
|
145
|
+
| apiRequest | ApiRequest | ✗ | 内置 fetch | 自定义 API 请求函数 |
|
|
146
|
+
|
|
147
|
+
### ApiRequest
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
interface ApiRequest {
|
|
151
|
+
<T = unknown>(url: string, options?: RequestInit): Promise<T>;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### CrudPageSchema
|
|
156
|
+
|
|
157
|
+
完整的 schema 配置请参考类型定义文件。
|
|
158
|
+
|
|
159
|
+
## 字段类型支持
|
|
160
|
+
|
|
161
|
+
- `string` - 字符串
|
|
162
|
+
- `number` - 数字
|
|
163
|
+
- `boolean` - 布尔值
|
|
164
|
+
- `date` - 日期
|
|
165
|
+
- `datetime` - 日期时间
|
|
166
|
+
- `array` - 数组
|
|
167
|
+
- `objectArray` - 对象数组
|
|
168
|
+
|
|
169
|
+
## 组件类型支持
|
|
170
|
+
|
|
171
|
+
- `input` - 输入框
|
|
172
|
+
- `textarea` - 文本域
|
|
173
|
+
- `inputNumber` - 数字输入
|
|
174
|
+
- `select` - 下拉选择
|
|
175
|
+
- `multiselect` - 多选下拉
|
|
176
|
+
- `radio` - 单选按钮
|
|
177
|
+
- `checkbox` - 复选框
|
|
178
|
+
- `switch` - 开关
|
|
179
|
+
- `datePicker` - 日期选择
|
|
180
|
+
- `rangePicker` - 日期范围
|
|
181
|
+
- `timePicker` - 时间选择
|
|
182
|
+
- `editableTable` - 可编辑表格
|
|
183
|
+
- `jsonInput` - JSON 编辑器
|
|
184
|
+
|
|
185
|
+
## 开发
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# 安装依赖
|
|
189
|
+
npm install
|
|
190
|
+
|
|
191
|
+
# 开发模式
|
|
192
|
+
npm run dev
|
|
193
|
+
|
|
194
|
+
# 构建
|
|
195
|
+
npm run build
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## 许可证
|
|
199
|
+
|
|
200
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CrudPageSchema, ApiRequest } from '../types/schema';
|
|
3
|
+
interface CrudPageProps {
|
|
4
|
+
schema: CrudPageSchema;
|
|
5
|
+
initialData?: Record<string, unknown>[];
|
|
6
|
+
apiRequest?: ApiRequest;
|
|
7
|
+
}
|
|
8
|
+
declare const CrudPage: React.FC<CrudPageProps>;
|
|
9
|
+
export default CrudPage;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CrudPageSchema } from '../types/schema';
|
|
2
|
+
interface DynamicFilterProps {
|
|
3
|
+
schema: CrudPageSchema;
|
|
4
|
+
onSearch: (values: Record<string, unknown>) => void;
|
|
5
|
+
onReset: () => void;
|
|
6
|
+
}
|
|
7
|
+
export default function DynamicFilter({ schema, onSearch, onReset }: DynamicFilterProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CrudPageSchema } from '../types/schema';
|
|
2
|
+
type FormMode = 'create' | 'edit' | 'view';
|
|
3
|
+
interface DynamicFormProps {
|
|
4
|
+
schema: CrudPageSchema;
|
|
5
|
+
mode: FormMode;
|
|
6
|
+
visible: boolean;
|
|
7
|
+
initialValues?: Record<string, unknown>;
|
|
8
|
+
onSubmit: (values: Record<string, unknown>) => void;
|
|
9
|
+
onCancel: () => void;
|
|
10
|
+
}
|
|
11
|
+
export default function DynamicForm({ schema, mode, visible, initialValues, onSubmit, onCancel, }: DynamicFormProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CrudPageSchema } from '../types/schema';
|
|
2
|
+
interface DynamicTableProps {
|
|
3
|
+
schema: CrudPageSchema;
|
|
4
|
+
data: Record<string, unknown>[];
|
|
5
|
+
loading: boolean;
|
|
6
|
+
pagination: {
|
|
7
|
+
current: number;
|
|
8
|
+
pageSize: number;
|
|
9
|
+
total: number;
|
|
10
|
+
onChange: (page: number, pageSize: number) => void;
|
|
11
|
+
};
|
|
12
|
+
onView: (record: Record<string, unknown>) => void;
|
|
13
|
+
onEdit: (record: Record<string, unknown>) => void;
|
|
14
|
+
onDelete: (record: Record<string, unknown>) => void;
|
|
15
|
+
onCustomAction?: (actionKey: string, record: Record<string, unknown>) => void;
|
|
16
|
+
}
|
|
17
|
+
export default function DynamicTable({ schema, data, loading, pagination, onView, onEdit, onDelete, onCustomAction, }: DynamicTableProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
import { Rule } from 'antd/es/form';
|
|
4
|
+
|
|
5
|
+
/** API 请求函数类型 */
|
|
6
|
+
interface ApiRequest {
|
|
7
|
+
<T = unknown>(url: string, options?: RequestInit): Promise<T>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 数据类型:描述字段存储的值类型。
|
|
11
|
+
*
|
|
12
|
+
* 嵌套对象不再作为独立类型,而是通过 key 的点分路径(dot-path)表达,
|
|
13
|
+
* 例如 `emergencyContact.name`、`emergencyContact.phone`。
|
|
14
|
+
* 框架会自动将 Form 数据写入/读出对应的嵌套路径。
|
|
15
|
+
*/
|
|
16
|
+
type DataType = 'string' | 'number' | 'boolean' | 'datetime' | 'date' | 'array' | 'objectArray';
|
|
17
|
+
/** UI 组件类型:描述字段渲染使用的组件 */
|
|
18
|
+
type WidgetType = 'input' | 'textarea' | 'inputNumber' | 'select' | 'multiselect' | 'radio' | 'checkbox' | 'switch' | 'datePicker' | 'rangePicker' | 'timePicker' | 'editableTable' | 'jsonInput';
|
|
19
|
+
interface SelectOption {
|
|
20
|
+
label: string;
|
|
21
|
+
value: string | number | boolean;
|
|
22
|
+
color?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 筛选项配置 —— 仅放筛选独有配置。
|
|
26
|
+
* options / placeholder / dateFormat 统一在 FieldSchema.config 里配置。
|
|
27
|
+
*/
|
|
28
|
+
interface FilterConfig {
|
|
29
|
+
/** 覆盖字段级 widget,指定筛选组件类型 */
|
|
30
|
+
widget?: WidgetType;
|
|
31
|
+
/** inputNumber 时可开启数字范围(min/max 两个输入框) */
|
|
32
|
+
range?: boolean;
|
|
33
|
+
defaultValue?: unknown;
|
|
34
|
+
}
|
|
35
|
+
/** 表格列配置 */
|
|
36
|
+
interface TableColumnConfig {
|
|
37
|
+
width?: number;
|
|
38
|
+
fixed?: 'left' | 'right';
|
|
39
|
+
sortable?: boolean;
|
|
40
|
+
ellipsis?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 表单字段配置 —— 仅放表单独有配置。
|
|
44
|
+
* options / placeholder / dateFormat / rows 统一在 FieldSchema.config 里配置。
|
|
45
|
+
*/
|
|
46
|
+
interface FormFieldConfig {
|
|
47
|
+
/** 覆盖字段级 widget,指定表单组件类型 */
|
|
48
|
+
widget?: WidgetType;
|
|
49
|
+
required?: boolean;
|
|
50
|
+
min?: number;
|
|
51
|
+
max?: number;
|
|
52
|
+
step?: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 字段级共用组件配置。
|
|
56
|
+
* filter 和 form 均可读取,无需在两处重复填写。
|
|
57
|
+
*/
|
|
58
|
+
interface FieldConfig {
|
|
59
|
+
/** 下拉/多选/单选等组件的选项列表 */
|
|
60
|
+
options?: SelectOption[];
|
|
61
|
+
/** 输入框、选择框等的占位提示文字 */
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
/** 日期/时间组件的显示格式,如 'YYYY-MM-DD' */
|
|
64
|
+
dateFormat?: string;
|
|
65
|
+
/** textarea / jsonInput 的行数 */
|
|
66
|
+
rows?: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 对象数组(objectArray)中每个 item 的字段定义。
|
|
70
|
+
* 故意保持简单:不支持嵌套 objectArray,不支持 dot-path key。
|
|
71
|
+
*/
|
|
72
|
+
interface ArrayItemField {
|
|
73
|
+
/** item 对象的属性名,不使用点分路径 */
|
|
74
|
+
key: string;
|
|
75
|
+
label: string;
|
|
76
|
+
/** 不允许嵌套数组 */
|
|
77
|
+
type: Exclude<DataType, 'array' | 'objectArray'>;
|
|
78
|
+
/** 不允许嵌套 editableTable */
|
|
79
|
+
widget?: Exclude<WidgetType, 'editableTable'>;
|
|
80
|
+
config?: Pick<FieldConfig, 'options' | 'placeholder' | 'dateFormat'>;
|
|
81
|
+
required?: boolean;
|
|
82
|
+
/** 列宽(px) */
|
|
83
|
+
width?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 字段定义。
|
|
87
|
+
*
|
|
88
|
+
* ### 点分路径(dot-path)规则
|
|
89
|
+
* `key` 支持点分路径表达嵌套结构,例如:
|
|
90
|
+
* - `emergencyContact.name`
|
|
91
|
+
* - `emergencyContact.phone`
|
|
92
|
+
*
|
|
93
|
+
* Form 层会自动将值写入 / 读取对应的嵌套对象属性;
|
|
94
|
+
* 具有相同前缀的字段在表单中会被归为同一视觉分组,并显示分组标题。
|
|
95
|
+
*/
|
|
96
|
+
interface FieldSchema {
|
|
97
|
+
key: string;
|
|
98
|
+
label: string;
|
|
99
|
+
/** 数据类型(值的类型) */
|
|
100
|
+
type: DataType;
|
|
101
|
+
/**
|
|
102
|
+
* 默认 UI 组件类型;可被 filter / form 级别的 widget 覆盖。
|
|
103
|
+
* 不填时由 defaultWidgetForType 推导。
|
|
104
|
+
*/
|
|
105
|
+
widget?: WidgetType;
|
|
106
|
+
filter?: boolean | FilterConfig;
|
|
107
|
+
table?: boolean | TableColumnConfig;
|
|
108
|
+
form?: boolean | FormFieldConfig;
|
|
109
|
+
/**
|
|
110
|
+
* 字段级共用组件配置(options、placeholder、dateFormat 等)。
|
|
111
|
+
* filter 和 form 均从这里读取,不再重复配置。
|
|
112
|
+
*/
|
|
113
|
+
config?: FieldConfig;
|
|
114
|
+
render?: string;
|
|
115
|
+
/**
|
|
116
|
+
* 对象数组子字段定义,仅 type='objectArray' 时生效。
|
|
117
|
+
* 配置后 widget 默认推导为 'editableTable'。
|
|
118
|
+
*/
|
|
119
|
+
itemFields?: ArrayItemField[];
|
|
120
|
+
/**
|
|
121
|
+
* 校验规则 key 数组,引用 validationRules.ts 中内置或自定义规则的 key。
|
|
122
|
+
* 例如 `rules: ['phone_cn', 'max_len_50']`
|
|
123
|
+
* 注意:required 规则通过 form.required 单独控制,无需在此重复。
|
|
124
|
+
*/
|
|
125
|
+
rules?: string[];
|
|
126
|
+
}
|
|
127
|
+
type ActionType = 'edit' | 'delete' | 'view' | 'custom';
|
|
128
|
+
interface ActionPermission {
|
|
129
|
+
role?: string[];
|
|
130
|
+
condition?: string;
|
|
131
|
+
}
|
|
132
|
+
interface ActionSchema {
|
|
133
|
+
key: string;
|
|
134
|
+
label: string;
|
|
135
|
+
type: ActionType;
|
|
136
|
+
icon?: string;
|
|
137
|
+
danger?: boolean;
|
|
138
|
+
permission?: ActionPermission;
|
|
139
|
+
confirm?: {
|
|
140
|
+
title: string;
|
|
141
|
+
content?: string;
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
interface PaginationConfig {
|
|
145
|
+
pageSize?: number;
|
|
146
|
+
pageSizeOptions?: number[];
|
|
147
|
+
showTotal?: boolean;
|
|
148
|
+
}
|
|
149
|
+
interface CrudPageSchema {
|
|
150
|
+
id: string;
|
|
151
|
+
title: string;
|
|
152
|
+
api: {
|
|
153
|
+
list: string;
|
|
154
|
+
create?: string;
|
|
155
|
+
update?: string;
|
|
156
|
+
delete?: string;
|
|
157
|
+
detail?: string;
|
|
158
|
+
};
|
|
159
|
+
fields: FieldSchema[];
|
|
160
|
+
actions?: ActionSchema[];
|
|
161
|
+
pagination?: PaginationConfig;
|
|
162
|
+
rowKey?: string;
|
|
163
|
+
createButtonLabel?: string;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 根据数据类型推导默认 UI 组件
|
|
167
|
+
*
|
|
168
|
+
* string → input
|
|
169
|
+
* number → inputNumber
|
|
170
|
+
* boolean → switch
|
|
171
|
+
* date → datePicker
|
|
172
|
+
* datetime → datePicker
|
|
173
|
+
* array → multiselect
|
|
174
|
+
* objectArray → editableTable
|
|
175
|
+
*/
|
|
176
|
+
declare function defaultWidgetForType(type: DataType): WidgetType;
|
|
177
|
+
/** 获取实际生效的组件类型(context.widget > field.widget > type 推导) */
|
|
178
|
+
declare function getEffectiveWidget(field: FieldSchema, config?: FilterConfig | FormFieldConfig): WidgetType;
|
|
179
|
+
/**
|
|
180
|
+
* 从嵌套对象按点分路径取值
|
|
181
|
+
*
|
|
182
|
+
* getNestedValue({ a: { b: 1 } }, 'a.b') → 1
|
|
183
|
+
* getNestedValue({ x: [1, 2] }, 'x') → [1, 2]
|
|
184
|
+
*/
|
|
185
|
+
declare function getNestedValue(obj: Record<string, unknown>, path: string): unknown;
|
|
186
|
+
/**
|
|
187
|
+
* 从点分路径 key 中提取分组前缀(第一个 segment)。
|
|
188
|
+
* 无前缀的顶层字段返回 null。
|
|
189
|
+
*
|
|
190
|
+
* 'emergencyContact.name' → 'emergencyContact'
|
|
191
|
+
* 'name' → null
|
|
192
|
+
*/
|
|
193
|
+
declare function getFieldGroupPrefix(key: string): string | null;
|
|
194
|
+
|
|
195
|
+
interface CrudPageProps {
|
|
196
|
+
schema: CrudPageSchema;
|
|
197
|
+
initialData?: Record<string, unknown>[];
|
|
198
|
+
apiRequest?: ApiRequest;
|
|
199
|
+
}
|
|
200
|
+
declare const CrudPage: React.FC<CrudPageProps>;
|
|
201
|
+
|
|
202
|
+
interface DynamicFilterProps {
|
|
203
|
+
schema: CrudPageSchema;
|
|
204
|
+
onSearch: (values: Record<string, unknown>) => void;
|
|
205
|
+
onReset: () => void;
|
|
206
|
+
}
|
|
207
|
+
declare function DynamicFilter({ schema, onSearch, onReset }: DynamicFilterProps): react_jsx_runtime.JSX.Element;
|
|
208
|
+
|
|
209
|
+
interface DynamicTableProps {
|
|
210
|
+
schema: CrudPageSchema;
|
|
211
|
+
data: Record<string, unknown>[];
|
|
212
|
+
loading: boolean;
|
|
213
|
+
pagination: {
|
|
214
|
+
current: number;
|
|
215
|
+
pageSize: number;
|
|
216
|
+
total: number;
|
|
217
|
+
onChange: (page: number, pageSize: number) => void;
|
|
218
|
+
};
|
|
219
|
+
onView: (record: Record<string, unknown>) => void;
|
|
220
|
+
onEdit: (record: Record<string, unknown>) => void;
|
|
221
|
+
onDelete: (record: Record<string, unknown>) => void;
|
|
222
|
+
onCustomAction?: (actionKey: string, record: Record<string, unknown>) => void;
|
|
223
|
+
}
|
|
224
|
+
declare function DynamicTable({ schema, data, loading, pagination, onView, onEdit, onDelete, onCustomAction, }: DynamicTableProps): react_jsx_runtime.JSX.Element;
|
|
225
|
+
|
|
226
|
+
type FormMode = 'create' | 'edit' | 'view';
|
|
227
|
+
interface DynamicFormProps {
|
|
228
|
+
schema: CrudPageSchema;
|
|
229
|
+
mode: FormMode;
|
|
230
|
+
visible: boolean;
|
|
231
|
+
initialValues?: Record<string, unknown>;
|
|
232
|
+
onSubmit: (values: Record<string, unknown>) => void;
|
|
233
|
+
onCancel: () => void;
|
|
234
|
+
}
|
|
235
|
+
declare function DynamicForm({ schema, mode, visible, initialValues, onSubmit, onCancel, }: DynamicFormProps): react_jsx_runtime.JSX.Element;
|
|
236
|
+
|
|
237
|
+
/** 校验规则配置(内置 + 自定义均使用此结构) */
|
|
238
|
+
interface ValidationRuleConfig {
|
|
239
|
+
key: string;
|
|
240
|
+
label: string;
|
|
241
|
+
description?: string;
|
|
242
|
+
message: string;
|
|
243
|
+
/** 正则字符串(将转为 RegExp) */
|
|
244
|
+
pattern?: string;
|
|
245
|
+
/** 最小值(number)或最小长度(string) */
|
|
246
|
+
min?: number;
|
|
247
|
+
/** 最大值(number)或最大长度(string) */
|
|
248
|
+
max?: number;
|
|
249
|
+
/** antd 内置类型校验 */
|
|
250
|
+
type?: 'string' | 'number' | 'email' | 'url' | 'integer';
|
|
251
|
+
/** 是否不允许纯空白字符 */
|
|
252
|
+
whitespace?: boolean;
|
|
253
|
+
/** 是否内置(内置规则不可删除) */
|
|
254
|
+
builtin?: boolean;
|
|
255
|
+
}
|
|
256
|
+
/** 内置规则集 */
|
|
257
|
+
declare const BUILTIN_RULES: ValidationRuleConfig[];
|
|
258
|
+
declare function loadCustomRules(): ValidationRuleConfig[];
|
|
259
|
+
declare function saveCustomRules(rules: ValidationRuleConfig[]): void;
|
|
260
|
+
/** 获取所有规则(内置 + 自定义) */
|
|
261
|
+
declare function getAllRules(): ValidationRuleConfig[];
|
|
262
|
+
/** 根据 key 查找规则 */
|
|
263
|
+
declare function getRuleByKey(key: string): ValidationRuleConfig | undefined;
|
|
264
|
+
/** 将规则配置转为 Ant Design Form Rule */
|
|
265
|
+
declare function ruleConfigToAntdRule(config: ValidationRuleConfig): Rule;
|
|
266
|
+
/** 将一组规则 key 转为 Ant Design Form Rules 数组 */
|
|
267
|
+
declare function keysToAntdRules(keys: string[]): Rule[];
|
|
268
|
+
|
|
269
|
+
export { BUILTIN_RULES, CrudPage, DynamicFilter, DynamicForm, DynamicTable, defaultWidgetForType, getAllRules, getEffectiveWidget, getFieldGroupPrefix, getNestedValue, getRuleByKey, keysToAntdRules, loadCustomRules, ruleConfigToAntdRule, saveCustomRules };
|
|
270
|
+
export type { ActionPermission, ActionSchema, ActionType, ApiRequest, ArrayItemField, CrudPageSchema, DataType, FieldConfig, FieldSchema, FilterConfig, FormFieldConfig, PaginationConfig, SelectOption, TableColumnConfig, ValidationRuleConfig, WidgetType };
|