|
|
@@ -182,7 +182,7 @@
|
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
style="margin-top: 12px; justify-content: flex-end"
|
|
|
- @change="loadData"
|
|
|
+ @change="() => loadData()"
|
|
|
/>
|
|
|
</el-card>
|
|
|
|
|
|
@@ -440,6 +440,7 @@ import {
|
|
|
} from "@/api/module_payment/collection";
|
|
|
import TenantAPI, { type TenantTable } from "@/api/module_system/tenant";
|
|
|
import { useUserStore } from "@/store";
|
|
|
+import { useLiveRefetch } from "@/composables";
|
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
|
@@ -874,10 +875,14 @@ function refundTagType(v: string) {
|
|
|
if (v === "FAIL") return "danger";
|
|
|
return "warning";
|
|
|
}
|
|
|
-async function loadData() {
|
|
|
- loading.value = true;
|
|
|
+async function loadData(silent = false) {
|
|
|
+ // ★ 静默刷新不碰 loading:它是一个全局开关,后台那一次把它拉起来,
|
|
|
+ // 正在看页面的人会看到表格「闪一下转圈」—— 这正是「用户无感知」禁止的动静。
|
|
|
+ if (!silent) {
|
|
|
+ loading.value = true;
|
|
|
+ }
|
|
|
try {
|
|
|
- const res: any = await getLsyOrderPage(query);
|
|
|
+ const res: any = await getLsyOrderPage(query, silent);
|
|
|
// res 是 AxiosResponse(request.ts 的响应拦截器 `return response`,**不做解包**)
|
|
|
// → res.data = {code,msg,data} → res.data.data = PageResult
|
|
|
// PageResult 的分页字段名是 `list`(不是 records/items);`total` 是单词,命名策略不影响它。
|
|
|
@@ -885,10 +890,72 @@ async function loadData() {
|
|
|
list.value = res.data.data?.list || [];
|
|
|
total.value = res.data.data?.total || 0;
|
|
|
} finally {
|
|
|
- loading.value = false;
|
|
|
+ if (!silent) {
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// ─────────────────── 实时联动(2026-10-05)───────────────────
|
|
|
+
|
|
|
+/**
|
|
|
+ * 退款确认框开着时也算「操作中」。
|
|
|
+ * 弹窗期间列表在脚下换行,操作员会重新核对金额 —— 而那个金额是从**行对象**里读的快照。
|
|
|
+ */
|
|
|
+const confirmingRefund = ref(false);
|
|
|
+
|
|
|
+/**
|
|
|
+ * 什么算「用户正在操作」,信号在此期间挂起:
|
|
|
+ * 勾选着行 / 批量退款的两个弹窗 / 提交与轮询在跑 / 退款确认框开着。
|
|
|
+ *
|
|
|
+ * ★ 详情抽屉**不在**这里 —— 抽屉要跟着实时变(见计划头「与已批 spec 的偏差」①):
|
|
|
+ * 收银台的人正盯着这一单等它从「支付中」翻成「支付成功」,挂起等于把这个功能关掉。
|
|
|
+ */
|
|
|
+const liveBusy = computed(
|
|
|
+ () =>
|
|
|
+ selectedRows.value.length > 0 ||
|
|
|
+ batchRefundVisible.value ||
|
|
|
+ batchRefundResultVisible.value ||
|
|
|
+ batchRefundRunning.value ||
|
|
|
+ confirmingRefund.value
|
|
|
+);
|
|
|
+
|
|
|
+/**
|
|
|
+ * 抽屉开着时的静默联动:两个请求都回来、且还是同一单,才整体覆盖。
|
|
|
+ *
|
|
|
+ * ★ 为什么不复用 `openDetail`:它**刻意先清空**(防上一次的内容在请求失败时冒充这一单),
|
|
|
+ * 那是「人点开某一单」的前提;后台刷新没有点错单的可能,闪一下空白反倒成了可见的动静。
|
|
|
+ * ★ 两个请求一起 await:只覆盖一半(比如详情新了、退款单还是旧的)会让界面自相矛盾。
|
|
|
+ */
|
|
|
+async function refreshOpenDetail() {
|
|
|
+ const no = detail.value?.out_trade_no;
|
|
|
+ if (!detailVisible.value || !no) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const [d, rfs]: any[] = await Promise.all([
|
|
|
+ getLsyOrderDetail(no, true),
|
|
|
+ getLsyOrderRefunds(no, true),
|
|
|
+ ]);
|
|
|
+ // 请求在飞的时候人可能已经关了抽屉、或点开了另一单
|
|
|
+ if (detailVisible.value && detail.value?.out_trade_no === no) {
|
|
|
+ detail.value = d.data.data;
|
|
|
+ refunds.value = rfs.data.data || [];
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ // 后台刷新失败静默:留着上一次的数据,比清空好
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+useLiveRefetch(
|
|
|
+ ["lsy_order", "lsy_refund"],
|
|
|
+ async () => {
|
|
|
+ await refreshOpenDetail();
|
|
|
+ await loadData(true);
|
|
|
+ },
|
|
|
+ { busy: liveBusy }
|
|
|
+);
|
|
|
+
|
|
|
function handleSearch() {
|
|
|
query.pageNo = 1;
|
|
|
loadData();
|
|
|
@@ -951,6 +1018,7 @@ async function handleRefund(row: any) {
|
|
|
}
|
|
|
|
|
|
let input = "";
|
|
|
+ confirmingRefund.value = true;
|
|
|
try {
|
|
|
const { value } = await ElMessageBox.prompt(
|
|
|
`订单 ${row.out_trade_no}:共 ${fen2yuan(row.total_amount)} 元,` +
|
|
|
@@ -969,6 +1037,9 @@ async function handleRefund(row: any) {
|
|
|
input = value ?? "";
|
|
|
} catch {
|
|
|
return; // 取消(ElMessageBox 以 "cancel" reject),不发请求
|
|
|
+ } finally {
|
|
|
+ // finally 在 catch 里那个 return 之前执行 ⇒ 取消路径也会复位,不会把页面永久卡在 busy
|
|
|
+ confirmingRefund.value = false;
|
|
|
}
|
|
|
|
|
|
// 元 → 分。`Math.round` 而不是 `* 100` 取整:0.29 * 100 在二进制浮点下是 28.999…。
|