|
@@ -208,8 +208,8 @@
|
|
|
:total="total"
|
|
:total="total"
|
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
- @size-change="load"
|
|
|
|
|
- @current-change="load"
|
|
|
|
|
|
|
+ @size-change="() => load()"
|
|
|
|
|
+ @current-change="() => load()"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</el-card>
|
|
</el-card>
|
|
@@ -457,7 +457,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { onMounted, reactive, ref } from "vue";
|
|
|
|
|
|
|
+import { onMounted, reactive, ref, computed } from "vue";
|
|
|
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from "element-plus";
|
|
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from "element-plus";
|
|
|
import dayjs from "dayjs";
|
|
import dayjs from "dayjs";
|
|
|
import HarAPI, {
|
|
import HarAPI, {
|
|
@@ -472,6 +472,7 @@ import HarAPI, {
|
|
|
type HarOrderVO,
|
|
type HarOrderVO,
|
|
|
} from "@/api/module_payment/har";
|
|
} from "@/api/module_payment/har";
|
|
|
import { useEnterpriseStore } from "@/store/modules/enterprise.store";
|
|
import { useEnterpriseStore } from "@/store/modules/enterprise.store";
|
|
|
|
|
+import { useLiveRefetch } from "@/composables";
|
|
|
|
|
|
|
|
const enterpriseStore = useEnterpriseStore();
|
|
const enterpriseStore = useEnterpriseStore();
|
|
|
|
|
|
|
@@ -563,25 +564,32 @@ const tradeTypeText = (v?: string) =>
|
|
|
|
|
|
|
|
const formatTime = (v?: string) => (v ? dayjs(v).format("YYYY-MM-DD HH:mm:ss") : "-");
|
|
const formatTime = (v?: string) => (v ? dayjs(v).format("YYYY-MM-DD HH:mm:ss") : "-");
|
|
|
|
|
|
|
|
-async function load() {
|
|
|
|
|
- loading.value = true;
|
|
|
|
|
|
|
+async function load(silent = false) {
|
|
|
|
|
+ if (!silent) {
|
|
|
|
|
+ loading.value = true;
|
|
|
|
|
+ }
|
|
|
try {
|
|
try {
|
|
|
- const res = await HarAPI.orderList({
|
|
|
|
|
- enterprise_id: searchForm.enterprise_id || undefined,
|
|
|
|
|
- merchant_code: searchForm.merchant_code || undefined,
|
|
|
|
|
- order_no: searchForm.order_no || undefined,
|
|
|
|
|
- out_biz_no: searchForm.out_biz_no || undefined,
|
|
|
|
|
- trade_status: searchForm.trade_status || undefined,
|
|
|
|
|
- trade_type: searchForm.trade_type || undefined,
|
|
|
|
|
- start_date: searchForm.start_date || undefined,
|
|
|
|
|
- end_date: searchForm.end_date || undefined,
|
|
|
|
|
- page_no: pageNo.value,
|
|
|
|
|
- page_size: pageSize.value,
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ const res = await HarAPI.orderList(
|
|
|
|
|
+ {
|
|
|
|
|
+ enterprise_id: searchForm.enterprise_id || undefined,
|
|
|
|
|
+ merchant_code: searchForm.merchant_code || undefined,
|
|
|
|
|
+ order_no: searchForm.order_no || undefined,
|
|
|
|
|
+ out_biz_no: searchForm.out_biz_no || undefined,
|
|
|
|
|
+ trade_status: searchForm.trade_status || undefined,
|
|
|
|
|
+ trade_type: searchForm.trade_type || undefined,
|
|
|
|
|
+ start_date: searchForm.start_date || undefined,
|
|
|
|
|
+ end_date: searchForm.end_date || undefined,
|
|
|
|
|
+ page_no: pageNo.value,
|
|
|
|
|
+ page_size: pageSize.value,
|
|
|
|
|
+ },
|
|
|
|
|
+ silent
|
|
|
|
|
+ );
|
|
|
list.value = res.data.data?.items || res.data.data?.list || [];
|
|
list.value = res.data.data?.items || res.data.data?.list || [];
|
|
|
total.value = res.data.data?.total || 0;
|
|
total.value = res.data.data?.total || 0;
|
|
|
} finally {
|
|
} finally {
|
|
|
- loading.value = false;
|
|
|
|
|
|
|
+ if (!silent) {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -713,6 +721,7 @@ async function handleSync(row: HarOrderVO) {
|
|
|
*/
|
|
*/
|
|
|
async function handleRefund(row: HarOrderVO) {
|
|
async function handleRefund(row: HarOrderVO) {
|
|
|
let reason = "";
|
|
let reason = "";
|
|
|
|
|
+ confirmingRefund.value = true;
|
|
|
try {
|
|
try {
|
|
|
const { value } = await ElMessageBox.prompt(
|
|
const { value } = await ElMessageBox.prompt(
|
|
|
`订单 ${row.order_no} 将按 ¥${row.price} 发起全额退款,金额不可修改;` +
|
|
`订单 ${row.order_no} 将按 ¥${row.price} 发起全额退款,金额不可修改;` +
|
|
@@ -727,6 +736,8 @@ async function handleRefund(row: HarOrderVO) {
|
|
|
reason = value ?? "";
|
|
reason = value ?? "";
|
|
|
} catch {
|
|
} catch {
|
|
|
return; // 取消(ElMessageBox 以 "cancel" reject),不发请求
|
|
return; // 取消(ElMessageBox 以 "cancel" reject),不发请求
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ confirmingRefund.value = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
refundingId.value = row.id;
|
|
refundingId.value = row.id;
|
|
@@ -769,6 +780,44 @@ async function copyPayUrl(url?: string) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// ─────────────────── 实时联动(2026-10-05)───────────────────
|
|
|
|
|
+
|
|
|
|
|
+/** 退款确认框(ElMessageBox.prompt)开着时也算操作中:弹窗背后列表不该在脚下换行。 */
|
|
|
|
|
+const confirmingRefund = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 「操作中」判据:创建弹窗开着 / 正在提交 / 退款确认框开着。
|
|
|
|
|
+ * ★ 不含 `syncingId` / `refundingId`:这两条腿自己结束时会 `load()`,期间行上按钮是转圈的
|
|
|
|
|
+ * —— 后台静默刷新在这中间落地,只是把同样的数据重画一遍。
|
|
|
|
|
+ * ★ 不含 `detailVisible`:详情要跟着实时变(偏差 ①)。
|
|
|
|
|
+ */
|
|
|
|
|
+const liveBusy = computed(() => createVisible.value || saving.value || confirmingRefund.value);
|
|
|
|
|
+
|
|
|
|
|
+/** 详情弹层开着时的静默联动:只有还是同一单才覆盖(理由同 Task 11 Step 4)。 */
|
|
|
|
|
+async function refreshOpenDetail() {
|
|
|
|
|
+ const id = detail.value?.id;
|
|
|
|
|
+ if (!detailVisible.value || !id) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await HarAPI.orderDetail(id, true);
|
|
|
|
|
+ if (detailVisible.value && detail.value?.id === id) {
|
|
|
|
|
+ detail.value = res.data.data;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ // 静默
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+useLiveRefetch(
|
|
|
|
|
+ ["har_order"],
|
|
|
|
|
+ async () => {
|
|
|
|
|
+ await refreshOpenDetail();
|
|
|
|
|
+ await load(true);
|
|
|
|
|
+ },
|
|
|
|
|
+ { busy: liveBusy }
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
load();
|
|
load();
|
|
|
loadMerchantOptions();
|
|
loadMerchantOptions();
|