fix: 体验优化

This commit is contained in:
ggyy
2026-05-13 02:25:56 +08:00
parent 1db9abc0f0
commit bf0bf1f32a
5 changed files with 44 additions and 7 deletions

View File

@@ -82,6 +82,11 @@ defineProps<{
flex-shrink: 0;
}
.app-btn__spinner circle {
stroke-dasharray: 90 150;
stroke-dashoffset: 0;
}
@keyframes btn-spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }

View File

@@ -99,10 +99,11 @@ export async function deliverOrder(prisma: PrismaClient, orderNo: string) {
items: contents,
};
} catch (error) {
const failedDeliveryType = order.product.deliveryType === "FIXED_CARD" ? "FIXED_CARD" : "CARD";
await prisma.orderDelivery.create({
data: {
orderId: order.id,
deliveryType: "CARD",
deliveryType: failedDeliveryType,
contentSnapshot: error instanceof Error ? error.message : "delivery failed",
status: "FAILED",
},

View File

@@ -142,7 +142,7 @@ export async function getOrderForQuery(
// notify 与 return 几乎同时到达时return 这次读取可能正好卡在
// “订单已支付但异步发货还没写完”的瞬间。这里做一次短暂重查,
// 优先把最终的 DELIVERED 状态和发货内容返回给页面,避免用户手动刷新。
if (order.paymentStatus === "PAID" && order.deliveryStatus === "NOT_DELIVERED") {
if (order.product.deliveryType !== "MANUAL" && order.paymentStatus === "PAID" && order.deliveryStatus === "NOT_DELIVERED") {
for (let index = 0; index < 3; index += 1) {
await sleep(150);
const refreshed = await findOrderWithProduct(client, orderNo);

View File

@@ -385,7 +385,12 @@ export async function queryAlipayPayment(orderNo: string, prisma?: PrismaClient)
});
try {
await deliverOrder(client, orderNo);
} catch {}
} catch (error) {
logger.error(error instanceof Error ? error : String(error), {
event: "payment.alipay_query.delivery_failed",
orderNo,
});
}
}
}
@@ -508,6 +513,32 @@ export async function handlePaymentNotify(
}
if (order.paymentStatus === "PAID") {
let message = "already paid";
if (order.deliveryStatus === "NOT_DELIVERED") {
const product = await prisma.product.findUnique({
where: { id: order.productId },
select: { deliveryType: true },
});
if (product?.deliveryType !== "MANUAL") {
try {
await deliverOrder(prisma, order.orderNo);
message = "already paid; delivery retried";
} catch (error) {
writePaymentNotifyDiagnostic({
provider,
source,
reason: "delivery retry failed for already paid order",
orderNo: verified.orderNo,
payload,
error,
});
message = "already paid; delivery retry failed";
}
}
}
await createNotifyLog(prisma, {
orderId: order.id,
provider,
@@ -516,14 +547,14 @@ export async function handlePaymentNotify(
rawPayload,
verifyStatus: "VERIFIED",
source,
message: "already paid",
message,
status: verified.status,
});
return {
ok: true,
status: verified.status,
message: "already paid",
message,
};
}

View File

@@ -75,7 +75,7 @@
<p v-if="product.deliveryType === 'CARD_AUTO' && product.availableStock >= 0 && product.availableStock < 10" class="text-sm" :class="product.availableStock === 0 ? 'text-error' : 'text-warning'">
{{ product.availableStock === 0 ? '商品都卖光了看看其他商品' : `库存紧张仅剩 ${product.availableStock} ` }}
</p>
<p v-else-if="product.deliveryType === 'FIXED_CARD'" class="text-sm text-success">固定内容自动发货库存充足</p>
<p v-else-if="product.deliveryType === 'FIXED_CARD'" class="text-sm text-success">自动发货无限库存</p>
<p v-else-if="product.deliveryType === 'MANUAL'" class="text-sm text-info">手动发货商品支付后等待管理员处理</p>
<AppButton variant="primary" :loading="submitting" :disabled="!paymentMethods.length || (product.deliveryType === 'CARD_AUTO' && product.availableStock === 0)" @click="handleCreateOrder">
@@ -142,7 +142,7 @@ watch(() => form.paymentProvider, (provider) => {
const descriptionHtml = formatDescriptionHtml(product?.description || "");
async function handleCreateOrder() {
if (!product) return;
if (!product || submitting.value) return;
const contactEmail = form.contactValue.trim();
if (!contactEmail) {