押金解冻天数可配置与待解冻押金扣减,超时订单保留记录
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
const SCHEDULED_JOBS_FILE_PATH = path.join(PROJECT_ROOT, 'data', 'scheduled-jobs.json')
|
||||
const CLOUDTENTACLES_HEALTH_JOB_ID = 'cloudtentacles-health'
|
||||
const WORK_ORDER_TIMEOUT_JOB_ID = 'work-order-timeout'
|
||||
const DEPOSIT_UNFREEZE_JOB_ID = 'deposit-unfreeze'
|
||||
|
||||
export function getScheduledJobsFilePath() {
|
||||
return SCHEDULED_JOBS_FILE_PATH
|
||||
@@ -46,6 +47,12 @@ export function getWorkOrderTimeoutJob(config: JsonObject = getScheduledJobsConf
|
||||
|| createDefaultWorkOrderTimeoutJob()
|
||||
}
|
||||
|
||||
export function getDepositUnfreezeJob(config: JsonObject = getScheduledJobsConfig()) {
|
||||
return (Array.isArray(config.jobs) ? config.jobs : [])
|
||||
.find((item) => String(item.id || '').trim() === DEPOSIT_UNFREEZE_JOB_ID)
|
||||
|| createDefaultDepositUnfreezeJob()
|
||||
}
|
||||
|
||||
export function getScheduledJobById(jobId: unknown, config: JsonObject = getScheduledJobsConfig()) {
|
||||
return (Array.isArray(config.jobs) ? config.jobs : [])
|
||||
.find((item) => String(item.id || '').trim() === String(jobId || '').trim()) || null
|
||||
@@ -59,6 +66,7 @@ export function normalizeScheduledJobsConfig(rawValue: unknown) {
|
||||
.filter((item): item is NonNullable<ReturnType<typeof normalizeScheduledJob>> => Boolean(item))
|
||||
const hasCloudtentaclesHealth = jobs.some((item) => item.id === CLOUDTENTACLES_HEALTH_JOB_ID)
|
||||
const hasWorkOrderTimeout = jobs.some((item) => item.id === WORK_ORDER_TIMEOUT_JOB_ID)
|
||||
const hasDepositUnfreeze = jobs.some((item) => item.id === DEPOSIT_UNFREEZE_JOB_ID)
|
||||
|
||||
if (!hasCloudtentaclesHealth) {
|
||||
jobs.push(createDefaultCloudtentaclesHealthJob())
|
||||
@@ -66,6 +74,9 @@ export function normalizeScheduledJobsConfig(rawValue: unknown) {
|
||||
if (!hasWorkOrderTimeout) {
|
||||
jobs.push(createDefaultWorkOrderTimeoutJob())
|
||||
}
|
||||
if (!hasDepositUnfreeze) {
|
||||
jobs.push(createDefaultDepositUnfreezeJob())
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: typeof source.enabled === 'boolean' ? source.enabled : true,
|
||||
@@ -85,10 +96,27 @@ function normalizeScheduledJob(rawValue: unknown) {
|
||||
if (type === 'work_order_timeout') {
|
||||
return normalizeWorkOrderTimeoutJob(rawValue)
|
||||
}
|
||||
if (type === 'deposit_unfreeze') {
|
||||
return normalizeDepositUnfreezeJob(rawValue)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function normalizeDepositUnfreezeJob(rawValue: JsonObject) {
|
||||
const config = isPlainObject(rawValue.config) ? rawValue.config : {}
|
||||
|
||||
return {
|
||||
id: DEPOSIT_UNFREEZE_JOB_ID,
|
||||
type: 'deposit_unfreeze',
|
||||
enabled: rawValue.enabled !== false,
|
||||
intervalSeconds: normalizeRangeInteger(rawValue.intervalSeconds, 60, 30, 3600),
|
||||
config: {
|
||||
scanLimit: normalizeRangeInteger(config.scanLimit, 100, 1, 2000),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeWorkOrderTimeoutJob(rawValue: JsonObject) {
|
||||
const config = isPlainObject(rawValue.config) ? rawValue.config : {}
|
||||
|
||||
@@ -171,10 +199,23 @@ function createDefaultScheduledJobsConfig() {
|
||||
jobs: [
|
||||
createDefaultCloudtentaclesHealthJob(),
|
||||
createDefaultWorkOrderTimeoutJob(),
|
||||
createDefaultDepositUnfreezeJob(),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function createDefaultDepositUnfreezeJob() {
|
||||
return {
|
||||
id: DEPOSIT_UNFREEZE_JOB_ID,
|
||||
type: 'deposit_unfreeze',
|
||||
enabled: true,
|
||||
intervalSeconds: 60,
|
||||
config: {
|
||||
scanLimit: 100,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function createDefaultWorkOrderTimeoutJob() {
|
||||
return {
|
||||
id: WORK_ORDER_TIMEOUT_JOB_ID,
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { JsonObject } from '../../types/json.js'
|
||||
import { logInfo } from '../../utils/logger.js'
|
||||
import { settleDueDepositUnfreezes } from '../worker-platform/worker-service.js'
|
||||
|
||||
export async function runDepositUnfreezeJob(job: JsonObject) {
|
||||
const config =
|
||||
job.config && typeof job.config === 'object' && !Array.isArray(job.config)
|
||||
? (job.config as JsonObject)
|
||||
: {}
|
||||
const scanLimit = Math.max(1, Number(config.scanLimit || 100))
|
||||
|
||||
const result = await settleDueDepositUnfreezes({ limit: scanLimit })
|
||||
|
||||
logInfo('[deposit-unfreeze]', '押金解冻扫描完成', result)
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
status: 'ok',
|
||||
message: `扫描 ${result.checkedCount} 笔,解冻 ${result.processedCount} 笔`,
|
||||
checkedCount: result.checkedCount,
|
||||
failedCount: 0,
|
||||
asset: result.processedCount,
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
getScheduledJobsConfig,
|
||||
} from './config-service.js'
|
||||
import { runCloudtentaclesHealthJob } from './cloudtentacles-health-job.js'
|
||||
import { runDepositUnfreezeJob } from './deposit-unfreeze-job.js'
|
||||
import { runWorkOrderTimeoutJob } from './work-order-timeout-job.js'
|
||||
|
||||
const timers = new Map<string, NodeJS.Timeout>()
|
||||
@@ -182,6 +183,9 @@ function dispatchJob(job: JsonObject) {
|
||||
if (job.type === 'work_order_timeout') {
|
||||
return runWorkOrderTimeoutJob(job)
|
||||
}
|
||||
if (job.type === 'deposit_unfreeze') {
|
||||
return runDepositUnfreezeJob(job)
|
||||
}
|
||||
|
||||
throw createHttpError(`不支持的定时任务类型:${job.type}`, {
|
||||
statusCode: 400,
|
||||
|
||||
Reference in New Issue
Block a user