From dffe32e84a1d4d5ae9083300e7ef8019b74db901 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Fri, 14 Aug 2026 15:14:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=86=BB=E7=BB=93/=E6=8B=92=E7=BB=9D?= =?UTF-8?q?=E7=9A=84=E6=89=93=E6=89=8B=E8=B4=A6=E5=8F=B7=E7=A6=81=E6=AD=A2?= =?UTF-8?q?=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - loginWorker 仅允许 active 状态登录,rejected(冻结)/pending_review/disabled 均拦截并返回对应错误码 - verifyWorkerSessionToken 对非 active 状态直接失效会话,冻结后已登录会话立即退出 - 补充 assertWorkerLoginAllowed 四种状态的单元测试 --- .../worker-platform-service.test.ts | 67 ++++++++++++++++++- .../worker-platform/worker-service.ts | 30 +++++++-- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/apps/backend/src/services/worker-platform/worker-platform-service.test.ts b/apps/backend/src/services/worker-platform/worker-platform-service.test.ts index feaf44f4..45f96eda 100644 --- a/apps/backend/src/services/worker-platform/worker-platform-service.test.ts +++ b/apps/backend/src/services/worker-platform/worker-platform-service.test.ts @@ -1,8 +1,71 @@ import assert from 'node:assert/strict' import test from 'node:test' -import type { WorkOrderRow } from '../../repositories/worker-platform/index.js' -import { resolveCollectSubmitTargetWorkOrder } from './index.js' +import type { WorkOrderRow, WorkerUserRow } from '../../repositories/worker-platform/index.js' +import { assertWorkerLoginAllowed, resolveCollectSubmitTargetWorkOrder } from './index.js' + +function buildWorkerUserRow(overrides: Partial = {}): WorkerUserRow { + return { + id: 1, + username: 'jd01', + password_hash: 'scrypt$salt$hash', + display_name: '测试打手', + phone: '', + level_id: 1, + status: 'active', + review_note: '', + session_version: 1, + created_at: '2026-07-28T00:00:00.000Z', + updated_at: '2026-07-28T00:00:00.000Z', + reviewed_at: null, + inviter_id: null, + invite_code: 'TEST0001', + ...overrides, + } +} + +test('assertWorkerLoginAllowed allows active workers', () => { + assert.doesNotThrow(() => assertWorkerLoginAllowed(buildWorkerUserRow())) +}) + +test('assertWorkerLoginAllowed blocks rejected (frozen) workers with worker_rejected', () => { + assert.throws( + () => assertWorkerLoginAllowed(buildWorkerUserRow({ status: 'rejected' })), + (error: unknown) => + Boolean( + error && + typeof error === 'object' && + (error as { statusCode?: number }).statusCode === 403 && + (error as { errorCode?: string }).errorCode === 'worker_rejected', + ), + ) +}) + +test('assertWorkerLoginAllowed blocks pending review workers with worker_pending_review', () => { + assert.throws( + () => assertWorkerLoginAllowed(buildWorkerUserRow({ status: 'pending_review' })), + (error: unknown) => + Boolean( + error && + typeof error === 'object' && + (error as { statusCode?: number }).statusCode === 403 && + (error as { errorCode?: string }).errorCode === 'worker_pending_review', + ), + ) +}) + +test('assertWorkerLoginAllowed blocks disabled workers with worker_disabled', () => { + assert.throws( + () => assertWorkerLoginAllowed(buildWorkerUserRow({ status: 'disabled' })), + (error: unknown) => + Boolean( + error && + typeof error === 'object' && + (error as { statusCode?: number }).statusCode === 403 && + (error as { errorCode?: string }).errorCode === 'worker_disabled', + ), + ) +}) function buildWorkOrderRow( overrides: Partial = {}, diff --git a/apps/backend/src/services/worker-platform/worker-service.ts b/apps/backend/src/services/worker-platform/worker-service.ts index ff65df88..fd44bf73 100644 --- a/apps/backend/src/services/worker-platform/worker-service.ts +++ b/apps/backend/src/services/worker-platform/worker-service.ts @@ -335,14 +335,34 @@ export async function loginWorker(username: unknown, password: unknown) { }) } - if (worker.status === 'disabled') { - throw createHttpError('接单账号已停用', { + assertWorkerLoginAllowed(worker) + + return createWorkerSession(worker) +} + +export function assertWorkerLoginAllowed(worker: WorkerUserRow) { + if (worker.status === 'active') { + return + } + + if (worker.status === 'rejected') { + throw createHttpError('接单账号已被冻结,无法登录', { statusCode: 403, - errorCode: 'worker_disabled', + errorCode: 'worker_rejected', }) } - return createWorkerSession(worker) + if (worker.status === 'pending_review') { + throw createHttpError('接单账号待审核,暂无法登录', { + statusCode: 403, + errorCode: 'worker_pending_review', + }) + } + + throw createHttpError('接单账号已停用', { + statusCode: 403, + errorCode: 'worker_disabled', + }) } export async function logoutWorkerSession(token: unknown) { @@ -411,7 +431,7 @@ export async function verifyWorkerSessionToken(token: unknown): Promise