feat: 完成后台联调与通用列表组件

This commit is contained in:
2026-08-01 12:17:33 +08:00
parent b53fe81999
commit 29dbae573f
50 changed files with 3394 additions and 580 deletions
+81 -8
View File
@@ -1,19 +1,29 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { http } from '@/api/http'
import {
assignPlatformInternalUserRoles,
changePlatformInternalUserStatus,
changePlatformPermissionStatus,
changePlatformRoleStatus,
createPlatformPermission,
createPlatformRole,
deletePlatformPermission,
deletePlatformRole,
downloadTenantQualification,
listPlatformTenants,
listTenantQualifications,
listCurrentPlatformPermissionCodes,
listPlatformPermissions,
listPlatformRoles,
listPlatformInternalUsers,
qualificationFileName,
replacePlatformRolePermissions,
resetPlatformInternalUserPassword,
updatePlatformInternalUser,
updatePlatformPermission,
updatePlatformRole,
type PlatformPermissionResource,
type PlatformInternalUser,
type PlatformRoleResource,
} from './platformIam'
@@ -46,6 +56,21 @@ const permission: PlatformPermissionResource = {
httpMethod: null,
sortNo: 10,
status: 'ACTIVE',
builtIn: false,
}
const internalUser: PlatformInternalUser = {
membershipId: 3000001,
userId: 2000001,
authUserId: 2000001,
username: 'platform_admin',
displayName: '平台管理员',
phone: '13800138000',
email: 'admin@example.com',
memberType: 'INTERNAL',
memberNo: 'PLATFORM-0001',
status: 'ACTIVE',
roleIds: [4000001],
}
describe('platform IAM roles', () => {
@@ -57,7 +82,7 @@ describe('platform IAM roles', () => {
})
it('loads roles from the platform IAM prefix', async () => {
vi.mocked(http.get).mockResolvedValue({ code: '0', message: 'success', data: [role] })
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'success', data: [role] })
await expect(listPlatformRoles()).resolves.toEqual([role])
expect(http.get).toHaveBeenCalledWith('/platform/v1/iam/roles')
@@ -69,15 +94,15 @@ describe('platform IAM roles', () => {
roleName: '企业审核员',
description: '企业资料与入驻审核',
}
vi.mocked(http.post).mockResolvedValue({ code: '0', message: 'success', data: role })
vi.mocked(http.post).mockResolvedValue({ code: '200', message: 'success', data: role })
await expect(createPlatformRole(payload)).resolves.toEqual(role)
expect(http.post).toHaveBeenCalledWith('/platform/v1/iam/roles', payload)
})
it('updates status, permissions, and deletes roles with the implemented IAM routes', async () => {
vi.mocked(http.put).mockResolvedValue({ code: '0', message: 'success', data: role })
vi.mocked(http.delete).mockResolvedValue({ code: '0', message: 'success', data: null })
vi.mocked(http.put).mockResolvedValue({ code: '200', message: 'success', data: role })
vi.mocked(http.delete).mockResolvedValue({ code: '200', message: 'success', data: null })
await expect(updatePlatformRole(role.id, { roleName: '审核主管', description: '负责企业审核' })).resolves.toEqual(role)
await expect(changePlatformRoleStatus(role.id, 'DISABLED')).resolves.toEqual(role)
@@ -91,8 +116,8 @@ describe('platform IAM roles', () => {
})
it('loads and creates permission resources under the platform IAM prefix', async () => {
vi.mocked(http.get).mockResolvedValue({ code: '0', message: 'success', data: [permission] })
vi.mocked(http.post).mockResolvedValue({ code: '0', message: 'success', data: permission })
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'success', data: [permission] })
vi.mocked(http.post).mockResolvedValue({ code: '200', message: 'success', data: permission })
const payload = {
type: 'MENU' as const,
code: permission.permissionCode,
@@ -109,8 +134,46 @@ describe('platform IAM roles', () => {
expect(http.post).toHaveBeenCalledWith('/platform/v1/iam/permissions', payload)
})
it('updates, changes status, and deletes custom permission resources with IAM routes', async () => {
vi.mocked(http.put).mockResolvedValue({ code: '200', message: 'success', data: permission })
vi.mocked(http.delete).mockResolvedValue({ code: '200', message: 'success', data: null })
const payload = { name: '企业客户', parentId: permission.parentId, routePath: '/customers', httpMethod: null, sortNo: 10 }
await expect(updatePlatformPermission(permission.id, payload)).resolves.toEqual(permission)
await expect(changePlatformPermissionStatus(permission.id, 'DISABLED')).resolves.toEqual(permission)
await expect(deletePlatformPermission(permission.id)).resolves.toBeNull()
expect(http.put).toHaveBeenNthCalledWith(1, `/platform/v1/iam/permissions/${permission.id}`, payload)
expect(http.put).toHaveBeenNthCalledWith(2, `/platform/v1/iam/permissions/${permission.id}/status`, { status: 'DISABLED' })
expect(http.delete).toHaveBeenCalledWith(`/platform/v1/iam/permissions/${permission.id}`)
})
it('maintains internal users through their public membership ID', async () => {
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'success', data: [internalUser] })
vi.mocked(http.put).mockResolvedValue({ code: '200', message: 'success', data: internalUser })
const update = {
displayName: '平台管理员',
phone: '13800138000',
email: 'admin@example.com',
memberNo: 'PLATFORM-0001',
roleIds: [4000001],
}
await expect(listPlatformInternalUsers()).resolves.toEqual([internalUser])
await expect(updatePlatformInternalUser(internalUser.membershipId, update)).resolves.toEqual(internalUser)
await expect(changePlatformInternalUserStatus(internalUser.membershipId, 'DISABLED')).resolves.toEqual(internalUser)
await expect(resetPlatformInternalUserPassword(internalUser.membershipId, 'ChangeMe123')).resolves.toEqual(internalUser)
await expect(assignPlatformInternalUserRoles(internalUser.membershipId, [4000001])).resolves.toEqual(internalUser)
expect(http.get).toHaveBeenCalledWith('/platform/v1/iam/internal-users')
expect(http.put).toHaveBeenNthCalledWith(1, `/platform/v1/iam/internal-users/${internalUser.membershipId}`, update)
expect(http.put).toHaveBeenNthCalledWith(2, `/platform/v1/iam/internal-users/${internalUser.membershipId}/status`, { status: 'DISABLED' })
expect(http.put).toHaveBeenNthCalledWith(3, `/platform/v1/iam/internal-users/${internalUser.membershipId}/password`, { newPassword: 'ChangeMe123' })
expect(http.put).toHaveBeenNthCalledWith(4, `/platform/v1/iam/internal-users/${internalUser.membershipId}/roles`, { roleIds: [4000001] })
})
it('loads the current users permission snapshot without calling the role-management endpoint', async () => {
vi.mocked(http.get).mockResolvedValue({ code: '0', message: 'success', data: ['platform:warehouse:list'] })
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'success', data: ['platform:warehouse:list'] })
await expect(listCurrentPlatformPermissionCodes()).resolves.toEqual(['platform:warehouse:list'])
expect(http.get).toHaveBeenCalledWith('/platform/v1/iam/authorization/permissions')
@@ -126,12 +189,22 @@ describe('platform IAM roles', () => {
status: 'PENDING' as const,
reviewComment: null,
}
vi.mocked(http.get).mockResolvedValue({ code: '0', message: 'success', data: [qualification] })
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'success', data: [qualification] })
await expect(listTenantQualifications(8)).resolves.toEqual([qualification])
expect(http.get).toHaveBeenCalledWith('/platform/v1/iam/tenants/8/qualifications')
})
it('loads paginated tenants with the documented filters', async () => {
const page = { records: [], page: 2, size: 10, total: 11, pages: 2 }
vi.mocked(http.get).mockResolvedValue({ code: '200', message: 'success', data: page })
await expect(listPlatformTenants({ page: 2, size: 10, keyword: '柏悦', status: 'ACTIVE' })).resolves.toEqual(page)
expect(http.get).toHaveBeenCalledWith('/platform/v1/iam/tenants', {
params: { page: 2, size: 10, keyword: '柏悦', status: 'ACTIVE' },
})
})
it('downloads a qualification with the platform file endpoint and a safe filename', async () => {
const blob = new Blob(['image'], { type: 'image/png' })
vi.mocked(http.get).mockResolvedValue(blob)