feat: 在授权管理表格中显示详细的卡密类型信息

- 每个卡密类型单独显示一行

- 显示授权状态图标(Check/X)

- 使用 rowspan 合并应用名称、余额、状态和操作列

- 改进暗色模式样式
This commit is contained in:
2026-05-09 04:15:41 +08:00
parent 82e62ab3aa
commit f650efc7a1
+51 -31
View File
@@ -415,44 +415,64 @@ onMounted(() => {
<thead class="bg-muted/50">
<tr>
<th class="text-left p-3 font-medium">应用</th>
<th class="text-left p-3 font-medium">卡密权限</th>
<th class="text-left p-3 font-medium">卡密类型</th>
<th class="text-left p-3 font-medium">余额</th>
<th class="text-left p-3 font-medium">状态</th>
<th class="text-right p-3 font-medium w-20">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="app in authApps" :key="app.id" class="border-t">
<td class="p-3 font-medium">{{ app.app_name }}</td>
<td class="p-3">
<div v-if="app.card_types && app.card_types.length > 0" class="flex flex-wrap gap-1">
<span
v-for="ct in app.card_types"
:key="ct.card_type_id"
class="inline-flex items-center px-2 py-0.5 rounded text-xs"
:class="ct.can_generate ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'"
<template v-for="app in authApps" :key="app.id">
<tr class="border-t">
<td class="p-3 font-medium" :rowspan="app.card_types && app.card_types.length > 0 ? app.card_types.length : 1">
{{ app.app_name }}
</td>
<td class="p-3">
<div v-if="app.card_types && app.card_types.length > 0" class="flex items-center gap-2">
<span
class="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs"
:class="app.card_types[0].can_generate ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' : 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400'"
>
<Check v-if="app.card_types[0].can_generate" class="size-3" />
<X v-else class="size-3" />
{{ app.card_types[0].name || `卡类#${app.card_types[0].card_type_id}` }}
</span>
</div>
<span v-else class="text-muted-foreground">-</span>
</td>
<td class="p-3 font-medium" :rowspan="app.card_types && app.card_types.length > 0 ? app.card_types.length : 1">
¥{{ (app.balance || 0).toFixed(2) }}
</td>
<td class="p-3" :rowspan="app.card_types && app.card_types.length > 0 ? app.card_types.length : 1">
<button
class="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs cursor-pointer"
:class="app.status === 'active' ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' : 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400'"
@click="handleToggleAuthStatus(app)"
>
{{ ct.name || `卡类#${ct.card_type_id}` }}
</span>
</div>
<span v-else class="text-muted-foreground">-</span>
</td>
<td class="p-3 font-medium">¥{{ (app.balance || 0).toFixed(2) }}</td>
<td class="p-3">
<button
class="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs cursor-pointer"
:class="app.status === 'active' ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'"
@click="handleToggleAuthStatus(app)"
>
{{ app.status === 'active' ? '已启用' : '已禁用' }}
</button>
</td>
<td class="p-3 text-right">
<UiButton variant="ghost" size="icon" class="text-destructive" @click="handleRemoveAuth(app)">
<Trash2 class="size-4" />
</UiButton>
</td>
</tr>
{{ app.status === 'active' ? '已启用' : '已禁用' }}
</button>
</td>
<td class="p-3 text-right" :rowspan="app.card_types && app.card_types.length > 0 ? app.card_types.length : 1">
<UiButton variant="ghost" size="icon" class="text-destructive" @click="handleRemoveAuth(app)">
<Trash2 class="size-4" />
</UiButton>
</td>
</tr>
<tr v-for="(ct, index) in app.card_types?.slice(1) || []" :key="ct.card_type_id" class="border-t">
<td class="p-3">
<div class="flex items-center gap-2">
<span
class="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs"
:class="ct.can_generate ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' : 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400'"
>
<Check v-if="ct.can_generate" class="size-3" />
<X v-else class="size-3" />
{{ ct.name || `卡类#${ct.card_type_id}` }}
</span>
</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>