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
@@ -0,0 +1,43 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { Document } from 'mongoose'
export type GravityTransactionDocument = GravityTransaction & Document
export type GravityTransactionType =
| 'registration' // 注册赠送
| 'interview_deduct' // AI 面试消耗
| 'optimize_deduct' // 简历优化消耗
| 'download_deduct' // 简历下载消耗
| 'purchase' // 充值购买
| 'monthly_topup' // 月度补给
| 'migration' // 旧额度迁移
| 'plan_set' // 套餐设置
| 'share' // 分享所得
| 'contribution' // 面经贡献奖励
| 'share_credits_fallback' // 分享币后备抵扣
| 'admin_adjust' // 管理员调整
@Schema({ timestamps: true })
export class GravityTransaction {
@Prop({ required: true, index: true })
userId: string
@Prop({ required: true })
amount: number // 变动数量(正=增加,负=减少)
@Prop({ required: true })
balance: number // 变动后余额
@Prop({ required: true })
type: GravityTransactionType
@Prop({ default: '' })
description: string // 描述(如 "AI 模拟面试消耗"
@Prop()
refId?: string // 关联 ID(订单号、面试ID 等)
}
export const GravityTransactionSchema = SchemaFactory.createForClass(GravityTransaction)
GravityTransactionSchema.index({ userId: 1, createdAt: -1 })