feat: registration gravity from DB config instead of hardcoded
- Add registrationGravity to pricing config (default 50, adjustable via admin) - Inject PricingService into UserService, read config for all 4 registration paths - Expose registrationGravity in /member/plans response for frontend - Login page fetches dynamic value from API, replaces hardcoded '50' - Update user.vue gravity card copy
This commit is contained in:
@@ -53,6 +53,7 @@ export class MemberController {
|
||||
}
|
||||
|
||||
return {
|
||||
registrationGravity: pricing.registrationGravity,
|
||||
interview: { dailyFreeLimit: FREE_DAILY_LIMIT, maxRoundsFree: 5, maxRoundsVip: 10 },
|
||||
gravityRates: pricing.gravityRates,
|
||||
products: {
|
||||
|
||||
@@ -10,6 +10,8 @@ export interface GravityRates {
|
||||
}
|
||||
|
||||
interface PricingConfig {
|
||||
/** 新用户注册赠送引力值 */
|
||||
registrationGravity: number
|
||||
interview: { pricePerSession: number; creditsPerPurchase: number }
|
||||
resumeOptimize: { freeLimit: number; pricePerOptimize: number; creditsPerPurchase: number }
|
||||
resumeDownload: { pricePerDownload: number; creditsPerPurchase: number }
|
||||
@@ -21,6 +23,7 @@ interface PricingConfig {
|
||||
}
|
||||
|
||||
const DEFAULT_PRICING: PricingConfig = {
|
||||
registrationGravity: 50,
|
||||
interview: { pricePerSession: 600, creditsPerPurchase: 1 },
|
||||
resumeOptimize: { freeLimit: 3, pricePerOptimize: 400, creditsPerPurchase: 1 },
|
||||
resumeDownload: { pricePerDownload: 200, creditsPerPurchase: 1 },
|
||||
@@ -62,6 +65,7 @@ export class PricingService {
|
||||
|
||||
private mergeDefaults(value: any): PricingConfig {
|
||||
return {
|
||||
registrationGravity: value?.registrationGravity ?? DEFAULT_PRICING.registrationGravity,
|
||||
interview: { ...DEFAULT_PRICING.interview, ...value?.interview },
|
||||
resumeOptimize: { ...DEFAULT_PRICING.resumeOptimize, ...value?.resumeOptimize },
|
||||
resumeDownload: { ...DEFAULT_PRICING.resumeDownload, ...value?.resumeDownload },
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Model } from 'mongoose'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { User, UserDocument } from './user.schema'
|
||||
import { EmailService } from '../email/email.service'
|
||||
import { PricingService } from '../schemas/pricing.service'
|
||||
|
||||
/** 通过 IP 查询粗略地理位置(ip-api.com 免费接口) */
|
||||
async function lookupIpLocation(ip: string): Promise<string> {
|
||||
@@ -30,6 +31,7 @@ export class UserService {
|
||||
@InjectModel(User.name) private userModel: Model<UserDocument>,
|
||||
private jwtService: JwtService,
|
||||
private emailService: EmailService,
|
||||
private pricingService: PricingService,
|
||||
) {}
|
||||
|
||||
async sendCode(phone: string) {
|
||||
@@ -58,7 +60,7 @@ export class UserService {
|
||||
|
||||
let user = await this.userModel.findOne({ phone }).exec()
|
||||
if (!user) {
|
||||
user = await this.userModel.create({ phone, nickname: `用户${phone.slice(-4)}`, gravity: 5 })
|
||||
user = await this.userModel.create({ phone, nickname: `用户${phone.slice(-4)}`, gravity: (await this.pricingService.getConfig()).registrationGravity })
|
||||
}
|
||||
|
||||
await this.recordLogin(user._id.toString(), ip)
|
||||
@@ -94,7 +96,7 @@ export class UserService {
|
||||
|
||||
let user = await this.userModel.findOne({ wxOpenid: openid }).exec()
|
||||
if (!user) {
|
||||
user = await this.userModel.create({ wxOpenid: openid, nickname: '微信用户', gravity: 5 })
|
||||
user = await this.userModel.create({ wxOpenid: openid, nickname: '微信用户', gravity: (await this.pricingService.getConfig()).registrationGravity })
|
||||
}
|
||||
|
||||
await this.recordLogin(user._id.toString(), ip)
|
||||
@@ -170,7 +172,7 @@ export class UserService {
|
||||
if (!user) {
|
||||
isNew = true
|
||||
const nick = email.split('@')[0]
|
||||
user = await this.userModel.create({ email, nickname: nick, remaining: 0, gravity: 5 })
|
||||
user = await this.userModel.create({ email, nickname: nick, remaining: 0, gravity: (await this.pricingService.getConfig()).registrationGravity })
|
||||
}
|
||||
await this.recordLogin(user._id.toString(), ip)
|
||||
return { ...this.generateAuthResponse(user), isNew, hasPassword: !!user.password }
|
||||
@@ -208,7 +210,7 @@ export class UserService {
|
||||
}
|
||||
const nick = email.split('@')[0]
|
||||
const hashed = await bcrypt.hash(password, 10)
|
||||
const user = await this.userModel.create({ email, nickname: nick, password: hashed, remaining: 0, gravity: 5 })
|
||||
const user = await this.userModel.create({ email, nickname: nick, password: hashed, remaining: 0, gravity: (await this.pricingService.getConfig()).registrationGravity })
|
||||
await this.recordLogin(user._id.toString(), ip)
|
||||
return this.generateAuthResponse(user)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user