This commit is contained in:
张成
2026-04-01 10:37:51 +08:00
parent 494555a6e1
commit 7199c6b5cf
10 changed files with 187 additions and 17 deletions

View File

@@ -54,11 +54,49 @@
</Form>
</Modal>
<Modal v-model="detailVisible" title="用户详情" width="720" footer-hide>
<p v-if="detail">Token 数量{{ detail.tokenCount }}</p>
<Modal v-model="detailVisible" title="用户详情" width="800" footer-hide>
<p v-if="detail" class="mb8">Token 数量{{ detail.tokenCount }}</p>
<p v-if="detail && detail.tokens && detail.tokens.length" class="sub-title">API Token</p>
<Table
v-if="detail && detail.tokens && detail.tokens.length"
:columns="tokenCols"
:data="detail.tokens"
size="small"
border
highlight-row
class="mb16"
@on-row-click="onTokenRowClick"
/>
<p v-if="detail && detail.subscriptions && detail.subscriptions.length" class="sub-title">订阅记录</p>
<Table v-if="detail && detail.subscriptions" :columns="subCols" :data="detail.subscriptions" size="small"
border />
</Modal>
<Modal v-model="tokenListVisible" :title="tokenListTitle" width="820" footer-hide>
<p v-if="tokenListRows.length" class="text-muted mb8">点击表格某一行查看该 Token 详情明文不可查需重新创建</p>
<Table
v-if="tokenListRows.length"
:columns="tokenCols"
:data="tokenListRows"
size="small"
border
highlight-row
@on-row-click="onTokenRowClick"
/>
<p v-else class="text-muted">暂无 Token</p>
</Modal>
<Modal v-model="tokenDetailVisible" title="Token 详情" width="520" footer-hide>
<div v-if="selectedToken" class="token-detail">
<p><span class="label">ID</span>{{ selectedToken.id }}</p>
<p><span class="label">名称</span>{{ selectedToken.token_name }}</p>
<p><span class="label">用户</span>{{ selectedToken.user_id }}</p>
<p><span class="label">套餐</span>{{ selectedToken.plan_id != null ? selectedToken.plan_id : '—' }}</p>
<p><span class="label">状态</span>{{ selectedToken.status }}</p>
<p><span class="label">过期时间</span>{{ selectedToken.expire_at || '—' }}</p>
<p><span class="label">最后使用</span>{{ selectedToken.last_used_at || '—' }}</p>
</div>
</Modal>
</div>
</template>
@@ -85,6 +123,11 @@ export default {
},
detailVisible: false,
detail: null,
tokenListVisible: false,
tokenListRows: [],
tokenListUserName: '',
tokenDetailVisible: false,
selectedToken: null,
subCols: [
{ title: 'ID', key: 'id', width: 80 },
{ title: '套餐ID', key: 'plan_id', width: 90 },
@@ -102,6 +145,25 @@ export default {
{ title: '手机', key: 'mobile', width: 130 },
{ title: '公司', key: 'company_name', minWidth: 140 },
{ title: '状态', key: 'status', width: 90 },
{
title: 'API Token',
key: 'token_count',
width: 130,
render: (h, p) => {
const n = p.row.token_count != null ? Number(p.row.token_count) : 0
return h('div', [
h('span', { class: { mr8: true } }, String(n)),
h(
'Button',
{
props: { type: 'primary', size: 'small', ghost: true },
on: { click: () => this.openTokenList(p.row) },
},
'查看'
),
])
},
},
{
title: '操作',
key: 'a',
@@ -167,6 +229,20 @@ export default {
},
]
},
tokenCols() {
return [
{ title: 'ID', key: 'id', width: 72 },
{ title: '名称', key: 'token_name', minWidth: 100 },
{ title: '套餐', key: 'plan_id', width: 80 },
{ title: '状态', key: 'status', width: 90 },
{ title: '过期', key: 'expire_at', minWidth: 150 },
{ title: '最后使用', key: 'last_used_at', minWidth: 150 },
]
},
tokenListTitle() {
const name = this.tokenListUserName || ''
return name ? `Token 列表 — ${name}` : 'Token 列表'
},
},
mounted() {
this.load(1)
@@ -230,6 +306,20 @@ export default {
this.$Message.error((res && res.message) || '加载详情失败')
}
},
async openTokenList(row) {
const res = await userServer.detail(row.id)
if (res && res.code === 0) {
this.tokenListRows = res.data.tokens || []
this.tokenListUserName = row.name || String(row.id)
this.tokenListVisible = true
} else {
this.$Message.error((res && res.message) || '加载 Token 失败')
}
},
onTokenRowClick(row) {
this.selectedToken = row
this.tokenDetailVisible = true
},
doDisable(row) {
this.$Modal.confirm({
title: '禁用用户',
@@ -340,4 +430,31 @@ export default {
margin-top: 12px;
text-align: right;
}
.mb8 {
margin-bottom: 8px;
}
.mb16 {
margin-bottom: 16px;
}
.sub-title {
font-weight: 600;
margin: 10px 0 8px;
}
.text-muted {
color: #808695;
}
.mr8 {
margin-right: 8px;
}
.token-detail .label {
display: inline-block;
width: 88px;
color: #808695;
}
</style>