feat: 支持网站目标分组轻量管理(新增、编辑、描述展示),不修改和不提交倍率
This commit is contained in:
@@ -217,6 +217,7 @@ export interface WebsiteGroup {
|
||||
id: string
|
||||
name: string
|
||||
rate_multiplier: string | null
|
||||
description?: string | null
|
||||
raw: Record<string, any>
|
||||
}
|
||||
|
||||
@@ -336,6 +337,8 @@ export const websitesApi = {
|
||||
delete: (id: number) => api.delete(`/api/websites/${id}`),
|
||||
test: (id: number) => api.post<{ success: boolean; message: string; detail?: string }>(`/api/websites/${id}/test`),
|
||||
groups: (id: number) => api.get<WebsiteGroup[]>(`/api/websites/${id}/groups`),
|
||||
createGroup: (id: number, data: { name: string; description?: string | null }) => api.post<any>(`/api/websites/${id}/groups`, data),
|
||||
updateGroup: (id: number, groupId: string, data: { name: string; description?: string | null }) => api.put<any>(`/api/websites/${id}/groups/${groupId}`, data),
|
||||
importGroupsFromUpstream: (id: number, upstreamId: number, data: { group_ids: string[]; name_prefix: string }) =>
|
||||
api.post<{ success: boolean; message: string; items: ImportGroupItem[] }>(`/api/websites/${id}/groups/import-from-upstream/${upstreamId}`, data),
|
||||
syncImportedUpstreamKeys: (id: number, data: { upstream_id: number }) =>
|
||||
|
||||
@@ -70,16 +70,19 @@
|
||||
<el-option v-for="site in websites" :key="site.id" :label="site.name" :value="site.id" />
|
||||
</el-select>
|
||||
<el-button size="small" :disabled="!selectedWebsite" :loading="groupsLoading" @click="loadWebsiteGroups">拉取分组</el-button>
|
||||
<el-button size="small" type="primary" :disabled="!selectedWebsite" @click="openGroupCreate">新增分组</el-button>
|
||||
</div>
|
||||
<el-table :data="sortedWebsiteGroups" v-loading="groupsLoading" row-key="id" size="small" style="width:100%">
|
||||
<el-table-column prop="name" label="分组" min-width="150" />
|
||||
<el-table-column prop="id" label="ID" min-width="130" />
|
||||
<el-table-column prop="description" label="描述" min-width="150" />
|
||||
<el-table-column label="倍率" width="100">
|
||||
<template #default="{ row }"><span class="rate-value">{{ row.rate_multiplier ?? '—' }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90">
|
||||
<el-table-column label="操作" width="140">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" text :disabled="!selectedWebsite" @click="openBindingCreate(selectedWebsite, row)">绑定</el-button>
|
||||
<el-button size="small" text :disabled="!selectedWebsite" @click="openGroupEdit(row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -307,6 +310,30 @@
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 新增/编辑分组弹窗 -->
|
||||
<el-dialog
|
||||
v-model="groupFormVisible"
|
||||
:title="groupFormTitle"
|
||||
width="450px"
|
||||
destroy-on-close
|
||||
class="custom-theme-dialog"
|
||||
>
|
||||
<el-form :model="groupForm" :rules="groupFormRules" ref="groupFormRef" label-width="80px">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="groupForm.name" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="groupForm.description" type="textarea" :rows="3" placeholder="请输入描述/备注(可选)" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="groupFormVisible = false" class="btn-cancel">取消</el-button>
|
||||
<el-button type="primary" :loading="groupFormSaving" @click="saveWebsiteGroup" class="btn-save">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 选择上游分组弹窗 -->
|
||||
<el-dialog v-model="groupSelectVisible" title="选择上游分组" width="min(85vw, 1200px)" destroy-on-close class="group-select-dialog custom-theme-dialog">
|
||||
<!-- 搜索和倍率筛选条 -->
|
||||
@@ -851,6 +878,22 @@ const importGroupsForm = ref({
|
||||
})
|
||||
const importGroupResults = ref<ImportGroupItem[]>([])
|
||||
|
||||
const groupFormVisible = ref(false)
|
||||
const groupFormSaving = ref(false)
|
||||
const editingGroupId = ref<string | null>(null)
|
||||
const groupFormRef = ref<FormInstance>()
|
||||
const groupForm = ref({
|
||||
name: '',
|
||||
description: '',
|
||||
})
|
||||
const groupFormRules = {
|
||||
name: [{ required: true, message: '请输入分组名称', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
const groupFormTitle = computed(() => {
|
||||
return editingGroupId.value ? '编辑分组' : '新增分组'
|
||||
})
|
||||
|
||||
const importAccountsDialog = ref(false)
|
||||
const importAccountsForm = ref({
|
||||
website_id: 0,
|
||||
@@ -1255,6 +1298,56 @@ function onSourceGroupsChange(values: string[]) {
|
||||
bindingForm.value.source_groups = values.map(value => options.get(value)).filter((item): item is BindingSourceGroup => Boolean(item))
|
||||
}
|
||||
|
||||
function openGroupCreate() {
|
||||
editingGroupId.value = null
|
||||
groupForm.value = {
|
||||
name: '',
|
||||
description: '',
|
||||
}
|
||||
groupFormVisible.value = true
|
||||
}
|
||||
|
||||
function openGroupEdit(row: WebsiteGroup) {
|
||||
editingGroupId.value = row.id
|
||||
groupForm.value = {
|
||||
name: row.name,
|
||||
description: row.description || '',
|
||||
}
|
||||
groupFormVisible.value = true
|
||||
}
|
||||
|
||||
async function saveWebsiteGroup() {
|
||||
if (!selectedWebsite.value) return
|
||||
const websiteId = selectedWebsite.value.id
|
||||
if (!groupFormRef.value) return
|
||||
|
||||
await groupFormRef.value.validate(async (valid) => {
|
||||
if (!valid) return
|
||||
groupFormSaving.value = true
|
||||
try {
|
||||
if (editingGroupId.value) {
|
||||
await websitesApi.updateGroup(websiteId, editingGroupId.value, {
|
||||
name: groupForm.value.name,
|
||||
description: groupForm.value.description,
|
||||
})
|
||||
ElMessage.success('编辑成功')
|
||||
} else {
|
||||
await websitesApi.createGroup(websiteId, {
|
||||
name: groupForm.value.name,
|
||||
description: groupForm.value.description,
|
||||
})
|
||||
ElMessage.success('新增成功')
|
||||
}
|
||||
groupFormVisible.value = false
|
||||
await loadWebsiteGroups()
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e.response?.data?.detail || e.message || '保存失败')
|
||||
} finally {
|
||||
groupFormSaving.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function saveBinding() {
|
||||
if (!bindingForm.value.source_groups.length) {
|
||||
ElMessage.error('请选择至少一个监听上游分组')
|
||||
|
||||
Reference in New Issue
Block a user