fix(funds): 结算幂等键复用与转账冲正按钮对齐 API
Some checks failed
lotteryadmin CI / build (push) Has been cancelled
Some checks failed
lotteryadmin CI / build (push) Has been cancelled
- 账单收付/补差幂等键在首次操作时生成并复用至成功 - 冲正按钮仅当 API 返回 can_reverse=true 时展示
This commit is contained in:
@@ -11,7 +11,7 @@ export type TransferOrderActionRow = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function canReverseTransferOrder(row: TransferOrderActionRow, canWriteWallet: boolean): boolean {
|
export function canReverseTransferOrder(row: TransferOrderActionRow, canWriteWallet: boolean): boolean {
|
||||||
return canWriteWallet && (row.can_reverse ?? row.status === "pending_reconcile");
|
return canWriteWallet && row.can_reverse === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canCompleteTransferInCredit(row: TransferOrderActionRow, canWriteWallet: boolean): boolean {
|
export function canCompleteTransferInCredit(row: TransferOrderActionRow, canWriteWallet: boolean): boolean {
|
||||||
|
|||||||
@@ -67,8 +67,23 @@ export function AgentBillDetail({
|
|||||||
const [advancedOpen, setAdvancedOpen] = useState(false);
|
const [advancedOpen, setAdvancedOpen] = useState(false);
|
||||||
const confirmRef = useRef<HTMLDivElement>(null);
|
const confirmRef = useRef<HTMLDivElement>(null);
|
||||||
const paymentRef = useRef<HTMLDivElement>(null);
|
const paymentRef = useRef<HTMLDivElement>(null);
|
||||||
|
const paymentIdempotencyKeyRef = useRef<string | null>(null);
|
||||||
|
const adjustmentIdempotencyKeyRef = useRef<string | null>(null);
|
||||||
const { request: requestConfirm, ConfirmDialog, busy: confirmBusy } = useConfirmAction();
|
const { request: requestConfirm, ConfirmDialog, busy: confirmBusy } = useConfirmAction();
|
||||||
|
|
||||||
|
const createIdempotencyKey = useCallback((prefix: string): string => {
|
||||||
|
const random =
|
||||||
|
typeof crypto !== "undefined" && typeof crypto.randomUUID === "function"
|
||||||
|
? crypto.randomUUID()
|
||||||
|
: Math.random().toString(36).slice(2, 10);
|
||||||
|
return `${prefix}-${billId}-${Date.now()}-${random}`;
|
||||||
|
}, [billId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
paymentIdempotencyKeyRef.current = null;
|
||||||
|
adjustmentIdempotencyKeyRef.current = null;
|
||||||
|
}, [billId]);
|
||||||
|
|
||||||
const load = useCallback(async () => {
|
const load = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setLoadErr(null);
|
setLoadErr(null);
|
||||||
@@ -202,7 +217,10 @@ export function AgentBillDetail({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const idempotencyKey = `pay-${billId}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
if (!paymentIdempotencyKeyRef.current) {
|
||||||
|
paymentIdempotencyKeyRef.current = createIdempotencyKey("pay");
|
||||||
|
}
|
||||||
|
const idempotencyKey = paymentIdempotencyKeyRef.current;
|
||||||
requestConfirm({
|
requestConfirm({
|
||||||
title: t("settlementBills.paymentConfirmTitle", { defaultValue: "确认登记收付?" }),
|
title: t("settlementBills.paymentConfirmTitle", { defaultValue: "确认登记收付?" }),
|
||||||
description: t("settlementBills.paymentConfirmDescription", {
|
description: t("settlementBills.paymentConfirmDescription", {
|
||||||
@@ -218,6 +236,7 @@ export function AgentBillDetail({
|
|||||||
proof: payProof.trim() || undefined,
|
proof: payProof.trim() || undefined,
|
||||||
idempotency_key: idempotencyKey,
|
idempotency_key: idempotencyKey,
|
||||||
});
|
});
|
||||||
|
paymentIdempotencyKeyRef.current = null;
|
||||||
await load();
|
await load();
|
||||||
await onUpdated?.();
|
await onUpdated?.();
|
||||||
toast.success(t("settlementBills.paid", { defaultValue: "已登记收付" }));
|
toast.success(t("settlementBills.paid", { defaultValue: "已登记收付" }));
|
||||||
@@ -273,7 +292,10 @@ export function AgentBillDetail({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const idempotencyKey = `adj-${billId}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
if (!adjustmentIdempotencyKeyRef.current) {
|
||||||
|
adjustmentIdempotencyKeyRef.current = createIdempotencyKey("adj");
|
||||||
|
}
|
||||||
|
const idempotencyKey = adjustmentIdempotencyKeyRef.current;
|
||||||
requestConfirm({
|
requestConfirm({
|
||||||
title: t("settlementBills.adjustmentConfirmTitle", { defaultValue: "确认创建补差/冲正单?" }),
|
title: t("settlementBills.adjustmentConfirmTitle", { defaultValue: "确认创建补差/冲正单?" }),
|
||||||
description: t("settlementBills.adjustmentConfirmDescription", {
|
description: t("settlementBills.adjustmentConfirmDescription", {
|
||||||
@@ -289,6 +311,7 @@ export function AgentBillDetail({
|
|||||||
reason,
|
reason,
|
||||||
idempotency_key: idempotencyKey,
|
idempotency_key: idempotencyKey,
|
||||||
});
|
});
|
||||||
|
adjustmentIdempotencyKeyRef.current = null;
|
||||||
setAdjustAmount("");
|
setAdjustAmount("");
|
||||||
setAdjustReason("");
|
setAdjustReason("");
|
||||||
toast.success(t("settlementBills.adjustmentCreated", { defaultValue: "已创建补差单" }));
|
toast.success(t("settlementBills.adjustmentCreated", { defaultValue: "已创建补差单" }));
|
||||||
|
|||||||
Reference in New Issue
Block a user