feat: 支持同卡种续卡叠加并修复过期登录态
支付成功后将次数或有效期叠加到已有会员卡,首页与详情页引导续卡;接口 401 时同步清掉本地登录态。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,10 +5,11 @@ import {
|
||||
NotFoundException,
|
||||
} from '@nestjs/common'
|
||||
import { CardType, Order } from '@prisma/client'
|
||||
import { MembershipStatus, OrderStatus, FlashSaleOrderStatus } from '@mp-pilates/shared'
|
||||
import { OrderStatus, FlashSaleOrderStatus } from '@mp-pilates/shared'
|
||||
import { PrismaService } from '../prisma/prisma.service'
|
||||
import { WechatPayService, WxPaymentParams } from './wechat-pay.service'
|
||||
import { InviteService } from '../invite/invite.service'
|
||||
import { MembershipService } from '../membership/membership.service'
|
||||
|
||||
export interface CreateOrderResult {
|
||||
order: Order
|
||||
@@ -30,6 +31,7 @@ export class PaymentService {
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly wechatPayService: WechatPayService,
|
||||
private readonly inviteService: InviteService,
|
||||
private readonly membershipService: MembershipService,
|
||||
) {}
|
||||
|
||||
// ─── User: create order ────────────────────────────────────────────────────
|
||||
@@ -118,32 +120,29 @@ export class PaymentService {
|
||||
}
|
||||
|
||||
const now = new Date()
|
||||
const expireDate = new Date(now.getTime() + cardType.durationDays * 86_400_000)
|
||||
|
||||
await this.prisma.$transaction([
|
||||
this.prisma.order.update({
|
||||
await this.prisma.$transaction(async (tx) => {
|
||||
const membership = await this.membershipService.grantPurchasedCard(
|
||||
tx,
|
||||
existingOrder.userId,
|
||||
cardType,
|
||||
now,
|
||||
)
|
||||
|
||||
await tx.order.update({
|
||||
where: { id: existingOrder.id },
|
||||
data: {
|
||||
status: OrderStatus.PAID,
|
||||
wxTransactionId: notification.wxTransactionId,
|
||||
paidAt: now,
|
||||
membershipId: membership.id,
|
||||
},
|
||||
}),
|
||||
this.prisma.membership.create({
|
||||
data: {
|
||||
userId: existingOrder.userId,
|
||||
cardTypeId: existingOrder.cardTypeId,
|
||||
startDate: now,
|
||||
expireDate,
|
||||
remainingTimes: cardType.totalTimes ?? null,
|
||||
status: MembershipStatus.ACTIVE,
|
||||
},
|
||||
}),
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
await this.inviteService.recordTrialOrderPaid(existingOrder.id)
|
||||
|
||||
this.logger.log(`Order PAID and Membership created: orderNo=${notification.orderNo}`)
|
||||
this.logger.log(`Order PAID and membership granted: orderNo=${notification.orderNo}`)
|
||||
|
||||
// ── Flash sale order: mark as PAID ──
|
||||
if (existingOrder.flashSaleId) {
|
||||
|
||||
Reference in New Issue
Block a user