|
|
/**
|
|
|
* Flock 登录态首价 hold:继续填写 / 放弃二级
|
|
|
*/
|
|
|
import { requestReleaseParkedSession } from "@/modules/address/parked-session-queue";
|
|
|
import {
|
|
|
assertFlockQuoteHoldUsable,
|
|
|
clearFlockQuoteHold,
|
|
|
readFlockQuoteHold,
|
|
|
updateFlockQuoteHoldStatus,
|
|
|
} from "@/lib/flock/flock-quote-hold-store";
|
|
|
import {
|
|
|
FLOCK_HOLD_MSG,
|
|
|
isFlockQuoteHoldExpired,
|
|
|
shouldAutoDeclineFlockHold,
|
|
|
} from "@/lib/constants/flock-quote-hold";
|
|
|
|
|
|
export async function declineFlockQuoteHold(input: {
|
|
|
customerId: string;
|
|
|
quoteId: string;
|
|
|
sessionId: string;
|
|
|
}): Promise<{ released: boolean }> {
|
|
|
const state = await readFlockQuoteHold(input.sessionId);
|
|
|
if (state && state.customer_id !== input.customerId) {
|
|
|
throw new Error("无权操作该询价会话");
|
|
|
}
|
|
|
if (state && state.quote_id !== input.quoteId) {
|
|
|
throw new Error("报价单与询价会话不匹配");
|
|
|
}
|
|
|
await updateFlockQuoteHoldStatus(input.sessionId, "declined");
|
|
|
await requestReleaseParkedSession(input.sessionId);
|
|
|
await clearFlockQuoteHold(input.sessionId);
|
|
|
return { released: true };
|
|
|
}
|
|
|
|
|
|
/** 用户确认继续填二级:避免 60s 决策窗被 GET auto-decline */
|
|
|
export async function continueFlockQuoteHold(input: {
|
|
|
customerId: string;
|
|
|
quoteId: string;
|
|
|
sessionId: string;
|
|
|
}): Promise<{ status: "filling" }> {
|
|
|
const state = await assertFlockQuoteHoldUsable(input.sessionId);
|
|
|
if (state.customer_id !== input.customerId) {
|
|
|
throw new Error("无权操作该询价会话");
|
|
|
}
|
|
|
if (state.quote_id !== input.quoteId) {
|
|
|
throw new Error("报价单与询价会话不匹配");
|
|
|
}
|
|
|
if (isFlockQuoteHoldExpired(state)) {
|
|
|
await declineFlockQuoteHold(input);
|
|
|
throw new Error(FLOCK_HOLD_MSG.totalTimeoutApi);
|
|
|
}
|
|
|
if (
|
|
|
state.status === "awaiting_decision" &&
|
|
|
shouldAutoDeclineFlockHold(state)
|
|
|
) {
|
|
|
await declineFlockQuoteHold(input);
|
|
|
throw new Error(FLOCK_HOLD_MSG.decisionTimeoutApi);
|
|
|
}
|
|
|
if (
|
|
|
state.status === "filling" ||
|
|
|
state.status === "checking_out"
|
|
|
) {
|
|
|
return { status: "filling" };
|
|
|
}
|
|
|
await updateFlockQuoteHoldStatus(input.sessionId, "filling");
|
|
|
return { status: "filling" };
|
|
|
}
|