diff --git a/apps/backend/src/services/worker-platform/admin-service.ts b/apps/backend/src/services/worker-platform/admin-service.ts index 2e52df3a..61007fe8 100644 --- a/apps/backend/src/services/worker-platform/admin-service.ts +++ b/apps/backend/src/services/worker-platform/admin-service.ts @@ -9,13 +9,11 @@ import { unassignWorkOrder, countWorkerActiveOrders, countWorkOrderPendingSharingSubmissions, - countTimeoutEventsByWorkerIds, createWorkProductMatchLog, createWorkOrder, createWorkOrderEvent, deductPendingDepositUnfreeze, deleteWorkOrder, - getWorkerLevelById, getWorkerUserById, getWorkOrderStatistics, getWorkOrderByOrderItemId, @@ -35,9 +33,6 @@ import { reviewWorkerCancelRequest, updateWorkOrder, updateWorkOrderBasic, - updateWorkerUser, - updateWorkerPassword, - revokeAllWorkerSessions, type WorkOrderRow, } from '../../repositories/worker-platform/index.js' import type { JsonObject } from '../../types/json.js' @@ -67,7 +62,6 @@ import { DEFAULT_DEPOSIT_THRESHOLD_AMOUNT, mapWorkOrderAdmin, mapWorkOrderShare, - mapWorkerUser, mapWorkerCancelRequest, mapWorkerOrderFeedback, normalizeAmountFen, @@ -78,15 +72,9 @@ import { normalizeProblemResolutionAction, normalizeRequirementFields, normalizeRequirementFieldsFromPayload, - normalizeReviewStatus, - normalizeSessionVersion, - hashWorkerPassword, - validateWorkerPassword, normalizeStatuses, normalizeSubmittedFields, normalizeUploadedFiles, - normalizeWorkerType, - normalizeWorkerFreezeReason, resolveFreezeDepositAmount, mapWorkOrderEvents, resolveMatchingProductRuleDecision, @@ -108,96 +96,11 @@ import { type KuaishouIndustryShopConfig, } from '../platforms/kuaishou-industry/source-config-service.js' -export async function listAdminWorkerUsers(query: JsonObject = {}) { - const page = normalizePage(query.page) - const pageSize = normalizePageSize(query.pageSize) - const workerId = normalizeOptionalId(query.workerId ?? query.worker_id) || 0 - const { items, total } = await listWorkerUsers({ - page, - pageSize, - workerId, - status: String(query.status || '').trim(), - keyword: String(query.keyword || '').trim(), - workerType: String(query.workerType || query.worker_type || '').trim(), - }) - const timeoutCounts = await countTimeoutEventsByWorkerIds(items.map((item) => Number(item.id))) - return { - items: items.map((item) => { - const worker = mapWorkerUser(item) - return { - ...worker, - timeoutOrderCount: timeoutCounts.get(Number(item.id)) || 0, - } - }), - pagination: { page, pageSize, total }, - } -} - -export async function reviewAdminWorkerUser(workerId: number | string, payload: JsonObject = {}) { - const worker = await getRequiredWorker(workerId) - const status = normalizeReviewStatus(payload.status) - const freezeReason = - status === 'rejected' - ? normalizeWorkerFreezeReason(payload.freezeReason ?? payload.freeze_reason) - : worker.frozen_reason || '' - const workerType = normalizeWorkerType(payload.workerType ?? payload.worker_type) - const requestedLevelId = normalizeOptionalId(payload.levelId) - let levelId = worker.level_id || null - if (requestedLevelId) { - const level = await getWorkerLevelById(requestedLevelId) - if (!level) { - throw createHttpError('接单等级不存在', { - statusCode: 404, - errorCode: 'worker_level_not_found', - }) - } - levelId = Number(level.id) - } - if (!levelId) { - levelId = (await ensureWorkerPlatformDefaults()).level?.id || null - } - const now = nowIso() - const updated = await updateWorkerUser(worker.id, { - status, - worker_type: workerType, - level_id: levelId, - review_note: - status === 'rejected' - ? freezeReason - : String((payload.reviewNote ?? payload.note ?? worker.review_note) || '').trim(), - frozen_reason: freezeReason, - frozen_at: status === 'rejected' ? now : worker.frozen_at, - session_version: normalizeSessionVersion(worker.session_version) + 1, - reviewed_at: now, - updated_at: now, - }) - await revokeAllWorkerSessions(worker.id, now) - return { worker: mapWorkerUser(updated || worker) } -} - -export async function resetAdminWorkerPassword( - workerId: number | string, - payload: JsonObject = {}, -) { - const worker = await getRequiredWorker(workerId) - const password = String(payload.password || payload.newPassword || '').trim() - if (!password) { - throw createHttpError('请输入新密码', { - statusCode: 400, - errorCode: 'worker_password_required', - }) - } - validateWorkerPassword(password) - const now = nowIso() - const updated = await updateWorkerPassword({ - workerId: worker.id, - passwordHash: hashWorkerPassword(password), - sessionVersion: normalizeSessionVersion(worker.session_version) + 1, - now, - }) - await revokeAllWorkerSessions(worker.id, now) - return { worker: mapWorkerUser(updated || worker), reloginRequired: true } -} +export { + listAdminWorkerUsers, + resetAdminWorkerPassword, + reviewAdminWorkerUser, +} from './admin-worker-user-service.js' export async function assignAdminWorkOrderToWorker( workOrderId: number | string, diff --git a/apps/backend/src/services/worker-platform/admin-worker-user-service.ts b/apps/backend/src/services/worker-platform/admin-worker-user-service.ts new file mode 100644 index 00000000..0311883a --- /dev/null +++ b/apps/backend/src/services/worker-platform/admin-worker-user-service.ts @@ -0,0 +1,112 @@ +import { + countTimeoutEventsByWorkerIds, + getWorkerLevelById, + listWorkerUsers, + revokeAllWorkerSessions, + updateWorkerPassword, + updateWorkerUser, +} from '../../repositories/worker-platform/index.js' +import type { JsonObject } from '../../types/json.js' +import { createHttpError } from '../../utils/http.js' +import { nowIso } from '../../utils/time.js' +import { normalizePage, normalizePageSize } from '../admin/admin-query-utils.js' +import { + hashWorkerPassword, + mapWorkerUser, + normalizeOptionalId, + normalizeReviewStatus, + normalizeSessionVersion, + normalizeWorkerFreezeReason, + normalizeWorkerType, + validateWorkerPassword, +} from './mappers.js' +import { ensureWorkerPlatformDefaults } from './worker-platform-defaults.js' +import { getRequiredWorker } from './worker-session-context-service.js' + +export async function listAdminWorkerUsers(query: JsonObject = {}) { + const page = normalizePage(query.page) + const pageSize = normalizePageSize(query.pageSize) + const workerId = normalizeOptionalId(query.workerId ?? query.worker_id) || 0 + const { items, total } = await listWorkerUsers({ + page, + pageSize, + workerId, + status: String(query.status || '').trim(), + keyword: String(query.keyword || '').trim(), + workerType: String(query.workerType || query.worker_type || '').trim(), + }) + const timeoutCounts = await countTimeoutEventsByWorkerIds(items.map((item) => Number(item.id))) + return { + items: items.map((item) => ({ + ...mapWorkerUser(item), + timeoutOrderCount: timeoutCounts.get(Number(item.id)) || 0, + })), + pagination: { page, pageSize, total }, + } +} + +export async function reviewAdminWorkerUser(workerId: number | string, payload: JsonObject = {}) { + const worker = await getRequiredWorker(workerId) + const status = normalizeReviewStatus(payload.status) + const freezeReason = + status === 'rejected' + ? normalizeWorkerFreezeReason(payload.freezeReason ?? payload.freeze_reason) + : worker.frozen_reason || '' + const workerType = normalizeWorkerType(payload.workerType ?? payload.worker_type) + const requestedLevelId = normalizeOptionalId(payload.levelId) + let levelId = worker.level_id || null + if (requestedLevelId) { + const level = await getWorkerLevelById(requestedLevelId) + if (!level) { + throw createHttpError('接单等级不存在', { + statusCode: 404, + errorCode: 'worker_level_not_found', + }) + } + levelId = Number(level.id) + } + if (!levelId) { + levelId = (await ensureWorkerPlatformDefaults()).level?.id || null + } + const now = nowIso() + const updated = await updateWorkerUser(worker.id, { + status, + worker_type: workerType, + level_id: levelId, + review_note: + status === 'rejected' + ? freezeReason + : String((payload.reviewNote ?? payload.note ?? worker.review_note) || '').trim(), + frozen_reason: freezeReason, + frozen_at: status === 'rejected' ? now : worker.frozen_at, + session_version: normalizeSessionVersion(worker.session_version) + 1, + reviewed_at: now, + updated_at: now, + }) + await revokeAllWorkerSessions(worker.id, now) + return { worker: mapWorkerUser(updated || worker) } +} + +export async function resetAdminWorkerPassword( + workerId: number | string, + payload: JsonObject = {}, +) { + const worker = await getRequiredWorker(workerId) + const password = String(payload.password || payload.newPassword || '').trim() + if (!password) { + throw createHttpError('请输入新密码', { + statusCode: 400, + errorCode: 'worker_password_required', + }) + } + validateWorkerPassword(password) + const now = nowIso() + const updated = await updateWorkerPassword({ + workerId: worker.id, + passwordHash: hashWorkerPassword(password), + sessionVersion: normalizeSessionVersion(worker.session_version) + 1, + now, + }) + await revokeAllWorkerSessions(worker.id, now) + return { worker: mapWorkerUser(updated || worker), reloginRequired: true } +} diff --git a/apps/backend/src/services/worker-platform/index.ts b/apps/backend/src/services/worker-platform/index.ts index be78311c..17591c7e 100644 --- a/apps/backend/src/services/worker-platform/index.ts +++ b/apps/backend/src/services/worker-platform/index.ts @@ -24,6 +24,7 @@ export * from './admin-worker-finance-service.js' export * from './admin-worker-catalog-service.js' export * from './admin-kuaishou-match-service.js' export * from './admin-worker-config-service.js' +export * from './admin-worker-user-service.js' export * from './worker-product-match-config-service.js' export * from './worker-announcement-config-service.js' export * from './worker-hall-config-service.js'