增加管理员联系二维码
This commit is contained in:
@@ -17,6 +17,9 @@ export type WorkerFinanceConfig = {
|
||||
qrCodeImage: UploadedFileDto | null
|
||||
instructions: string
|
||||
}
|
||||
adminContact: {
|
||||
wechatQrCodeImage: UploadedFileDto | null
|
||||
}
|
||||
withdraw: {
|
||||
enabled: boolean
|
||||
instructions: string
|
||||
@@ -44,6 +47,11 @@ export async function saveWorkerFinanceConfig(rawValue: unknown): Promise<Worker
|
||||
export function normalizeWorkerFinanceConfig(rawValue: unknown): WorkerFinanceConfig {
|
||||
const source = isPlainObject(rawValue) ? rawValue : {}
|
||||
const recharge = isPlainObject(source.recharge) ? source.recharge : {}
|
||||
const adminContact = isPlainObject(source.adminContact)
|
||||
? source.adminContact
|
||||
: isPlainObject(source.admin_contact)
|
||||
? source.admin_contact
|
||||
: {}
|
||||
const withdraw = isPlainObject(source.withdraw) ? source.withdraw : {}
|
||||
|
||||
return {
|
||||
@@ -58,6 +66,12 @@ export function normalizeWorkerFinanceConfig(rawValue: unknown): WorkerFinanceCo
|
||||
),
|
||||
instructions: String(recharge.instructions || '').trim(),
|
||||
},
|
||||
adminContact: {
|
||||
wechatQrCodeImage: normalizeUploadedFileForStorage(
|
||||
adminContact.wechatQrCodeImage || adminContact.wechat_qr_code_image,
|
||||
'管理员微信二维码',
|
||||
),
|
||||
},
|
||||
withdraw: {
|
||||
enabled: typeof withdraw.enabled === 'boolean' ? withdraw.enabled : true,
|
||||
instructions: String(withdraw.instructions || '').trim(),
|
||||
@@ -76,6 +90,9 @@ export function createDefaultWorkerFinanceConfig(): WorkerFinanceConfig {
|
||||
qrCodeImage: null,
|
||||
instructions: '',
|
||||
},
|
||||
adminContact: {
|
||||
wechatQrCodeImage: null,
|
||||
},
|
||||
withdraw: {
|
||||
enabled: true,
|
||||
instructions: '',
|
||||
@@ -92,6 +109,11 @@ function refreshWorkerFinanceConfig(config: WorkerFinanceConfig): WorkerFinanceC
|
||||
? (refreshUploadedFileUrls(config.recharge.qrCodeImage) as UploadedFileDto)
|
||||
: null,
|
||||
},
|
||||
adminContact: {
|
||||
wechatQrCodeImage: config.adminContact.wechatQrCodeImage
|
||||
? (refreshUploadedFileUrls(config.adminContact.wechatQrCodeImage) as UploadedFileDto)
|
||||
: null,
|
||||
},
|
||||
withdraw: {
|
||||
...config.withdraw,
|
||||
},
|
||||
@@ -106,7 +128,10 @@ function normalizeRangeInteger(value: unknown, fallback: number, min: number, ma
|
||||
return Math.min(max, Math.max(min, parsed))
|
||||
}
|
||||
|
||||
function normalizeUploadedFileForStorage(value: unknown): UploadedFileDto | null {
|
||||
function normalizeUploadedFileForStorage(
|
||||
value: unknown,
|
||||
fallbackFilename = '收款二维码',
|
||||
): UploadedFileDto | null {
|
||||
if (!isPlainObject(value)) {
|
||||
return null
|
||||
}
|
||||
@@ -124,7 +149,7 @@ function normalizeUploadedFileForStorage(value: unknown): UploadedFileDto | null
|
||||
objectKey,
|
||||
),
|
||||
mediumUrl: normalizeStoredFileUrl(value.mediumUrl || value.medium_url, objectKey),
|
||||
filename: String(value.filename || '').trim() || '收款二维码',
|
||||
filename: String(value.filename || '').trim() || fallbackFilename,
|
||||
contentType: String(value.contentType || value.content_type || '').trim(),
|
||||
size: Math.max(0, Number(value.size || 0) || 0),
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ import {
|
||||
countWorkCategoryUsages,
|
||||
countWorkerLevelUsages,
|
||||
countWorkOrderPendingSharingSubmissions,
|
||||
countWorkerCancellationsSince,
|
||||
countWorkerSmsCodesOnDay,
|
||||
cancelWorkerWorkOrder,
|
||||
consumeWorkerSmsCode,
|
||||
createWorkerSmsCode,
|
||||
createWorkOrder,
|
||||
@@ -102,7 +100,7 @@ import {
|
||||
saveWorkerFinanceConfig,
|
||||
} from './worker-finance-config-service.js'
|
||||
|
||||
import { DEFAULT_CATEGORY_KEY, DEFAULT_LEVEL_KEY, DEFAULT_LEVEL_NAME, INVITE_CODE_LENGTH, INVITE_CODE_RETRY_LIMIT, WORKER_CANCEL_LIMIT_PER_WINDOW, WORKER_CANCEL_LIMIT_WINDOW_MS, createWorkerSession, ensureWorkerAuthConfigured, hashWorkerPassword, isIgnorableWorkerAuthError, mapCollectLookupOrder, mapFinanceRequest, mapWalletLedger, mapWorkCategory, mapWorkOrderForWorker, mapWorkOrderPublic, mapWorkOrderShare, mapWorkerUser, normalizeAmountFen, normalizeFinanceRequestStatus, normalizeFinanceRequestType, normalizeInteger, normalizeOptionalId, normalizePassword, normalizePositiveInteger, normalizeProofFiles, normalizeSessionVersion, normalizeStringArray, normalizeSubmittedFields, normalizeUploadedFiles, normalizeUsername, normalizeWalletLedgerType, normalizeWithdrawChannel, resolveFreezeDepositAmount, resolveRequirementFields, resolveWorkerPermissions, safeCompare, signWorkerPayload, throwGrabWorkOrderFailure, validateWorkerPassword, validateWorkerUsername, verifyWorkerPassword } from './mappers.js'
|
||||
import { DEFAULT_CATEGORY_KEY, DEFAULT_LEVEL_KEY, DEFAULT_LEVEL_NAME, INVITE_CODE_LENGTH, INVITE_CODE_RETRY_LIMIT, createWorkerSession, ensureWorkerAuthConfigured, hashWorkerPassword, isIgnorableWorkerAuthError, mapCollectLookupOrder, mapFinanceRequest, mapWalletLedger, mapWorkCategory, mapWorkOrderForWorker, mapWorkOrderPublic, mapWorkOrderShare, mapWorkerUser, normalizeAmountFen, normalizeFinanceRequestStatus, normalizeFinanceRequestType, normalizeInteger, normalizeOptionalId, normalizePassword, normalizePositiveInteger, normalizeProofFiles, normalizeSessionVersion, normalizeStringArray, normalizeSubmittedFields, normalizeUploadedFiles, normalizeUsername, normalizeWalletLedgerType, normalizeWithdrawChannel, resolveFreezeDepositAmount, resolveRequirementFields, resolveWorkerPermissions, safeCompare, signWorkerPayload, throwGrabWorkOrderFailure, validateWorkerPassword, validateWorkerUsername, verifyWorkerPassword } from './mappers.js'
|
||||
|
||||
export type WorkerSession = {
|
||||
sessionId: string
|
||||
@@ -1086,49 +1084,6 @@ function resolveWorkOrderShareJoinError(
|
||||
})
|
||||
}
|
||||
|
||||
export async function cancelWorkerOrder(
|
||||
workOrderId: number | string,
|
||||
session: WorkerSession,
|
||||
) {
|
||||
requireActiveWorkerSession(session)
|
||||
const worker = await getRequiredWorker(session.workerId)
|
||||
const now = nowIso()
|
||||
const since = new Date(Date.now() - WORKER_CANCEL_LIMIT_WINDOW_MS).toISOString()
|
||||
const cancelCount = await countWorkerCancellationsSince(worker.id, since)
|
||||
if (cancelCount >= WORKER_CANCEL_LIMIT_PER_WINDOW) {
|
||||
throw createHttpError(
|
||||
`30 天内取消接单已达 ${WORKER_CANCEL_LIMIT_PER_WINDOW} 次上限,请谨慎接单`,
|
||||
{
|
||||
statusCode: 409,
|
||||
errorCode: 'worker_cancel_limit_reached',
|
||||
},
|
||||
)
|
||||
}
|
||||
const result = await cancelWorkerWorkOrder({
|
||||
workOrderId: Number(workOrderId),
|
||||
workerId: Number(worker.id),
|
||||
now,
|
||||
})
|
||||
if (result.failureReason === 'work_order_owner_required') {
|
||||
throw createHttpError('只能取消自己接的订单', {
|
||||
statusCode: 403,
|
||||
errorCode: 'work_order_owner_required',
|
||||
})
|
||||
}
|
||||
if (!result.order) {
|
||||
throw createHttpError('当前订单状态不能取消,仅进行中的订单可取消', {
|
||||
statusCode: 409,
|
||||
errorCode: 'work_order_cancel_status_invalid',
|
||||
})
|
||||
}
|
||||
return {
|
||||
order: mapWorkOrderForWorker(
|
||||
result.order,
|
||||
resolveWorkerPermissions(await getRequiredWorker(session.workerId)),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
export async function submitWorkerOrderAcceptance(
|
||||
workOrderId: number | string,
|
||||
payload: JsonObject = {},
|
||||
|
||||
Reference in New Issue
Block a user