修正快手行业电子凭证核销参数
This commit is contained in:
@@ -104,11 +104,12 @@ export async function reverseAdminKuaishouIndustryVoucher(input: JsonObject = {}
|
||||
export async function consumeAdminKuaishouIndustryVoucherByCode(input: JsonObject = {}) {
|
||||
const voucher = await resolveRequiredVoucher(input)
|
||||
const task = voucher.task_id ? await getTaskById(voucher.task_id) : null
|
||||
const consumeType = String(input.consumeType || '').trim()
|
||||
const consumeInput: Parameters<typeof consumeKuaishouIndustryVoucher>[1] = {
|
||||
source: 'admin_tool_manual_consume',
|
||||
token: String(input.token || voucher.token || '').trim(),
|
||||
consumeType: String(input.consumeType || 'delivery').trim() || 'delivery',
|
||||
consumeTime: Date.now(),
|
||||
...(consumeType ? { consumeType } : {}),
|
||||
...(input.serialNum ? { serialNum: String(input.serialNum).trim() } : {}),
|
||||
...(input.eticketType ? { eticketType: String(input.eticketType).trim() } : {}),
|
||||
...(input.storeName ? { storeName: String(input.storeName).trim() } : {}),
|
||||
|
||||
@@ -857,12 +857,13 @@ export async function consumeAdminTaskKuaishouIndustryVoucher(
|
||||
}
|
||||
|
||||
const voucher = await getRequiredIndustryVoucherForTask(task)
|
||||
const consumeType = String(payload.consumeType || '').trim()
|
||||
const result = await consumeKuaishouIndustryVoucher(voucher, {
|
||||
source: 'admin_manual_consume',
|
||||
task,
|
||||
token: voucher.token,
|
||||
consumeType: String(payload.consumeType || 'delivery').trim() || 'delivery',
|
||||
consumeTime: Date.now(),
|
||||
...(consumeType ? { consumeType } : {}),
|
||||
...(payload.storeName ? { storeName: payload.storeName } : {}),
|
||||
...(payload.storeAddress ? { storeAddress: payload.storeAddress } : {}),
|
||||
...(payload.expressCode ? { expressCode: payload.expressCode } : {}),
|
||||
|
||||
@@ -817,7 +817,6 @@ export async function returnKuaishouCloudFulfillmentTask(
|
||||
? await consumeKuaishouIndustryVouchersForTask(task, {
|
||||
source: String(options.source || "system_auto_finalize").trim() || "system_auto_finalize",
|
||||
token: String(taskContext.kuaishouIndustryVoucher?.token || "").trim(),
|
||||
consumeType: "delivery",
|
||||
consumeTime: Date.now(),
|
||||
})
|
||||
: { ok: true, consumed: [], failed: [] };
|
||||
|
||||
@@ -146,7 +146,6 @@ export async function syncKuaishouFeifeiTaskStatus(task: TaskRow) {
|
||||
if (order.rechargeStatus === 30) {
|
||||
const consumeResult = await consumeKuaishouIndustryVouchersForTask(task, {
|
||||
source: 'kuaishou_feifei_completed',
|
||||
consumeType: 'delivery',
|
||||
consumeTime: Date.now(),
|
||||
})
|
||||
const consumedVoucher = consumeResult.consumed[0] || null
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { buildConsumeCallbackBizParams } from './consume-callback-service.js'
|
||||
|
||||
test('buildConsumeCallbackBizParams omits eticket status', () => {
|
||||
const bizParams = buildConsumeCallbackBizParams({
|
||||
oid: '2619000086068982',
|
||||
etickets: [{
|
||||
id: 'KSVASXT6Q955WT4SS36',
|
||||
num: 1,
|
||||
status: 'CONSUMED',
|
||||
} as any],
|
||||
status: 'CONSUMED',
|
||||
consumeType: 'consume',
|
||||
consumeTime: 1783596649024,
|
||||
token: 'ticket-token',
|
||||
seriallNum: 'CONSUME-KSVASXT6Q955WT4SS36',
|
||||
})
|
||||
|
||||
assert.deepEqual(bizParams.etickets, [{
|
||||
id: 'KSVASXT6Q955WT4SS36',
|
||||
num: 1,
|
||||
}])
|
||||
assert.equal(bizParams.consumeType, 'consume')
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
import { logInfo, logWarn } from '../../../utils/logger.js'
|
||||
import { requestKuaishouIndustryOpenApi, type JsonObject } from './openapi-client.js'
|
||||
|
||||
type ConsumeCallbackInput = {
|
||||
export type ConsumeCallbackInput = {
|
||||
oid: string
|
||||
sellerId?: string
|
||||
etickets: Array<{
|
||||
@@ -9,7 +9,6 @@ type ConsumeCallbackInput = {
|
||||
code?: string
|
||||
num: number
|
||||
goodsValue?: number
|
||||
status?: string
|
||||
}>
|
||||
status: string
|
||||
consumeType: string
|
||||
@@ -29,30 +28,7 @@ type ConsumeCallbackInput = {
|
||||
export async function consumeCallback(
|
||||
input: ConsumeCallbackInput,
|
||||
): Promise<{ success: boolean; response?: JsonObject; error?: string }> {
|
||||
const bizParams: JsonObject = {
|
||||
oid: input.oid,
|
||||
etickets: input.etickets.map((e) => {
|
||||
const item: JsonObject = { id: e.id, num: e.num }
|
||||
if (e.code) item.code = e.code
|
||||
if (e.goodsValue != null) item.goodsValue = e.goodsValue
|
||||
if (e.status) item.status = e.status
|
||||
return item
|
||||
}),
|
||||
status: input.status,
|
||||
consumeType: input.consumeType,
|
||||
token: input.token,
|
||||
}
|
||||
|
||||
if (input.consumeTime != null) bizParams.consumeTime = input.consumeTime
|
||||
if (input.storeName) bizParams.storeName = input.storeName
|
||||
if (input.storeAddress) bizParams.storeAddress = input.storeAddress
|
||||
if (input.expressNo) bizParams.expressNo = input.expressNo
|
||||
if (input.expressCode) bizParams.expressCode = input.expressCode
|
||||
if (input.appointmentTime) bizParams.appointmentTime = input.appointmentTime
|
||||
if (input.eticketType) bizParams.eticketType = input.eticketType
|
||||
if (input.ext) bizParams.ext = input.ext
|
||||
if (input.seriallNum) bizParams.seriallNum = input.seriallNum
|
||||
if (input.consumePoiId != null) bizParams.consumePoiId = input.consumePoiId
|
||||
const bizParams = buildConsumeCallbackBizParams(input)
|
||||
|
||||
const result = await requestKuaishouIndustryOpenApi({
|
||||
apiMethod: 'integration.callback.virtual.eticket.consume',
|
||||
@@ -115,3 +91,31 @@ export async function consumeCallback(
|
||||
...(result.error ? { error: result.error } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
export function buildConsumeCallbackBizParams(input: ConsumeCallbackInput): JsonObject {
|
||||
const bizParams: JsonObject = {
|
||||
oid: input.oid,
|
||||
etickets: input.etickets.map((e) => {
|
||||
const item: JsonObject = { id: e.id, num: e.num }
|
||||
if (e.code) item.code = e.code
|
||||
if (e.goodsValue != null) item.goodsValue = e.goodsValue
|
||||
return item
|
||||
}),
|
||||
status: input.status,
|
||||
consumeType: input.consumeType,
|
||||
token: input.token,
|
||||
}
|
||||
|
||||
if (input.consumeTime != null) bizParams.consumeTime = input.consumeTime
|
||||
if (input.storeName) bizParams.storeName = input.storeName
|
||||
if (input.storeAddress) bizParams.storeAddress = input.storeAddress
|
||||
if (input.expressNo) bizParams.expressNo = input.expressNo
|
||||
if (input.expressCode) bizParams.expressCode = input.expressCode
|
||||
if (input.appointmentTime) bizParams.appointmentTime = input.appointmentTime
|
||||
if (input.eticketType) bizParams.eticketType = input.eticketType
|
||||
if (input.ext) bizParams.ext = input.ext
|
||||
if (input.seriallNum) bizParams.seriallNum = input.seriallNum
|
||||
if (input.consumePoiId != null) bizParams.consumePoiId = input.consumePoiId
|
||||
|
||||
return bizParams
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { generateKuaishouIndustryVoucherCode } from '../../../repositories/kuais
|
||||
import { buildKuaishouIndustryVoucherContext } from './voucher-binding-service.js'
|
||||
import {
|
||||
buildKuaishouIndustryEticketFromVoucher,
|
||||
normalizeKuaishouIndustryConsumeType,
|
||||
resolveKuaishouIndustryVoucherValidity,
|
||||
} from './voucher-service.js'
|
||||
|
||||
@@ -62,6 +63,12 @@ test('resolveKuaishouIndustryVoucherValidity prefers actual certificate time ran
|
||||
assert.equal(validity.validEndTime, 5000)
|
||||
})
|
||||
|
||||
test('normalizeKuaishouIndustryConsumeType defaults to consume', () => {
|
||||
assert.equal(normalizeKuaishouIndustryConsumeType(undefined), 'consume')
|
||||
assert.equal(normalizeKuaishouIndustryConsumeType(''), 'consume')
|
||||
assert.equal(normalizeKuaishouIndustryConsumeType(' pickup '), 'pickup')
|
||||
})
|
||||
|
||||
test('buildKuaishouIndustryEticketFromVoucher mirrors voucher code into id and code', () => {
|
||||
const eticket = buildKuaishouIndustryEticketFromVoucher({
|
||||
voucher_code: 'KSV15K821FDHPMTX1ST',
|
||||
|
||||
@@ -17,6 +17,7 @@ export const KUAISHOU_INDUSTRY_SEND_CALLBACK_STATUS = {
|
||||
SUCCESS: 'success',
|
||||
FAILED: 'failed',
|
||||
} as const
|
||||
export const KUAISHOU_INDUSTRY_DEFAULT_CONSUME_TYPE = 'consume'
|
||||
|
||||
export function resolveKuaishouIndustryVoucherValidity(
|
||||
input: {
|
||||
@@ -124,7 +125,7 @@ export async function consumeKuaishouIndustryVouchersForTask(
|
||||
for (const voucher of vouchers) {
|
||||
const consumeInput: Parameters<typeof consumeKuaishouIndustryVoucher>[1] = {
|
||||
source: input.source || 'fulfillment_completed',
|
||||
consumeType: input.consumeType || 'delivery',
|
||||
consumeType: normalizeKuaishouIndustryConsumeType(input.consumeType),
|
||||
consumeTime: input.consumeTime || Date.now(),
|
||||
task,
|
||||
}
|
||||
@@ -202,7 +203,7 @@ export async function consumeKuaishouIndustryVoucher(
|
||||
|
||||
const now = new Date().toISOString()
|
||||
const consumeTime = Number(input.consumeTime || Date.now()) || Date.now()
|
||||
const consumeType = String(input.consumeType || 'delivery').trim() || 'delivery'
|
||||
const consumeType = normalizeKuaishouIndustryConsumeType(input.consumeType)
|
||||
const serialNum = String(input.serialNum || voucher.consume_serial_num || `CONSUME-${voucher.voucher_code}`).trim()
|
||||
const token = String(input.token || voucher.token || '').trim()
|
||||
const consumeDetail = {
|
||||
@@ -224,7 +225,6 @@ export async function consumeKuaishouIndustryVoucher(
|
||||
etickets: [{
|
||||
id: voucher.voucher_code,
|
||||
num: 1,
|
||||
status: 'CONSUMED',
|
||||
}],
|
||||
status: 'CONSUMED',
|
||||
consumeType,
|
||||
@@ -317,7 +317,7 @@ function resolveVoucherConsumeDetails(voucher: KuaishouIndustryVoucherRow): Json
|
||||
|
||||
return [{
|
||||
serialNum: voucher.consume_serial_num,
|
||||
consumeType: 'delivery',
|
||||
consumeType: KUAISHOU_INDUSTRY_DEFAULT_CONSUME_TYPE,
|
||||
consumeTime: voucher.consumed_at ? Date.parse(voucher.consumed_at) : 0,
|
||||
}]
|
||||
}
|
||||
@@ -340,6 +340,11 @@ function normalizeVoucherStatus(value: unknown): string {
|
||||
return 'UNUSED'
|
||||
}
|
||||
|
||||
export function normalizeKuaishouIndustryConsumeType(value: unknown): string {
|
||||
return String(value || KUAISHOU_INDUSTRY_DEFAULT_CONSUME_TYPE).trim() ||
|
||||
KUAISHOU_INDUSTRY_DEFAULT_CONSUME_TYPE
|
||||
}
|
||||
|
||||
function normalizePositiveTimestamp(value: unknown): number {
|
||||
const parsed = Number(value)
|
||||
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : 0
|
||||
|
||||
@@ -91,7 +91,7 @@ export default function AdminKuaishouIndustryPage() {
|
||||
})
|
||||
const [toolForm, setToolForm] = useState<AdminKuaishouIndustryVoucherToolPayload>({
|
||||
eticketType: DEFAULT_ETICKET_TYPE,
|
||||
consumeType: 'delivery',
|
||||
consumeType: 'consume',
|
||||
})
|
||||
const [refundDateRange, setRefundDateRange] = useState<DateRangeValue>(() => [
|
||||
dayjs().subtract(1, 'day'),
|
||||
|
||||
Reference in New Issue
Block a user