feat: security hardening, wechat pay v3 platform cert integration, companion certification revocation, and audit closed-loop

这个提交包含在:
xcbyy
2026-10-16 17:38:17 +08:00
父节点 3bf38db8b6
当前提交 78117bb4e1
共有 58 个文件被更改,包括 12971 次插入 和 952 次删除

查看文件

@@ -12,6 +12,7 @@ describe('PC总后台管理端核心业务与闭环能力自动化测试 (Post M
const adminFinanceWithdrawVuePath = path.join(rootDir, 'admin/arco-design-pro-vite/src/views/finance/withdraw/index.vue');
const adminPlatformConfigVuePath = path.join(rootDir, 'admin/arco-design-pro-vite/src/views/safety/platform-config/index.vue');
const adminCommunityRouterPath = path.join(rootDir, 'admin/arco-design-pro-vite/src/router/routes/modules/community.ts');
const adminUserListVuePath = path.join(rootDir, 'admin/arco-design-pro-vite/src/views/user/list/index.vue');
describe('1. 友圈广场动态管理与置顶/状态流转/级联删除闭环验证', () => {
it('数据库层必须扩展 posts 表结构并包含 is_top 与 status 字段', () => {
@@ -118,14 +119,91 @@ describe('PC总后台管理端核心业务与闭环能力自动化测试 (Post M
});
});
describe('4. 全流程无 Emoji 门禁合规校验', () => {
describe('4. 全平台用户列表删除与批量删除闭环校验', () => {
it('数据仓储层 MysqlRepository 必须实现 deleteUser 与 deleteUsers 方法', () => {
const repoCode = fs.readFileSync(serverRepoPath, 'utf-8');
expect(repoCode).toContain('async deleteUser(id: number): Promise<boolean>');
expect(repoCode).toContain('async deleteUsers(ids: number[]): Promise<number>');
expect(repoCode).toContain('DELETE FROM users WHERE id = ?');
expect(repoCode).toContain('DELETE FROM users WHERE id IN');
});
it('后端服务 index.ts 必须注册单个删除与批量删除 API 路由', () => {
const serverCode = fs.readFileSync(serverIndexPath, 'utf-8');
expect(serverCode).toContain("app.delete('/api/users/:id'");
expect(serverCode).toContain("app.post('/api/users/batch-delete'");
expect(serverCode).toContain('repo.deleteUser(');
expect(serverCode).toContain('repo.deleteUsers(');
});
it('用户列表前端视图 user/list/index.vue 必须包含行级删除与批量删除按钮及确认弹窗', () => {
const userListCode = fs.readFileSync(adminUserListVuePath, 'utf-8');
expect(userListCode).toContain('handleDeleteUser');
expect(userListCode).toContain('handleBatchDelete');
expect(userListCode).toContain('selectedRowKeys');
expect(userListCode).toContain('icon-delete');
expect(userListCode).toContain('a-popconfirm');
expect(userListCode).toContain('/api/users/batch-delete');
expect(userListCode).toContain('/api/users/${record.id}');
});
});
describe('5. 大神认证资质解除与接单状态持久化闭环校验', () => {
const adminCompanionListVuePath = path.join(rootDir, 'admin/arco-design-pro-vite/src/views/companion/list/index.vue');
const adminCompanionAuditVuePath = path.join(rootDir, 'admin/arco-design-pro-vite/src/views/companion/audit/index.vue');
const uniApiJsPath = path.join(rootDir, 'pwuniapp/common/api.js');
it('仓储层 auditCompanion 必须支持 revoke 解除认证动作并联动回退用户角色与双身份标识', () => {
const repoCode = fs.readFileSync(serverRepoPath, 'utf-8');
expect(repoCode).toContain("action: 'approve' | 'reject' | 'revoke'");
expect(repoCode).toContain('已解除大神认证资质');
expect(repoCode).toContain('const isCertExpert = companionRow ? certStatus === 2 : (certStatus === 2 || roleHasExpert)');
});
it('管理后台大神档案库必须支持解除认证弹窗与接单状态真实持久化', () => {
const listCode = fs.readFileSync(adminCompanionListVuePath, 'utf-8');
expect(listCode).toContain('解除认证');
expect(listCode).toContain('openRevokeModal');
expect(listCode).toContain('handleRevokeSubmit');
expect(listCode).toContain("action: 'revoke'");
expect(listCode).toContain('axios.put(`/api/companions/${record.id}`');
});
it('管理后台入驻资质审核页必须支持对已通过大神解除认证及对已驳回记录恢复认证', () => {
const auditCode = fs.readFileSync(adminCompanionAuditVuePath, 'utf-8');
expect(auditCode).toContain('解除认证');
expect(auditCode).toContain('恢复认证');
expect(auditCode).toContain("openRejectModal(record, 'revoke')");
});
it('小程序端获取同城大神列表必须过滤未通过或已解除认证的记录', () => {
const apiCode = fs.readFileSync(uniApiJsPath, 'utf-8');
expect(apiCode).toContain("c.auditStatus === '已通过'");
});
it('微信支付配置必须支持微信支付平台公钥上传与商户证书序列号自动提取', () => {
const configViewCode = fs.readFileSync(adminPlatformConfigVuePath, 'utf-8');
const serverCode = fs.readFileSync(serverIndexPath, 'utf-8');
expect(configViewCode).toContain('platformPublicKeyId');
expect(configViewCode).toContain('platformPublicKey');
expect(configViewCode).toContain("triggerPemSelect('platformPublicKey')");
expect(configViewCode).toContain('extractCertSerialNo');
expect(serverCode).toContain("app.post('/api/admin/pay/wechat/parse-cert'");
expect(serverCode).toContain('extractSerialNoFromCertPem');
});
});
describe('6. 全流程无 Emoji 门禁合规校验', () => {
it('新增的前后端代码中严禁包含任何系统 Emoji 图标字符', () => {
const filesToCheck = [
adminCommunityRouterPath,
adminPostManageVuePath,
adminFinanceRecordsVuePath,
adminFinanceWithdrawVuePath,
adminPlatformConfigVuePath
adminPlatformConfigVuePath,
adminUserListVuePath,
path.join(rootDir, 'admin/arco-design-pro-vite/src/views/companion/list/index.vue'),
path.join(rootDir, 'admin/arco-design-pro-vite/src/views/companion/audit/index.vue')
];
const emojiRegex = /[\uD83C-\uDBFF\uDC00-\uDFFF\u2600-\u26FF\u2700-\u27BF]/;