增加接单分类和大厅分类配额
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
import {
|
||||
createWorkOrder,
|
||||
createWorkOrderEvent,
|
||||
getWorkCategoryById,
|
||||
listWorkOrdersByPlatformOrderId,
|
||||
} from '../../repositories/worker-platform/index.js'
|
||||
import type { JsonObject } from '../../types/json.js'
|
||||
@@ -47,6 +48,18 @@ export async function createAdminMockWorkOrder(payload: JsonObject = {}) {
|
||||
: 0
|
||||
: normalizeAmountFen(payload.requiredDepositAmount, 0)
|
||||
const paymentFen = input.paymentAmount
|
||||
const requestedCategoryId = Number(payload.categoryId || payload.category_id || 0)
|
||||
let categoryId = defaults.category?.id || null
|
||||
if (requestedCategoryId > 0) {
|
||||
const category = await getWorkCategoryById(requestedCategoryId)
|
||||
if (!category || category.status !== 'active') {
|
||||
throw createHttpError('所选接单分类不存在或已停用', {
|
||||
statusCode: 409,
|
||||
errorCode: 'mock_work_order_category_invalid',
|
||||
})
|
||||
}
|
||||
categoryId = Number(category.id)
|
||||
}
|
||||
const materialComplete = payload.materialComplete === true || payload.materialComplete === 'true'
|
||||
const fields = normalizeRequirementFields(payload.fields)
|
||||
const { platformOrderId, productName, shop } = input
|
||||
@@ -92,7 +105,7 @@ export async function createAdminMockWorkOrder(payload: JsonObject = {}) {
|
||||
workOrderNo: randomId('WO'),
|
||||
platformOrderId,
|
||||
productName,
|
||||
categoryId: defaults.category?.id || null,
|
||||
categoryId,
|
||||
status: materialComplete ? WORK_ORDER_STATUS.UNASSIGNED : WORK_ORDER_STATUS.PENDING_MATERIAL,
|
||||
rewardAmount,
|
||||
requiredDepositAmount,
|
||||
|
||||
@@ -250,6 +250,7 @@ export async function publishAdminWorkOrder(workOrderId: number | string, actorN
|
||||
workOrderId: Number(workOrder.id),
|
||||
statuses: [WORK_ORDER_STATUS.OPEN],
|
||||
hallCandidateLimit: hallConfig.maxVisibleOrders,
|
||||
hallCategoryLimits: hallConfig.categoryMaxVisibleOrders,
|
||||
excludeFilledSharing: true,
|
||||
})
|
||||
return {
|
||||
|
||||
@@ -30,6 +30,7 @@ export async function listAdminWorkOrders(query: JsonObject = {}) {
|
||||
const page = normalizePage(query.page)
|
||||
const pageSize = normalizePageSize(query.pageSize)
|
||||
const workOrderId = normalizeOptionalId(query.workOrderId ?? query.work_order_id) || 0
|
||||
const categoryId = normalizeOptionalId(query.categoryId ?? query.category_id) || 0
|
||||
const workerId = normalizeOptionalId(query.workerId ?? query.worker_id) || 0
|
||||
const workerLevelIds = normalizeStatuses(query.workerLevelIds ?? query.worker_level_ids)
|
||||
.map(normalizeOptionalId)
|
||||
@@ -43,6 +44,7 @@ export async function listAdminWorkOrders(query: JsonObject = {}) {
|
||||
const filters = {
|
||||
statuses,
|
||||
workOrderId,
|
||||
categoryId,
|
||||
keyword: String(query.keyword || '').trim(),
|
||||
workerSharingId: workerId,
|
||||
workerLevelIds,
|
||||
|
||||
+44
-25
@@ -5,9 +5,44 @@ import { getWorkerHallConfig, saveWorkerHallConfig } from './worker-hall-config-
|
||||
|
||||
export async function getAdminWorkerPlatformSummary() {
|
||||
const hallConfig = getWorkerHallConfig()
|
||||
const [pendingWorkers, pendingMaterial, openOrders, inProgressOrders] = await Promise.all([
|
||||
listWorkerUsers({ page: 1, pageSize: 1, status: 'pending_review' }),
|
||||
listWorkOrders({ page: 1, pageSize: 1, statuses: [WORK_ORDER_STATUS.PENDING_MATERIAL] }),
|
||||
const [pendingWorkers, pendingMaterial, openOrders, visibleOpenOrders, inProgressOrders] =
|
||||
await Promise.all([
|
||||
listWorkerUsers({ page: 1, pageSize: 1, status: 'pending_review' }),
|
||||
listWorkOrders({ page: 1, pageSize: 1, statuses: [WORK_ORDER_STATUS.PENDING_MATERIAL] }),
|
||||
listWorkOrders({
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
statuses: [WORK_ORDER_STATUS.OPEN],
|
||||
excludeFilledSharing: true,
|
||||
}),
|
||||
listWorkOrders({
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
statuses: [WORK_ORDER_STATUS.OPEN],
|
||||
hallCandidateLimit: hallConfig.maxVisibleOrders,
|
||||
hallCategoryLimits: hallConfig.categoryMaxVisibleOrders,
|
||||
excludeFilledSharing: true,
|
||||
}),
|
||||
listWorkOrders({
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
statuses: [WORK_ORDER_STATUS.IN_PROGRESS],
|
||||
useOperationalStatus: true,
|
||||
}),
|
||||
])
|
||||
return {
|
||||
pendingWorkerCount: pendingWorkers.total,
|
||||
pendingMaterialCount: pendingMaterial.total,
|
||||
openOrderCount: visibleOpenOrders.total,
|
||||
queuedHallOrderCount: Math.max(0, openOrders.total - visibleOpenOrders.total),
|
||||
hallMaxVisibleOrders: hallConfig.maxVisibleOrders,
|
||||
inProgressOrderCount: inProgressOrders.total,
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAdminWorkerHallConfig() {
|
||||
const config = getWorkerHallConfig()
|
||||
const [openOrders, visibleOpenOrders] = await Promise.all([
|
||||
listWorkOrders({
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
@@ -17,32 +52,16 @@ export async function getAdminWorkerPlatformSummary() {
|
||||
listWorkOrders({
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
statuses: [WORK_ORDER_STATUS.IN_PROGRESS],
|
||||
useOperationalStatus: true,
|
||||
statuses: [WORK_ORDER_STATUS.OPEN],
|
||||
hallCandidateLimit: config.maxVisibleOrders,
|
||||
hallCategoryLimits: config.categoryMaxVisibleOrders,
|
||||
excludeFilledSharing: true,
|
||||
}),
|
||||
])
|
||||
return {
|
||||
pendingWorkerCount: pendingWorkers.total,
|
||||
pendingMaterialCount: pendingMaterial.total,
|
||||
openOrderCount: Math.min(openOrders.total, hallConfig.maxVisibleOrders),
|
||||
queuedHallOrderCount: Math.max(0, openOrders.total - hallConfig.maxVisibleOrders),
|
||||
hallMaxVisibleOrders: hallConfig.maxVisibleOrders,
|
||||
inProgressOrderCount: inProgressOrders.total,
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAdminWorkerHallConfig() {
|
||||
const config = getWorkerHallConfig()
|
||||
const openOrders = await listWorkOrders({
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
statuses: [WORK_ORDER_STATUS.OPEN],
|
||||
excludeFilledSharing: true,
|
||||
})
|
||||
return {
|
||||
...config,
|
||||
visibleOrderCount: Math.min(openOrders.total, config.maxVisibleOrders),
|
||||
queuedOrderCount: Math.max(0, openOrders.total - config.maxVisibleOrders),
|
||||
visibleOrderCount: visibleOpenOrders.total,
|
||||
queuedOrderCount: Math.max(0, openOrders.total - visibleOpenOrders.total),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ export async function grabWorkerHallOrder(workOrderId: number | string, session:
|
||||
takeRemaining: true,
|
||||
maxActiveOrders: permissions.maxActiveOrders,
|
||||
hallCandidateLimit: hallConfig.maxVisibleOrders,
|
||||
hallCategoryLimits: hallConfig.categoryMaxVisibleOrders,
|
||||
visibleAfterIso,
|
||||
now,
|
||||
})
|
||||
@@ -91,6 +92,7 @@ export async function grabWorkerHallOrder(workOrderId: number | string, session:
|
||||
depositAmount: freezeAmount,
|
||||
maxActiveOrders: permissions.maxActiveOrders,
|
||||
hallCandidateLimit: hallConfig.maxVisibleOrders,
|
||||
hallCategoryLimits: hallConfig.categoryMaxVisibleOrders,
|
||||
visibleAfterIso,
|
||||
deadlineAt: resolveWorkOrderDeadlineAt(workOrder, now),
|
||||
now,
|
||||
@@ -143,6 +145,7 @@ export async function joinWorkerSharingOrder(
|
||||
quantity,
|
||||
maxActiveOrders: permissions.maxActiveOrders,
|
||||
hallCandidateLimit: hallConfig.maxVisibleOrders,
|
||||
hallCategoryLimits: hallConfig.categoryMaxVisibleOrders,
|
||||
visibleAfterIso,
|
||||
now,
|
||||
})
|
||||
|
||||
@@ -7,17 +7,36 @@ import {
|
||||
} from './worker-hall-config-service.js'
|
||||
|
||||
test('大厅配置默认展示 50 个订单', () => {
|
||||
assert.deepEqual(createDefaultWorkerHallConfig(), { maxVisibleOrders: 50 })
|
||||
assert.deepEqual(normalizeWorkerHallConfig({}), { maxVisibleOrders: 50 })
|
||||
assert.deepEqual(createDefaultWorkerHallConfig(), {
|
||||
maxVisibleOrders: 50,
|
||||
categoryMaxVisibleOrders: {},
|
||||
})
|
||||
assert.deepEqual(normalizeWorkerHallConfig({}), {
|
||||
maxVisibleOrders: 50,
|
||||
categoryMaxVisibleOrders: {},
|
||||
})
|
||||
})
|
||||
|
||||
test('大厅配置只接受 1 到 500 的整数', () => {
|
||||
assert.deepEqual(normalizeWorkerHallConfig({ maxVisibleOrders: 88 }), { maxVisibleOrders: 88 })
|
||||
assert.deepEqual(normalizeWorkerHallConfig({ maxVisibleOrders: 88 }), {
|
||||
maxVisibleOrders: 88,
|
||||
categoryMaxVisibleOrders: {},
|
||||
})
|
||||
assert.deepEqual(normalizeWorkerHallConfig({ max_visible_orders: 999 }), {
|
||||
maxVisibleOrders: 500,
|
||||
categoryMaxVisibleOrders: {},
|
||||
})
|
||||
assert.deepEqual(normalizeWorkerHallConfig({ maxVisibleOrders: 0 }), {
|
||||
maxVisibleOrders: 1,
|
||||
categoryMaxVisibleOrders: {},
|
||||
})
|
||||
assert.deepEqual(normalizeWorkerHallConfig({ maxVisibleOrders: 0 }), { maxVisibleOrders: 1 })
|
||||
assert.deepEqual(normalizeWorkerHallConfig({ maxVisibleOrders: 1.5 }), {
|
||||
maxVisibleOrders: 50,
|
||||
categoryMaxVisibleOrders: {},
|
||||
})
|
||||
assert.deepEqual(
|
||||
normalizeWorkerHallConfig({ categoryMaxVisibleOrders: { '1': 12, '2': 0, '3': 501 } })
|
||||
.categoryMaxVisibleOrders,
|
||||
{ '1': 12 },
|
||||
)
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import { readAppConfigEntry, saveAppConfigEntry } from '../config/app-config-sto
|
||||
|
||||
export type WorkerHallConfig = {
|
||||
maxVisibleOrders: number
|
||||
categoryMaxVisibleOrders: Record<string, number>
|
||||
}
|
||||
|
||||
export function getWorkerHallConfig(): WorkerHallConfig {
|
||||
@@ -23,7 +24,7 @@ export async function saveWorkerHallConfig(rawValue: unknown): Promise<WorkerHal
|
||||
}
|
||||
|
||||
export function createDefaultWorkerHallConfig(): WorkerHallConfig {
|
||||
return { maxVisibleOrders: 50 }
|
||||
return { maxVisibleOrders: 50, categoryMaxVisibleOrders: {} }
|
||||
}
|
||||
|
||||
export function normalizeWorkerHallConfig(rawValue: unknown): WorkerHallConfig {
|
||||
@@ -31,9 +32,24 @@ export function normalizeWorkerHallConfig(rawValue: unknown): WorkerHallConfig {
|
||||
const value = Number(source.maxVisibleOrders ?? source.max_visible_orders)
|
||||
return {
|
||||
maxVisibleOrders: Number.isInteger(value) ? Math.min(500, Math.max(1, value)) : 50,
|
||||
categoryMaxVisibleOrders: normalizeCategoryMaxVisibleOrders(
|
||||
source.categoryMaxVisibleOrders ?? source.category_max_visible_orders,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeCategoryMaxVisibleOrders(value: unknown): Record<string, number> {
|
||||
if (!isPlainObject(value)) return {}
|
||||
return Object.entries(value).reduce<Record<string, number>>((result, [categoryId, raw]) => {
|
||||
const id = Number(categoryId)
|
||||
const limit = Number(raw)
|
||||
if (Number.isInteger(id) && id > 0 && Number.isInteger(limit) && limit >= 1 && limit <= 500) {
|
||||
result[String(id)] = limit
|
||||
}
|
||||
return result
|
||||
}, {})
|
||||
}
|
||||
|
||||
function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Object.prototype.toString.call(value) === '[object Object]'
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ export async function listWorkerHallOrders(query: JsonObject = {}, session: Work
|
||||
keyword: String(query.keyword || '').trim(),
|
||||
categoryId: categoryId || 0,
|
||||
hallCandidateLimit: hallConfig.maxVisibleOrders,
|
||||
hallCategoryLimits: hallConfig.categoryMaxVisibleOrders,
|
||||
visibleAfterIso,
|
||||
excludeFilledSharing: true,
|
||||
pinnedFirst: true,
|
||||
|
||||
Reference in New Issue
Block a user