Files
chunyu_project/tool/models.py
T
chunyu 24874aae23 feat(C-02):工具热榜周榜+最近使用
新增ToolUsageRecord使用日志(tool+created_at索引);/tool/top/总榜按累计排序、周榜按近7天聚合(无日志回退总榜,兼容period旧参);/tool/recent/登录去重倒序;seed新增AI图片放大/代码运行两个工具。
2026-09-15 15:20:27 +08:00

260 lines
6.4 KiB
Python

from django.db import models
from django.conf import settings
class ToolCategory(models.Model):
name = models.CharField(
max_length=50,
unique=True,
verbose_name='分类名称'
)
icon = models.CharField(
max_length=100,
default='AppstoreOutlined',
verbose_name='图标名称'
)
sort_order = models.IntegerField(
default=0,
verbose_name='排序'
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name='创建时间'
)
class Meta:
ordering = ['sort_order', '-created_at']
verbose_name = '工具分类'
verbose_name_plural = '工具分类'
def __str__(self):
return self.name
class Tool(models.Model):
name = models.CharField(
max_length=100,
verbose_name='工具名称'
)
description = models.TextField(
default='',
blank=True,
verbose_name='工具描述'
)
icon = models.CharField(
max_length=100,
default='ToolOutlined',
verbose_name='图标名称'
)
url_path = models.CharField(
max_length=200,
unique=True,
verbose_name='路由路径'
)
category = models.ForeignKey(
ToolCategory,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='tools',
verbose_name='所属分类'
)
is_enabled = models.BooleanField(
default=True,
verbose_name='是否启用'
)
is_new = models.BooleanField(
default=False,
verbose_name='是否为新工具'
)
color = models.CharField(
max_length=20,
default='#667eea',
blank=True,
verbose_name='主题颜色'
)
usage_count = models.IntegerField(
default=0,
verbose_name='使用次数'
)
sort_order = models.IntegerField(
default=0,
verbose_name='排序'
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name='创建时间'
)
updated_at = models.DateTimeField(
auto_now=True,
verbose_name='更新时间'
)
class Meta:
ordering = ['sort_order', '-created_at']
verbose_name = '工具'
verbose_name_plural = '工具'
def __str__(self):
return self.name
class ToolFavorite(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='tool_favorites',
verbose_name='用户'
)
tool = models.ForeignKey(
Tool,
on_delete=models.CASCADE,
related_name='tool_favorites',
verbose_name='工具'
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name='创建时间'
)
class Meta:
verbose_name = '工具收藏'
verbose_name_plural = '工具收藏'
unique_together = ['user', 'tool']
ordering = ['-created_at']
def __str__(self):
return f'{self.user} favorites {self.tool}'
class ToolUsageRecord(models.Model):
"""工具使用日志:用于周榜等时间窗聚合统计"""
tool = models.ForeignKey(
Tool,
on_delete=models.CASCADE,
related_name='usage_records',
verbose_name='工具'
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='tool_usage_records',
verbose_name='用户'
)
session_id = models.CharField(
max_length=64,
blank=True,
default='',
verbose_name='会话ID'
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name='使用时间'
)
class Meta:
verbose_name = '工具使用记录'
verbose_name_plural = '工具使用记录'
ordering = ['-created_at']
indexes = [
models.Index(fields=['tool', 'created_at']),
]
def __str__(self):
return f'{self.tool} used at {self.created_at}'
class CompressionHistory(models.Model):
COMPRESSION_MODE_CHOICES = [
('lossy', '有损压缩'),
('lossless', '无损优化'),
]
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
null=True,
blank=True,
verbose_name='用户'
)
session_id = models.CharField(
max_length=64,
null=True,
blank=True,
verbose_name='会话ID'
)
original_filename = models.CharField(
max_length=255,
verbose_name='原始文件名'
)
original_size = models.BigIntegerField(
verbose_name='原始大小(字节)'
)
compressed_size = models.BigIntegerField(
verbose_name='压缩后大小(字节)'
)
compression_ratio = models.FloatField(
verbose_name='压缩率'
)
original_format = models.CharField(
max_length=10,
verbose_name='原始格式'
)
output_format = models.CharField(
max_length=10,
verbose_name='输出格式'
)
compression_mode = models.CharField(
max_length=10,
choices=COMPRESSION_MODE_CHOICES,
verbose_name='压缩模式'
)
quality = models.IntegerField(
null=True,
blank=True,
verbose_name='压缩质量'
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name='创建时间'
)
file_path = models.CharField(
max_length=500,
verbose_name='文件路径'
)
class Meta:
ordering = ['-created_at']
verbose_name = '压缩历史'
verbose_name_plural = '压缩历史'
def __str__(self):
return f"{self.original_filename} - {self.compression_ratio:.1f}%"
class ColorHistory(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='color_histories',
verbose_name='用户'
)
color = models.CharField(
max_length=7,
verbose_name='颜色值(HEX)'
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name='创建时间'
)
class Meta:
ordering = ['-created_at']
verbose_name = '颜色历史'
verbose_name_plural = '颜色历史'
def __str__(self):
return f'{self.user} - {self.color}'