feat(打手): 支持个人追加免押额度
This commit is contained in:
@@ -16,6 +16,8 @@ export type WorkerUserRow = {
|
||||
display_name: string
|
||||
phone: string
|
||||
level_id: number | null
|
||||
/** 个人追加免押额度(分),与等级额度叠加。 */
|
||||
personal_deposit_free_amount?: number | null
|
||||
status: string
|
||||
worker_type: string
|
||||
review_note: string
|
||||
|
||||
@@ -95,12 +95,37 @@ export function resolveWorkOrderShareJoinQuantity(input: {
|
||||
return input.takeRemaining ? Math.max(0, input.remaining) : input.quantity
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算打手当前累计拼单份额实际需要冻结的押金。
|
||||
* 等级与个人叠加后的免押额度针对该打手在本工单的累计份额生效;已经冻结的金额不自动回退。
|
||||
*/
|
||||
export function resolveWorkOrderShareDepositAmount(input: {
|
||||
requiredDepositAmount: number
|
||||
totalQuantity: number
|
||||
nextQuantity: number
|
||||
depositFreeAmount?: number
|
||||
currentFrozenDeposit?: number
|
||||
}) {
|
||||
const totalQuantity = Math.max(1, Number(input.totalQuantity || 0))
|
||||
const nextRequiredDeposit = Math.round(
|
||||
(Math.max(0, Number(input.requiredDepositAmount || 0)) * Math.max(0, Number(input.nextQuantity || 0))) /
|
||||
totalQuantity,
|
||||
)
|
||||
const requiredShareDeposit = Math.max(
|
||||
0,
|
||||
nextRequiredDeposit - Math.max(0, Number(input.depositFreeAmount || 0)),
|
||||
)
|
||||
return Math.max(Math.max(0, Number(input.currentFrozenDeposit || 0)), requiredShareDeposit)
|
||||
}
|
||||
|
||||
export async function joinWorkOrderShare(input: {
|
||||
workOrderId: number
|
||||
workerId: number
|
||||
quantity: number
|
||||
/** 立即抢单时在事务锁内承接全部剩余份数。 */
|
||||
takeRemaining?: boolean
|
||||
/** 当前打手的有效免押额度(分),按其本次累计拼单份额抵扣。 */
|
||||
depositFreeAmount?: number
|
||||
maxActiveOrders: number
|
||||
hallCandidateLimit?: number
|
||||
hallCategoryLimits?: Record<string, number>
|
||||
@@ -192,9 +217,15 @@ export async function joinWorkOrderShare(input: {
|
||||
const unitReward = toPositiveInteger(workOrder.sharing_unit_reward, 0)
|
||||
const nextQuantity = Number(existingShare?.quantity || 0) + requestedQuantity
|
||||
const shareReward = nextQuantity * unitReward
|
||||
const nextShareDeposit = Math.round(
|
||||
(Number(workOrder.required_deposit_amount || 0) * nextQuantity) / totalQuantity,
|
||||
)
|
||||
const nextShareDeposit = resolveWorkOrderShareDepositAmount({
|
||||
requiredDepositAmount: Number(workOrder.required_deposit_amount || 0),
|
||||
totalQuantity,
|
||||
nextQuantity,
|
||||
...(input.depositFreeAmount === undefined
|
||||
? {}
|
||||
: { depositFreeAmount: input.depositFreeAmount }),
|
||||
currentFrozenDeposit: Number(existingShare?.share_deposit || 0),
|
||||
})
|
||||
const depositToFreeze = Math.max(
|
||||
0,
|
||||
nextShareDeposit - Number(existingShare?.share_deposit || 0),
|
||||
|
||||
@@ -145,6 +145,7 @@ export async function updateWorkerUser(
|
||||
| 'frozen_reason'
|
||||
| 'frozen_at'
|
||||
| 'level_id'
|
||||
| 'personal_deposit_free_amount'
|
||||
| 'session_version'
|
||||
| 'updated_at'
|
||||
| 'reviewed_at'
|
||||
@@ -165,10 +166,11 @@ export async function updateWorkerUser(
|
||||
frozen_reason = $4,
|
||||
frozen_at = $5,
|
||||
level_id = $6,
|
||||
session_version = $7,
|
||||
reviewed_at = $8,
|
||||
updated_at = $9
|
||||
WHERE id = $10
|
||||
personal_deposit_free_amount = $7,
|
||||
session_version = $8,
|
||||
reviewed_at = $9,
|
||||
updated_at = $10
|
||||
WHERE id = $11
|
||||
`,
|
||||
[
|
||||
next.status,
|
||||
@@ -177,6 +179,7 @@ export async function updateWorkerUser(
|
||||
next.frozen_reason || '',
|
||||
next.frozen_at || null,
|
||||
next.level_id || null,
|
||||
next.personal_deposit_free_amount ?? null,
|
||||
Number(next.session_version || 1),
|
||||
next.reviewed_at || null,
|
||||
next.updated_at,
|
||||
|
||||
Reference in New Issue
Block a user