AirGate/frontend/src/views/portal/MyKeysView.vue
seaislee1209 3d2b332657 feat: add sub-account portal (login + my keys view)
- Login page: toggle between admin/sub-account login
- Auth store: isAdmin/isIamUser computed properties
- MainLayout: role-based sidebar (admin sees all, sub-account sees only my keys)
- HomeRedirect: auto-redirect based on role
- MyKeysView: sub-account can view/reveal their own API Keys
- Portal is completely isolated from admin functions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:33:02 +08:00

78 lines
2.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div style="max-width: 1000px; margin: 0 auto;">
<h2 style="margin-bottom: 16px;">我的 API Key</h2>
<el-table :data="keys" stripe v-loading="loading" style="width: 100%;"
empty-text="暂无 API Key请联系管理员分配">
<el-table-column prop="project_name" label="所属项目" min-width="150" />
<el-table-column prop="key_name" label="名称/用途" min-width="180" />
<el-table-column label="API Key" min-width="260">
<template #default="{ row }">
<template v-if="revealedKeys[row.id]">
<code style="font-size: 13px; color: #409eff; word-break: break-all;">
{{ revealedKeys[row.id] }}
</code>
<el-button size="small" text @click="copyKey(revealedKeys[row.id])"
style="margin-left: 4px;">复制</el-button>
</template>
<template v-else>
<code style="color: #999;">{{ row.api_key_hint }}</code>
<el-button size="small" text type="primary" @click="handleReveal(row)"
style="margin-left: 4px;">查看</el-button>
</template>
</template>
</el-table-column>
<el-table-column label="状态" width="90">
<template #default="{ row }">
<el-tag :type="row.status === 'active' ? 'success' : 'danger'" size="small">
{{ row.status === 'active' ? '启用' : '停用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
</el-table>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import api from '../../api'
const keys = ref([])
const loading = ref(false)
const revealedKeys = reactive({})
async function loadKeys() {
loading.value = true
try {
const { data } = await api.get('/api/v1/auth/iam/my-keys/')
keys.value = data
} catch (e) {
keys.value = []
} finally {
loading.value = false
}
}
async function handleReveal(row) {
try {
const { data } = await api.get(`/api/v1/auth/iam/my-keys/${row.id}/reveal/`)
revealedKeys[row.id] = data.api_key
} catch (e) {
ElMessage.error('获取 Key 失败')
}
}
async function copyKey(key) {
try {
await navigator.clipboard.writeText(key)
ElMessage.success('已复制')
} catch {
ElMessage.error('复制失败')
}
}
onMounted(loadKeys)
</script>