import { Router } from 'express' import { createRateLimitMiddleware, getBodyFieldRateLimitKey } from '../middleware/rate-limit.js' import { uploadSingleFile } from './file-upload.js' import { uploadFileAsset } from '../services/file-storage/file-storage-service.js' import { changeWorkerPassword, createWorkerRechargeRequest, createWorkerWithdrawalAccount, saveWorkerAlipayWithdrawalQrCode, createWorkerWithdrawRequest, getWorkerProfile, getWorkerSessionSummary, getWorkerHallLeaderboard, getWorkerMyOrderOverview, grabWorkerHallOrder, joinWorkerSharingOrder, listWorkerProfileFinanceRequests, listWorkerProfileWalletLedgers, listWorkerHallOrders, listWorkerMyOrders, markWorkerOrderRead, getWorkerMyOrderEvents, loginWorker, loginWorkerBySmsCode, getWorkerSessions, deleteWorkerSession, manageWorkerSessions, deleteWorkerSessionWithCredentials, logoutWorkerSession, registerWorker, sendWorkerSmsCode, sendWorkerLoginSmsCode, sendWorkerPasswordResetSmsCode, resetWorkerPassword, saveWorkerOrderAcceptanceDraft, saveWorkerOrderNote, remindWorkerOrderAcceptance, supplementWorkerAcceptedOrderEvidence, submitWorkerOrderAcceptance, getWorkerCancelRequestSummary, getWorkerAnnouncement, getWorkerOrderFeedbackSummary, submitWorkerCancelRequest, submitWorkerOrderFeedback, } from '../services/worker-platform/index.js' import { buildNotFoundPayload, createRouteHandler } from '../utils/http.js' import { extractOptionalWorkerBearerToken, extractWorkerBearerToken, getRequiredWorkerSession, requireActiveWorker, requireWorkerSession, } from './worker/session.js' import { openWorkerRealtimeStream } from '../services/realtime/realtime-event-service.js' const router = Router() router.post( '/auth/sms-code', createRateLimitMiddleware({ scope: 'worker:sms-code', windowMs: 60_000, max: 5, key: getBodyFieldRateLimitKey('phone'), }), createRouteHandler((req) => sendWorkerSmsCode(req.body || {}), { successMessage: '验证码已发送', errorMessage: '验证码发送失败', scope: '[worker/auth/sms-code]', }), ) router.post( '/auth/register', createRateLimitMiddleware({ scope: 'worker:register', windowMs: 60_000, max: 5, key: getBodyFieldRateLimitKey('phone'), }), createRouteHandler((req) => registerWorker(req.body || {}), { successMessage: '注册成功,请使用手机号登录', errorMessage: '接单账号注册失败', scope: '[worker/auth/register]', }), ) router.post( '/auth/password-reset/sms-code', createRateLimitMiddleware({ scope: 'worker:password-reset-sms-code', windowMs: 60_000, max: 5, key: getBodyFieldRateLimitKey('phone'), }), createRouteHandler((req) => sendWorkerPasswordResetSmsCode(req.body || {}), { successMessage: '验证码已发送', errorMessage: '验证码发送失败', scope: '[worker/auth/password-reset/sms-code]', }), ) router.post( '/auth/password-reset', createRateLimitMiddleware({ scope: 'worker:password-reset', windowMs: 60_000, max: 10, key: getBodyFieldRateLimitKey('phone'), }), createRouteHandler((req) => resetWorkerPassword(req.body || {}), { successMessage: '密码已重置,请重新登录', errorMessage: '密码重置失败', scope: '[worker/auth/password-reset]', }), ) router.post( '/auth/login', createRateLimitMiddleware({ scope: 'worker:login', windowMs: 60_000, max: 10, key: getBodyFieldRateLimitKey('username'), }), createRouteHandler( (req) => loginWorker(req.body?.username, req.body?.password, { deviceId: req.body?.deviceId, deviceType: req.body?.deviceType, deviceName: req.body?.deviceName, userAgent: req.headers['user-agent'], ipAddress: req.ip, }), { successMessage: '登录成功', errorMessage: '接单端登录失败', scope: '[worker/auth/login]', }, ), ) router.post( '/auth/login/sms-code', createRateLimitMiddleware({ scope: 'worker:login-sms-code', windowMs: 60_000, max: 5, key: getBodyFieldRateLimitKey('phone'), }), createRouteHandler((req) => sendWorkerLoginSmsCode(req.body || {}), { successMessage: '验证码已发送', errorMessage: '验证码发送失败', scope: '[worker/auth/login/sms-code]', }), ) router.post( '/auth/login/sms', createRateLimitMiddleware({ scope: 'worker:login-sms', windowMs: 60_000, max: 10, key: getBodyFieldRateLimitKey('phone'), }), createRouteHandler( (req) => loginWorkerBySmsCode(req.body?.phone, req.body?.code, { deviceId: req.body?.deviceId, deviceType: req.body?.deviceType, deviceName: req.body?.deviceName, userAgent: req.headers['user-agent'], ipAddress: req.ip, }), { successMessage: '登录成功', errorMessage: '接单端验证码登录失败', scope: '[worker/auth/login/sms]', }, ), ) router.post( '/auth/devices/manage/list', createRateLimitMiddleware({ scope: 'worker:devices-manage', windowMs: 60_000, max: 10, key: getBodyFieldRateLimitKey('username'), }), createRouteHandler((req) => manageWorkerSessions(req.body?.username, req.body?.password), { successMessage: 'ok', errorMessage: '读取登录设备失败', scope: '[worker/auth/devices/manage/list]', }), ) router.post( '/auth/devices/manage/delete', createRateLimitMiddleware({ scope: 'worker:devices-manage-delete', windowMs: 60_000, max: 10, key: getBodyFieldRateLimitKey('username'), }), createRouteHandler( (req) => deleteWorkerSessionWithCredentials( req.body?.username, req.body?.password, req.body?.sessionId, ), { successMessage: '登录设备已删除', errorMessage: '删除登录设备失败', scope: '[worker/auth/devices/manage/delete]', }, ), ) router.get( '/auth/session', createRouteHandler((req) => getWorkerSessionSummary(extractWorkerBearerToken(req)), { successMessage: 'ok', errorMessage: '读取接单登录态失败', scope: '[worker/auth/session]', }), ) router.post( '/auth/logout', createRouteHandler((req) => logoutWorkerSession(extractOptionalWorkerBearerToken(req)), { successMessage: '已退出登录', errorMessage: '退出失败', scope: '[worker/auth/logout]', }), ) router.use(requireWorkerSession) router.get( '/auth/devices', createRouteHandler((req) => getWorkerSessions(getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取登录设备失败', scope: '[worker/auth/devices]', }), ) router.delete( '/auth/devices/:sessionId', createRouteHandler( (req) => deleteWorkerSession(getRequiredWorkerSession(req), req.params.sessionId), { successMessage: '登录设备已删除', errorMessage: '删除登录设备失败', scope: '[worker/auth/devices/delete]', }, ), ) router.get('/realtime', (req, res) => { openWorkerRealtimeStream( res, getRequiredWorkerSession(req).workerId, Number(req.get('Last-Event-ID') || req.query.lastEventId || 0) || 0, ) }) router.get( '/profile', createRouteHandler((req) => getWorkerProfile(getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取打手信息失败', scope: '[worker/profile]', }), ) router.get( '/profile/wallet-ledgers', createRouteHandler( (req) => listWorkerProfileWalletLedgers(req.query, getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取钱包流水失败', scope: '[worker/profile/wallet-ledgers]', }, ), ) router.get( '/profile/finance-requests', createRouteHandler( (req) => listWorkerProfileFinanceRequests(req.query, getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取资金申请记录失败', scope: '[worker/profile/finance-requests]', }, ), ) router.post( '/profile/recharge-requests', requireActiveWorker, createRouteHandler( (req) => createWorkerRechargeRequest(req.body || {}, getRequiredWorkerSession(req)), { successMessage: '充值申请已提交', errorMessage: '提交充值申请失败', scope: '[worker/profile/recharge-requests]', }, ), ) router.post( '/profile/withdrawal-account', requireActiveWorker, createRouteHandler( (req) => createWorkerWithdrawalAccount(req.body || {}, getRequiredWorkerSession(req)), { successMessage: '提现信息已添加', errorMessage: '添加提现信息失败', scope: '[worker/profile/withdrawal-account]', }, ), ) router.put( '/profile/withdrawal-account/alipay-qr-code', requireActiveWorker, createRouteHandler( (req) => saveWorkerAlipayWithdrawalQrCode(req.body || {}, getRequiredWorkerSession(req)), { successMessage: '支付宝收款二维码已保存', errorMessage: '保存支付宝收款二维码失败', scope: '[worker/profile/withdrawal-account/alipay-qr-code]', }, ), ) router.post( '/profile/withdraw-requests', requireActiveWorker, createRouteHandler( (req) => createWorkerWithdrawRequest(req.body || {}, getRequiredWorkerSession(req)), { successMessage: '提现申请已提交', errorMessage: '提交提现申请失败', scope: '[worker/profile/withdraw-requests]', }, ), ) router.post( '/profile/change-password', createRouteHandler((req) => changeWorkerPassword(req.body || {}, getRequiredWorkerSession(req)), { successMessage: '密码已修改', errorMessage: '修改密码失败', scope: '[worker/profile/change-password]', }), ) router.post( '/files/upload', requireActiveWorker, uploadSingleFile, createRouteHandler( (req) => { const session = getRequiredWorkerSession(req) return uploadFileAsset({ file: req.file, scene: req.body?.scene || 'worker-acceptance', uploaderType: 'worker', uploaderId: String(session.workerId), }) }, { successMessage: '文件已上传', errorMessage: '文件上传失败', scope: '[worker/files/upload]', }, ), ) router.get( '/hall/orders', requireActiveWorker, createRouteHandler((req) => listWorkerHallOrders(req.query, getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取抢单大厅失败', scope: '[worker/hall/orders]', }), ) router.get( '/hall/leaderboard', requireActiveWorker, createRouteHandler( (req) => getWorkerHallLeaderboard(getRequiredWorkerSession(req), req.query?.period), { successMessage: 'ok', errorMessage: '读取接单排行榜失败', scope: '[worker/hall/leaderboard]', }, ), ) router.post( '/hall/orders/:workOrderId/grab', requireActiveWorker, createRouteHandler( (req) => grabWorkerHallOrder(String(req.params.workOrderId || ''), getRequiredWorkerSession(req)), { successMessage: '抢单成功', errorMessage: '抢单失败', scope: '[worker/hall/orders/:workOrderId/grab]', }, ), ) router.post( '/hall/orders/:workOrderId/join-sharing', requireActiveWorker, createRouteHandler( (req) => joinWorkerSharingOrder( String(req.params.workOrderId || ''), req.body || {}, getRequiredWorkerSession(req), ), { successMessage: '拼单成功', errorMessage: '拼单失败', scope: '[worker/hall/orders/:workOrderId/join-sharing]', }, ), ) router.get( '/orders', requireActiveWorker, createRouteHandler((req) => listWorkerMyOrders(req.query, getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取我的订单失败', scope: '[worker/orders]', }), ) router.get( '/orders/overview', requireActiveWorker, createRouteHandler((req) => getWorkerMyOrderOverview(getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取我的订单概览失败', scope: '[worker/orders/overview]', }), ) router.get( '/orders/cancel-requests', requireActiveWorker, createRouteHandler((req) => getWorkerCancelRequestSummary(getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取取消申请失败', scope: '[worker/orders/cancel-requests]', }), ) router.get( '/announcement', requireActiveWorker, createRouteHandler((req) => getWorkerAnnouncement(getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取公告失败', scope: '[worker/announcement]', }), ) router.get( '/orders/feedbacks', requireActiveWorker, createRouteHandler((req) => getWorkerOrderFeedbackSummary(getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取问题反馈失败', scope: '[worker/orders/feedbacks]', }), ) router.post( '/orders/:workOrderId/feedbacks', requireActiveWorker, createRouteHandler( (req) => submitWorkerOrderFeedback( String(req.params.workOrderId || ''), req.body || {}, getRequiredWorkerSession(req), ), { successMessage: '问题反馈已提交,等待客服处理', errorMessage: '提交问题反馈失败', scope: '[worker/orders/:workOrderId/feedbacks]', }, ), ) router.post( '/orders/:workOrderId/cancel-requests', requireActiveWorker, createRouteHandler( (req) => submitWorkerCancelRequest( String(req.params.workOrderId || ''), req.body || {}, getRequiredWorkerSession(req), ), { successMessage: '取消申请已提交,等待客服审核', errorMessage: '提交取消申请失败', scope: '[worker/orders/:workOrderId/cancel-requests]', }, ), ) router.get( '/orders/:workOrderId/events', requireActiveWorker, createRouteHandler( (req) => getWorkerMyOrderEvents(String(req.params.workOrderId || ''), getRequiredWorkerSession(req)), { successMessage: 'ok', errorMessage: '读取订单流转记录失败', scope: '[worker/orders/:workOrderId/events]', }, ), ) router.post( '/orders/:workOrderId/read', requireActiveWorker, createRouteHandler( (req) => markWorkerOrderRead(String(req.params.workOrderId || ''), getRequiredWorkerSession(req)), { successMessage: '订单已标记为已读', errorMessage: '标记订单已读失败', scope: '[worker/orders/:workOrderId/read]', }, ), ) router.post( '/orders/:workOrderId/note', requireActiveWorker, createRouteHandler( (req) => saveWorkerOrderNote( String(req.params.workOrderId || ''), req.body || {}, getRequiredWorkerSession(req), ), { successMessage: '备注已保存', errorMessage: '保存备注失败', scope: '[worker/orders/:workOrderId/note]', }, ), ) router.post( '/orders/:workOrderId/submit-acceptance', requireActiveWorker, createRouteHandler( (req) => submitWorkerOrderAcceptance( String(req.params.workOrderId || ''), req.body || {}, getRequiredWorkerSession(req), ), { successMessage: '验收资料已提交', errorMessage: '提交验收资料失败', scope: '[worker/orders/:workOrderId/submit-acceptance]', }, ), ) router.post( '/orders/:workOrderId/remind-acceptance', requireActiveWorker, createRouteHandler( (req) => remindWorkerOrderAcceptance( String(req.params.workOrderId || ''), getRequiredWorkerSession(req), ), { successMessage: '已催促管理员验收', errorMessage: '催验收失败', scope: '[worker/orders/:workOrderId/remind-acceptance]', }, ), ) router.post( '/orders/:workOrderId/acceptance-draft', requireActiveWorker, createRouteHandler( (req) => saveWorkerOrderAcceptanceDraft( String(req.params.workOrderId || ''), req.body || {}, getRequiredWorkerSession(req), ), { successMessage: '验收图片已保存', errorMessage: '保存验收图片失败', scope: '[worker/orders/:workOrderId/acceptance-draft]', }, ), ) router.post( '/orders/:workOrderId/acceptance-evidence', requireActiveWorker, createRouteHandler( (req) => supplementWorkerAcceptedOrderEvidence( String(req.params.workOrderId || ''), req.body || {}, getRequiredWorkerSession(req), ), { successMessage: '验收图片已补充', errorMessage: '补充验收图片失败', scope: '[worker/orders/:workOrderId/acceptance-evidence]', }, ), ) router.use((req, res) => { res.status(404).json(buildNotFoundPayload(req)) }) export default router