deploy-ease-platform/frontend/src/pages/FormDesigner/components/ValidationRuleEditor.tsx
2025-10-23 23:53:43 +08:00

176 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 验证规则编辑器
*/
import React from 'react';
import { Select, Input, InputNumber, Button, Space, Typography } from 'antd';
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
import type { ValidationRule } from '../types';
const { Text } = Typography;
interface ValidationRuleEditorProps {
value?: ValidationRule[];
onChange?: (value: ValidationRule[]) => void;
}
const ValidationRuleEditor: React.FC<ValidationRuleEditorProps> = ({ value = [], onChange }) => {
const handleAddRule = () => {
const newRule: ValidationRule = {
type: 'required',
message: '',
trigger: 'blur',
};
onChange?.([...value, newRule]);
};
const handleDeleteRule = (index: number) => {
const newRules = value.filter((_, i) => i !== index);
onChange?.(newRules);
};
const handleRuleChange = (index: number, field: keyof ValidationRule, fieldValue: any) => {
const newRules = [...value];
newRules[index] = { ...newRules[index], [field]: fieldValue };
onChange?.(newRules);
};
const getRuleValueInput = (rule: ValidationRule, index: number) => {
switch (rule.type) {
case 'required':
return null;
case 'pattern':
return (
<Input
placeholder="输入正则表达式,如:^[a-zA-Z0-9]+$"
value={rule.value}
onChange={(e) => handleRuleChange(index, 'value', e.target.value)}
/>
);
case 'min':
case 'max':
case 'minLength':
case 'maxLength':
return (
<InputNumber
style={{ width: '100%' }}
placeholder={`请输入${rule.type === 'min' || rule.type === 'minLength' ? '最小' : '最大'}`}
value={rule.value}
onChange={(val) => handleRuleChange(index, 'value', val)}
/>
);
case 'email':
case 'url':
case 'phone':
case 'idCard':
return null;
case 'custom':
return (
<Input
placeholder="输入自定义验证函数名"
value={rule.value}
onChange={(e) => handleRuleChange(index, 'value', e.target.value)}
/>
);
default:
return null;
}
};
return (
<div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
<Text strong></Text>
<Button type="dashed" size="small" icon={<PlusOutlined />} onClick={handleAddRule}>
</Button>
</div>
{value.length === 0 ? (
<div style={{ padding: '24px 0', textAlign: 'center', color: '#8c8c8c', fontSize: 12 }}>
</div>
) : (
<Space direction="vertical" style={{ width: '100%' }} size="middle">
{value.map((rule, index) => (
<div
key={index}
style={{
padding: 12,
border: '1px solid #e8e8e8',
borderRadius: 4,
background: '#fafafa',
}}
>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
<Text style={{ fontSize: 12, color: '#666' }}> {index + 1}</Text>
<Button
type="text"
size="small"
danger
icon={<DeleteOutlined />}
onClick={() => handleDeleteRule(index)}
/>
</div>
<Space direction="vertical" style={{ width: '100%' }} size="small">
<div>
<Text style={{ fontSize: 12, marginBottom: 4, display: 'block' }}></Text>
<Select
style={{ width: '100%' }}
value={rule.type}
onChange={(val) => handleRuleChange(index, 'type', val)}
>
<Select.Option value="required"></Select.Option>
<Select.Option value="pattern"></Select.Option>
<Select.Option value="min"></Select.Option>
<Select.Option value="max"></Select.Option>
<Select.Option value="minLength"></Select.Option>
<Select.Option value="maxLength"></Select.Option>
<Select.Option value="email"></Select.Option>
<Select.Option value="url">URL格式</Select.Option>
<Select.Option value="phone"></Select.Option>
<Select.Option value="idCard"></Select.Option>
<Select.Option value="custom"></Select.Option>
</Select>
</div>
{getRuleValueInput(rule, index) && (
<div>
<Text style={{ fontSize: 12, marginBottom: 4, display: 'block' }}></Text>
{getRuleValueInput(rule, index)}
</div>
)}
<div>
<Text style={{ fontSize: 12, marginBottom: 4, display: 'block' }}></Text>
<Input
placeholder="请输入验证失败时的提示信息"
value={rule.message}
onChange={(e) => handleRuleChange(index, 'message', e.target.value)}
/>
</div>
<div>
<Text style={{ fontSize: 12, marginBottom: 4, display: 'block' }}></Text>
<Select
style={{ width: '100%' }}
value={rule.trigger}
onChange={(val) => handleRuleChange(index, 'trigger', val)}
>
<Select.Option value="blur"></Select.Option>
<Select.Option value="change"></Select.Option>
</Select>
</div>
</Space>
</div>
))}
</Space>
)}
</div>
);
};
export default ValidationRuleEditor;