diff --git a/frontend/src/components/admin-sidebar/index.vue b/frontend/src/components/admin-sidebar/index.vue index c8e6d2f..4b5a529 100644 --- a/frontend/src/components/admin-sidebar/index.vue +++ b/frontend/src/components/admin-sidebar/index.vue @@ -1,5 +1,5 @@ - - diff --git a/frontend/src/pages/admin/agent-apps/[id]/recharge.vue b/frontend/src/pages/admin/agent-apps/[id]/recharge.vue deleted file mode 100644 index 6ec6912..0000000 --- a/frontend/src/pages/admin/agent-apps/[id]/recharge.vue +++ /dev/null @@ -1,185 +0,0 @@ - - - diff --git a/frontend/src/pages/admin/agent-apps/[id]/view.vue b/frontend/src/pages/admin/agent-apps/[id]/view.vue deleted file mode 100644 index 5547ac1..0000000 --- a/frontend/src/pages/admin/agent-apps/[id]/view.vue +++ /dev/null @@ -1,232 +0,0 @@ - - - diff --git a/frontend/src/pages/admin/agent-apps/components/columns.ts b/frontend/src/pages/admin/agent-apps/components/columns.ts deleted file mode 100644 index faac45d..0000000 --- a/frontend/src/pages/admin/agent-apps/components/columns.ts +++ /dev/null @@ -1,144 +0,0 @@ -import type { ColumnDef } from '@tanstack/vue-table' - -import { Eye, MoreHorizontal, Pencil, Trash2 } from 'lucide-vue-next' -import { h } from 'vue' - -import type { AgentApp } from '@/pages/admin/agent-apps/data/schema' - -import Badge from '@/components/ui/badge/Badge.vue' -import Button from '@/components/ui/button/Button.vue' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu' - -export function getColumns(actions: { - onView: (row: AgentApp) => void - onEdit: (row: AgentApp) => void - onDelete: (row: AgentApp) => void -}): ColumnDef[] { - return [ - { - accessorKey: 'agent_name', - header: '代理', - cell: ({ row }) => { - const name = row.getValue('agent_name') as string - const email = row.original.agent_email - return h('div', { class: 'flex items-center space-x-3' }, [ - h('div', { class: 'h-8 w-8 rounded bg-primary/10 flex items-center justify-center flex-shrink-0' }, [ - h('span', { class: 'text-primary font-bold text-sm' }, name ? name.charAt(0).toUpperCase() : '?'), - ]), - h('div', {}, [ - h('p', { class: 'font-medium' }, name || '-'), - email ? h('p', { class: 'text-xs text-muted-foreground' }, email) : null, - ]), - ]) - }, - }, - { - accessorKey: 'app_name', - header: '应用', - cell: ({ row }) => { - const appName = row.getValue('app_name') as string - return appName ? h(Badge, { variant: 'secondary' }, () => appName) : '-' - }, - }, - { - accessorKey: 'card_types', - header: '卡密权限', - cell: ({ row }) => { - const cardTypes = row.original.card_types || [] - if (cardTypes.length === 0) - return h('span', { class: 'text-muted-foreground text-sm' }, '-') - const authorized = cardTypes.filter(ct => ct.can_generate).length - return h('span', { class: 'text-sm' }, `${authorized}/${cardTypes.length}`) - }, - }, - { - accessorKey: 'balance', - header: '余额', - cell: ({ row }) => { - const balance = row.getValue('balance') as number - return h('span', { class: 'font-medium' }, `¥${(balance || 0).toFixed(2)}`) - }, - }, - { - accessorKey: 'status', - header: '状态', - cell: ({ row }) => { - const status = row.getValue('status') as string - const isActive = status === 'active' - return h(Badge, { variant: isActive ? 'default' : 'secondary' }, () => isActive ? '已启用' : '已禁用') - }, - }, - { - accessorKey: 'created_at', - header: '授权时间', - cell: ({ row }) => { - const createdAt = row.getValue('created_at') - if (!createdAt) - return '-' - try { - const date = new Date(createdAt as string) - if (Number.isNaN(date.getTime())) - return '-' - return date.toLocaleString('zh-CN', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - }) - } - catch { - return '-' - } - }, - }, - { - id: 'actions', - header: () => h('span', { class: 'sr-only' }, '操作'), - cell: ({ row }) => { - const item = row.original - return h( - DropdownMenu, - {}, - { - default: () => [ - h(DropdownMenuTrigger, { asChild: true }, () => - h(Button, { variant: 'ghost', class: 'h-8 w-8 p-0' }, () => [ - h(MoreHorizontal, { class: 'h-4 w-4' }), - h('span', { class: 'sr-only' }, '打开菜单'), - ]), - ), - h( - DropdownMenuContent, - { align: 'end' }, - () => [ - h(DropdownMenuItem, { onClick: () => actions.onView(item) }, () => [ - h(Eye, { class: 'mr-2 h-4 w-4' }), - '查看授权', - ]), - h(DropdownMenuItem, { onClick: () => actions.onEdit(item) }, () => [ - h(Pencil, { class: 'mr-2 h-4 w-4' }), - '编辑授权', - ]), - h(DropdownMenuSeparator), - h(DropdownMenuItem, { class: 'text-destructive', onClick: () => actions.onDelete(item) }, () => [ - h(Trash2, { class: 'mr-2 h-4 w-4' }), - '移除授权', - ]), - ], - ), - ], - }, - ) - }, - enableSorting: false, - enableHiding: false, - }, - ] -} diff --git a/frontend/src/pages/admin/agent-apps/components/data-table.vue b/frontend/src/pages/admin/agent-apps/components/data-table.vue deleted file mode 100644 index 3cffc65..0000000 --- a/frontend/src/pages/admin/agent-apps/components/data-table.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - diff --git a/frontend/src/pages/admin/agent-apps/create.vue b/frontend/src/pages/admin/agent-apps/create.vue deleted file mode 100644 index 82d9325..0000000 --- a/frontend/src/pages/admin/agent-apps/create.vue +++ /dev/null @@ -1,349 +0,0 @@ - - - diff --git a/frontend/src/pages/admin/agent-apps/data/schema.ts b/frontend/src/pages/admin/agent-apps/data/schema.ts deleted file mode 100644 index 805b00b..0000000 --- a/frontend/src/pages/admin/agent-apps/data/schema.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { z } from 'zod' - -export const agentAppStatusSchema = z.enum(['active', 'inactive']) - -export const cardTypeSchema = z.object({ - id: z.number().optional(), - card_type_id: z.number(), - name: z.string().optional(), - billing_type: z.string().optional(), - can_generate: z.boolean(), - price: z.number().optional(), - origin_price: z.number().optional(), -}) - -export const agentAppSchema = z.object({ - id: z.number(), - agent_id: z.number(), - agent_name: z.string(), - agent_email: z.string().optional(), - application_id: z.number(), - app_name: z.string(), - status: agentAppStatusSchema, - discount: z.number(), - balance: z.number(), - card_types: z.array(cardTypeSchema).optional(), - created_at: z.string(), -}) - -export type CardTypeAuth = z.infer -export type AgentApp = z.infer diff --git a/frontend/src/pages/admin/agent-apps/index.vue b/frontend/src/pages/admin/agent-apps/index.vue deleted file mode 100644 index d1b851c..0000000 --- a/frontend/src/pages/admin/agent-apps/index.vue +++ /dev/null @@ -1,254 +0,0 @@ - - - diff --git a/frontend/src/pages/admin/agents/[id].vue b/frontend/src/pages/admin/agents/[id].vue index 3023d14..01f6ce0 100644 --- a/frontend/src/pages/admin/agents/[id].vue +++ b/frontend/src/pages/admin/agents/[id].vue @@ -1,5 +1,5 @@ @@ -247,6 +386,78 @@ onMounted(() => { + + + +
+ + + 授权应用 + + 管理该代理可生成卡密的应用和卡类权限 +
+ + + 添加授权 + +
+ +
+ +
+
+ +

