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:
parent
dacc521c1c
commit
c4c6a03f61
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user