fix(web): 修复 visible_when 表达式评估器 !=/||/&& 支持 + 添加 validation 前端校验
- exprEvaluator: 新增 neq 类型修复 != 操作符被当作 == 处理的 bug - exprEvaluator: 支持 || 和 && 作为 OR/AND 的别名 - PluginCRUDPage: 读取 field.validation.pattern 添加表单正则校验规则
This commit is contained in:
@@ -773,9 +773,14 @@ export default function PluginCRUDPage({
|
|||||||
name={field.name}
|
name={field.name}
|
||||||
label={field.display_name || field.name}
|
label={field.display_name || field.name}
|
||||||
rules={
|
rules={
|
||||||
field.required
|
[
|
||||||
? [{ required: true, message: `请输入${field.display_name || field.name}` }]
|
...(field.required
|
||||||
: []
|
? [{ required: true, message: `请输入${field.display_name || field.name}` }]
|
||||||
|
: []),
|
||||||
|
...(field.validation?.pattern
|
||||||
|
? [{ pattern: new RegExp(field.validation.pattern), message: field.validation.message || '格式不正确' }]
|
||||||
|
: []),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
valuePropName={field.field_type === 'boolean' ? 'checked' : 'value'}
|
valuePropName={field.field_type === 'boolean' ? 'checked' : 'value'}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
interface ExprNode {
|
interface ExprNode {
|
||||||
type: 'eq' | 'and' | 'or' | 'not';
|
type: 'eq' | 'neq' | 'and' | 'or' | 'not';
|
||||||
field?: string;
|
field?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
left?: ExprNode;
|
left?: ExprNode;
|
||||||
@@ -49,6 +49,16 @@ function tokenize(input: string): string[] {
|
|||||||
i += 2;
|
i += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (input[i] === '&' && input[i + 1] === '&') {
|
||||||
|
tokens.push('&&');
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (input[i] === '|' && input[i + 1] === '|') {
|
||||||
|
tokens.push('||');
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let j = i;
|
let j = i;
|
||||||
while (
|
while (
|
||||||
j < input.length &&
|
j < input.length &&
|
||||||
@@ -81,12 +91,12 @@ function parseAtom(tokens: string[]): ExprNode | null {
|
|||||||
if (op !== '==' && op !== '!=') return null;
|
if (op !== '==' && op !== '!=') return null;
|
||||||
const rawValue = tokens.shift() || '';
|
const rawValue = tokens.shift() || '';
|
||||||
const value = rawValue.replace(/^'(.*)'$/, '$1');
|
const value = rawValue.replace(/^'(.*)'$/, '$1');
|
||||||
return { type: 'eq', field, value };
|
return { type: op === '!=' ? 'neq' : 'eq', field, value };
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseAnd(tokens: string[]): ExprNode | null {
|
function parseAnd(tokens: string[]): ExprNode | null {
|
||||||
let left = parseAtom(tokens);
|
let left = parseAtom(tokens);
|
||||||
while (tokens[0] === 'AND') {
|
while (tokens[0] === 'AND' || tokens[0] === '&&') {
|
||||||
tokens.shift();
|
tokens.shift();
|
||||||
const right = parseAtom(tokens);
|
const right = parseAtom(tokens);
|
||||||
if (left && right) {
|
if (left && right) {
|
||||||
@@ -98,7 +108,7 @@ function parseAnd(tokens: string[]): ExprNode | null {
|
|||||||
|
|
||||||
function parseOr(tokens: string[]): ExprNode | null {
|
function parseOr(tokens: string[]): ExprNode | null {
|
||||||
let left = parseAnd(tokens);
|
let left = parseAnd(tokens);
|
||||||
while (tokens[0] === 'OR') {
|
while (tokens[0] === 'OR' || tokens[0] === '||') {
|
||||||
tokens.shift();
|
tokens.shift();
|
||||||
const right = parseAnd(tokens);
|
const right = parseAnd(tokens);
|
||||||
if (left && right) {
|
if (left && right) {
|
||||||
@@ -117,6 +127,8 @@ export function evaluateExpr(node: ExprNode, values: Record<string, unknown>): b
|
|||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case 'eq':
|
case 'eq':
|
||||||
return String(values[node.field!] ?? '') === node.value;
|
return String(values[node.field!] ?? '') === node.value;
|
||||||
|
case 'neq':
|
||||||
|
return String(values[node.field!] ?? '') !== node.value;
|
||||||
case 'and':
|
case 'and':
|
||||||
return evaluateExpr(node.left!, values) && evaluateExpr(node.right!, values);
|
return evaluateExpr(node.left!, values) && evaluateExpr(node.right!, values);
|
||||||
case 'or':
|
case 'or':
|
||||||
|
|||||||
Reference in New Issue
Block a user