refactor: remove old project/policy dialogs from IAMUserList

All project management and policy operations now handled in the
unified UserPoliciesView page. Removed unused dialogs, variables,
and functions from IAMUserList.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209 2026-03-28 23:07:16 +08:00
parent dacc521c1c
commit c4c6a03f61

View File

@ -53,7 +53,7 @@
</el-table-column>
<el-table-column label="项目" min-width="80" align="center">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="openProjectsDialog(row)">
<el-button link type="primary" size="small" @click="$router.push(`/iam-users/${row.id}/policies`)">
{{ row.monitored_project_count || 0 }} / {{ (row.projects || []).length }}
</el-button>
</template>
@ -76,7 +76,6 @@
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openProjectsDialog(row)">项目管理</el-dropdown-item>
<el-dropdown-item @click="openConfig(row)">监控配置</el-dropdown-item>
<el-dropdown-item @click="openEditProfile(row)">编辑信息</el-dropdown-item>
<el-dropdown-item @click="toggleVolcLogin(row)">
@ -163,87 +162,6 @@
</template>
</el-dialog>
<!-- Projects Dialog -->
<el-dialog v-model="projectsDialogVisible" :title="`${projectsUser?.username} 关联项目`" width="90%" style="max-width: 900px;">
<div style="margin-bottom:12px; display:flex; gap:8px; align-items:center;">
<el-select v-model="projectToAdd" placeholder="选择火山项目" filterable style="flex:1;"
:loading="volcProjectsLoading">
<el-option v-for="p in volcProjects" :key="p.name" :label="p.display_name || p.name" :value="p.name" />
</el-select>
<el-button @click="loadVolcProjects" :loading="volcProjectsLoading" text>
<el-icon><Refresh /></el-icon>
</el-button>
</div>
<div v-if="projectToAdd" style="margin-bottom:12px;">
<div style="margin-bottom:4px; font-size:13px; color:#606266;">授权策略可多选不选则仅加入监测不授权</div>
<el-checkbox-group v-model="projectPoliciesToAttach">
<el-checkbox label="ArkFullAccess">方舟/Seedance 完整权限</el-checkbox>
<el-checkbox label="ArkExperienceAccess">方舟体验权限API Key 管理需要</el-checkbox>
<el-checkbox label="ArkReadOnlyAccess">方舟只读</el-checkbox>
<el-checkbox label="TOSFullAccess">对象存储完整权限</el-checkbox>
<el-checkbox label="TOSReadOnlyAccess">对象存储只读</el-checkbox>
<el-checkbox label="AccessKeySelfManageAccess">自管理密钥</el-checkbox>
</el-checkbox-group>
<el-button type="primary" @click="handleAddProject" style="margin-top:8px;">确认添加</el-button>
</div>
<div style="margin-bottom:12px;">
<el-button size="small" @click="handleToggleAll(true)">全部开启监测</el-button>
<el-button size="small" @click="handleToggleAll(false)">全部关闭监测</el-button>
</div>
<el-table :data="userProjects" stripe v-loading="projectsDialogLoading" empty-text="暂无关联项目">
<el-table-column prop="project_name" label="项目名" min-width="160" />
<el-table-column prop="display_name" label="显示名" min-width="120" />
<el-table-column label="消费" min-width="100" align="right">
<template #default="{ row }">
<span style="color:#e6a23c;">¥{{ Number(row.current_spending).toLocaleString() }}</span>
</template>
</el-table-column>
<el-table-column label="已授权策略" min-width="180">
<template #default="{ row }">
<el-tag v-for="p in (row.attached_policies || [])" :key="p" size="small"
style="margin:1px 2px;">{{ p }}</el-tag>
<span v-if="!(row.attached_policies || []).length" style="color:#999;font-size:12px;"></span>
</template>
</el-table-column>
<el-table-column label="监测" min-width="70" align="center">
<template #default="{ row }">
<el-switch :model-value="row.monitor_enabled" @change="val => handleToggleProject(row, val)" />
</template>
</el-table-column>
<el-table-column label="操作" width="140" align="center">
<template #default="{ row }">
<el-button size="small" type="primary" text @click="openProjectPolicies(row)">授权</el-button>
<el-button size="small" type="danger" text @click="handleRemoveProject(row)">移除</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!-- Project Policies Dialog -->
<el-dialog v-model="projectPolicyVisible"
:title="`${projectPolicyProject?.project_name} 项目级授权`"
width="90%" style="max-width: 550px;">
<el-alert type="info" :closable="false" style="margin-bottom:12px;">
<template #title>
以下权限仅在 <strong>{{ projectPolicyProject?.project_name }}</strong> 项目范围内生效不影响其他项目
</template>
</el-alert>
<el-checkbox-group v-model="projectPolicySelected">
<div style="display:flex; flex-direction:column; gap:8px;">
<el-checkbox label="ArkFullAccess">方舟/Seedance 完整权限</el-checkbox>
<el-checkbox label="ArkExperienceAccess">方舟体验权限API Key 管理需要</el-checkbox>
<el-checkbox label="ArkReadOnlyAccess">方舟只读</el-checkbox>
<el-checkbox label="TOSFullAccess">对象存储完整权限</el-checkbox>
<el-checkbox label="TOSReadOnlyAccess">对象存储只读</el-checkbox>
<el-checkbox label="AccessKeySelfManageAccess">自管理密钥</el-checkbox>
</div>
</el-checkbox-group>
<template #footer>
<el-button @click="projectPolicyVisible = false">取消</el-button>
<el-button type="primary" @click="handleSaveProjectPolicies" :loading="projectPolicySaving">保存</el-button>
</template>
</el-dialog>
<!-- Set Login Password Dialog -->
<el-dialog v-model="loginPwdVisible" :title="`设置 ${loginPwdUser?.username} 的 AirGate 登录密码`"
width="90%" style="max-width: 450px;">
@ -284,40 +202,6 @@
</el-table>
</el-dialog>
<!-- Policies Dialog (Global) -->
<el-dialog v-model="policiesVisible" :title="`${policiesUser?.username} 全局权限策略`" width="90%" style="max-width: 850px;">
<el-alert type="info" :closable="false" style="margin-bottom:12px;">
<template #title>
<strong>全局策略</strong>对所有项目生效如需限定到某个项目请在项目管理 授权中设置项目级策略
</template>
</el-alert>
<div style="margin-bottom:12px; display:flex; gap:8px;">
<el-select v-model="policyToAttach" placeholder="选择要附加的策略" filterable style="flex:1;">
<el-option-group label="常用策略">
<el-option v-for="opt in globalPolicyOptions" :key="opt.value"
:value="opt.value" :label="opt.label"
:disabled="policies.some(p => p.PolicyName === opt.value)" />
</el-option-group>
</el-select>
<el-button type="primary" @click="handleAttachPolicy" :disabled="!policyToAttach">附加</el-button>
</div>
<el-table :data="policies" stripe v-loading="policiesLoading" empty-text="暂无策略">
<el-table-column prop="PolicyName" label="策略名" min-width="200" />
<el-table-column prop="PolicyType" label="类型" width="80">
<template #default="{ row }">
<el-tag :type="row.PolicyType === 'Custom' ? 'warning' : 'info'" size="small">
{{ row.PolicyType === 'Custom' ? '自定义' : '系统' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="Description" label="说明" min-width="200" />
<el-table-column label="操作" width="80">
<template #default="{ row }">
<el-button size="small" type="danger" text @click="handleDetachPolicy(row)">移除</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!-- Create User Dialog -->
<el-dialog v-model="showCreate" title="创建子账号" width="90%" style="max-width: 580px;">
@ -488,16 +372,6 @@ async function handleEnable(row) {
}
}
// Global policy options
const globalPolicyOptions = [
{ value: 'ArkFullAccess', label: 'ArkFullAccess方舟/Seedance 完整权限)' },
{ value: 'ArkExperienceAccess', label: 'ArkExperienceAccess方舟体验权限' },
{ value: 'ArkReadOnlyAccess', label: 'ArkReadOnlyAccess方舟只读' },
{ value: 'TOSFullAccess', label: 'TOSFullAccess对象存储完整权限' },
{ value: 'TOSReadOnlyAccess', label: 'TOSReadOnlyAccess对象存储只读' },
{ value: 'AccessKeySelfManageAccess', label: 'AccessKeySelfManageAccess自管理密钥' },
]
// Toggle Volcengine console login
async function toggleVolcLogin(row) {
const action = row.volc_login_allowed ? '关闭' : '开启'
@ -547,22 +421,9 @@ async function handleEditProfile() {
}
}
// Policies
const policiesVisible = ref(false)
const policiesUser = ref(null)
const policies = ref([])
const policiesLoading = ref(false)
const policyToAttach = ref('')
// (Policies dialog removed - now in UserPoliciesView)
// Projects dialog
const projectsDialogVisible = ref(false)
const projectsUser = ref(null)
const userProjects = ref([])
const projectsDialogLoading = ref(false)
const projectToAdd = ref('')
const projectPoliciesToAttach = ref([])
const volcProjects = ref([])
const volcProjectsLoading = ref(false)
// (Projects dialog removed - now in UserPoliciesView)
// --- Allocate ---
const maxDeduct = computed(() => {
@ -618,126 +479,6 @@ function openConfig(row) {
configVisible.value = true
}
// --- Projects Dialog ---
async function loadVolcProjects() {
volcProjectsLoading.value = true
try {
const { data } = await api.get('/api/v1/projects/')
volcProjects.value = data
} catch (e) {
ElMessage.error(e.response?.data?.message || '获取火山项目列表失败')
} finally {
volcProjectsLoading.value = false
}
}
async function openProjectsDialog(row) {
projectsUser.value = row
projectsDialogVisible.value = true
projectToAdd.value = ''
await loadUserProjects(row.id)
if (volcProjects.value.length === 0) loadVolcProjects()
}
async function loadUserProjects(userId) {
projectsDialogLoading.value = true
try {
const { data } = await api.get(`/api/v1/iam-users/${userId}/projects/`)
userProjects.value = data
} catch (e) {
ElMessage.error('获取项目列表失败')
userProjects.value = []
} finally {
projectsDialogLoading.value = false
}
}
async function handleAddProject() {
if (!projectToAdd.value) return
try {
const { data } = await api.post(`/api/v1/iam-users/${projectsUser.value.id}/projects/add/`, {
project_name: projectToAdd.value,
policies: projectPoliciesToAttach.value,
})
const policyMsg = data.attached_policies?.length
? `,已授权 ${data.attached_policies.length} 个策略`
: ''
ElMessage.success(`已添加${policyMsg}`)
projectToAdd.value = ''
projectPoliciesToAttach.value = []
await loadUserProjects(projectsUser.value.id)
await loadUsers()
} catch (e) {
ElMessage.error(e.response?.data?.message || '添加失败')
}
}
async function handleToggleProject(row, val) {
try {
await api.put(`/api/v1/iam-users/${projectsUser.value.id}/projects/${row.id}/`, {
monitor_enabled: val,
})
await loadUserProjects(projectsUser.value.id)
await loadUsers()
} catch (e) {
ElMessage.error('切换失败')
}
}
// === Project Policies ===
const projectPolicyVisible = ref(false)
const projectPolicyProject = ref(null)
const projectPolicySelected = ref([])
const projectPolicySaving = ref(false)
function openProjectPolicies(row) {
projectPolicyProject.value = row
projectPolicySelected.value = [...(row.attached_policies || [])]
projectPolicyVisible.value = true
}
async function handleSaveProjectPolicies() {
projectPolicySaving.value = true
try {
const { data } = await api.put(
`/api/v1/iam-users/${projectsUser.value.id}/projects/${projectPolicyProject.value.id}/policies/`,
{ policies: projectPolicySelected.value }
)
ElMessage.success(data.message || '已更新')
projectPolicyVisible.value = false
await loadUserProjects(projectsUser.value.id)
} catch (e) {
ElMessage.error(e.response?.data?.message || '更新失败')
} finally {
projectPolicySaving.value = false
}
}
async function handleRemoveProject(row) {
await ElMessageBox.confirm(`确定移除项目 "${row.project_name}" 吗?`, '确认', { type: 'warning' })
try {
await api.delete(`/api/v1/iam-users/${projectsUser.value.id}/projects/${row.id}/delete/`)
ElMessage.success('已移除')
await loadUserProjects(projectsUser.value.id)
await loadUsers()
} catch (e) {
ElMessage.error('移除失败')
}
}
async function handleToggleAll(enable) {
try {
const { data } = await api.post(`/api/v1/iam-users/${projectsUser.value.id}/projects/toggle-all/`, {
monitor_enabled: enable,
})
ElMessage.success(data.message)
await loadUserProjects(projectsUser.value.id)
await loadUsers()
} catch (e) {
ElMessage.error('操作失败')
}
}
function addStep() {
if (!newStep.value || newStep.value < 1 || newStep.value > 99) {
ElMessage.warning('请输入 1-99 之间的百分比')
@ -822,52 +563,6 @@ async function openQuotaHistory(row) {
}
}
// --- Policies ---
async function openPolicies(row) {
policiesUser.value = row
policiesVisible.value = true
policiesLoading.value = true
policyToAttach.value = ''
try {
const { data } = await api.get(`/api/v1/iam-users/${row.id}/policies/`)
policies.value = data.policies || []
} catch (e) {
ElMessage.error(e.response?.data?.message || '获取权限失败')
policies.value = []
} finally {
policiesLoading.value = false
}
}
async function handleAttachPolicy() {
if (!policyToAttach.value) return
try {
await api.post(`/api/v1/iam-users/${policiesUser.value.id}/policies/attach/`, {
policy_name: policyToAttach.value,
policy_type: 'System',
})
ElMessage.success(`已附加 ${policyToAttach.value}`)
policyToAttach.value = ''
await openPolicies(policiesUser.value)
} catch (e) {
ElMessage.error(e.response?.data?.message || '附加失败')
}
}
async function handleDetachPolicy(row) {
await ElMessageBox.confirm(`确定移除策略 "${row.PolicyName}" 吗?`, '确认移除', { type: 'warning' })
try {
await api.post(`/api/v1/iam-users/${policiesUser.value.id}/policies/detach/`, {
policy_name: row.PolicyName,
policy_type: row.PolicyType,
})
ElMessage.success(`已移除 ${row.PolicyName}`)
await openPolicies(policiesUser.value)
} catch (e) {
ElMessage.error(e.response?.data?.message || '移除失败')
}
}
// --- Create User ---
async function handleCreate() {
if (!createForm.value.username) {