You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* MotherShip fill-only 结账进度(Redis)
*/
import { withBoundedRedis } from "@/lib/redis";
export type MsCheckoutStatusPayload = {
quote_id: string;
status: "processing" | "done" | "failed";
stage?: string | null;
selected_carrier?: string | null;
selected_total?: number | null;
coverage?: "basic" | "freight_protect" | null;
cargo_value_usd?: number | null;
message?: string | null;
/** 仅服务端日志/诊断,不对前端暴露 */
screenshot_path?: string | null;
updated_at_ms: number;
};
/** GET 报价附加字段:脱敏 */
export type MsCheckoutPublic = {
status: "processing" | "done" | "failed";
stage?: string | null;
selected_carrier?: string | null;
selected_total?: number | null;
coverage?: "basic" | "freight_protect" | null;
cargo_value_usd?: number | null;
message?: string | null;
};
const PREFIX = "ms_checkout:";
const TTL_SEC = 30 * 60;
const SAFE_DONE_MSG = "已在官网填齐详情(未支付)";
const SAFE_FAIL_MSG = "官网同步失败,请稍后重试";
const SAFE_PROCESSING_MSG = "正在官网选择承运商与保障并填齐详情…";
function key(quoteId: string): string {
return `${PREFIX}${quoteId}`;
}
export function toMsCheckoutPublic(
payload: MsCheckoutStatusPayload,
): MsCheckoutPublic {
let message = payload.message ?? null;
if (payload.status === "failed") {
message = SAFE_FAIL_MSG;
} else if (payload.status === "done") {
message = SAFE_DONE_MSG;
} else if (payload.status === "processing") {
message = SAFE_PROCESSING_MSG;
}
return {
status: payload.status,
stage: payload.stage ?? null,
selected_carrier: payload.selected_carrier ?? null,
selected_total: payload.selected_total ?? null,
coverage: payload.coverage ?? null,
cargo_value_usd: payload.cargo_value_usd ?? null,
message,
};
}
export async function saveMsCheckoutStatus(
payload: MsCheckoutStatusPayload,
): Promise<void> {
const ok = await withBoundedRedis((redis) =>
redis.setex(key(payload.quote_id), TTL_SEC, JSON.stringify(payload)),
);
if (ok === null) {
console.warn("[ms-checkout] save skipped: Redis 不可达");
}
}
export async function readMsCheckoutStatus(
quoteId: string,
): Promise<MsCheckoutStatusPayload | null> {
const raw = await withBoundedRedis((redis) => redis.get(key(quoteId)));
if (!raw) return null;
try {
return JSON.parse(raw) as MsCheckoutStatusPayload;
} catch {
return null;
}
}