feat(plugin-field-sequence): add random character pattern (#5959)

* chore(plugin-field-sequence): add random number and random string patterns

- Add random number pattern with configurable length (padded with zeros)
- Add random string pattern with configurable length (alphanumeric)
- Update Chinese translations for new patterns

* fix(plugin-workflow): fix date range variables (#5954)

* feat: hidden date range variables from nodes which is not filter components

* feat: remove system daterange variables from plugin

* refactor(plugin-workflow): move date range variables to component

* fix(plugin-workflow): remove useless code

---------

Co-authored-by: Linda <huanghui9850@gmail.com>

* Update sequence-field.ts

合并了随机字符

* Update sequence.tsx

合并成了随机字符

* Update zh-CN.json

* Update zh-CN.json

更新中文翻译

* Update zh-CN.json

修改了重复的文本

* Update sequence.tsx

删掉了旧的随机数字和随机字符,保留合并后的随机字符,可以配置字符集选择数字、大小写字母、符号,配置字符长度,配置要不要根据长度补零、不补充,

* Update sequence-field.ts

* Update sequence.tsx

除了数字以外的字符集隐藏掉是否补0的选项,因为用不上

* Update sequence.tsx

重新提交下防止之前发错了

* Update sequence.tsx

重新提交下,不小心把服务端内容贴进去了

* Update sequence.tsx

隐藏补充类型改成禁用补充类型

* Update sequence.tsx

补零改成了前补零和后补零两个选项

* Update sequence-field.ts

补零改成了前补零和后补零

* Update zh-CN.json

修改了文本

* Update sequence-field.ts

去掉了多余还影响观感的后补零

* Update sequence.tsx

去掉了多余的后补零

* Update zh-CN.json

* Update zh-CN.json

删了多余的padding

* Update sequence.tsx

去掉了多余的padding

* Update sequence-field.ts

去掉了多余的padding

---------

Co-authored-by: Junyi <mytharcher@users.noreply.github.com>
Co-authored-by: Linda <huanghui9850@gmail.com>
This commit is contained in:
kennnnn 2025-01-23 17:33:15 +08:00 committed by GitHub
parent 0b6ed37fa4
commit 6c922ba7e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 143 additions and 1 deletions

View File

@ -109,6 +109,66 @@ const RuleTypes = {
},
},
},
randomChar: {
title: `{{t("Random character", { ns: "${NAMESPACE}" })}}`,
optionRenders: {
length: function Length({ value }) {
return <code>{value}</code>;
},
charsets: function Charsets({ value }) {
const { t } = useTranslation();
const charsetLabels = {
number: t('Number', { ns: NAMESPACE }),
lowercase: t('Lowercase letters', { ns: NAMESPACE }),
uppercase: t('Uppercase letters', { ns: NAMESPACE }),
symbol: t('Symbols', { ns: NAMESPACE })
};
return <code>{value?.map(charset => charsetLabels[charset]).join(', ') || t('Number', { ns: NAMESPACE })}</code>;
},
},
fieldset: {
length: {
type: 'number',
title: `{{t("Length", { ns: "${NAMESPACE}" })}}`,
description: `{{t("Will generate random characters with specified length.", { ns: "${NAMESPACE}" })}}`,
'x-decorator': 'FormItem',
'x-component': 'InputNumber',
'x-component-props': {
min: 1,
max: 32,
},
required: true,
default: 6,
},
charsets: {
type: 'array',
title: `{{t("Character sets", { ns: "${NAMESPACE}" })}}`,
description: `{{t("Select character sets to generate random characters.", { ns: "${NAMESPACE}" })}}`,
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
mode: 'multiple',
allowClear: false,
},
enum: [
{ value: 'number', label: `{{t("Number", { ns: "${NAMESPACE}" })}}` },
{ value: 'lowercase', label: `{{t("Lowercase letters", { ns: "${NAMESPACE}" })}}` },
{ value: 'uppercase', label: `{{t("Uppercase letters", { ns: "${NAMESPACE}" })}}` },
{ value: 'symbol', label: `{{t("Symbols", { ns: "${NAMESPACE}" })}}` }
],
required: true,
default: ['number'],
'x-validator': {
minItems: 1,
message: `{{t("At least one character set should be selected", { ns: "${NAMESPACE}" })}}`
}
},
},
defaults: {
length: 6,
charsets: ['number'],
},
},
integer: {
title: `{{t("Autoincrement", { ns: "${NAMESPACE}" })}}`,
optionRenders: {

View File

@ -24,5 +24,14 @@
"Monthly": "每月",
"Yearly": "每年",
"Operations": "操作",
"Customize": "自定义"
"Customize": "自定义",
"Random character": "随机字符",
"Length": "长度",
"Will generate random characters with specified length.": "将生成指定长度的随机字符。",
"Character sets": "字符集",
"Select character sets to generate random characters.": "选择用于生成随机字符的字符集。",
"Number": "数字",
"Lowercase letters": "小写字母",
"Uppercase letters": "大写字母",
"Symbols": "符号"
}

View File

@ -295,6 +295,79 @@ sequencePatterns.register('date', {
},
});
// 字符集常量定义
const CHAR_SETS = {
number: '0123456789',
lowercase: 'abcdefghijklmnopqrstuvwxyz',
uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
// 符号只保留常用且安全的符号,有需要的可以自己加比如[]{}|;:,.<>放在链接或者文件名里容易出问题的字符
symbol: '!@#$%^&*_-+'
} as const;
interface RandomCharOptions {
length?: number;
charsets?: Array<keyof typeof CHAR_SETS>;
}
sequencePatterns.register('randomChar', {
validate(options?: RandomCharOptions) {
if (!options?.length || options.length < 1) {
return 'options.length should be configured as a positive integer';
}
if (!options?.charsets || options.charsets.length === 0) {
return 'At least one character set should be selected';
}
if (options.charsets.some(charset => !CHAR_SETS[charset])) {
return 'Invalid charset selected';
}
return null;
},
generate(instance: any, options: RandomCharOptions) {
const {
length = 6,
charsets = ['number']
} = options;
const chars = [...new Set(
charsets.reduce((acc, charset) => acc + CHAR_SETS[charset], '')
)];
const getRandomChar = () => {
const randomIndex = Math.floor(Math.random() * chars.length);
return chars[randomIndex];
};
return Array.from({ length }, () => getRandomChar()).join('');
},
batchGenerate(instances: any[], values: string[], options: RandomCharOptions) {
instances.forEach((instance, i) => {
values[i] = sequencePatterns.get('randomChar').generate.call(this, instance, options);
});
},
getLength(options: RandomCharOptions) {
return options.length || 6;
},
getMatcher(options: RandomCharOptions) {
const pattern = [...new Set(
(options.charsets || ['number']).reduce((acc, charset) => {
switch (charset) {
case 'number': return acc + '0-9';
case 'lowercase': return acc + 'a-z';
case 'uppercase': return acc + 'A-Z';
case 'symbol': return acc + CHAR_SETS.symbol.replace('-', '').replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '-';
default: return acc;
}
}, '')
)].join('');
return `[${pattern}]{${options.length || 6}}`;
}
});
interface PatternConfig {
type: string;
title?: string;