2026-03-17 13:17:02 +08:00

107 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.db import models
from django.conf import settings
from card.storage import OSSStorage
# 初始化OSS存储指定achievements目录
oss_storage = OSSStorage(base_dir='achievements')
class Achievement(models.Model):
"""
成就模型
存储各种成就的基本信息和获取条件
"""
name = models.CharField('成就名称', max_length=100)
description = models.TextField('成就描述')
icon = models.ImageField(
'成就图标',
upload_to='icons/',
storage=oss_storage,
null=True,
blank=True
)
conditions = models.JSONField('获取条件', help_text='JSON格式的成就获取条件')
# 成就等级/稀有度
RARITY_CHOICES = (
('common', '普通'),
('precious', '珍贵'),
('rare', '稀有'),
('epic', '史诗'),
('legendary', '传说'),
)
rarity = models.CharField('稀有度', max_length=20, choices=RARITY_CHOICES, default='common')
# 成就类型分类
TYPE_CHOICES = (
('login', '登录相关'),
('activity', '活动相关'),
('social', '社交相关'),
('usage', '使用相关'),
('special', '特殊成就'),
('hidden', '隐藏成就'),
)
achievement_type = models.CharField('成就类型', max_length=20, choices=TYPE_CHOICES, default='special')
# 是否为隐藏成就(不在成就列表中显示,直到获得)
is_hidden = models.BooleanField('隐藏成就', default=False)
# 成就积分(获得该成就奖励的积分)
points = models.IntegerField('成就积分', default=0)
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
class Meta:
verbose_name = '成就'
verbose_name_plural = '成就'
ordering = ['rarity', 'name']
indexes = [
models.Index(fields=['name']),
models.Index(fields=['achievement_type']),
models.Index(fields=['rarity']),
]
def __str__(self):
return self.name
class UserAchievement(models.Model):
"""
用户成就关联模型
记录用户获得的成就信息
"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='achievements',
verbose_name='用户'
)
achievement = models.ForeignKey(
Achievement,
on_delete=models.CASCADE,
related_name='users',
verbose_name='成就'
)
acquired_at = models.DateTimeField('获得时间', auto_now_add=True)
# 如果需要存储获得成就时的特定数据
acquisition_data = models.JSONField('获得数据', null=True, blank=True, help_text='JSON格式的获得成就时的相关数据')
# 是否已显示通知(用于控制成就获得的通知提醒)
notification_shown = models.BooleanField('已显示通知', default=False)
class Meta:
verbose_name = '用户成就'
verbose_name_plural = '用户成就'
ordering = ['-acquired_at']
# 确保一个用户不会重复获得同一个成就
unique_together = ['user', 'achievement']
indexes = [
models.Index(fields=['user']),
models.Index(fields=['achievement']),
models.Index(fields=['acquired_at']),
]
def __str__(self):
return f"{self.user} - {self.achievement}"