移除快手小店以及 api
This commit is contained in:
@@ -45,7 +45,7 @@ async function preparePaidTask(
|
||||
claim_token: claimToken.token,
|
||||
claim_expires_at: claimToken.expired_at,
|
||||
user_action_status: 'pending_claim',
|
||||
last_error: task.last_error || '领取链接已生成,等待客户提交核销码',
|
||||
last_error: task.last_error || '领取链接已生成,等待电子凭证流程推进',
|
||||
updated_at: now,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import { getOrderById } from "../../../repositories/order-repo.js";
|
||||
import { createTaskEvent } from "../../../repositories/task-event-repo.js";
|
||||
import { updateTask } from "../../../repositories/task-repo.js";
|
||||
import { createHttpError } from "../../../utils/http.js";
|
||||
import { nowIso } from "../../../utils/time.js";
|
||||
import { TASK_STATUS, normalizeTaskStatus, type TaskStatus } from "../../../domain/task-status.js";
|
||||
import {
|
||||
notifyKuaishouCloudAssetNotEnough,
|
||||
notifyKuaishouCloudConsumeFailed,
|
||||
} from "../../notification/domain-notifications.js";
|
||||
import { notifyKuaishouCloudAssetNotEnough } from "../../notification/domain-notifications.js";
|
||||
import {
|
||||
buyCloudtentaclesSku,
|
||||
getCloudtentaclesAsset,
|
||||
@@ -16,13 +12,7 @@ import {
|
||||
} from "../../platforms/cloudtentacles/catalog-service.js";
|
||||
import { getCloudtentaclesKnapsack } from "../../platforms/cloudtentacles/knapsack-service.js";
|
||||
import { backCloudtentaclesVirtualNumber } from "../../platforms/cloudtentacles/virtual-number-service.js";
|
||||
import { consumeKuaishouEticket } from "../../platforms/kuaishou-eticket/consume-service.js";
|
||||
import { isKuaishouEticketMockTicketCode } from "../../platforms/kuaishou-eticket/mock-ticket-service.js";
|
||||
import { consumeKuaishouIndustryVouchersForTask } from "../../platforms/kuaishou-industry/voucher-service.js";
|
||||
import {
|
||||
getKuaishouEticketSourceConfig,
|
||||
resolveKuaishouEticketShopConfig,
|
||||
} from "../../platforms/kuaishou-eticket/source-config-service.js";
|
||||
import {
|
||||
isKuaishouCloudTask,
|
||||
isIndustryEVoucherTask,
|
||||
@@ -95,10 +85,19 @@ export async function dispatchKuaishouCloudFulfillmentTask(
|
||||
);
|
||||
}
|
||||
|
||||
const ticketCode = String(options.ticketCode || "").trim();
|
||||
const persistedTicketCode = String(flow.ticket.code || "").trim();
|
||||
if (!persistedTicketCode && !ticketCode) {
|
||||
throw createHttpError("客户还没有提交有效核销码,暂时不能继续兑换", {
|
||||
const voucherContext = isPlainObject(taskContext.kuaishouIndustryVoucher)
|
||||
? taskContext.kuaishouIndustryVoucher
|
||||
: {};
|
||||
const industryVoucherCode = String(
|
||||
voucherContext.voucherCode || voucherContext.eticketId || ""
|
||||
).trim();
|
||||
const hasIndustryVoucherForDispatch =
|
||||
Boolean(industryVoucherCode) || isIndustryEVoucherTask(task);
|
||||
const resolvedTicketCode = persistedTicketCode || industryVoucherCode;
|
||||
|
||||
if (!resolvedTicketCode && !hasIndustryVoucherForDispatch) {
|
||||
throw createHttpError("旧快手小店核销流程已停用,请改用行业电子凭证处理", {
|
||||
statusCode: 409,
|
||||
errorCode: "kuaishou_cloud_missing_ticket_code",
|
||||
});
|
||||
@@ -173,9 +172,11 @@ export async function dispatchKuaishouCloudFulfillmentTask(
|
||||
...syncedFlow,
|
||||
ticket: {
|
||||
...syncedFlow.ticket,
|
||||
code: ticketCode || persistedTicketCode,
|
||||
capturedAt: ticketCode ? now : syncedFlow.ticket.capturedAt,
|
||||
capturedBy: ticketCode && actor ? actor : syncedFlow.ticket.capturedBy,
|
||||
code: resolvedTicketCode,
|
||||
capturedAt: resolvedTicketCode
|
||||
? syncedFlow.ticket.capturedAt || now
|
||||
: syncedFlow.ticket.capturedAt,
|
||||
capturedBy: syncedFlow.ticket.capturedBy,
|
||||
},
|
||||
dispatch: {
|
||||
...syncedFlow.dispatch,
|
||||
@@ -222,7 +223,7 @@ export async function dispatchKuaishouCloudFulfillmentTask(
|
||||
"kuaishou_cloud_dispatched",
|
||||
{
|
||||
source: String(options.source || "system").trim() || "system",
|
||||
ticketCodeMasked: maskCode(ticketCode || persistedTicketCode),
|
||||
ticketCodeMasked: maskCode(resolvedTicketCode),
|
||||
skuId: syncedFlow.binding.skuId,
|
||||
vnId: syncedFlow.binding.vnId,
|
||||
vnPhoneMasked: maskPhone(syncedFlow.binding.vnPhone),
|
||||
@@ -785,34 +786,25 @@ export async function returnKuaishouCloudFulfillmentTask(
|
||||
id: flow.binding.vnId,
|
||||
});
|
||||
|
||||
const order = await getOrderById(task.order_id);
|
||||
const ticketCode = String(flow.ticket.code || "").trim();
|
||||
const shopId = String(flow.consume.shopId || order?.shop_id || "").trim();
|
||||
const shopName = String(
|
||||
flow.consume.shopName || order?.shop_name || ""
|
||||
).trim();
|
||||
const mockTicketCode = isKuaishouEticketMockTicketCode(ticketCode);
|
||||
const eticketSource = getKuaishouEticketSourceConfig();
|
||||
const shopConfig = resolveKuaishouEticketShopConfig({
|
||||
shopId,
|
||||
shopName,
|
||||
});
|
||||
|
||||
let consumeStatus = "pending";
|
||||
let consumeErrorMessage = "";
|
||||
let consumedAt = null;
|
||||
let nextTaskStatus: TaskStatus = TASK_STATUS.COMPLETED;
|
||||
let nextResultCode = "kuaishou_cloud_completed";
|
||||
let nextResultMessage = "cloudtentacles 发货、退号并完成快手核销";
|
||||
const consumeAlreadyCompleted = flow.consume.status === "success";
|
||||
const hasIndustryVoucher = hasKuaishouIndustryVoucherContext(taskContext);
|
||||
const isIndustryTask = isIndustryEVoucherTask(task);
|
||||
const shouldConsumeIndustryVoucher = hasIndustryVoucher || isIndustryTask;
|
||||
let nextResultMessage = shouldConsumeIndustryVoucher
|
||||
? "cloudtentacles 发货、退号并完成电子凭证核销"
|
||||
: "cloudtentacles 发货、退号并收口";
|
||||
let industryVoucherContextPatch: JsonObject | null = null;
|
||||
|
||||
if (consumeAlreadyCompleted) {
|
||||
consumeStatus = "success";
|
||||
consumedAt = flow.consume.consumedAt || now;
|
||||
} else if (hasIndustryVoucher || isIndustryTask) {
|
||||
} else if (shouldConsumeIndustryVoucher) {
|
||||
const industryResult = hasIndustryVoucher
|
||||
? await consumeKuaishouIndustryVouchersForTask(task, {
|
||||
source: String(options.source || "system_auto_finalize").trim() || "system_auto_finalize",
|
||||
@@ -844,59 +836,20 @@ export async function returnKuaishouCloudFulfillmentTask(
|
||||
consumeErrorMessage =
|
||||
industryResult.failed[0]?.errorMessage || "电子凭证核销回调失败,请人工处理";
|
||||
}
|
||||
} else if (!order) {
|
||||
consumeStatus = "failed";
|
||||
consumeErrorMessage = "任务关联订单不存在,无法执行快手核销";
|
||||
} else if (!ticketCode) {
|
||||
consumeStatus = "failed";
|
||||
consumeErrorMessage = "客户未提交有效核销码,无法执行快手核销";
|
||||
} else if (mockTicketCode) {
|
||||
const consumeResult = await consumeKuaishouEticket({
|
||||
eTicketId: ticketCode,
|
||||
oid: String(flow.ticket.oid || "").trim(),
|
||||
formToken: String(flow.ticket.formToken || "").trim(),
|
||||
});
|
||||
consumeStatus = consumeResult.consumed ? "success" : "failed";
|
||||
consumedAt = consumeResult.consumed ? now : null;
|
||||
consumeErrorMessage = String(consumeResult.errorMessage || "").trim();
|
||||
} else if (
|
||||
!shopConfig ||
|
||||
shopConfig.enabled === false ||
|
||||
!String(shopConfig.cookie || "").trim()
|
||||
) {
|
||||
consumeStatus = "failed";
|
||||
consumeErrorMessage = "订单对应快手小店缺少可用 Cookie,无法执行快手核销";
|
||||
} else {
|
||||
try {
|
||||
const consumeResult = await consumeKuaishouEticket({
|
||||
baseUrl: eticketSource.baseUrl,
|
||||
cookie: shopConfig.cookie,
|
||||
eTicketId: ticketCode,
|
||||
oid: String(flow.ticket.oid || "").trim(),
|
||||
formToken: String(flow.ticket.formToken || "").trim(),
|
||||
});
|
||||
|
||||
if (consumeResult.consumed) {
|
||||
consumeStatus = "success";
|
||||
consumedAt = now;
|
||||
} else {
|
||||
consumeStatus = "failed";
|
||||
consumeErrorMessage = String(
|
||||
consumeResult.errorMessage || "快手核销失败"
|
||||
).trim();
|
||||
}
|
||||
} catch (error) {
|
||||
consumeStatus = "failed";
|
||||
consumeErrorMessage =
|
||||
error instanceof Error ? error.message : "快手核销失败";
|
||||
}
|
||||
consumeStatus = "skipped";
|
||||
consumeErrorMessage = "";
|
||||
}
|
||||
|
||||
if (consumeStatus !== "success") {
|
||||
nextTaskStatus = TASK_STATUS.MANUAL_REVIEW;
|
||||
nextResultCode = "kuaishou_cloud_consume_failed";
|
||||
nextResultMessage =
|
||||
consumeErrorMessage || "号码已退还,但快手核销未完成,请人工处理";
|
||||
if (shouldConsumeIndustryVoucher) {
|
||||
nextTaskStatus = TASK_STATUS.MANUAL_REVIEW;
|
||||
nextResultCode = "kuaishou_cloud_consume_failed";
|
||||
nextResultMessage =
|
||||
consumeErrorMessage || "号码已退还,但电子凭证核销未完成,请人工处理";
|
||||
} else {
|
||||
nextResultCode = "kuaishou_cloud_completed_without_eticket_consume";
|
||||
}
|
||||
}
|
||||
|
||||
const nextContext = {
|
||||
@@ -922,8 +875,8 @@ export async function returnKuaishouCloudFulfillmentTask(
|
||||
consume: {
|
||||
...flow.consume,
|
||||
status: consumeStatus,
|
||||
shopId: shopId || flow.consume.shopId,
|
||||
shopName,
|
||||
shopId: flow.consume.shopId,
|
||||
shopName: flow.consume.shopName,
|
||||
autoConsumeEnabled: flow.consume.autoConsumeEnabled === true,
|
||||
consumedAt,
|
||||
errorMessage: consumeErrorMessage,
|
||||
@@ -936,7 +889,7 @@ export async function returnKuaishouCloudFulfillmentTask(
|
||||
delivery_status: "delivered",
|
||||
result_code: nextResultCode,
|
||||
result_message: nextResultMessage,
|
||||
redeemed_at: consumeStatus === "success" ? now : task.redeemed_at,
|
||||
redeemed_at: consumeStatus === "failed" ? task.redeemed_at : now,
|
||||
last_error: consumeErrorMessage,
|
||||
context_json: JSON.stringify(nextContext),
|
||||
updated_at: now,
|
||||
@@ -954,36 +907,30 @@ export async function returnKuaishouCloudFulfillmentTask(
|
||||
now
|
||||
);
|
||||
|
||||
const consumeEventType = consumeAlreadyCompleted
|
||||
? "kuaishou_cloud_consume_already_completed"
|
||||
: consumeStatus === "success"
|
||||
? "kuaishou_cloud_consumed"
|
||||
: consumeStatus === "skipped"
|
||||
? "kuaishou_cloud_consume_skipped"
|
||||
: "kuaishou_cloud_consume_failed";
|
||||
|
||||
await createTaskEvent(
|
||||
task.id,
|
||||
consumeAlreadyCompleted
|
||||
? "kuaishou_cloud_consume_already_completed"
|
||||
: consumeStatus === "success"
|
||||
? "kuaishou_cloud_consumed"
|
||||
: "kuaishou_cloud_consume_failed",
|
||||
consumeEventType,
|
||||
{
|
||||
source: String(options.source || "system").trim() || "system",
|
||||
ticketCodeMasked: maskCode(ticketCode),
|
||||
shopId,
|
||||
shopName,
|
||||
shopId: flow.consume.shopId,
|
||||
shopName: flow.consume.shopName,
|
||||
consumeStatus,
|
||||
consumeMode: shouldConsumeIndustryVoucher ? "industry_voucher" : "legacy_writeoff_disabled",
|
||||
errorMessage: consumeErrorMessage,
|
||||
actor,
|
||||
},
|
||||
now
|
||||
);
|
||||
|
||||
if (consumeStatus !== "success") {
|
||||
await notifyKuaishouCloudConsumeFailed({
|
||||
task: updatedTask,
|
||||
order,
|
||||
ticketCodeMasked: maskCode(ticketCode),
|
||||
shopId,
|
||||
shopName,
|
||||
errorMessage: consumeErrorMessage,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
task: updatedTask,
|
||||
flow: normalizeKuaishouCloudFlow(
|
||||
|
||||
Reference in New Issue
Block a user