lty/qy_lty/food_app/models.py
2026-03-17 13:17:02 +08:00

274 lines
8.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.utils.translation import gettext_lazy as _
from django.utils import timezone
class Food(models.Model):
"""
食物模型
存储各种食物的基本信息、多媒体资源等
"""
# 食物类型选择
TYPE_CHOICES = [
('fruit', '水果'),
('vegetable', '蔬菜'),
('meat', '肉类'),
('seafood', '海鲜'),
('dairy', '乳制品'),
('grain', '谷物'),
('snack', '零食'),
('drink', '饮品'),
('dessert', '甜品'),
('spice', '调料'),
('other', '其他'),
]
# 稀有程度选择(参考成就和卡片系统的稀有度设计)
RARITY_CHOICES = [
('common', '普通'),
('uncommon', '不常见'),
('rare', '稀有'),
('epic', '史诗'),
('legendary', '传说'),
('mythic', '神话'),
]
# 状态选择
STATUS_CHOICES = [
('draft', '草稿'),
('published', '已发布'),
('archived', '已归档'),
]
# 基本信息
name = models.CharField('食物名称', max_length=100)
food_type = models.CharField('食物类型', max_length=20, choices=TYPE_CHOICES)
description = models.TextField('食物描述', blank=True, null=True)
# 稀有程度
rarity = models.CharField('稀有程度', max_length=20, choices=RARITY_CHOICES, default='common')
# 多媒体资源
image = models.URLField(
'食物图片',
max_length=500,
blank=True,
null=True,
help_text='食物的展示图片URL通过 /api/common/upload/ 接口上传获取'
)
animation_file = models.URLField(
'动画文件',
max_length=500,
blank=True,
null=True,
help_text='食物的动画文件URL支持gif/mp4等格式通过 /api/common/upload/ 接口上传获取'
)
sound_effect = models.URLField(
'音效文件',
max_length=500,
blank=True,
null=True,
help_text='食物相关的音效文件URL如咀嚼声、烹饪声等通过 /api/common/upload/ 接口上传获取'
)
# 额外属性
calories = models.PositiveIntegerField('卡路里', blank=True, null=True, help_text='每100g的卡路里')
taste_tags = models.CharField('口味标签', max_length=200, blank=True, null=True, help_text='用逗号分隔,如:甜,酸,脆')
cooking_methods = models.TextField('烹饪方法', blank=True, null=True)
nutritional_value = models.TextField('营养价值', blank=True, null=True)
# 游戏相关属性
effect_description = models.TextField('效果描述', blank=True, null=True, help_text='在游戏中的特殊效果')
boost_attributes = models.JSONField('属性加成', blank=True, null=True, help_text='JSON格式的属性加成数据')
# 获取和使用
unlock_condition = models.TextField('解锁条件', blank=True, null=True)
usage_limit = models.PositiveIntegerField('使用次数限制', blank=True, null=True, help_text='0表示无限制')
# 状态和时间
status = models.CharField('状态', max_length=20, choices=STATUS_CHOICES, default='draft')
is_limited = models.BooleanField('限时食物', default=False)
available_from = models.DateTimeField('开始时间', blank=True, null=True)
available_until = models.DateTimeField('结束时间', blank=True, null=True)
# 时间戳
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
published_at = models.DateTimeField('发布时间', blank=True, null=True)
def publish(self):
"""发布食物"""
self.status = 'published'
self.published_at = timezone.now()
self.save()
def archive(self):
"""归档食物"""
self.status = 'archived'
self.save()
def is_available(self):
"""检查食物是否可用"""
if self.status != 'published':
return False
if not self.is_limited:
return True
now = timezone.now()
if self.available_from and now < self.available_from:
return False
if self.available_until and now > self.available_until:
return False
return True
def get_taste_tags_list(self):
"""获取口味标签列表"""
if self.taste_tags:
return [tag.strip() for tag in self.taste_tags.split(',') if tag.strip()]
return []
class Meta:
verbose_name = '食物'
verbose_name_plural = '食物'
ordering = ['-created_at']
indexes = [
models.Index(fields=['name']),
models.Index(fields=['food_type']),
models.Index(fields=['rarity']),
models.Index(fields=['status']),
models.Index(fields=['created_at']),
]
def __str__(self):
return f"{self.name} ({self.get_rarity_display()})"
class UserFood(models.Model):
"""
用户食物关联模型
记录用户拥有的食物及使用情况
"""
from userapp.models import ParadiseUser
user = models.ForeignKey(
ParadiseUser,
on_delete=models.CASCADE,
related_name='foods',
verbose_name='用户'
)
food = models.ForeignKey(
Food,
on_delete=models.CASCADE,
related_name='users',
verbose_name='食物'
)
# 拥有数量和使用记录
quantity = models.PositiveIntegerField('拥有数量', default=1)
used_count = models.PositiveIntegerField('已使用次数', default=0)
# 获得信息
obtained_at = models.DateTimeField('获得时间', auto_now_add=True)
obtained_method = models.CharField(
'获得方式',
max_length=50,
blank=True,
null=True,
help_text='如:购买、奖励、活动等'
)
# 最后使用时间
last_used_at = models.DateTimeField('最后使用时间', blank=True, null=True)
class Meta:
verbose_name = '用户食物'
verbose_name_plural = '用户食物'
ordering = ['-obtained_at']
unique_together = ['user', 'food']
indexes = [
models.Index(fields=['user']),
models.Index(fields=['food']),
models.Index(fields=['obtained_at']),
]
def __str__(self):
return f"{self.user.username} - {self.food.name} (x{self.quantity})"
def can_use(self):
"""检查是否可以使用"""
if self.quantity <= 0:
return False
if self.food.usage_limit and self.used_count >= self.food.usage_limit:
return False
return self.food.is_available()
def use_food(self):
"""使用食物"""
if not self.can_use():
return False
self.used_count += 1
if self.food.usage_limit and self.used_count >= self.food.usage_limit:
self.quantity = 0
else:
self.quantity = max(0, self.quantity - 1)
self.last_used_at = timezone.now()
self.save()
return True
class FoodUsageLog(models.Model):
"""
食物使用记录
记录食物的详细使用日志
"""
from userapp.models import ParadiseUser
user = models.ForeignKey(
ParadiseUser,
on_delete=models.CASCADE,
related_name='food_usage_logs',
verbose_name='用户'
)
food = models.ForeignKey(
Food,
on_delete=models.CASCADE,
related_name='usage_logs',
verbose_name='食物'
)
# 使用信息
used_at = models.DateTimeField('使用时间', auto_now_add=True)
effect_applied = models.JSONField('应用效果', blank=True, null=True, help_text='JSON格式的效果数据')
notes = models.TextField('备注', blank=True, null=True)
# 使用环境
usage_context = models.CharField(
'使用场景',
max_length=100,
blank=True,
null=True,
help_text='如:战斗中、休息时、特殊活动等'
)
class Meta:
verbose_name = '食物使用记录'
verbose_name_plural = '食物使用记录'
ordering = ['-used_at']
indexes = [
models.Index(fields=['user']),
models.Index(fields=['food']),
models.Index(fields=['used_at']),
]
def __str__(self):
return f"{self.user.username} 使用了 {self.food.name} ({self.used_at.strftime('%Y-%m-%d %H:%M')})"