✨ feat(ui): add incremental-add feedback & translations for model lists (#1218)
Front-end enhancements around “Add custom models”:
• EditChannel.js / EditTagModal.js
– Skip models that already exist instead of blocking the action.
– Collect actually inserted items and display:
• Success toast: “Added N models: model1, model2 …”
• Info toast when no new model detected.
– Keeps UX smooth while preserving deduplication logic.
• i18n
– en.json: added keys
• "已新增 {{count}} 个模型:{{list}}"
• "未发现新增模型"
– Fixed a broken JSON string containing smart quotes to maintain valid syntax.
Result:
Users can bulk-paste model names; duplicates are silently ignored and the UI clearly lists what was incrementally appended. All messages are fully internationalised.
Closes #1218
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Ability struct {
|
type Ability struct {
|
||||||
@@ -158,7 +159,7 @@ func (channel *Channel) AddAbilities() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, chunk := range lo.Chunk(abilities, 50) {
|
for _, chunk := range lo.Chunk(abilities, 50) {
|
||||||
err := DB.Create(&chunk).Error
|
err := DB.Clauses(clause.OnConflict{DoNothing: true}).Create(&chunk).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -224,7 +225,7 @@ func (channel *Channel) UpdateAbilities(tx *gorm.DB) error {
|
|||||||
|
|
||||||
if len(abilities) > 0 {
|
if len(abilities) > 0 {
|
||||||
for _, chunk := range lo.Chunk(abilities, 50) {
|
for _, chunk := range lo.Chunk(abilities, 50) {
|
||||||
err = tx.Create(&chunk).Error
|
err = tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&chunk).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isNewTx {
|
if isNewTx {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
|
|||||||
@@ -1652,5 +1652,7 @@
|
|||||||
"开启后,仅“消费”和“错误”日志将记录您的客户端 IP 地址": "After enabling, only \"consumption\" and \"error\" logs will record your client IP address",
|
"开启后,仅“消费”和“错误”日志将记录您的客户端 IP 地址": "After enabling, only \"consumption\" and \"error\" logs will record your client IP address",
|
||||||
"只有当用户设置开启IP记录时,才会进行请求和错误类型日志的IP记录": "Only when the user sets IP recording, the IP recording of request and error type logs will be performed",
|
"只有当用户设置开启IP记录时,才会进行请求和错误类型日志的IP记录": "Only when the user sets IP recording, the IP recording of request and error type logs will be performed",
|
||||||
"设置保存成功": "Settings saved successfully",
|
"设置保存成功": "Settings saved successfully",
|
||||||
"设置保存失败": "Settings save failed"
|
"设置保存失败": "Settings save failed",
|
||||||
|
"已新增 {{count}} 个模型:{{list}}": "Added {{count}} models: {{list}}",
|
||||||
|
"未发现新增模型": "No new models were added"
|
||||||
}
|
}
|
||||||
@@ -385,7 +385,7 @@ const EditChannel = (props) => {
|
|||||||
|
|
||||||
let localModels = [...inputs.models];
|
let localModels = [...inputs.models];
|
||||||
let localModelOptions = [...modelOptions];
|
let localModelOptions = [...modelOptions];
|
||||||
let hasError = false;
|
const addedModels = [];
|
||||||
|
|
||||||
modelArray.forEach((model) => {
|
modelArray.forEach((model) => {
|
||||||
if (model && !localModels.includes(model)) {
|
if (model && !localModels.includes(model)) {
|
||||||
@@ -395,17 +395,24 @@ const EditChannel = (props) => {
|
|||||||
text: model,
|
text: model,
|
||||||
value: model,
|
value: model,
|
||||||
});
|
});
|
||||||
} else if (model) {
|
addedModels.push(model);
|
||||||
showError(t('某些模型已存在!'));
|
|
||||||
hasError = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hasError) return;
|
|
||||||
|
|
||||||
setModelOptions(localModelOptions);
|
setModelOptions(localModelOptions);
|
||||||
setCustomModel('');
|
setCustomModel('');
|
||||||
handleInputChange('models', localModels);
|
handleInputChange('models', localModels);
|
||||||
|
|
||||||
|
if (addedModels.length > 0) {
|
||||||
|
showSuccess(
|
||||||
|
t('已新增 {{count}} 个模型:{{list}}', {
|
||||||
|
count: addedModels.length,
|
||||||
|
list: addedModels.join(', '),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
showInfo(t('未发现新增模型'));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ const EditTagModal = (props) => {
|
|||||||
|
|
||||||
let localModels = [...inputs.models];
|
let localModels = [...inputs.models];
|
||||||
let localModelOptions = [...modelOptions];
|
let localModelOptions = [...modelOptions];
|
||||||
let hasError = false;
|
const addedModels = [];
|
||||||
|
|
||||||
modelArray.forEach((model) => {
|
modelArray.forEach((model) => {
|
||||||
// 检查模型是否已存在,且模型名称非空
|
// 检查模型是否已存在,且模型名称非空
|
||||||
@@ -241,18 +241,25 @@ const EditTagModal = (props) => {
|
|||||||
text: model,
|
text: model,
|
||||||
value: model,
|
value: model,
|
||||||
});
|
});
|
||||||
} else if (model) {
|
addedModels.push(model);
|
||||||
showError('某些模型已存在!');
|
|
||||||
hasError = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hasError) return; // 如果有错误则终止操作
|
|
||||||
|
|
||||||
// 更新状态值
|
// 更新状态值
|
||||||
setModelOptions(localModelOptions);
|
setModelOptions(localModelOptions);
|
||||||
setCustomModel('');
|
setCustomModel('');
|
||||||
handleInputChange('models', localModels);
|
handleInputChange('models', localModels);
|
||||||
|
|
||||||
|
if (addedModels.length > 0) {
|
||||||
|
showSuccess(
|
||||||
|
t('已新增 {{count}} 个模型:{{list}}', {
|
||||||
|
count: addedModels.length,
|
||||||
|
list: addedModels.join(', '),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
showInfo(t('未发现新增模型'));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user