feat: gravity transaction logging + user-facing history popup

- New GravityTransaction schema tracks all gravity changes (registration,
  interview/optimize/download deduction, purchase, monthly topup, migration)
- GravityTopUpService: bulk log for monthly VIP topup
- PaymentController.activateMembership: log plan_set transactions
- QuotaService: add logTransaction, wire into all gravity-modifying methods
- UserService: log registration grants (phone/wx/email/password)
- GET /user/gravity-transactions?page=&limit= API
- Frontend: user.vue '明细' button + paginated popup
- Docs: update PROJECT-STATUS v4.10, FEATURE-LIST, DEPLOYMENT
This commit is contained in:
yuzhiran
2026-07-04 11:12:55 +08:00
parent d8a7872cd2
commit 2230a95b45
14 changed files with 268 additions and 38 deletions
@@ -9,6 +9,7 @@ import { WechatPayService } from './wechat-pay.service'
import { QuotaService } from '../user/quota.service'
import { PricingService } from '../schemas/pricing.service'
import { Public } from '../../common/decorators/public.decorator'
import { GravityTransaction } from '../schemas/gravity-transaction.schema'
@Controller('payment')
export class PaymentController {
@@ -17,6 +18,7 @@ export class PaymentController {
constructor(
@InjectModel(User.name) private userModel: Model<UserDocument>,
@InjectModel(PaymentOrder.name) private orderModel: Model<PaymentOrderDocument>,
@InjectModel(GravityTransaction.name) private gravityTxModel: Model<GravityTransaction>,
private wechatPay: WechatPayService,
private quotaService: QuotaService,
private pricingService: PricingService,
@@ -226,6 +228,14 @@ export class PaymentController {
user.gravity = planCfg.gravityPerMonth
user.freeOptimizeUsed = 3
await user.save()
await this.gravityTxModel.create({
userId: order.userId,
amount: planCfg.gravityPerMonth,
balance: planCfg.gravityPerMonth,
type: 'plan_set',
description: `开通${isSprint ? '冲刺版' : '成长版'}会员,获得 ${planCfg.gravityPerMonth} 引力值`,
refId: order.outTradeNo,
})
}
private async activateProduct(order: PaymentOrderDocument) {