docs: annotate payment, host operations and shared components

This commit is contained in:
cieanyau committed 2026-11-06 00:29:13 +08:00
1 parent d37ce57d09
commit dc32a74d7a
17 files changed
+100

No files matched your search

+23
View File
@@ -1,4 +1,10 @@
<script>
/**
* 订单支付面板:支持弹窗与内嵌两种展示,共用同一套订单、余额及代金券状态。
* 父级传入 orderId/amount,以 modelValue 控制可见性;success 表示服务端已确认支付,
* updated 用于通知父级刷新抵扣后的订单。amount 仅作初始展示,支付前会重新读取订单。
* 本文件保留恢复后的渲染函数与短变量名;金额换算和异步代次是维护时的关键约束。
*/
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -295,6 +301,7 @@ var ue = {
),
emits: mergeModels([`success`, `updated`], [`update:modelValue`]),
setup(i, { emit: _ }) {
// C 为支付步骤,O 为已支付标记;余额和订单金额在内部统一使用整数分。
let b = useModel(i, `modelValue`),
x = i,
Et = _,
@@ -358,6 +365,7 @@ var ue = {
: `可用余额 ¥0.00`,
);
function H(e) {
// 后端金额以元返回;拒绝空值、负值及超出安全整数范围的金额,避免错误抵扣。
if (e == null || String(e).trim() === ``) return null;
let t = Number(e),
n = Math.round(t * 100);
@@ -366,6 +374,7 @@ var ue = {
: null;
}
function U(e) {
// 仅在展示及接口金额文本边界将分转换回两位小数的元。
return (e / 100).toFixed(2);
}
let W = ref([]),
@@ -384,6 +393,7 @@ var ue = {
paymentPoll = null,
Z = (e, t) => e === X && b.value && String(x.orderId) === String(t);
function stopPaymentPolling() {
// 一个支付面板只保留一个轮询会话,同时取消周期任务和绝对截止定时器。
const session = paymentPoll;
paymentPoll = null;
if (!session) return;
@@ -391,6 +401,7 @@ var ue = {
clearTimeout(session.deadlineTimer);
}
function It() {
// 支付成功只通知一次;刷新账户概览失败不能反向撤销服务端支付结果。
O.value ||
(stopPaymentPolling(),
(O.value = !0),
@@ -398,6 +409,7 @@ var ue = {
Et(`success`));
}
async function $(e = X, t = x.orderId, n = !1) {
// 以订单 ID 和面板代次验证响应归属,关闭弹窗或切换订单后丢弃旧结果。
if (!t) return !1;
let r = await S.get(`/order/${t}`);
if (!Z(e, t)) return !1;
@@ -425,6 +437,7 @@ var ue = {
);
}
async function Lt(e = X, t = x.orderId) {
// 余额读取失败保留“不可用”状态,而不是把未知余额当作可支付的零余额。
if (t) {
M.value = ``;
try {
@@ -444,6 +457,7 @@ var ue = {
}
}
async function Rt(e = X, t = x.orderId) {
// credit 由独立余额开关管理;只有唯一外部支付渠道时才自动选中该渠道。
if (t)
try {
let n = await S.get(`/gateway`);
@@ -458,6 +472,7 @@ var ue = {
}
}
async function zt(e = X, t = x.orderId, n = !0) {
// 代金券可用列表与已使用状态都以服务端为准,不能在前端自行扣减订单金额。
if (t) {
(n && (J.value = !0), (Y.value = ``));
try {
@@ -493,6 +508,7 @@ var ue = {
return t === null ? `` : t > 0 ? `满 ¥${U(t)} 可用` : `无金额门槛`;
}
async function Ht() {
// 打开支付面板时并行读取订单、账户余额与渠道;订单类型决定是否再加载代金券。
// A visible dialog can outlive session invalidation until route teardown.
if (!Dt.isLoggedIn) return;
let e = x.orderId,
@@ -543,6 +559,7 @@ var ue = {
((T.value = e), (k.value = ``)));
}
async function Kt(e) {
// 切换代金券后重新获取订单;失败时也回读券状态,覆盖服务端可能已完成的更新。
let t = x.orderId,
n = X;
if (!(!t || D.value || A.value || J.value)) {
@@ -576,6 +593,7 @@ var ue = {
Kt(e.value ?? null);
}
(watch(
// 可见性、订单或登录身份任一变化都会推进代次,使此前请求和轮询立即失效。
[b, () => x.orderId, () => Dt.token],
() => {
(X++,
@@ -614,6 +632,8 @@ var ue = {
(X++, stopPaymentPolling());
}));
async function Jt() {
// 真正发起支付前再次确认订单状态、金额和余额,防止用户依据过期快照付款。
// 组合支付先提交余额抵扣,再让 /pay 处理剩余款项;Paid 必须来自后端确认。
if (D.value || A.value || J.value || !b.value || !x.orderId) return;
if (!Mt.value) {
k.value = I.value
@@ -688,6 +708,8 @@ var ue = {
}
}
function startPaymentPolling(generation, orderId) {
// 轮询绑定面板代次、订单和 JWT;最多五分钟,且同一时刻只允许一个查询在途。
// 单次请求的超时不超过会话剩余寿命,切换账号或卸载后不会继续报告旧订单成功。
stopPaymentPolling();
const session = {
identity: S.identity(),
@@ -749,6 +771,7 @@ var ue = {
session.interval = setInterval(pollStatus, 2000);
}
return (n, a) => {
// 内嵌与弹窗仅展示外壳不同,支付选择、错误提示及下一步动作复用上面的状态。
let o = NuxtLink,
c = button,
d = select,