mixlinker-actionitem 1.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 +124 -0
- package/dist/ActionItem.vue.d.ts +49 -0
- package/dist/ActionItemComponent.d.ts +338 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +1323 -0
- package/dist/style.css +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# @mixlinker/actionitem
|
|
2
|
+
|
|
3
|
+
ActionItem 动态表单组件 - 支持多种表单类型、字段联动、WebSocket 数据交互
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @mixlinker/actionitem
|
|
9
|
+
# 或
|
|
10
|
+
pnpm add @mixlinker/actionitem
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 使用
|
|
14
|
+
|
|
15
|
+
### 全局注册
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createApp } from 'vue'
|
|
19
|
+
import ElementPlus from 'element-plus'
|
|
20
|
+
import { ActionItemPlugin } from '@mixlinker/actionitem'
|
|
21
|
+
import '@mixlinker/actionitem/style.css'
|
|
22
|
+
|
|
23
|
+
const app = createApp(App)
|
|
24
|
+
app.use(ElementPlus)
|
|
25
|
+
app.use(ActionItemPlugin)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 局部使用
|
|
29
|
+
|
|
30
|
+
```vue
|
|
31
|
+
<template>
|
|
32
|
+
<ActionItem
|
|
33
|
+
:config="config"
|
|
34
|
+
:show-toolbar="true"
|
|
35
|
+
:show-ws-controls="true"
|
|
36
|
+
@submit="onSubmit"
|
|
37
|
+
@ws-data="onWsData"
|
|
38
|
+
/>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script setup>
|
|
42
|
+
import { ActionItem } from '@mixlinker/actionitem'
|
|
43
|
+
import '@mixlinker/actionitem/style.css'
|
|
44
|
+
|
|
45
|
+
const config = {
|
|
46
|
+
action_name: '用户信息',
|
|
47
|
+
params: [
|
|
48
|
+
{ key: 'name', cn_name: '姓名', form_type: 'text', required: true },
|
|
49
|
+
{ key: 'age', cn_name: '年龄', form_type: 'number' }
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const onSubmit = (data) => console.log('提交:', data)
|
|
54
|
+
const onWsData = (data) => console.log('WebSocket:', data)
|
|
55
|
+
</script>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 直接使用类
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { ActionItemComponent } from '@mixlinker/actionitem'
|
|
62
|
+
|
|
63
|
+
const acti = new ActionItemComponent({
|
|
64
|
+
action_name: '表单',
|
|
65
|
+
params: [...]
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
// 连接 WebSocket
|
|
69
|
+
acti.connectWebSocket('ws://localhost:8080', {
|
|
70
|
+
onData: (data) => console.log(data)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// 导出数据
|
|
74
|
+
const result = acti.exportToOriginalFormat()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Props
|
|
78
|
+
|
|
79
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
80
|
+
|------|------|--------|------|
|
|
81
|
+
| config | ActionItemConfig | - | 表单配置 |
|
|
82
|
+
| style | ActionItemStyle | - | 样式配置 |
|
|
83
|
+
| wsUrl | string | - | WebSocket URL |
|
|
84
|
+
| autoConnect | boolean | false | 自动连接 WebSocket |
|
|
85
|
+
| showToolbar | boolean | true | 显示工具栏 |
|
|
86
|
+
| showWsControls | boolean | true | 显示 WebSocket 控制 |
|
|
87
|
+
|
|
88
|
+
## Events
|
|
89
|
+
|
|
90
|
+
| 事件 | 参数 | 说明 |
|
|
91
|
+
|------|------|------|
|
|
92
|
+
| submit | data | 提交表单 |
|
|
93
|
+
| generate | data | 生成 JSON |
|
|
94
|
+
| wsConnect | - | WebSocket 连接成功 |
|
|
95
|
+
| wsDisconnect | - | WebSocket 断开 |
|
|
96
|
+
| wsData | data | 收到 WebSocket 数据 |
|
|
97
|
+
| wsError | error | WebSocket 错误 |
|
|
98
|
+
|
|
99
|
+
## 支持的 form_type
|
|
100
|
+
|
|
101
|
+
- text, textarea, select, radio_group, checkbox_group
|
|
102
|
+
- number, switch, date_picker, time_picker
|
|
103
|
+
- file_upload, sub_form, hidden
|
|
104
|
+
|
|
105
|
+
## 联动功能
|
|
106
|
+
|
|
107
|
+
通过 `rules` 配置实现字段联动:hidden, disabled, required, enum, placeholder, default_value, tooltip
|
|
108
|
+
|
|
109
|
+
## 开发
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 安装依赖
|
|
113
|
+
pnpm install
|
|
114
|
+
|
|
115
|
+
# 启动测试环境
|
|
116
|
+
pnpm test
|
|
117
|
+
|
|
118
|
+
# 构建
|
|
119
|
+
pnpm build
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ActionItemComponent, ActionItemConfig, ActionItemStyle } from './ActionItemComponent';
|
|
2
|
+
import { DefineComponent, ExtractPropTypes, Ref, ComponentOptionsMixin, PublicProps, ComponentProvideOptions, PropType } from 'vue';
|
|
3
|
+
|
|
4
|
+
declare const _default: DefineComponent<ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
|
|
5
|
+
config?: ActionItemConfig;
|
|
6
|
+
style?: Partial<ActionItemStyle>;
|
|
7
|
+
layout?: "line" | "tab";
|
|
8
|
+
}>, {
|
|
9
|
+
layout: string;
|
|
10
|
+
}>>, {
|
|
11
|
+
acti: ActionItemComponent;
|
|
12
|
+
formRef: Ref<any, any>;
|
|
13
|
+
}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
14
|
+
submit: (data: any) => void;
|
|
15
|
+
generate: (data: any) => void;
|
|
16
|
+
confirm: (data: any) => void;
|
|
17
|
+
cancel: () => void;
|
|
18
|
+
}, string, PublicProps, Readonly< ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
|
|
19
|
+
config?: ActionItemConfig;
|
|
20
|
+
style?: Partial<ActionItemStyle>;
|
|
21
|
+
layout?: "line" | "tab";
|
|
22
|
+
}>, {
|
|
23
|
+
layout: string;
|
|
24
|
+
}>>> & Readonly<{
|
|
25
|
+
onSubmit?: ((data: any) => any) | undefined;
|
|
26
|
+
onGenerate?: ((data: any) => any) | undefined;
|
|
27
|
+
onConfirm?: ((data: any) => any) | undefined;
|
|
28
|
+
onCancel?: (() => any) | undefined;
|
|
29
|
+
}>, {
|
|
30
|
+
layout: "line" | "tab";
|
|
31
|
+
}, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
34
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
35
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
36
|
+
type: PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
37
|
+
} : {
|
|
38
|
+
type: PropType<T[K]>;
|
|
39
|
+
required: true;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
type __VLS_WithDefaults<P, D> = {
|
|
43
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
|
|
44
|
+
default: D[K];
|
|
45
|
+
}> : P[K];
|
|
46
|
+
};
|
|
47
|
+
type __VLS_Prettify<T> = {
|
|
48
|
+
[K in keyof T]: T[K];
|
|
49
|
+
} & {};
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
export type FormType = 'text' | 'textarea' | 'select' | 'radio_group' | 'checkbox_group' | 'number' | 'switch' | 'date_picker' | 'time_picker' | 'file_upload' | 'sub_form' | 'hidden';
|
|
4
|
+
export interface EnumOption {
|
|
5
|
+
value: any;
|
|
6
|
+
cn_name: string;
|
|
7
|
+
}
|
|
8
|
+
export interface FormatRule {
|
|
9
|
+
enum?: any[];
|
|
10
|
+
min_length?: number;
|
|
11
|
+
max_length?: number;
|
|
12
|
+
length?: number;
|
|
13
|
+
pattern?: string;
|
|
14
|
+
allow_empty?: boolean;
|
|
15
|
+
trim?: boolean;
|
|
16
|
+
min?: number;
|
|
17
|
+
max?: number;
|
|
18
|
+
equal?: number;
|
|
19
|
+
not_equal?: number;
|
|
20
|
+
precision?: number;
|
|
21
|
+
integer?: boolean;
|
|
22
|
+
min_date?: string;
|
|
23
|
+
max_date?: string;
|
|
24
|
+
min_time?: string;
|
|
25
|
+
max_time?: string;
|
|
26
|
+
file_type?: string[];
|
|
27
|
+
max_size?: number;
|
|
28
|
+
min_size?: number;
|
|
29
|
+
min_items?: number;
|
|
30
|
+
max_items?: number;
|
|
31
|
+
unique_items?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface RuleConditionProperty {
|
|
34
|
+
hidden?: boolean;
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
required?: boolean;
|
|
37
|
+
default_value?: any;
|
|
38
|
+
tooltip?: string;
|
|
39
|
+
placeholder?: string;
|
|
40
|
+
enum?: EnumOption[];
|
|
41
|
+
}
|
|
42
|
+
export interface RuleCondition {
|
|
43
|
+
value: any;
|
|
44
|
+
property: RuleConditionProperty;
|
|
45
|
+
}
|
|
46
|
+
export interface DependencyRule {
|
|
47
|
+
related_key: string;
|
|
48
|
+
conditions: RuleCondition[];
|
|
49
|
+
}
|
|
50
|
+
export interface ActionItemParam {
|
|
51
|
+
key: string;
|
|
52
|
+
cn_name: string;
|
|
53
|
+
db_type?: string;
|
|
54
|
+
form_type: FormType;
|
|
55
|
+
required?: boolean;
|
|
56
|
+
default_value?: any;
|
|
57
|
+
description?: string;
|
|
58
|
+
enum?: EnumOption[];
|
|
59
|
+
format?: FormatRule;
|
|
60
|
+
rules?: DependencyRule[];
|
|
61
|
+
items?: {
|
|
62
|
+
type?: string;
|
|
63
|
+
properties?: ActionItemParam[];
|
|
64
|
+
};
|
|
65
|
+
properties?: ActionItemParam[];
|
|
66
|
+
auto_index?: boolean;
|
|
67
|
+
layout?: 'line' | 'tab';
|
|
68
|
+
}
|
|
69
|
+
export interface ActionItemConfig {
|
|
70
|
+
action_name?: string;
|
|
71
|
+
description?: string;
|
|
72
|
+
block?: string;
|
|
73
|
+
action?: string;
|
|
74
|
+
params?: ActionItemParam[];
|
|
75
|
+
data?: any;
|
|
76
|
+
socketData?: any;
|
|
77
|
+
layout?: 'line' | 'tab';
|
|
78
|
+
}
|
|
79
|
+
export interface ActionItemStyle {
|
|
80
|
+
bgColor: string;
|
|
81
|
+
titleColor: string;
|
|
82
|
+
radiusSize: number;
|
|
83
|
+
labelWidth: number;
|
|
84
|
+
isHideTitle: boolean;
|
|
85
|
+
showButtons: boolean;
|
|
86
|
+
}
|
|
87
|
+
export interface WebSocketCallbacks {
|
|
88
|
+
onData?: (data: any) => void;
|
|
89
|
+
onConnect?: () => void;
|
|
90
|
+
onDisconnect?: () => void;
|
|
91
|
+
onError?: (error: any) => void;
|
|
92
|
+
}
|
|
93
|
+
export declare class ActionItemComponent {
|
|
94
|
+
config: ActionItemConfig;
|
|
95
|
+
formData: Record<string, any>;
|
|
96
|
+
showJsonEditor: Ref<boolean>;
|
|
97
|
+
jsonInput: Ref<string>;
|
|
98
|
+
style: ActionItemStyle;
|
|
99
|
+
private ws;
|
|
100
|
+
wsConnected: Ref<boolean>;
|
|
101
|
+
private wsCallbacks;
|
|
102
|
+
constructor(initialConfig?: ActionItemConfig, styleOptions?: Partial<ActionItemStyle>);
|
|
103
|
+
/**
|
|
104
|
+
* 连接 WebSocket
|
|
105
|
+
*/
|
|
106
|
+
connectWebSocket(url: string, callbacks?: WebSocketCallbacks): void;
|
|
107
|
+
/**
|
|
108
|
+
* 断开 WebSocket
|
|
109
|
+
*/
|
|
110
|
+
disconnectWebSocket(): void;
|
|
111
|
+
/**
|
|
112
|
+
* 发送 WebSocket 消息
|
|
113
|
+
*/
|
|
114
|
+
sendWebSocketMessage(message: any): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* 处理 WebSocket 接收的数据
|
|
117
|
+
* 支持多种格式:
|
|
118
|
+
* 1. { result: { action_item: {...} } }
|
|
119
|
+
* 2. { result: { params: [...] } }
|
|
120
|
+
* 3. { code: 200, result: { params: [...] } } (uid 机制)
|
|
121
|
+
* 4. 直接 { params: [...] }
|
|
122
|
+
*/
|
|
123
|
+
setSocketData(res: any): void;
|
|
124
|
+
/**
|
|
125
|
+
* 发送请求到后端(uid 机制)
|
|
126
|
+
*/
|
|
127
|
+
sendRequest(action: string, payload?: any, uid?: string): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* 请求表单配置
|
|
130
|
+
*/
|
|
131
|
+
requestConfig(block?: string, name?: string, uid?: string): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* 提交表单数据
|
|
134
|
+
*/
|
|
135
|
+
submitToServer(uid?: string): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* 加载配置
|
|
138
|
+
*/
|
|
139
|
+
loadConfig(config: ActionItemConfig): void;
|
|
140
|
+
/**
|
|
141
|
+
* 解析后端数据
|
|
142
|
+
*/
|
|
143
|
+
parseBackendData(backendData: any): void;
|
|
144
|
+
/**
|
|
145
|
+
* 获取参数列表
|
|
146
|
+
*/
|
|
147
|
+
getParams(): ActionItemParam[];
|
|
148
|
+
/**
|
|
149
|
+
* 是否有参数
|
|
150
|
+
*/
|
|
151
|
+
get hasParams(): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* 获取可见参数(排除 hidden 和联动隐藏的)
|
|
154
|
+
*/
|
|
155
|
+
getVisibleParams(): ActionItemParam[];
|
|
156
|
+
/**
|
|
157
|
+
* 初始化表单数据
|
|
158
|
+
*/
|
|
159
|
+
initFormData(): void;
|
|
160
|
+
/**
|
|
161
|
+
* 重置表单
|
|
162
|
+
*/
|
|
163
|
+
resetForm(): void;
|
|
164
|
+
/**
|
|
165
|
+
* 获取默认值(支持递归嵌套)
|
|
166
|
+
*/
|
|
167
|
+
getDefaultValue(param: ActionItemParam): any;
|
|
168
|
+
/**
|
|
169
|
+
* 通过路径获取值
|
|
170
|
+
*/
|
|
171
|
+
getValueByPath(obj: any, path: string): any;
|
|
172
|
+
/**
|
|
173
|
+
* 通过路径设置值
|
|
174
|
+
*/
|
|
175
|
+
setValueByPath(obj: any, path: string, value: any): void;
|
|
176
|
+
/**
|
|
177
|
+
* 评估条件表达式(支持比较运算符)
|
|
178
|
+
*/
|
|
179
|
+
evaluateCondition(value: any, condition: string): boolean;
|
|
180
|
+
/**
|
|
181
|
+
* 获取动态属性(根据 rules 条件)
|
|
182
|
+
*/
|
|
183
|
+
getDynamicProperty(param: ActionItemParam, propName: keyof RuleConditionProperty, context?: any): any;
|
|
184
|
+
/**
|
|
185
|
+
* 判断字段在上下文中是否隐藏(用于嵌套路径)
|
|
186
|
+
*/
|
|
187
|
+
isHiddenInContext(param: ActionItemParam, parentPath: string, rootData: any): boolean;
|
|
188
|
+
/**
|
|
189
|
+
* 字段是否隐藏
|
|
190
|
+
*/
|
|
191
|
+
isFieldHidden(param: ActionItemParam, context?: any): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* 字段是否禁用
|
|
194
|
+
*/
|
|
195
|
+
isFieldDisabled(param: ActionItemParam, context?: any): boolean;
|
|
196
|
+
/**
|
|
197
|
+
* 字段是否必填(动态)
|
|
198
|
+
*/
|
|
199
|
+
isFieldRequired(param: ActionItemParam, context?: any): boolean;
|
|
200
|
+
/**
|
|
201
|
+
* 获取字段 placeholder
|
|
202
|
+
*/
|
|
203
|
+
getFieldPlaceholder(param: ActionItemParam, context?: any): string;
|
|
204
|
+
/**
|
|
205
|
+
* 获取字段 tooltip
|
|
206
|
+
*/
|
|
207
|
+
getFieldTooltip(param: ActionItemParam, context?: any): string | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* 获取字段选项(支持联动)
|
|
210
|
+
*/
|
|
211
|
+
getFieldOptions(param: ActionItemParam, context?: any): EnumOption[];
|
|
212
|
+
/**
|
|
213
|
+
* 获取动态默认值
|
|
214
|
+
*/
|
|
215
|
+
getDynamicDefaultValue(param: ActionItemParam, context?: any): any;
|
|
216
|
+
/**
|
|
217
|
+
* 字段变化时处理依赖
|
|
218
|
+
*/
|
|
219
|
+
onFieldChange(changedParam: ActionItemParam, _newValue?: any): void;
|
|
220
|
+
/**
|
|
221
|
+
* 添加子表单行
|
|
222
|
+
*/
|
|
223
|
+
addSubItem(param: ActionItemParam): boolean;
|
|
224
|
+
/**
|
|
225
|
+
* 删除子表单行
|
|
226
|
+
*/
|
|
227
|
+
removeSubItem(key: string, idx: number): boolean;
|
|
228
|
+
/**
|
|
229
|
+
* 获取子表单字段选项(支持行内联动)
|
|
230
|
+
*/
|
|
231
|
+
getSubFieldOptions(prop: ActionItemParam, item: Record<string, any>, _parentParam?: ActionItemParam): EnumOption[];
|
|
232
|
+
/**
|
|
233
|
+
* 子表单字段变化
|
|
234
|
+
*/
|
|
235
|
+
onSubFieldChange(param: ActionItemParam, prop: ActionItemParam, item: Record<string, any>): void;
|
|
236
|
+
/**
|
|
237
|
+
* 子表单字段是否禁用
|
|
238
|
+
*/
|
|
239
|
+
isSubFieldDisabled(prop: ActionItemParam, item: Record<string, any>): boolean;
|
|
240
|
+
/**
|
|
241
|
+
* 子表单字段是否隐藏
|
|
242
|
+
*/
|
|
243
|
+
isSubFieldHidden(prop: ActionItemParam, item: Record<string, any>): boolean;
|
|
244
|
+
/**
|
|
245
|
+
* 处理 trim
|
|
246
|
+
*/
|
|
247
|
+
processValue(param: ActionItemParam, value: any): any;
|
|
248
|
+
/**
|
|
249
|
+
* 解析日期值(支持 today, today+N, today-N)
|
|
250
|
+
*/
|
|
251
|
+
parseDateValue(value: string): Date | null;
|
|
252
|
+
/**
|
|
253
|
+
* 获取日期限制函数
|
|
254
|
+
*/
|
|
255
|
+
getDateDisabled(param: ActionItemParam): (date: Date) => boolean;
|
|
256
|
+
/**
|
|
257
|
+
* 获取文件上传 accept
|
|
258
|
+
*/
|
|
259
|
+
getFileAccept(param: ActionItemParam): string;
|
|
260
|
+
/**
|
|
261
|
+
* 获取文件大小限制(MB)
|
|
262
|
+
*/
|
|
263
|
+
getFileSizeLimit(param: ActionItemParam): number;
|
|
264
|
+
/**
|
|
265
|
+
* 验证文件
|
|
266
|
+
*/
|
|
267
|
+
validateFile(param: ActionItemParam, file: File): {
|
|
268
|
+
valid: boolean;
|
|
269
|
+
error?: string;
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* 使用正则表达式验证字段值
|
|
273
|
+
*/
|
|
274
|
+
validateWithRegex(param: ActionItemParam, value: any): {
|
|
275
|
+
valid: boolean;
|
|
276
|
+
error?: string;
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* 验证所有字段
|
|
280
|
+
*/
|
|
281
|
+
validateAllFields(): {
|
|
282
|
+
valid: boolean;
|
|
283
|
+
errors: {
|
|
284
|
+
key: string;
|
|
285
|
+
error: string;
|
|
286
|
+
}[];
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* 构建校验规则(用于 Element Plus Form)
|
|
290
|
+
*/
|
|
291
|
+
buildValidationRules(param: ActionItemParam): any[];
|
|
292
|
+
/**
|
|
293
|
+
* 获取表单校验规则(支持嵌套路径)
|
|
294
|
+
*/
|
|
295
|
+
getFormRules(): Record<string, any[]>;
|
|
296
|
+
/**
|
|
297
|
+
* 应用 JSON 配置
|
|
298
|
+
*/
|
|
299
|
+
applyJson(): {
|
|
300
|
+
success: boolean;
|
|
301
|
+
error?: string;
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* 导出为原始格式(生成 JSON 用)
|
|
305
|
+
*/
|
|
306
|
+
exportToOriginalFormat(): any;
|
|
307
|
+
/**
|
|
308
|
+
* 导出为目标 JSON 格式(别名)
|
|
309
|
+
*/
|
|
310
|
+
exportTargetJson(): any;
|
|
311
|
+
/**
|
|
312
|
+
* 递归转换 formData 为原始格式
|
|
313
|
+
*/
|
|
314
|
+
private convertFormDataToOriginal;
|
|
315
|
+
/**
|
|
316
|
+
* 转换数组项为原始格式
|
|
317
|
+
*/
|
|
318
|
+
private convertArrayItemToOriginal;
|
|
319
|
+
/**
|
|
320
|
+
* 设置参数变化监听
|
|
321
|
+
*/
|
|
322
|
+
watchParams(callback?: () => void): void;
|
|
323
|
+
/**
|
|
324
|
+
* 销毁(清理 WebSocket)
|
|
325
|
+
*/
|
|
326
|
+
destroy(): void;
|
|
327
|
+
static REGEX_PATTERNS: {
|
|
328
|
+
PHONE: string;
|
|
329
|
+
EMAIL: string;
|
|
330
|
+
ID_CARD: string;
|
|
331
|
+
CHINESE: string;
|
|
332
|
+
ENGLISH: string;
|
|
333
|
+
NUMBER: string;
|
|
334
|
+
URL: string;
|
|
335
|
+
IP: string;
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
export default ActionItemComponent;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(F,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("element-plus")):typeof define=="function"&&define.amd?define(["exports","vue","element-plus"],t):(F=typeof globalThis<"u"?globalThis:F||self,t(F.ActionItem={},F.Vue,F.ElementPlus))})(this,function(F,t,f){"use strict";var te=Object.defineProperty;var re=(F,t,f)=>t in F?te(F,t,{enumerable:!0,configurable:!0,writable:!0,value:f}):F[t]=f;var q=(F,t,f)=>re(F,typeof t!="symbol"?t+"":t,f);/*! Element Plus Icons Vue v2.3.2 */var v=t.defineComponent({name:"Delete",__name:"delete",setup(z){return(e,r)=>(t.openBlock(),t.createElementBlock("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 1024 1024"},[t.createElementVNode("path",{fill:"currentColor",d:"M160 256H96a32 32 0 0 1 0-64h256V95.936a32 32 0 0 1 32-32h256a32 32 0 0 1 32 32V192h256a32 32 0 1 1 0 64h-64v672a32 32 0 0 1-32 32H192a32 32 0 0 1-32-32zm448-64v-64H416v64zM224 896h576V256H224zm192-128a32 32 0 0 1-32-32V416a32 32 0 0 1 64 0v320a32 32 0 0 1-32 32m192 0a32 32 0 0 1-32-32V416a32 32 0 0 1 64 0v320a32 32 0 0 1-32 32"})]))}}),U=v,Y=t.defineComponent({name:"Plus",__name:"plus",setup(z){return(e,r)=>(t.openBlock(),t.createElementBlock("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 1024 1024"},[t.createElementVNode("path",{fill:"currentColor",d:"M480 480V128a32 32 0 0 1 64 0v352h352a32 32 0 1 1 0 64H544v352a32 32 0 1 1-64 0V544H128a32 32 0 0 1 0-64z"})]))}}),j=Y,O=t.defineComponent({name:"UploadFilled",__name:"upload-filled",setup(z){return(e,r)=>(t.openBlock(),t.createElementBlock("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 1024 1024"},[t.createElementVNode("path",{fill:"currentColor",d:"M544 864V672h128L512 480 352 672h128v192H320v-1.6c-5.376.32-10.496 1.6-16 1.6A240 240 0 0 1 64 624c0-123.136 93.12-223.488 212.608-237.248A239.81 239.81 0 0 1 512 192a239.87 239.87 0 0 1 235.456 194.752c119.488 13.76 212.48 114.112 212.48 237.248a240 240 0 0 1-240 240c-5.376 0-10.56-1.28-16-1.6v1.6z"})]))}}),K=O;class W{constructor(e,r){q(this,"config");q(this,"formData");q(this,"showJsonEditor");q(this,"jsonInput");q(this,"style");q(this,"ws",null);q(this,"wsConnected");q(this,"wsCallbacks",{});var a;this.config=t.reactive(e||{}),this.formData=t.reactive({}),this.showJsonEditor=t.ref(!1),this.jsonInput=t.ref(""),this.wsConnected=t.ref(!1),this.style=t.reactive({bgColor:(r==null?void 0:r.bgColor)||"#fff",titleColor:(r==null?void 0:r.titleColor)||"#333",radiusSize:(r==null?void 0:r.radiusSize)??8,labelWidth:(r==null?void 0:r.labelWidth)??100,isHideTitle:(r==null?void 0:r.isHideTitle)??!1,showButtons:(r==null?void 0:r.showButtons)??!0}),(a=e==null?void 0:e.params)!=null&&a.length&&this.initFormData()}connectWebSocket(e,r){var a,o;this.ws&&this.ws.close(),this.wsCallbacks=r||{};try{this.ws=new WebSocket(e),this.ws.onopen=()=>{var i,d;this.wsConnected.value=!0,(d=(i=this.wsCallbacks).onConnect)==null||d.call(i)},this.ws.onmessage=i=>{var d,s;try{const c=JSON.parse(i.data);this.setSocketData(c),(s=(d=this.wsCallbacks).onData)==null||s.call(d,c)}catch(c){console.error("WebSocket 消息解析失败:",c)}},this.ws.onclose=()=>{var i,d;this.wsConnected.value=!1,(d=(i=this.wsCallbacks).onDisconnect)==null||d.call(i)},this.ws.onerror=i=>{var d,s;console.error("WebSocket 错误:",i),(s=(d=this.wsCallbacks).onError)==null||s.call(d,i)}}catch(i){console.error("WebSocket 连接失败:",i),(o=(a=this.wsCallbacks).onError)==null||o.call(a,i)}}disconnectWebSocket(){this.ws&&(this.ws.close(),this.ws=null)}sendWebSocketMessage(e){return this.ws&&this.ws.readyState===WebSocket.OPEN?(this.ws.send(typeof e=="string"?e:JSON.stringify(e)),!0):!1}setSocketData(e){if(!e)return;if(e.code!==void 0&&e.code!==200){console.error("WebSocket 响应错误:",e.msg||e.code);return}const r=e.result||e,a=r.action_item||r;a!=null&&a.params&&this.parseBackendData(a)}sendRequest(e,r,a){const o={action:e,uid:a||"",...r};return this.sendWebSocketMessage(o)}requestConfig(e,r,a){return this.sendRequest("get_config_json",{block:e,name:r},a)}submitToServer(e){const r=this.exportToOriginalFormat();return this.sendRequest("submit_form",{data:r},e)}loadConfig(e){this.config.action_name=e.action_name,this.config.description=e.description,this.config.block=e.block,this.config.action=e.action,this.config.params=e.params,this.config.data=e,this.initFormData()}parseBackendData(e){e&&(this.config.action_name=e.action_name,this.config.description=e.description,this.config.params=e.params,this.config.block=e.block,this.config.action=e.action,this.config.data=e,this.initFormData())}getParams(){return Array.isArray(this.config.params)?this.config.params:[]}get hasParams(){return this.getParams().length>0}getVisibleParams(){return this.getParams().filter(e=>e.form_type!=="hidden"&&!this.isFieldHidden(e))}initFormData(){var r;const e=(r=this.config.data)==null?void 0:r.values;this.getParams().forEach(a=>{e&&e[a.key]!==void 0?this.formData[a.key]=e[a.key]:this.formData[a.key]=this.getDefaultValue(a)})}resetForm(){this.initFormData()}getDefaultValue(e){var r;if(e.form_type==="sub_form"&&e.properties&&!e.items){const a={};return e.properties.forEach(o=>{a[o.key]=this.getDefaultValue(o)}),a}return e.form_type==="sub_form"&&e.items?Array.isArray(e.default_value)?e.default_value:[]:e.form_type==="checkbox_group"?Array.isArray(e.default_value)?e.default_value:[]:e.default_value!==null&&e.default_value!==void 0?e.default_value:e.form_type==="switch"?!1:e.form_type==="number"?((r=e.format)==null?void 0:r.min)??0:""}getValueByPath(e,r){if(r)return r.split(".").reduce((a,o)=>a==null?void 0:a[o],e)}setValueByPath(e,r,a){const o=r.split("."),i=o.pop(),d=o.reduce((s,c)=>((!s[c]||typeof s[c]!="object")&&(s[c]={}),s[c]),e);d[i]=a}evaluateCondition(e,r){const a=parseFloat(e);return isNaN(a)?!1:r.startsWith(">=")?a>=parseFloat(r.slice(2)):r.startsWith("<=")?a<=parseFloat(r.slice(2)):r.startsWith(">")?a>parseFloat(r.slice(1)):r.startsWith("<")?a<parseFloat(r.slice(1)):r.startsWith("=")?a===parseFloat(r.slice(1)):!1}getDynamicProperty(e,r,a){var i;if(!((i=e.rules)!=null&&i.length))return;const o=a||this.formData;for(const d of e.rules){const s=d.related_key;if(!s)continue;let c;if(s.includes(".properties.")){const p=s.split(".properties.");c=this.getValueByPath(o,p.join("."))}else s.includes(".")?c=this.getValueByPath(o,s):c=o[s];for(const p of d.conditions){let D=!1;if(Array.isArray(p.value)?D=p.value.includes(c):typeof p.value=="string"&&/^[><=]/.test(p.value)?D=this.evaluateCondition(c,p.value):D=p.value===c,D&&p.property&&p.property[r]!==void 0)return p.property[r]}}}isHiddenInContext(e,r,a){var o,i,d;if(!((o=e.rules)!=null&&o.length))return!1;for(const s of e.rules){const c=s.related_key;if(!c)continue;const p=r?`${r}.${c}`:c,D=this.getValueByPath(a,p),P=(i=s.conditions)==null?void 0:i.find(N=>N.value===D);if((d=P==null?void 0:P.property)!=null&&d.hidden)return!0}return!1}isFieldHidden(e,r){return this.getDynamicProperty(e,"hidden",r)===!0}isFieldDisabled(e,r){return this.getDynamicProperty(e,"disabled",r)===!0}isFieldRequired(e,r){const a=this.getDynamicProperty(e,"required",r);return a!==void 0?a:e.required||!1}getFieldPlaceholder(e,r){return this.getDynamicProperty(e,"placeholder",r)||e.description||`请输入${e.cn_name}`}getFieldTooltip(e,r){return this.getDynamicProperty(e,"tooltip",r)||e.description}getFieldOptions(e,r){return this.getDynamicProperty(e,"enum",r)||e.enum||[]}getDynamicDefaultValue(e,r){const a=this.getDynamicProperty(e,"default_value",r);return a!==void 0?a:this.getDefaultValue(e)}onFieldChange(e,r){this.getParams().forEach(a=>{if(a.rules)for(const o of a.rules){const i=o.related_key;if(!i)continue;if(i===e.key||i.startsWith(e.key+".")||i.includes(".properties."+e.key)){const s=this.getDynamicProperty(a,"default_value");if(s!==void 0)this.formData[a.key]=s;else if(a.form_type==="select"||a.form_type==="radio_group"){const c=this.getFieldOptions(a),p=this.formData[a.key];p&&!c.find(D=>D.value===p)&&(this.formData[a.key]="")}else if(a.form_type==="checkbox_group"){const c=this.getFieldOptions(a),p=this.formData[a.key]||[];this.formData[a.key]=p.filter(D=>c.find(P=>P.value===D))}}}})}addSubItem(e){var i,d;Array.isArray(this.formData[e.key])||(this.formData[e.key]=[]);const r=(i=e.format)==null?void 0:i.max_items;if(r&&this.formData[e.key].length>=r)return!1;const a=((d=e.items)==null?void 0:d.properties)||e.properties||[],o={};return a.forEach(s=>{o[s.key]=this.getDefaultValue(s)}),this.formData[e.key].push(o),!0}removeSubItem(e,r){var i,d,s;const a=this.getParams().find(c=>c.key===e),o=(i=a==null?void 0:a.format)==null?void 0:i.min_items;return o&&((d=this.formData[e])==null?void 0:d.length)<=o?!1:((s=this.formData[e])==null||s.splice(r,1),!0)}getSubFieldOptions(e,r,a){var o,i,d;if((o=e.enum)!=null&&o.length&&!((i=e.rules)!=null&&i.length))return e.enum;if(e.rules)for(const s of e.rules){if(!s.related_key)continue;let c;const p=s.related_key;if(p.includes(".properties.")){const D=p.split(".properties.").pop();c=D?r[D]:void 0}else c=r[p];for(const D of s.conditions)if(D.value===c&&((d=D.property)!=null&&d.enum))return D.property.enum}return e.enum||[]}onSubFieldChange(e,r,a){var i;(((i=e.items)==null?void 0:i.properties)||e.properties||[]).forEach(d=>{var s,c;if(d.rules){for(const p of d.rules)if(((s=p.related_key)==null?void 0:s.split(".").pop())===r.key){const P=this.getSubFieldOptions(d,a,e);(d.form_type==="select"||d.form_type==="radio_group")&&(P.find(N=>N.value===a[d.key])||(a[d.key]=""));for(const N of p.conditions)N.value===a[r.key]&&((c=N.property)==null?void 0:c.default_value)!==void 0&&(a[d.key]=N.property.default_value)}}})}isSubFieldDisabled(e,r){var a,o,i;if(!((a=e.rules)!=null&&a.length))return!1;for(const d of e.rules){const s=(o=d.related_key)==null?void 0:o.split(".").pop();if(!s)continue;const c=r[s];for(const p of d.conditions)if(p.value===c&&((i=p.property)!=null&&i.disabled))return!0}return!1}isSubFieldHidden(e,r){var a,o,i;if(!((a=e.rules)!=null&&a.length))return!1;for(const d of e.rules){const s=(o=d.related_key)==null?void 0:o.split(".").pop();if(!s)continue;const c=r[s];for(const p of d.conditions)if(p.value===c&&((i=p.property)!=null&&i.hidden))return!0}return!1}processValue(e,r){var a;return(a=e.format)!=null&&a.trim&&typeof r=="string"?r.trim():r}parseDateValue(e){if(!e)return null;if(e==="today")return new Date;if(e.startsWith("today+")){const r=parseInt(e.slice(6)),a=new Date;return a.setDate(a.getDate()+r),a}if(e.startsWith("today-")){const r=parseInt(e.slice(6)),a=new Date;return a.setDate(a.getDate()-r),a}return new Date(e)}getDateDisabled(e){const r=e.format;return r?a=>{if(r.min_date){const o=this.parseDateValue(r.min_date);if(o&&a<o)return!0}if(r.max_date){const o=this.parseDateValue(r.max_date);if(o&&a>o)return!0}return!1}:()=>!1}getFileAccept(e){var a;const r=(a=e.format)==null?void 0:a.file_type;return r!=null&&r.length?r.join(","):"*"}getFileSizeLimit(e){var a;const r=(a=e.format)==null?void 0:a.max_size;return r?r/(1024*1024):10}validateFile(e,r){var o;const a=e.format;if(!a)return{valid:!0};if((o=a.file_type)!=null&&o.length){const i=r.type,d=r.name.toLowerCase();if(!a.file_type.some(c=>c.startsWith(".")?d.endsWith(c):i===c||i.startsWith(c.replace("*",""))))return{valid:!1,error:`文件类型不支持,允许: ${a.file_type.join(", ")}`}}return a.max_size&&r.size>a.max_size?{valid:!1,error:`文件大小超过限制 ${a.max_size/(1024*1024)}MB`}:a.min_size&&r.size<a.min_size?{valid:!1,error:`文件大小不能小于 ${a.min_size/1024}KB`}:{valid:!0}}validateWithRegex(e,r){var o;const a=(o=e.format)==null?void 0:o.pattern;if(!a||r===void 0||r===null||r==="")return{valid:!0};try{return new RegExp(a).test(String(r))?{valid:!0}:{valid:!1,error:`${e.cn_name}格式不正确`}}catch(i){return console.error(`正则表达式错误: ${a}`,i),{valid:!0}}}validateAllFields(){const e=[];return this.getParams().forEach(r=>{if(this.isFieldHidden(r))return;const a=this.formData[r.key];if(this.isFieldRequired(r)&&(a==null||a===""||Array.isArray(a)&&a.length===0)){e.push({key:r.key,error:`${r.cn_name}不能为空`});return}const o=this.validateWithRegex(r,a);!o.valid&&o.error&&e.push({key:r.key,error:o.error})}),{valid:e.length===0,errors:e}}buildValidationRules(e){const r=[],a=this.getDynamicProperty(e,"required");(a!==void 0?a:e.required)&&r.push({required:!0,message:`请输入${e.cn_name}`,trigger:"blur"});const i=e.format;return i&&(i.pattern&&r.push({pattern:new RegExp(i.pattern),message:`${e.cn_name}格式不正确`,trigger:"blur"}),i.length&&r.push({len:i.length,message:`${e.cn_name}长度必须为 ${i.length} 个字符`,trigger:"blur"}),(i.min_length||i.max_length)&&r.push({min:i.min_length,max:i.max_length,message:i.min_length&&i.max_length?`长度在 ${i.min_length} 到 ${i.max_length} 个字符`:i.min_length?`最少 ${i.min_length} 个字符`:`最多 ${i.max_length} 个字符`,trigger:"blur"}),e.form_type==="number"&&((i.min!==void 0||i.max!==void 0)&&r.push({type:"number",min:i.min,max:i.max,message:i.min!==void 0&&i.max!==void 0?`数值范围 ${i.min} 到 ${i.max}`:i.min!==void 0?`最小值 ${i.min}`:`最大值 ${i.max}`,trigger:"blur"}),i.integer&&r.push({validator:(d,s,c)=>{s!==void 0&&!Number.isInteger(s)?c(new Error(`${e.cn_name}必须为整数`)):c()},trigger:"blur"})),(e.form_type==="checkbox_group"||e.form_type==="sub_form"&&e.items)&&(i.min_items!==void 0&&r.push({type:"array",min:i.min_items,message:`至少选择 ${i.min_items} 项`,trigger:"change"}),i.max_items!==void 0&&r.push({type:"array",max:i.max_items,message:`最多选择 ${i.max_items} 项`,trigger:"change"}))),r}getFormRules(){const e={},r=(a,o="")=>{a.forEach(i=>{const d=o?`${o}.${i.key}`:i.key;if(i.form_type==="sub_form"&&i.properties&&!i.items){r(i.properties,d);return}if(i.form_type==="sub_form"&&i.items)return;const s=this.buildValidationRules(i);s.length&&(e[d]=s)})};return r(this.getParams()),e}applyJson(){try{const e=JSON.parse(this.jsonInput.value);if(e.params&&Array.isArray(e.params))this.loadConfig(e);else if(Array.isArray(e))this.loadConfig({params:e});else if(e.key&&e.form_type)this.loadConfig({params:[e]});else return{success:!1,error:"无法识别的 JSON 格式"};return this.showJsonEditor.value=!1,{success:!0}}catch(e){return{success:!1,error:e.message||"JSON 格式错误"}}}exportToOriginalFormat(){return this.convertFormDataToOriginal(this.formData,this.getParams())}exportTargetJson(){return this.exportToOriginalFormat()}convertFormDataToOriginal(e,r){const a={};return r.forEach(o=>{var d;let i=e[o.key];i=this.processValue(o,i),o.form_type==="sub_form"?o.properties&&!o.items?a[o.key]=this.convertFormDataToOriginal(i||{},o.properties):(d=o.items)!=null&&d.properties&&(a[o.key]=Array.isArray(i)?i.map((s,c)=>this.convertArrayItemToOriginal(s,o.items.properties,c)):[]):o.db_type==="boolean"&&typeof i=="boolean"?a[o.key]=i?"true":"false":a[o.key]=i}),a}convertArrayItemToOriginal(e,r,a){const o={};return r.forEach(i=>{i.form_type==="sub_form"&&i.properties?o[i.key]=this.convertFormDataToOriginal(e[i.key]||{},i.properties):i.auto_index?o[i.key]=String(a+1):o[i.key]=this.processValue(i,e[i.key])}),o}watchParams(e){t.watch(()=>this.config.params,()=>{this.initFormData(),e==null||e()},{immediate:!0,deep:!0})}destroy(){this.disconnectWebSocket()}}q(W,"REGEX_PATTERNS",{PHONE:"^1[3-9]\\d{9}$",EMAIL:"^[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$",ID_CARD:"^\\d{17}[\\dXx]$",CHINESE:"^[\\u4e00-\\u9fa5]+$",ENGLISH:"^[a-zA-Z]+$",NUMBER:"^\\d+$",URL:"^https?://[\\w.-]+",IP:"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"});const J={key:0,class:"empty-state"},L={key:1},G={key:0,class:"form-header"},X={key:0},Z={class:"form-footer"},H=((z,e)=>{const r=z.__vccOpts||z;for(const[a,o]of e)r[a]=o;return r})(t.defineComponent({__name:"ActionItem",props:{config:{},style:{},layout:{default:"line"}},emits:["submit","generate","confirm","cancel"],setup(z,{expose:e,emit:r}){const a=z,o=r,i=t.ref(),d=t.ref(0);t.computed(()=>s.config.layout||a.layout||"line");const s=new W(a.config,a.style);t.watch(()=>a.config,l=>{l&&(s.loadConfig(l),d.value=0)},{deep:!0}),e({acti:s,formRef:i}),t.onUnmounted(()=>{s.destroy()}),t.defineComponent({name:"TabPanelContent",props:{param:{type:Object,required:!0},rootData:{type:Object,required:!0},actionItem:{type:Object,required:!0}},setup(l){const n=l.param,y=l.rootData,m=l.actionItem,h=n.key;return()=>{var u;if(n.form_type==="sub_form"&&n.properties){const k=m.getValueByPath(y,h);(!k||typeof k!="object"||Array.isArray(k))&&m.setValueByPath(y,h,{});const C=n.properties.filter(_=>!m.isHiddenInContext(_,h,y));return t.h("div",{class:"tab-panel-content"},C.map(_=>t.h(c,{param:_,rootData:y,actionItem:m,key:_.key,parentPath:h})))}return n.form_type==="sub_form"&&((u=n.items)!=null&&u.properties)?t.h(c,{param:n,rootData:y,actionItem:m,key:n.key,parentPath:""}):t.h(c,{param:n,rootData:y,actionItem:m,key:n.key,parentPath:""})}}});const c=t.defineComponent({name:"FormField",props:{param:{type:Object,required:!0},rootData:{type:Object,required:!0},actionItem:{type:Object,required:!0},parentPath:{type:String,default:""}},setup(l){var A;const n=l.param,y=l.rootData,m=l.actionItem,h=n.key,u=l.parentPath?`${l.parentPath}.${h}`:h,k=n.form_type==="sub_form"&&n.properties&&!n.items,C=n.form_type==="sub_form"&&((A=n.items)==null?void 0:A.properties),_=t.ref(0);return()=>{var $,w;if(m.isHiddenInContext(n,l.parentPath,y))return null;if(k){const I=m.getValueByPath(y,u);(!I||typeof I!="object"||Array.isArray(I))&&m.setValueByPath(y,u,{});const B=n.properties.filter(b=>!m.isHiddenInContext(b,u,y));if(n.layout&&B.length>0){const b=B.filter(g=>g.form_type==="sub_form"),S=B.filter(g=>g.form_type!=="sub_form");return t.h(f.ElFormItem,{label:n.cn_name,class:"sub-form-field tab-inline-field"},()=>[t.h("div",{class:"sub-form-wrapper",style:{border:"none",padding:"0"}},[...S.map(g=>t.h(c,{param:g,rootData:y,actionItem:m,key:g.key,parentPath:u})),n.layout==="tab"&&b.length>0?t.h("div",{class:"sub-tab-container",style:{width:"100%"}},[t.h("div",{class:"sub-tab-header",style:{display:"flex",flexDirection:"row",flexWrap:"nowrap",alignItems:"center",borderBottom:"1px solid #e4e7ed",width:"100%"}},b.map((g,E)=>t.h("div",{class:["sub-tab-item",{active:_.value===E}],key:g.key,style:{padding:"10px 20px",fontSize:"14px",color:_.value===E?"#409eff":"#303133",cursor:"pointer",borderBottom:_.value===E?"2px solid #409eff":"2px solid transparent",marginBottom:"-1px",whiteSpace:"nowrap",fontWeight:_.value===E?"500":"400"},onClick:()=>{_.value=E}},g.cn_name))),t.h("div",{class:"sub-tab-content",style:{padding:"16px 0"}},b.map((g,E)=>t.h("div",{class:"sub-tab-panel",key:g.key,style:{display:_.value===E?"block":"none"}},[t.h(p,{param:g,rootData:y,actionItem:m,parentPath:u,key:g.key})])))]):t.h("div",{class:"sub-line-container"},b.map(g=>t.h("div",{class:"sub-line-item",key:g.key},[t.h("div",{class:"sub-line-title"},g.cn_name),t.h(p,{param:g,rootData:y,actionItem:m,parentPath:u})])))])])}return n.cn_name?t.h(f.ElFormItem,{label:n.cn_name,class:"sub-form-field"},()=>t.h("div",{class:"sub-form-inline"},B.map(b=>t.h(c,{param:b,rootData:y,actionItem:m,key:b.key,parentPath:u})))):t.h("div",{class:"sub-form-inline"},B.map(b=>t.h(c,{param:b,rootData:y,actionItem:m,key:b.key,parentPath:u})))}if(C){let I=m.getValueByPath(y,u);Array.isArray(I)||(m.setValueByPath(y,u,[]),I=m.getValueByPath(y,u));const B=n.items.properties,b=B.filter(E=>E.form_type!=="hidden"),S=($=n.format)==null?void 0:$.max_items,g=((w=n.format)==null?void 0:w.min_items)||0;return t.h(f.ElFormItem,{label:n.cn_name},()=>[t.h("div",{class:"sub-form"},[...I.map((E,V)=>t.h("div",{class:"sub-item",key:V},[t.h("div",{class:"sub-fields"},b.map(R=>m.isSubFieldHidden(R,E)?null:t.h("div",{class:"sub-field",key:R.key},[t.h("span",{class:"sub-label"},[m.isFieldRequired(R,E)?t.h("span",{class:"required-star"},"*"):null,R.cn_name]),P(R,E,m,n)]))),t.h(f.ElButton,{type:"danger",icon:U,circle:!0,size:"small",disabled:I.length<=g,onClick:()=>I.splice(V,1)})])),t.h(f.ElButton,{type:"primary",icon:j,disabled:S?I.length>=S:!1,onClick:()=>{const E={};B.forEach(V=>{E[V.key]=m.getDefaultValue(V)}),I.push(E)}},()=>"添加")])])}const x={label:n.cn_name,prop:u};return m.isFieldRequired(n)&&(x.rules=[{required:!0,message:`请输入${n.cn_name}`,trigger:"blur"}]),t.h(f.ElFormItem,x,()=>D(n,u,y,m))}}}),p=t.defineComponent({name:"SubFormContent",props:{param:{type:Object,required:!0},rootData:{type:Object,required:!0},actionItem:{type:Object,required:!0},parentPath:{type:String,default:""}},setup(l){const n=l.param,y=l.rootData,m=l.actionItem,h=l.parentPath?`${l.parentPath}.${n.key}`:n.key;return()=>{var C,_,A;if((C=n.items)!=null&&C.properties){let x=m.getValueByPath(y,h);Array.isArray(x)||(m.setValueByPath(y,h,[]),x=m.getValueByPath(y,h));const $=n.items.properties,w=$.filter(b=>b.form_type!=="hidden"),I=(_=n.format)==null?void 0:_.max_items,B=((A=n.format)==null?void 0:A.min_items)||0;return t.h("div",{class:"sub-form"},[...x.map((b,S)=>t.h("div",{class:"sub-item",key:S},[t.h("div",{class:"sub-fields"},w.map(g=>m.isSubFieldHidden(g,b)?null:t.h("div",{class:"sub-field",key:g.key},[t.h("span",{class:"sub-label"},[m.isFieldRequired(g,b)?t.h("span",{class:"required-star"},"*"):null,g.cn_name]),P(g,b,m,n)]))),t.h(f.ElButton,{type:"danger",icon:U,circle:!0,size:"small",disabled:x.length<=B,onClick:()=>x.splice(S,1)})])),t.h(f.ElButton,{type:"primary",icon:j,disabled:I?x.length>=I:!1,onClick:()=>{const b={};$.forEach(S=>{b[S.key]=m.getDefaultValue(S)}),x.push(b)}},()=>"添加")])}if(!n.properties)return null;const u=m.getValueByPath(y,h);(!u||typeof u!="object"||Array.isArray(u))&&m.setValueByPath(y,h,{});const k=n.properties.filter(x=>!m.isHiddenInContext(x,h,y));return t.h("div",{class:"sub-form-content"},k.map(x=>t.h(c,{param:x,rootData:y,actionItem:m,key:x.key,parentPath:h})))}}});function D(l,n,y,m){var A,x,$,w,I,B,b,S,g,E;const h=m.isFieldDisabled(l),u=m.getValueByPath(y,n),k=V=>{m.setValueByPath(y,n,V),m.onFieldChange(l,V)},C=m.getFieldPlaceholder(l),_=m.getFieldOptions(l);switch(l.form_type){case"text":return t.h(f.ElInput,{modelValue:u??"","onUpdate:modelValue":k,placeholder:C,disabled:h,size:"small",clearable:!0});case"textarea":return t.h(f.ElInput,{type:"textarea",modelValue:u??"","onUpdate:modelValue":k,placeholder:C,disabled:h,rows:3,maxlength:(A=l.format)==null?void 0:A.max_length,showWordLimit:!!((x=l.format)!=null&&x.max_length)});case"select":return t.h(f.ElSelect,{modelValue:u??"","onUpdate:modelValue":k,placeholder:`请选择${l.cn_name}`,disabled:h,style:"width:100%",size:"small",clearable:!0},()=>_.map(V=>t.h(f.ElOption,{key:V.value,label:V.cn_name,value:V.value})));case"radio_group":return t.h(f.ElRadioGroup,{modelValue:u??"","onUpdate:modelValue":k,disabled:h},()=>_.map(V=>t.h(f.ElRadio,{key:V.value,value:V.value},()=>V.cn_name)));case"checkbox_group":return t.h(f.ElCheckboxGroup,{modelValue:u??[],"onUpdate:modelValue":k,disabled:h},()=>_.map(V=>t.h(f.ElCheckbox,{key:V.value,value:V.value},()=>V.cn_name)));case"number":return t.h(f.ElInputNumber,{modelValue:u??0,"onUpdate:modelValue":k,disabled:h,min:($=l.format)==null?void 0:$.min,max:(w=l.format)==null?void 0:w.max,precision:(I=l.format)==null?void 0:I.precision,step:(B=l.format)!=null&&B.precision?Math.pow(10,-l.format.precision):1,style:"width:100%",size:"small",controlsPosition:"right"});case"switch":return t.h(f.ElSwitch,{modelValue:u===!0||u==="true","onUpdate:modelValue":k,disabled:h});case"date_picker":return t.h(f.ElDatePicker,{modelValue:u??"","onUpdate:modelValue":k,type:"date",placeholder:`请选择${l.cn_name}`,disabled:h,format:"YYYY-MM-DD",valueFormat:"YYYY-MM-DD",disabledDate:m.getDateDisabled(l),style:"width:100%",size:"small"});case"time_picker":return t.h(f.ElTimePicker,{modelValue:u??"","onUpdate:modelValue":k,placeholder:`请选择${l.cn_name}`,disabled:h,format:(S=(b=l.format)==null?void 0:b.min_time)!=null&&S.includes(":")&&l.format.min_time.split(":").length===3?"HH:mm:ss":"HH:mm",style:"width:100%",size:"small"});case"file_upload":return t.h("div",{class:"file-upload-wrapper"},[t.h(f.ElUpload,{action:"#",autoUpload:!1,disabled:h,accept:m.getFileAccept(l),limit:((g=l.format)==null?void 0:g.max_items)||1,fileList:Array.isArray(u)?u:u?[u]:[],onChange:(V,R)=>{var M;const T=m.validateFile(l,V.raw);if(!T.valid){f.ElMessage.error(T.error),R.pop();return}k((M=l.format)!=null&&M.max_items&&l.format.max_items>1?R:V)},onRemove:(V,R)=>{var T;k((T=l.format)!=null&&T.max_items&&l.format.max_items>1?R:null)}},()=>t.h(f.ElButton,{type:"primary",icon:K,size:"small"},()=>"选择文件")),(E=l.format)!=null&&E.max_size?t.h("span",{class:"upload-tip"},`最大 ${(l.format.max_size/(1024*1024)).toFixed(1)}MB`):null]);default:return t.h(f.ElInput,{modelValue:u??"","onUpdate:modelValue":k,disabled:h,size:"small",placeholder:C})}}function P(l,n,y,m){var A,x,$;const h=l.key,u=y.isSubFieldDisabled(l,n),k=y.getSubFieldOptions(l,n,m),C=l.description||`请输入${l.cn_name}`,_=w=>{n[h]=w,y.onSubFieldChange(m,l,n)};switch(l.form_type){case"text":return t.h(f.ElInput,{modelValue:n[h]??"","onUpdate:modelValue":_,placeholder:C,disabled:u,size:"small",clearable:!0});case"textarea":return t.h(f.ElInput,{type:"textarea",modelValue:n[h]??"","onUpdate:modelValue":_,placeholder:C,disabled:u,rows:2});case"select":return t.h(f.ElSelect,{modelValue:n[h]??"","onUpdate:modelValue":_,placeholder:`请选择${l.cn_name}`,disabled:u,style:"width:100%",size:"small",clearable:!0},()=>k.map(w=>t.h(f.ElOption,{key:w.value,label:w.cn_name,value:w.value})));case"radio_group":return t.h(f.ElRadioGroup,{modelValue:n[h]??"","onUpdate:modelValue":_,disabled:u,size:"small"},()=>k.map(w=>t.h(f.ElRadio,{key:w.value,value:w.value},()=>w.cn_name)));case"checkbox_group":return t.h(f.ElCheckboxGroup,{modelValue:n[h]??[],"onUpdate:modelValue":_,disabled:u,size:"small"},()=>k.map(w=>t.h(f.ElCheckbox,{key:w.value,value:w.value},()=>w.cn_name)));case"number":return t.h(f.ElInputNumber,{modelValue:n[h]??0,"onUpdate:modelValue":_,disabled:u,min:(A=l.format)==null?void 0:A.min,max:(x=l.format)==null?void 0:x.max,precision:($=l.format)==null?void 0:$.precision,style:"width:100%",size:"small",controlsPosition:"right"});case"switch":return t.h(f.ElSwitch,{modelValue:n[h]===!0||n[h]==="true","onUpdate:modelValue":_,disabled:u,size:"small"});case"date_picker":return t.h(f.ElDatePicker,{modelValue:n[h]??"","onUpdate:modelValue":_,type:"date",placeholder:`请选择${l.cn_name}`,disabled:u,format:"YYYY-MM-DD",valueFormat:"YYYY-MM-DD",style:"width:100%",size:"small"});case"time_picker":return t.h(f.ElTimePicker,{modelValue:n[h]??"","onUpdate:modelValue":_,placeholder:`请选择${l.cn_name}`,disabled:u,style:"width:100%",size:"small"});default:return t.h(f.ElInput,{modelValue:n[h]??"","onUpdate:modelValue":_,disabled:u,size:"small",placeholder:C})}}const N=async()=>{if(i.value)try{await i.value.validate();const l=s.exportToOriginalFormat();o("confirm",l)}catch{f.ElMessage.warning("请检查表单填写")}else{const l=s.exportToOriginalFormat();o("confirm",l)}},ee=()=>{o("cancel")};return(l,n)=>{const y=t.resolveComponent("el-empty"),m=t.resolveComponent("el-form");return t.openBlock(),t.createElementBlock("div",{class:"action-item-form",style:t.normalizeStyle({background:t.unref(s).style.bgColor,borderRadius:t.unref(s).style.radiusSize+"px"})},[t.unref(s).hasParams?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",J,[t.createVNode(y,{description:"暂无配置","image-size":80})])),t.unref(s).hasParams?(t.openBlock(),t.createElementBlock("div",L,[t.unref(s).config.action_name&&!t.unref(s).style.isHideTitle?(t.openBlock(),t.createElementBlock("div",G,[t.createElementVNode("h3",{style:t.normalizeStyle({color:t.unref(s).style.titleColor})},t.toDisplayString(t.unref(s).config.action_name),5),t.unref(s).config.description?(t.openBlock(),t.createElementBlock("p",X,t.toDisplayString(t.unref(s).config.description),1)):t.createCommentVNode("",!0)])):t.createCommentVNode("",!0),t.createVNode(m,{ref_key:"formRef",ref:i,model:t.unref(s).formData,rules:t.unref(s).getFormRules(),"label-width":t.unref(s).style.labelWidth+"px"},{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(t.unref(s).getVisibleParams(),h=>(t.openBlock(),t.createBlock(t.unref(c),{key:h.key,param:h,rootData:t.unref(s).formData,actionItem:t.unref(s)},null,8,["param","rootData","actionItem"]))),128))]),_:1},8,["model","rules","label-width"]),t.createElementVNode("div",Z,[t.createVNode(t.unref(f.ElButton),{onClick:ee},{default:t.withCtx(()=>[...n[0]||(n[0]=[t.createTextVNode("取消",-1)])]),_:1}),t.createVNode(t.unref(f.ElButton),{type:"primary",onClick:N},{default:t.withCtx(()=>[...n[1]||(n[1]=[t.createTextVNode("确认",-1)])]),_:1})])])):t.createCommentVNode("",!0)],4)}}}),[["__scopeId","data-v-083c5f60"]]),Q={install(z){z.component("ActionItem",H)}};F.ActionItem=H,F.ActionItemComponent=W,F.ActionItemPlugin=Q,F.default=H,Object.defineProperties(F,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { default as ActionItem } from './ActionItem.vue';
|
|
2
|
+
|
|
3
|
+
export { ActionItemComponent } from './ActionItemComponent';
|
|
4
|
+
export type { FormType, EnumOption, FormatRule, RuleConditionProperty, RuleCondition, DependencyRule, ActionItemParam, ActionItemConfig, ActionItemStyle, WebSocketCallbacks } from './ActionItemComponent';
|
|
5
|
+
export declare const ActionItemPlugin: {
|
|
6
|
+
install(app: any): void;
|
|
7
|
+
};
|
|
8
|
+
export { ActionItem };
|
|
9
|
+
export default ActionItem;
|