会员积分改版V1
This commit is contained in:
@@ -12,7 +12,6 @@ from app.dependencies import (
|
||||
get_current_user_allow_password_pending,
|
||||
get_db,
|
||||
)
|
||||
from app.models.credit_record import CreditRecord
|
||||
from app.models.system_config import SystemConfig
|
||||
from app.models.user import User
|
||||
from app.schemas.auth import (
|
||||
@@ -34,6 +33,10 @@ from app.services.auth import (
|
||||
)
|
||||
from app.services.sms import verify_sms_code
|
||||
from app.services.resource_capacity_service import get_user_resource_capacity_usage
|
||||
from app.enums.credit_balance import CreditBalanceSourceType, CreditLevel
|
||||
from app.services.credit.ledger_service import grant_credits
|
||||
from app.services.credit.query_service import attach_credit_snapshot, get_available_credits
|
||||
from app.services.credit.time_policy import add_natural_months
|
||||
from app.utils.id_gen import generate_id
|
||||
|
||||
router = APIRouter(prefix="/auth", tags=["auth"])
|
||||
@@ -93,50 +96,57 @@ async def _get_register_credits(db: AsyncSession) -> int:
|
||||
|
||||
async def _add_register_credit_record(db: AsyncSession, user: User, credits: int) -> None:
|
||||
if credits <= 0:
|
||||
attach_credit_snapshot(user, 0)
|
||||
return
|
||||
record = CreditRecord(
|
||||
id=generate_id(),
|
||||
now = datetime.now(timezone.utc)
|
||||
result = await grant_credits(
|
||||
db,
|
||||
user_id=user.id,
|
||||
type="recharge",
|
||||
amount=credits,
|
||||
balance_after=user.credits,
|
||||
description=f"注册赠送 {credits} 积分",
|
||||
source_type=CreditBalanceSourceType.REGISTER_GIFT.value,
|
||||
source_id=user.id,
|
||||
valid_from=now,
|
||||
expires_at=add_natural_months(now, 1),
|
||||
credit_level=CreditLevel.PROMOTIONAL.value,
|
||||
related_id=user.id,
|
||||
biz_key=f"register-gift:{user.id}",
|
||||
request_time=now,
|
||||
)
|
||||
db.add(record)
|
||||
attach_credit_snapshot(user, result.balance_after)
|
||||
|
||||
|
||||
async def _handle_daily_login_credits(db: AsyncSession, user: User) -> None:
|
||||
enabled_result = await db.execute(
|
||||
select(SystemConfig.value).where(SystemConfig.key == "user_login_credits_enabled").limit(1)
|
||||
)
|
||||
enabled = enabled_result.scalar_one_or_none() == "true"
|
||||
if not enabled:
|
||||
if enabled_result.scalar_one_or_none() != "true":
|
||||
attach_credit_snapshot(user, await get_available_credits(db, user.id))
|
||||
return
|
||||
|
||||
credits_result = await db.execute(
|
||||
select(SystemConfig.value).where(SystemConfig.key == "user_login_credits").limit(1)
|
||||
)
|
||||
credits = int(credits_result.scalar_one_or_none() or "0")
|
||||
if credits <= 0:
|
||||
return
|
||||
|
||||
today = datetime.now(CST).date()
|
||||
if user.last_login_at:
|
||||
last_login_date = user.last_login_at.date()
|
||||
if last_login_date >= today:
|
||||
return
|
||||
|
||||
user.credits += credits
|
||||
|
||||
record = CreditRecord(
|
||||
id=generate_id(),
|
||||
user_id=user.id,
|
||||
type="recharge",
|
||||
amount=credits,
|
||||
balance_after=user.credits,
|
||||
description=f"每日登录赠送 {credits} 积分",
|
||||
)
|
||||
db.add(record)
|
||||
now_cst = datetime.now(CST)
|
||||
if credits > 0:
|
||||
next_midnight_cst = datetime.combine(now_cst.date() + timedelta(days=1), datetime.min.time(), tzinfo=CST)
|
||||
result = await grant_credits(
|
||||
db,
|
||||
user_id=user.id,
|
||||
amount=credits,
|
||||
description=f"每日登录赠送 {credits} 积分",
|
||||
source_type=CreditBalanceSourceType.DAILY_LOGIN.value,
|
||||
source_id=now_cst.date().isoformat(),
|
||||
valid_from=now_cst,
|
||||
expires_at=next_midnight_cst,
|
||||
credit_level=CreditLevel.PROMOTIONAL.value,
|
||||
related_id=user.id,
|
||||
biz_key=f"daily-login:{user.id}:{now_cst.date().isoformat()}",
|
||||
request_time=now_cst,
|
||||
)
|
||||
attach_credit_snapshot(user, result.balance_after)
|
||||
else:
|
||||
attach_credit_snapshot(user, await get_available_credits(db, user.id))
|
||||
|
||||
|
||||
@router.post(
|
||||
@@ -226,7 +236,6 @@ async def register(req: RegisterRequest, db: AsyncSession = Depends(get_db)):
|
||||
phone=req.phone,
|
||||
hashed_password=hash_password(req.password),
|
||||
password_set_at=datetime.now(CST),
|
||||
credits=register_credits,
|
||||
is_admin=False,
|
||||
user_type="frontend",
|
||||
)
|
||||
@@ -342,7 +351,7 @@ async def get_site_info(db: AsyncSession = Depends(get_db)):
|
||||
"""Public endpoint returning site name, logo, agreement and copyright info."""
|
||||
result = await db.execute(
|
||||
select(SystemConfig).where(SystemConfig.key.in_([
|
||||
"site_name", "site_logo", "user_agreement_privacy_url", "site_copyright", "operation_manual", "login_bg_video", "optimize_hold_credits"
|
||||
"site_name", "site_logo", "user_agreement_privacy_url", "site_copyright", "operation_manual", "login_bg_video"
|
||||
]))
|
||||
)
|
||||
configs = result.scalars().all()
|
||||
@@ -366,7 +375,6 @@ async def get_site_info(db: AsyncSession = Depends(get_db)):
|
||||
"site_copyright": info.get("site_copyright", "© 2026 智创 版权所有"),
|
||||
"operation_manual": info.get("operation_manual", ""),
|
||||
"login_bg_video": to_full_url(info.get("login_bg_video")) if info.get("login_bg_video") else "",
|
||||
"optimize_hold_credits": int(info.get("optimize_hold_credits") or 5),
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user