暂无授权应用

+

点击上方按钮为代理添加应用授权

+
+
+ + + + + + + + + + + + + + + + + + + +
应用卡密权限余额状态操作
{{ app.app_name }} +
+ + {{ ct.name || `卡类#${ct.card_type_id}` }} + +
+ - +
¥{{ (app.balance || 0).toFixed(2) }} + + + + + +
+
+
+
@@ -309,5 +520,73 @@ onMounted(() => {
+ + + + + 添加授权 + 为该代理添加应用和卡类权限 + +
+
+ 选择应用 + + + + + + + {{ app.name }} + + + +
+ +
+ 卡类权限 +
+ + + + + + + + + + + + + + + + + +
卡类类型售价可生成
{{ ct.name }}{{ ct.billing_type }} + + + +
+
+
+
+ + 取消 + + + 确认授权 + + +
+
diff --git a/frontend/src/router/routes.ts b/frontend/src/router/routes.ts index 024071f..637536f 100644 --- a/frontend/src/router/routes.ts +++ b/frontend/src/router/routes.ts @@ -167,18 +167,6 @@ const routes: RouteRecordRaw[] = [ component: () => import('@/pages/admin/sessions/index.vue'), meta: { title: '在线实例 - 管理后台' }, }, - { - path: 'agent-apps', - name: 'AdminAgentApps', - component: () => import('@/pages/admin/agent-apps/index.vue'), - meta: { title: '授权管理 - 管理后台' }, - }, - { - path: 'agent-apps/create', - name: 'AdminAgentAppsCreate', - component: () => import('@/pages/admin/agent-apps/create.vue'), - meta: { title: '新建授权 - 管理后台' }, - }, { path: 'agents', name: 'AdminAgents', @@ -197,24 +185,6 @@ const routes: RouteRecordRaw[] = [ component: () => import('@/pages/admin/agents/[id].vue'), meta: { title: '编辑代理 - 管理后台' }, }, - { - path: 'agent-apps/:id/edit', - name: 'AdminAgentAppEdit', - component: () => import('@/pages/admin/agent-apps/[id]/edit.vue'), - meta: { title: '编辑授权 - 管理后台' }, - }, - { - path: 'agent-apps/:id/view', - name: 'AdminAgentAppView', - component: () => import('@/pages/admin/agent-apps/[id]/view.vue'), - meta: { title: '查看授权 - 管理后台' }, - }, - { - path: 'agent-apps/:id/recharge', - name: 'AdminAgentAppRecharge', - component: () => import('@/pages/admin/agent-apps/[id]/recharge.vue'), - meta: { title: '充值余额 - 管理后台' }, - }, { path: 'finance', name: 'AdminFinance',