Files
Django/rank/reward_models.py

148 lines
6.7 KiB
Python

"""排行榜奖励 — 按俱乐部分奖,与集团展示榜分离。"""
from django.db import models
from gvsdsdk.model_base import QModel
class RankRewardScheme(QModel):
"""俱乐部 + 身份 + 周期 奖励方案"""
PERIOD_DAY = 'day'
PERIOD_WEEK = 'week'
PERIOD_MONTH = 'month'
PERIOD_CHOICES = [
(PERIOD_DAY, '日榜(昨日)'),
(PERIOD_WEEK, '周榜(上周)'),
(PERIOD_MONTH, '月榜(上月)'),
]
club_id = models.CharField(max_length=16, db_index=True, verbose_name='俱乐部ID')
shenfen = models.CharField(max_length=16, db_index=True, verbose_name='身份')
period_type = models.CharField(max_length=16, choices=PERIOD_CHOICES, verbose_name='周期类型')
sort_field = models.CharField(max_length=32, verbose_name='排序指标键')
title = models.CharField(max_length=128, blank=True, default='', verbose_name='展示标题')
description = models.TextField(blank=True, default='', verbose_name='规则说明')
enabled = models.BooleanField(default=False, verbose_name='启用')
claim_days = models.PositiveSmallIntegerField(default=30, verbose_name='领取有效天数')
activity_start = models.DateField(null=True, blank=True, verbose_name='活动开始日期')
activity_end = models.DateField(null=True, blank=True, verbose_name='活动结束日期')
min_metric = models.DecimalField(
max_digits=12, decimal_places=2, default=0, verbose_name='最低指标门槛',
)
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'rank_reward_scheme'
verbose_name = '排行榜奖励方案'
verbose_name_plural = verbose_name
unique_together = [['club_id', 'shenfen', 'period_type']]
def __str__(self):
return f'{self.club_id}:{self.shenfen}:{self.period_type}'
class RankRewardTier(QModel):
scheme = models.ForeignKey(
RankRewardScheme, on_delete=models.CASCADE, related_name='tiers', verbose_name='方案',
)
rank_from = models.PositiveSmallIntegerField(verbose_name='名次起')
rank_to = models.PositiveSmallIntegerField(verbose_name='名次止')
reward_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='奖金(元)')
label = models.CharField(max_length=32, blank=True, default='', verbose_name='档位标签')
class Meta:
db_table = 'rank_reward_tier'
verbose_name = '排行榜奖励档位'
verbose_name_plural = verbose_name
ordering = ['rank_from']
def __str__(self):
return f'{self.rank_from}-{self.rank_to} ¥{self.reward_amount}'
class RankRewardSettlement(QModel):
"""结算批次 — 同一 club+方案+period_key 仅一条"""
scheme = models.ForeignKey(RankRewardScheme, on_delete=models.CASCADE, verbose_name='方案')
club_id = models.CharField(max_length=16, db_index=True, verbose_name='俱乐部ID')
period_key = models.CharField(max_length=32, db_index=True, verbose_name='周期键')
period_start = models.DateField(verbose_name='统计起始')
period_end = models.DateField(verbose_name='统计截止')
riqi_label = models.CharField(max_length=16, verbose_name='前端周期文案')
sort_field = models.CharField(max_length=32, verbose_name='结算时排序字段快照')
settled_at = models.DateTimeField(auto_now_add=True, verbose_name='结算时间')
claim_count = models.PositiveIntegerField(default=0, verbose_name='生成待领取数')
class Meta:
db_table = 'rank_reward_settlement'
verbose_name = '排行榜奖励结算'
verbose_name_plural = verbose_name
unique_together = [['club_id', 'scheme', 'period_key']]
class RankRewardClaim(QModel):
STATUS_PENDING = 0
STATUS_CLAIMED = 1
STATUS_EXPIRED = 2
STATUS_CANCELLED = 3
STATUS_CHOICES = [
(STATUS_PENDING, '待领取'),
(STATUS_CLAIMED, '已领取'),
(STATUS_EXPIRED, '已过期'),
(STATUS_CANCELLED, '已取消'),
]
settlement = models.ForeignKey(
RankRewardSettlement, on_delete=models.CASCADE, related_name='claims', verbose_name='结算批次',
)
club_id = models.CharField(max_length=16, db_index=True, verbose_name='俱乐部ID')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
shenfen = models.CharField(max_length=16, verbose_name='身份')
mingci = models.PositiveSmallIntegerField(verbose_name='名次')
metric_value = models.DecimalField(max_digits=12, decimal_places=2, default=0, verbose_name='指标快照')
reward_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='奖金')
status = models.PositiveSmallIntegerField(default=STATUS_PENDING, choices=STATUS_CHOICES, db_index=True)
expire_at = models.DateTimeField(verbose_name='领取截止')
claimed_at = models.DateTimeField(null=True, blank=True, verbose_name='领取时间')
balance_field = models.CharField(max_length=32, verbose_name='入账字段')
idempotent_key = models.CharField(max_length=96, unique=True, verbose_name='幂等键')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'rank_reward_claim'
verbose_name = '排行榜奖励领取'
verbose_name_plural = verbose_name
indexes = [
models.Index(fields=['yonghuid', 'status']),
models.Index(fields=['club_id', 'status']),
]
class RankRewardClaimLog(QModel):
"""领取审计 — 先记日志再入账"""
ACTION_START = 'claim_start'
ACTION_SUCCESS = 'claim_success'
ACTION_REJECT = 'claim_reject'
ACTION_CHOICES = [
(ACTION_START, '开始领取'),
(ACTION_SUCCESS, '领取成功'),
(ACTION_REJECT, '领取拒绝'),
]
claim = models.ForeignKey(
RankRewardClaim, on_delete=models.CASCADE, related_name='logs', verbose_name='领取记录',
)
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
action = models.CharField(max_length=32, choices=ACTION_CHOICES, verbose_name='动作')
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='金额')
detail = models.CharField(max_length=256, blank=True, default='', verbose_name='说明')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'rank_reward_claim_log'
verbose_name = '排行榜奖励领取日志'
verbose_name_plural = verbose_name
ordering = ['-CreateTime']