feat: permissions CRUD browser integration + E2E enhancements

Backend:
- permission_handler: 完善权限 CRUD 接口(列表/创建/更新/删除)
- auth_handler: 修复认证处理逻辑
- router: 新增权限管理路由
- handler_test: 新增权限 handler 测试覆盖

Frontend:
- permissions.ts/test.ts: 权限服务层完整实现
- profile/settings/service_tests: 服务适配器修正
- client.ts: HTTP 客户端健壮性增强
- vite.config.js: 构建配置优化
- E2E 脚本: run-playwright-cdp-e2e 大幅增强(权限流程覆盖)

Docs:
- REAL_PROJECT_STATUS: 状态更新
- PRODUCTION_CHECKLIST/QUALITY_STANDARD/TECHNICAL_GUIDE/PROJECT_EXPERIENCE_SUMMARY: 团队规范完善
- plans/2026-04-23: 权限浏览器 CRUD 设计方案

验证: go build 0错误
This commit is contained in:
2026-04-24 07:30:18 +08:00
parent 3f3bb82f1d
commit 9b1cea246e
25 changed files with 1868 additions and 133 deletions

View File

@@ -5,14 +5,58 @@
*/
import { get, post, put, del } from '@/lib/http/client'
import type { Permission, CreatePermissionRequest, UpdatePermissionRequest } from '@/types/permission'
import type {
Permission,
CreatePermissionRequest,
UpdatePermissionRequest,
PermissionType,
} from '@/types/permission'
type RawPermissionType = 0 | 1 | 2
interface RawPermission extends Omit<Permission, 'type' | 'children'> {
type: RawPermissionType
children?: RawPermission[]
}
function normalizePermissionType(type: RawPermissionType): PermissionType {
switch (type) {
case 0:
return 'menu'
case 1:
return 'button'
case 2:
return 'api'
default:
return 'api'
}
}
function serializePermissionType(type: PermissionType): RawPermissionType {
switch (type) {
case 'menu':
return 0
case 'button':
return 1
case 'api':
return 2
}
}
function normalizePermission(permission: RawPermission): Permission {
return {
...permission,
type: normalizePermissionType(permission.type),
children: permission.children?.map(normalizePermission),
}
}
/**
* 获取权限树
* GET /api/v1/permissions/tree
*/
export function getPermissionTree(): Promise<Permission[]> {
return get<Permission[]>('/permissions/tree')
return get<RawPermission[]>('/permissions/tree').then((permissions) => permissions.map(normalizePermission))
}
/**
@@ -20,7 +64,7 @@ export function getPermissionTree(): Promise<Permission[]> {
* GET /api/v1/permissions
*/
export function listPermissions(): Promise<Permission[]> {
return get<Permission[]>('/permissions')
return get<RawPermission[]>('/permissions').then((permissions) => permissions.map(normalizePermission))
}
/**
@@ -28,7 +72,7 @@ export function listPermissions(): Promise<Permission[]> {
* GET /api/v1/permissions/:id
*/
export function getPermission(id: number): Promise<Permission> {
return get<Permission>(`/permissions/${id}`)
return get<RawPermission>(`/permissions/${id}`).then(normalizePermission)
}
/**
@@ -36,7 +80,10 @@ export function getPermission(id: number): Promise<Permission> {
* POST /api/v1/permissions
*/
export function createPermission(data: CreatePermissionRequest): Promise<Permission> {
return post<Permission>('/permissions', data)
return post<RawPermission>('/permissions', {
...data,
type: serializePermissionType(data.type),
}).then(normalizePermission)
}
/**
@@ -44,7 +91,7 @@ export function createPermission(data: CreatePermissionRequest): Promise<Permiss
* PUT /api/v1/permissions/:id
*/
export function updatePermission(id: number, data: UpdatePermissionRequest): Promise<Permission> {
return put<Permission>(`/permissions/${id}`, data)
return put<RawPermission>(`/permissions/${id}`, data).then(normalizePermission)
}
/**