diff --git a/dashboard/src/components/shared/ItemCard.vue b/dashboard/src/components/shared/ItemCard.vue
index 6152c531f..14453ae7a 100644
--- a/dashboard/src/components/shared/ItemCard.vue
+++ b/dashboard/src/components/shared/ItemCard.vue
@@ -4,28 +4,28 @@
{{ getItemTitle() }}
-
{{ getItemEnabled() ? t('core.common.itemCard.enabled') : t('core.common.itemCard.disabled') }}
-
+
-
+
{{ t('core.common.itemCard.edit') }}
+
+ {{ t('core.common.itemCard.copy') }}
+
@@ -83,9 +92,13 @@ export default {
loading: {
type: Boolean,
default: false
+ },
+ showCopyButton: {
+ type: Boolean,
+ default: false
}
},
- emits: ['toggle-enabled', 'delete', 'edit'],
+ emits: ['toggle-enabled', 'delete', 'edit', 'copy'],
methods: {
getItemTitle() {
return this.item[this.titleField];
diff --git a/dashboard/src/i18n/locales/zh-CN/core/common.json b/dashboard/src/i18n/locales/zh-CN/core/common.json
index 5405c15f6..9a7f5eeaf 100644
--- a/dashboard/src/i18n/locales/zh-CN/core/common.json
+++ b/dashboard/src/i18n/locales/zh-CN/core/common.json
@@ -73,6 +73,7 @@
"disabled": "已禁用",
"delete": "删除",
"edit": "编辑",
+ "copy": "复制",
"noData": "暂无数据"
}
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/dashboard/src/views/ProviderPage.vue b/dashboard/src/views/ProviderPage.vue
index 9915f0112..b36c0db21 100644
--- a/dashboard/src/views/ProviderPage.vue
+++ b/dashboard/src/views/ProviderPage.vue
@@ -56,14 +56,16 @@
-
+ @delete="deleteProvider"
+ @edit="configExistingProvider"
+ @copy="copyProvider"
+ :show-copy-button="true">
@@ -95,7 +97,7 @@
{{ tm('availability.noData') }}
-
+
@@ -113,7 +115,7 @@
>
{{ status.id }}
-
+
{{ getStatusText(status.status) }}
@@ -348,10 +350,10 @@ export default {
save_message_success: "success",
showConsole: false,
-
+
// 显示状态部分
showStatus: false,
-
+
// 供应商状态相关
providerStatuses: [],
loadingStatus: false,
@@ -437,7 +439,7 @@ export default {
}
};
},
-
+
// 根据选择的标签过滤提供商列表
filteredProviders() {
if (!this.config_data.provider || this.activeProviderTypeTab === 'all') {
@@ -449,7 +451,7 @@ export default {
if (provider.provider_type) {
return provider.provider_type === this.activeProviderTypeTab;
}
-
+
// 否则使用映射关系
const mappedType = this.oldVersionProviderTypeMapping[provider.type];
return mappedType === this.activeProviderTypeTab;
@@ -657,6 +659,40 @@ export default {
}
},
+ async copyProvider(providerToCopy) {
+ console.log('copyProvider triggered for:', providerToCopy);
+ // 1. 创建深拷贝
+ const newProviderConfig = JSON.parse(JSON.stringify(providerToCopy));
+
+ // 2. 生成唯一的 ID
+ const generateUniqueId = (baseId) => {
+ let newId = `${baseId}_copy`;
+ let counter = 1;
+ const existingIds = this.config_data.provider.map(p => p.id);
+ while (existingIds.includes(newId)) {
+ newId = `${baseId}_copy_${counter}`;
+ counter++;
+ }
+ return newId;
+ };
+ newProviderConfig.id = generateUniqueId(providerToCopy.id);
+
+ // 3. 设置为禁用状态,等待用户手动开启
+ newProviderConfig.enable = false;
+
+ this.loading = true;
+ try {
+ // 4. 调用后端接口创建
+ const res = await axios.post('/api/config/provider/new', newProviderConfig);
+ this.showSuccess(res.data.message || `成功复制并创建了 ${newProviderConfig.id}`);
+ this.getConfig(); // 5. 刷新列表
+ } catch (err) {
+ this.showError(err.response?.data?.message || err.message);
+ } finally {
+ this.loading = false;
+ }
+ },
+
deleteProvider(provider) {
if (confirm(this.tm('messages.confirm.delete', { id: provider.id }))) {
axios.post('/api/config/provider/delete', { id: provider.id }).then((res) => {
@@ -694,14 +730,14 @@ export default {
this.save_message_success = "error";
this.save_message_snack = true;
},
-
+
// 获取供应商状态
async fetchProviderStatus() {
if (this.loadingStatus) return;
this.loadingStatus = true;
this.showStatus = true; // 自动展开状态部分
-
+
// 1. 立即初始化UI为pending状态
this.providerStatuses = this.config_data.provider.map(p => ({
id: p.id,