mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
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:
parent
0b6ed37fa4
commit
6c922ba7e1
@ -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: {
|
||||
|
@ -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": "符号"
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user