增加分组库存与客服
This commit is contained in:
@@ -19,7 +19,7 @@ import { createTaskEvent } from '../../repositories/task-event-repo.js'
|
||||
import { nowIso } from '../../utils/time.js'
|
||||
import { randomId } from '../../utils/random.js'
|
||||
import { closeAdminTask, confirmAdminTaskAssistedRole, redeemAdminTaskAssisted } from './admin-write-service.js'
|
||||
import { isAssistedClaimTask, parseTaskContext } from './admin-read-shared-helpers.js'
|
||||
import { createAdminViewerContext, isAssistedClaimTask, parseTaskContext } from './admin-read-shared-helpers.js'
|
||||
|
||||
const MANUAL_PROVIDER = 'manual'
|
||||
const MANUAL_PLATFORM = 'manual_redeem'
|
||||
@@ -36,6 +36,7 @@ export async function createAdminManualRedeemTask(
|
||||
payload = /** @type {AdminManualRedeemCreateInput} */ ({}),
|
||||
session = null,
|
||||
) {
|
||||
const viewerContext = createAdminViewerContext(session)
|
||||
const proofValue = normalizeManualProofValue(payload.proofValue)
|
||||
const skuCode = String(payload.skuCode || '').trim()
|
||||
const skuName = String(payload.skuName || '').trim() || skuCode
|
||||
@@ -81,9 +82,20 @@ export async function createAdminManualRedeemTask(
|
||||
const primaryRequirement = requirements.find((item) => item.is_required !== false) || requirements[0] || null
|
||||
const credentialType = String(primaryRequirement?.credential_type || primaryRequirement?.credentialType || 'tencent_code').trim() || 'tencent_code'
|
||||
const roleKey = String(primaryRequirement?.role_key || primaryRequirement?.roleKey || 'primary_code').trim() || 'primary_code'
|
||||
const availableInventory = await findFirstAvailableInventoryItemBySkuCode(skuCode, credentialType)
|
||||
const availableInventory = await findFirstAvailableInventoryItemBySkuCode(
|
||||
skuCode,
|
||||
credentialType,
|
||||
viewerContext.allowedInventoryGroupCodes,
|
||||
)
|
||||
|
||||
if (!availableInventory) {
|
||||
if (viewerContext.restrictInventoryGroups && viewerContext.allowedInventoryGroupCodes?.length === 0) {
|
||||
throw createHttpError('当前客服未绑定任何库存组,无法创建人工兑换任务', {
|
||||
statusCode: 403,
|
||||
errorCode: 'admin_manual_redeem_inventory_group_unbound',
|
||||
})
|
||||
}
|
||||
|
||||
throw createHttpError('当前 SKU 没有可用库存,无法创建人工兑换任务', {
|
||||
statusCode: 409,
|
||||
errorCode: 'admin_manual_redeem_inventory_unavailable',
|
||||
@@ -208,6 +220,7 @@ export async function createAdminManualRedeemTask(
|
||||
credentialType,
|
||||
}
|
||||
: null,
|
||||
inventoryGroupCode: String(availableInventory.inventory_group_code || '').trim(),
|
||||
manualRedeem: manualContext,
|
||||
}),
|
||||
createdAt: now,
|
||||
@@ -226,6 +239,7 @@ export async function createAdminManualRedeemTask(
|
||||
taskId: createdTask.id,
|
||||
credentialType,
|
||||
roleKey,
|
||||
inventoryGroupCodes: viewerContext.allowedInventoryGroupCodes,
|
||||
})
|
||||
|
||||
if (!reservedInventory) {
|
||||
@@ -250,6 +264,10 @@ export async function createAdminManualRedeemTask(
|
||||
claim_expires_at: claimToken.expired_at,
|
||||
user_action_status: 'pending_claim',
|
||||
last_error: '',
|
||||
context_json: JSON.stringify({
|
||||
...parseTaskContext(createdTask),
|
||||
inventoryGroupCode: String(reservedInventory.inventory_group_code || '').trim(),
|
||||
}),
|
||||
updated_at: nowIso(),
|
||||
})
|
||||
|
||||
@@ -259,73 +277,80 @@ export async function createAdminManualRedeemTask(
|
||||
skuCode,
|
||||
skuName,
|
||||
inventoryItemId: Number(reservedInventory.id || 0) || null,
|
||||
inventoryGroupCode: String(reservedInventory.inventory_group_code || '').trim(),
|
||||
createdBy: manualContext.createdBy,
|
||||
remark,
|
||||
}, nowIso())
|
||||
|
||||
return getAdminManualRedeemDetail(createdTask.id)
|
||||
return getAdminManualRedeemDetail(createdTask.id, session)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
export async function getAdminManualRedeemDetail(taskId) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function getAdminManualRedeemDetail(taskId, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
const detail = await getClaimDetailForAdminTask(task.id)
|
||||
return decorateManualRedeemDetail(task, detail)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
/** @param {{ loginType?: string, forceRecreate?: boolean }} [payload] */
|
||||
export async function createAdminManualRedeemSession(taskId, payload = {}) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function createAdminManualRedeemSession(taskId, payload = {}, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
const detail = await createClaimSessionForAdminTask(task.id, payload)
|
||||
return decorateManualRedeemDetail(task, detail)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
export async function getAdminManualRedeemSessionSummary(taskId) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function getAdminManualRedeemSessionSummary(taskId, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
const detail = await getClaimSessionSummaryForAdminTask(task.id)
|
||||
return decorateManualRedeemDetail(task, detail)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
export async function reloadAdminManualRedeemSession(taskId) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function reloadAdminManualRedeemSession(taskId, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
const detail = await reloadClaimSessionForAdminTask(task.id)
|
||||
return decorateManualRedeemDetail(task, detail)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
export async function closeAdminManualRedeemSession(taskId) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function closeAdminManualRedeemSession(taskId, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
const detail = await closeClaimSessionForAdminTask(task.id)
|
||||
return decorateManualRedeemDetail(task, detail)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
export async function closeAdminManualRedeemTask(taskId) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function closeAdminManualRedeemTask(taskId, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
await closeAdminTask(task.id)
|
||||
return getAdminManualRedeemDetail(task.id)
|
||||
return getAdminManualRedeemDetail(task.id, session)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function confirmAdminManualRedeemRole(taskId, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
await confirmAdminTaskAssistedRole(task.id, session)
|
||||
return getAdminManualRedeemDetail(task.id)
|
||||
return getAdminManualRedeemDetail(task.id, session)
|
||||
}
|
||||
|
||||
/** @param {AdminEntityIdInput} taskId */
|
||||
/** @param {AdminViewerSessionInput | null} [session] */
|
||||
export async function redeemAdminManualRedeemTask(taskId, session = null) {
|
||||
const task = await getRequiredManualRedeemTask(taskId)
|
||||
const task = await getRequiredManualRedeemTask(taskId, session)
|
||||
await redeemAdminTaskAssisted(task.id, session)
|
||||
return getAdminManualRedeemDetail(task.id)
|
||||
return getAdminManualRedeemDetail(task.id, session)
|
||||
}
|
||||
|
||||
async function getRequiredManualRedeemTask(taskId) {
|
||||
async function getRequiredManualRedeemTask(taskId, session = null) {
|
||||
const task = await getTaskById(Number(taskId))
|
||||
|
||||
if (!task) {
|
||||
@@ -345,6 +370,25 @@ async function getRequiredManualRedeemTask(taskId) {
|
||||
})
|
||||
}
|
||||
|
||||
const viewerContext = createAdminViewerContext(session)
|
||||
if (viewerContext.restrictInventoryGroups) {
|
||||
if (!Array.isArray(viewerContext.allowedInventoryGroupCodes) || viewerContext.allowedInventoryGroupCodes.length === 0) {
|
||||
throw createHttpError('当前客服未绑定任何库存组,无法操作人工兑换任务', {
|
||||
statusCode: 403,
|
||||
errorCode: 'admin_manual_redeem_inventory_group_unbound',
|
||||
})
|
||||
}
|
||||
|
||||
const inventoryGroupCode = String(taskContext?.inventoryGroupCode || '').trim()
|
||||
|
||||
if (inventoryGroupCode && !viewerContext.allowedInventoryGroupCodes.includes(inventoryGroupCode)) {
|
||||
throw createHttpError('当前客服无权操作该库存组下的人工兑换任务', {
|
||||
statusCode: 403,
|
||||
errorCode: 'admin_manual_redeem_inventory_group_denied',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return task
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user