feat: add duplicate key removal function when edit or add new channel

This commit is contained in:
HynoR
2025-09-21 17:26:56 +09:00
parent 7c27558de9
commit 2a54e989b4

View File

@@ -802,7 +802,9 @@ const EditChannelModal = (props) => {
delete localInputs.key; delete localInputs.key;
} }
} else { } else {
localInputs.key = batch ? JSON.stringify(keys) : JSON.stringify(keys[0]); localInputs.key = batch
? JSON.stringify(keys)
: JSON.stringify(keys[0]);
} }
} }
} }
@@ -899,6 +901,56 @@ const EditChannelModal = (props) => {
} }
}; };
// 密钥去重函数
const deduplicateKeys = () => {
const currentKey = formApiRef.current?.getValue('key') || inputs.key || '';
if (!currentKey.trim()) {
showInfo(t('请先输入密钥'));
return;
}
// 按行分割密钥
const keyLines = currentKey.split('\n');
const beforeCount = keyLines.length;
// 使用哈希表去重,保持原有顺序
const keySet = new Set();
const deduplicatedKeys = [];
keyLines.forEach((line) => {
const trimmedLine = line.trim();
if (trimmedLine && !keySet.has(trimmedLine)) {
keySet.add(trimmedLine);
deduplicatedKeys.push(trimmedLine);
}
});
const afterCount = deduplicatedKeys.length;
const deduplicatedKeyText = deduplicatedKeys.join('\n');
// 更新表单和状态
if (formApiRef.current) {
formApiRef.current.setValue('key', deduplicatedKeyText);
}
handleInputChange('key', deduplicatedKeyText);
// 显示去重结果
const message = t(
'去重完成:去重前 {{before}} 个密钥,去重后 {{after}} 个密钥',
{
before: beforeCount,
after: afterCount,
},
);
if (beforeCount === afterCount) {
showInfo(t('未发现重复密钥'));
} else {
showSuccess(message);
}
};
const addCustomModels = () => { const addCustomModels = () => {
if (customModel.trim() === '') return; if (customModel.trim() === '') return;
const modelArray = customModel.split(',').map((model) => model.trim()); const modelArray = customModel.split(',').map((model) => model.trim());
@@ -994,24 +1046,41 @@ const EditChannelModal = (props) => {
</Checkbox> </Checkbox>
)} )}
{batch && ( {batch && (
<Checkbox <>
disabled={isEdit} <Checkbox
checked={multiToSingle} disabled={isEdit}
onChange={() => { checked={multiToSingle}
setMultiToSingle((prev) => !prev); onChange={() => {
setInputs((prev) => { setMultiToSingle((prev) => {
const newInputs = { ...prev }; const nextValue = !prev;
if (!multiToSingle) { setInputs((prevInputs) => {
newInputs.multi_key_mode = multiKeyMode; const newInputs = { ...prevInputs };
} else { if (nextValue) {
delete newInputs.multi_key_mode; newInputs.multi_key_mode = multiKeyMode;
} } else {
return newInputs; delete newInputs.multi_key_mode;
}); }
}} return newInputs;
> });
{t('密钥聚合模式')} return nextValue;
</Checkbox> });
}}
>
{t('密钥聚合模式')}
</Checkbox>
{inputs.type !== 41 && (
<Button
size='small'
type='tertiary'
theme='outline'
onClick={deduplicateKeys}
style={{ textDecoration: 'underline' }}
>
{t('密钥去重')}
</Button>
)}
</>
)} )}
</Space> </Space>
) : null; ) : null;
@@ -1198,7 +1267,10 @@ const EditChannelModal = (props) => {
value={inputs.vertex_key_type || 'json'} value={inputs.vertex_key_type || 'json'}
onChange={(value) => { onChange={(value) => {
// 更新设置中的 vertex_key_type // 更新设置中的 vertex_key_type
handleChannelOtherSettingsChange('vertex_key_type', value); handleChannelOtherSettingsChange(
'vertex_key_type',
value,
);
// 切换为 api_key 时,关闭批量与手动/文件切换,并清理已选文件 // 切换为 api_key 时,关闭批量与手动/文件切换,并清理已选文件
if (value === 'api_key') { if (value === 'api_key') {
setBatch(false); setBatch(false);
@@ -1218,7 +1290,8 @@ const EditChannelModal = (props) => {
/> />
)} )}
{batch ? ( {batch ? (
inputs.type === 41 && (inputs.vertex_key_type || 'json') === 'json' ? ( inputs.type === 41 &&
(inputs.vertex_key_type || 'json') === 'json' ? (
<Form.Upload <Form.Upload
field='vertex_files' field='vertex_files'
label={t('密钥文件 (.json)')} label={t('密钥文件 (.json)')}
@@ -1254,7 +1327,7 @@ const EditChannelModal = (props) => {
autoComplete='new-password' autoComplete='new-password'
onChange={(value) => handleInputChange('key', value)} onChange={(value) => handleInputChange('key', value)}
extraText={ extraText={
<div className='flex items-center gap-2'> <div className='flex items-center gap-2 flex-wrap'>
{isEdit && {isEdit &&
isMultiKeyChannel && isMultiKeyChannel &&
keyMode === 'append' && ( keyMode === 'append' && (
@@ -1282,7 +1355,8 @@ const EditChannelModal = (props) => {
) )
) : ( ) : (
<> <>
{inputs.type === 41 && (inputs.vertex_key_type || 'json') === 'json' ? ( {inputs.type === 41 &&
(inputs.vertex_key_type || 'json') === 'json' ? (
<> <>
{!batch && ( {!batch && (
<div className='flex items-center justify-between mb-3'> <div className='flex items-center justify-between mb-3'>