feat(ticket): 添加水票可用数量计算和订单取消后水票回退功能
- 引入 getGltUserTicket 和 updateGltUserTicket API 接口 - 实现 getTicketAvailableQty 函数用于计算水票可用数量 - 添加 rollbackUserTicketAfterOrderCancel 函数处理订单取消后的水票回退逻辑 - 在订单取消时获取取消前的水票状态并进行数量对比 - 订单取消成功后自动回退相应的水票数量 - 添加水票回退失败时的错误提示和用户通知 - 更新取消订单的成功提示信息为"订单已取消,水票已退回"
This commit is contained in:
@@ -14,7 +14,7 @@ import {
|
||||
Tag
|
||||
} from '@nutui/nutui-react-taro';
|
||||
import { View, Text, Image } from '@tarojs/components';
|
||||
import { pageGltUserTicket } from '@/api/glt/gltUserTicket';
|
||||
import { getGltUserTicket, pageGltUserTicket, updateGltUserTicket } from '@/api/glt/gltUserTicket';
|
||||
import type { GltUserTicket } from '@/api/glt/gltUserTicket/model';
|
||||
import { pageGltTicketOrder, removeGltTicketOrder, updateGltTicketOrder } from '@/api/glt/gltTicketOrder';
|
||||
import type { GltTicketOrder } from '@/api/glt/gltTicketOrder/model';
|
||||
@@ -261,6 +261,65 @@ const UserTicketList = () => {
|
||||
return d.isValid() ? d.format('YYYY年MM月DD日') : v;
|
||||
};
|
||||
|
||||
const getTicketAvailableQty = (t?: Partial<GltUserTicket> | null) => {
|
||||
if (!t) return 0;
|
||||
const anyT: any = t;
|
||||
const raw =
|
||||
anyT.availableQty ??
|
||||
anyT.availableNum ??
|
||||
anyT.availableCount ??
|
||||
anyT.remainQty ??
|
||||
anyT.remainNum ??
|
||||
anyT.remainCount;
|
||||
const n = Number(raw);
|
||||
if (Number.isFinite(n)) return n;
|
||||
|
||||
const total = Number(anyT.totalQty ?? anyT.totalNum ?? anyT.totalCount ?? 0);
|
||||
const used = Number(anyT.usedQty ?? anyT.usedNum ?? anyT.usedCount ?? 0);
|
||||
const frozen = Number(anyT.frozenQty ?? anyT.frozenNum ?? anyT.frozenCount ?? 0);
|
||||
const computed =
|
||||
(Number.isFinite(total) ? total : 0) -
|
||||
(Number.isFinite(used) ? used : 0) -
|
||||
(Number.isFinite(frozen) ? frozen : 0);
|
||||
return Number.isFinite(computed) ? computed : 0;
|
||||
};
|
||||
|
||||
const rollbackUserTicketAfterOrderCancel = async (order: GltTicketOrder, before?: GltUserTicket | null) => {
|
||||
const ticketId = Number(order?.userTicketId);
|
||||
const qty = Math.max(0, Math.floor(Number((order as any)?.totalNum ?? 0)));
|
||||
if (!Number.isFinite(ticketId) || ticketId <= 0) return;
|
||||
if (!Number.isFinite(qty) || qty <= 0) return;
|
||||
|
||||
const after = await getGltUserTicket(ticketId);
|
||||
if (!after?.id) return;
|
||||
|
||||
const beforeAvail = before ? getTicketAvailableQty(before) : undefined;
|
||||
const afterAvail = getTicketAvailableQty(after);
|
||||
|
||||
let need = qty;
|
||||
if (typeof beforeAvail === 'number') {
|
||||
const delta = afterAvail - beforeAvail;
|
||||
if (delta >= qty) return; // backend already rolled back
|
||||
if (delta > 0) need = Math.max(0, qty - delta);
|
||||
}
|
||||
if (need <= 0) return;
|
||||
|
||||
const currentAvailRaw = Number((after as any)?.availableQty);
|
||||
const baseAvail = Number.isFinite(currentAvailRaw) ? currentAvailRaw : afterAvail;
|
||||
const nextAvail = (Number.isFinite(baseAvail) ? baseAvail : 0) + need;
|
||||
|
||||
const frozenRaw = Number((after as any)?.frozenQty ?? 0);
|
||||
const frozen = Number.isFinite(frozenRaw) ? frozenRaw : 0;
|
||||
const reduceFrozen = Math.min(frozen, need);
|
||||
const nextFrozen = reduceFrozen > 0 ? Math.max(0, frozen - reduceFrozen) : undefined;
|
||||
|
||||
await updateGltUserTicket({
|
||||
...after,
|
||||
availableQty: nextAvail,
|
||||
...(nextFrozen !== undefined ? { frozenQty: nextFrozen } : {})
|
||||
});
|
||||
};
|
||||
|
||||
// Allow users to modify/cancel before delivery starts (e.g. 待派单 / 待配送).
|
||||
const isTicketOrderPendingDelivery = (order: GltTicketOrder) => {
|
||||
if (!order?.id) return false;
|
||||
@@ -306,12 +365,26 @@ const UserTicketList = () => {
|
||||
|
||||
try {
|
||||
Taro.showLoading({ title: '取消中...' });
|
||||
let beforeTicket: GltUserTicket | null = null;
|
||||
if (order.userTicketId) {
|
||||
beforeTicket = await getGltUserTicket(Number(order.userTicketId)).catch(() => null);
|
||||
}
|
||||
try {
|
||||
await updateGltTicketOrder({ id: order.id, deleted: 1 });
|
||||
} catch (e) {
|
||||
await removeGltTicketOrder(order.id);
|
||||
}
|
||||
Taro.showToast({ title: '订单已取消', icon: 'success' });
|
||||
try {
|
||||
await rollbackUserTicketAfterOrderCancel(order, beforeTicket);
|
||||
Taro.showToast({ title: '订单已取消,水票已退回', icon: 'success' });
|
||||
} catch (e) {
|
||||
console.error('取消订单后退回水票失败:', e);
|
||||
await Taro.showModal({
|
||||
title: '取消成功',
|
||||
content: '订单已取消,但水票退回失败,请稍后刷新“我的水票”确认,或联系客服处理。',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
await reloadOrders(true);
|
||||
} catch (e) {
|
||||
console.error('取消送水订单失败:', e);
|
||||
|
||||
Reference in New Issue
Block a user