Files
along_django/shangpin/models.py

355 lines
16 KiB
Python
Raw Permalink 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 import timezone
class Shangpin(models.Model):
"""商品表 - 100-1000条数据"""
id = models.AutoField(primary_key=True, verbose_name='商品ID')
biaoqian = models.CharField(max_length=45,null=True, blank=True, verbose_name='商品标题') # 15汉字
jiage = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='商品价格')
kucun = models.PositiveIntegerField(default=0, verbose_name='商品库存')
leixing_id = models.PositiveIntegerField(null=True, blank=True,verbose_name='商品类型ID') # 直接存数字
zhuanqu_id = models.PositiveIntegerField(null=True, blank=True,verbose_name='商品专区ID') # 直接存数字
zhenshi_xiaoliang = models.PositiveIntegerField(default=0, verbose_name='商品真实销量')
duiwai_xiaoliang = models.PositiveIntegerField(default=0, verbose_name='商品对外销量')
jieshao = models.TextField(null=True, blank=True, verbose_name='商品介绍')
# 新增字段
xiadan_xuzhi = models.TextField(null=True, blank=True, verbose_name='下单须知') # 支持500字可换行
guize_tupian = models.CharField(max_length=500, null=True, blank=True, verbose_name='规则图片URL')
yaoqiuleixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='抢单要求类型')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
yongjin = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='佣金要求')
# 🔥 新增:是否开启打手额外分成
kaioi_ewai_dashou_fencheng = models.BooleanField(default=False, verbose_name='是否开启打手额外分成')
# 🔥 新增:打手额外分成金额(开启时使用此值,否则按利率计算)
ewai_dashou_fencheng = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='打手额外分成金额')
# 原有图片URL
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='商品图片URL')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更改时间')
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(
default=1,
verbose_name='审核状态',
help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式',
)
# 隐藏式商品归属的商家端类型ID点单写入订单抢单字段时用默认无归属
guishu_leixing_id = models.PositiveIntegerField(
null=True,
blank=True,
db_index=True,
verbose_name='归属商家端类型ID',
help_text='仅隐藏式商品使用;指向 shenhezhuangtai=3 的类型',
)
class Meta:
db_table = 'shangpin'
verbose_name = '商品'
verbose_name_plural = '商品'
# 不要索引!数据量太小
def __str__(self):
return f"商品{self.id}:{self.biaoqian}"
class ShangpinLeixing(models.Model):
"""商品类型表 - <10条数据"""
id = models.AutoField(primary_key=True, verbose_name='类型ID')
yaoqiuleixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='抢单要求类型')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
yongjin = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='佣金要求')
jieshao = models.CharField(max_length=45, null=True, blank=True, verbose_name='类型介绍') # 15汉字
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='类型图片URL') # 用CharField
is_cross_enabled = models.BooleanField(default=False, verbose_name='是否开启平台互通')
# 🔴 新增:是否特殊商品类型
is_special_type = models.BooleanField(default=False, verbose_name='是否特殊商品类型')
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(
default=1,
verbose_name='审核状态',
help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式',
)
# 隐藏式类型归属的商家端类型ID默认无归属
guishu_leixing_id = models.PositiveIntegerField(
null=True,
blank=True,
db_index=True,
verbose_name='归属商家端类型ID',
help_text='仅隐藏式类型使用;指向 shenhezhuangtai=3 的类型',
)
bankuai = models.ForeignKey(
'dengji.Bankuai',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name='所属板块'
)
class Meta:
db_table = 'shangpin_leixing'
verbose_name = '商品类型'
verbose_name_plural = '商品类型'
def __str__(self):
return f"{self.jieshao}"
class ShangpinZhuanqu(models.Model):
"""商品专区表 - <50条数据"""
id = models.AutoField(primary_key=True, verbose_name='专区ID')
mingzi = models.CharField(max_length=45, null=True, blank=True, verbose_name='专区名称') # 15汉字
leixing_id = models.PositiveIntegerField(verbose_name='类型ID') # 直接存数字,不关联
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(
default=1,
verbose_name='审核状态',
help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式',
)
class Meta:
db_table = 'shangpin_zhuanqu'
verbose_name = '商品专区'
verbose_name_plural = '商品专区'
def __str__(self):
return f"{self.mingzi}"
class Huiyuan(models.Model):
huiyuan_id = models.CharField(max_length=6, unique=True, verbose_name='会员ID')
jieshao = models.CharField(max_length=30, verbose_name='会员介绍')
jtjieshao = models.TextField(null=True, blank=True, verbose_name='会员规则介绍')
jiage = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='会员价格')
guanshifc = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='管事分成')
zuzhangfc = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='组长分成')
goumai_cishu = models.PositiveIntegerField(default=0, verbose_name='购买次数')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
bankuai = models.ForeignKey(
'dengji.Bankuai',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name='所属板块'
)
class Meta:
db_table = 'huiyuan'
verbose_name = '会员'
verbose_name_plural = '会员'
def __str__(self):
return f"会员{self.huiyuan_id}:{self.jieshao}"
class Huiyuangoumai(models.Model):
id = models.AutoField(primary_key=True, verbose_name='购买记录ID')
huiyuan_id = models.CharField(max_length=6, db_index=True, verbose_name='会员ID')
yonghu_id = models.CharField(max_length=32,db_index=True, verbose_name='用户ID')
huiyuan_zhuangtai = models.PositiveIntegerField(default=1, verbose_name='会员状态')
jieshao = models.CharField(max_length=30,null=True,verbose_name='会员介绍')
daoqi_time = models.DateTimeField(verbose_name='会员到期时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'huiyuangoumai'
verbose_name = '用户购买会员'
verbose_name_plural = '用户购买会员'
# 添加这个联合唯一约束
unique_together = [['yonghu_id', 'huiyuan_id']]
# 顺便优化索引(可选的,建议加)
indexes = [
models.Index(fields=['yonghu_id']),
models.Index(fields=['huiyuan_id']),
models.Index(fields=['yonghu_id', 'huiyuan_id']), # 复合索引加速查询
]
def __str__(self):
return f"用户{self.yonghu_id}-会员{self.huiyuan_id}"
def jiance_shifou_daoqi(self):
# 使用Django的timezone它会自动处理时区
now = timezone.now()
if now > self.daoqi_time:
# 过期了
if self.huiyuan_zhuangtai != 0:
self.huiyuan_zhuangtai = 0
self.save()
return True
else:
# 没过期
if self.huiyuan_zhuangtai != 1:
self.huiyuan_zhuangtai = 1
self.save()
return False
class Czjilu(models.Model):
dingdan_id = models.CharField(max_length=32, unique=True, db_index=True, verbose_name='订单ID')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
zhuangtai = models.IntegerField(null=True, blank=True, verbose_name='订单状态')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单金额')
leixing = models.IntegerField(null=True, blank=True, verbose_name='充值类型1:会员2:押金,3:积分,4:商家')
shuoming = models.CharField(max_length=100, null=True, blank=True, verbose_name='订单说明')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'czjilu'
verbose_name = '充值记录订单'
verbose_name_plural = '充值记录订单'
# 为高频查询字段添加索引
indexes = [
models.Index(fields=['dingdan_id']),
models.Index(fields=['yonghuid']),
]
class Gsfenhong(models.Model):
dingdan_id = models.CharField(max_length=32, db_index=True, verbose_name='订单ID')
guanshi = models.CharField(max_length=7, db_index=True, verbose_name='管事ID')
dashouid = models.CharField(max_length=7, db_index=True, verbose_name='关联用户ID')
shuoming = models.CharField(max_length=100, null=True, blank=True, verbose_name='订单说明')
fenhong = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单分红金额')
avatar = models.CharField(max_length=500, null=True, blank=True, verbose_name='打手头像')
nicheng = models.CharField(max_length=50, null=True, verbose_name='打手昵称')
zuzhang_id = models.CharField(max_length=7, null=True, blank=True, db_index=True, verbose_name='组长ID')
zuzhang_fenhong = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='组长分红金额')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
fenhong_leixing = models.PositiveSmallIntegerField(
default=1,
choices=[(1, '会员分红'), (2, '押金分红'), (3, '商家订单分红'), (4, '商家派单管事分红')],
verbose_name='分红类型'
)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'gsfenhong'
verbose_name = '管事分红记录'
verbose_name_plural = '管事分红记录'
constraints = [
models.UniqueConstraint(
fields=['dingdan_id', 'fenhong_leixing'],
name='unique_gsfenhong_dingdan_leixing',
),
]
indexes = [
models.Index(fields=['guanshi']),
models.Index(fields=['dashouid']),
]
class DuociFenhong(models.Model):
"""
多次分红配置表
用于配置不同次数下管事和组长的分红金额
"""
huiyuan = models.CharField(max_length=10, verbose_name='会员ID')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='管事ID')
cishu = models.PositiveIntegerField(verbose_name='分红次数')
guanshi_fenhong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='管事分红金额')
zuzhang_fenhong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='组长分红金额')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'duoci_fenhong'
verbose_name = '多次分红配置'
verbose_name_plural = '多次分红配置'
unique_together = ('huiyuan', 'yonghuid', 'cishu') # 同一管事、同一会员、同一次数唯一
indexes = [
models.Index(fields=['yonghuid']),
]
def __str__(self):
return f"会员{self.huiyuan_id} 用户{self.yonghuid} 次数{self.cishu}"
class ShangpinMeiriTongji(models.Model):
"""
商品每日统计表
按商品 + 日期维度记录点单、成交、退款及收益数据
日期精确到天,冗余年月日字段便于分组查询
"""
shangpin = models.ForeignKey(
'shangpin.Shangpin',
on_delete=models.CASCADE,
db_index=True,
verbose_name='商品ID'
)
riqi = models.DateField(db_index=True, verbose_name='统计日期')
nian = models.PositiveSmallIntegerField(verbose_name='年份')
yue = models.PositiveSmallIntegerField(verbose_name='月份')
ri = models.PositiveSmallIntegerField(verbose_name='')
# 点单统计(下单即累加)
diandan_zongliang = models.PositiveIntegerField(default=0, verbose_name='点单总量')
diandan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='点单总额')
# 成交统计(订单完成时累加)
chengjiao_zongliang = models.PositiveIntegerField(default=0, verbose_name='成交总量')
chengjiao_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='成交总额')
# 退款统计
tuikuan_zongliang = models.PositiveIntegerField(default=0, verbose_name='退款总量')
tuikuan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='退款总额')
# 收益统计(新增)
pingtai_shouyi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='平台收益')
dianpu_zongshouyi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='店铺总收益')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'shangpin_meiri_tongji'
verbose_name = '商品每日统计'
verbose_name_plural = verbose_name
# 每天每个商品唯一记录
unique_together = [['shangpin', 'riqi']]
indexes = [
models.Index(fields=['shangpin', 'riqi']),
models.Index(fields=['nian', 'yue', 'ri']),
]
def __str__(self):
return f"{self.shangpin.biaoqian} - {self.riqi}"
def clean(self):
"""保存前自动填充年月日冗余字段"""
if self.riqi:
self.nian = self.riqi.year
self.yue = self.riqi.month
self.ri = self.riqi.day
super().clean()
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)