from django.db import models from gvsdsdk.model_base import QModel class Lunbo(QModel): club_id = models.CharField(max_length=16, default='xq', db_index=True, verbose_name='俱乐部ID') page_key = models.CharField( max_length=32, default='order_pool', db_index=True, verbose_name='页面标识(order_pool/accept_order/merchant_home/dashou_center)', ) ImageURL = models.CharField(max_length=500, null=True, blank=True, verbose_name='轮播图片URL') ImageType = models.IntegerField(null=True, blank=True, verbose_name='图片类型:1:轮播2:个人中心背景') CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更改时间') class Meta: db_table = 'lunbo' verbose_name = '轮播' verbose_name_plural = '轮播' indexes = [ models.Index(fields=['club_id', 'page_key', 'ImageType']), ] class Gonggao(QModel): club_id = models.CharField(max_length=16, default='xq', db_index=True, verbose_name='俱乐部ID') NoticeType = models.IntegerField(null=True, blank=True, verbose_name='公告类型') CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更改时间') Content = models.TextField(null=True, blank=True, verbose_name='公告介绍') class Meta: db_table = 'gonggao' verbose_name = '公告' verbose_name_plural = '公告' # 不要索引!数据量太小 class Qunpeizhi(QModel): GroupType = models.IntegerField(null=True, blank=True, verbose_name='群类型:1.打手 2.管事') CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更改时间') GroupContent = models.CharField(max_length=200, null=True, blank=True, verbose_name='群介绍') GroupID = models.CharField(max_length=100, null=True, blank=True, verbose_name='群id') Description = models.CharField(max_length=200, null=True, blank=True, verbose_name='介绍') class Meta: db_table = 'qunpeizhi' class Tupianpeizhi(QModel): club_id = models.CharField(max_length=16, default='xq', db_index=True, verbose_name='俱乐部ID') ImageURL = models.CharField(max_length=500, null=True, blank=True, verbose_name='配置图片URL') ImageType = models.PositiveIntegerField(null=True, blank=True, verbose_name='提现类型1:打手规则图片2:默认头像图片') CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更改时间') AccessCount = models.PositiveIntegerField(default=0, verbose_name='访问次数') class Meta: db_table = 'tupianpeizhi' verbose_name = '配置图片' verbose_name_plural = '配置图片' unique_together = [['club_id', 'ImageType']] class Szjilu(QModel): id = models.AutoField(primary_key=True, verbose_name='记录ID') club_id = models.CharField(max_length=16, default='xq', db_index=True, verbose_name='俱乐部ID') TotalIncome = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='总收益') TotalFlow = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='总流水') TotalExpense = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='总支出') DailyExpense = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日支出') DailyFlow = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日流水') CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更改时间') class Meta: db_table = 'szjilu' verbose_name = '收支记录' verbose_name_plural = '收支记录' constraints = [ models.UniqueConstraint(fields=['club_id'], name='uniq_szjilu_club_id'), ] class ShangjiaMoban(QModel): """商家订单模板表 - 存储商家创建的订单模板""" # 主键ID(自动递增) id = models.AutoField(primary_key=True, verbose_name='模板ID') # 关联字段 UserID = models.CharField(max_length=7, db_index=True, verbose_name='用户ID') ProductTypeID = models.PositiveIntegerField(db_index=True, verbose_name='商品类型ID') # 模板内容 TemplateDesc = models.CharField(max_length=500, verbose_name='模板介绍') Price = models.DecimalField( max_digits=10, decimal_places=2, verbose_name='模板价格', help_text='单位:元' ) # 统计字段 PublishedCount = models.PositiveIntegerField(default=0, verbose_name='发布数量') CommissionGrabEnabled = models.BooleanField(default=False, verbose_name='是否开启佣金抢单') CommissionPrice = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='佣金价格') TitleID = models.IntegerField(null=True, blank=True, verbose_name='关联称号ID') # 时间字段 CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间') class Meta: db_table = 'shangjia_moban' verbose_name = '商家订单模板' verbose_name_plural = verbose_name indexes = [ # 高频查询组合索引 models.Index(fields=['UserID', 'ProductTypeID']), models.Index(fields=['UserID', 'ProductTypeID','id']), ] # 同一个商家同一类型下模板介绍不能重复(允许修改) unique_together = ['UserID', 'ProductTypeID', 'TemplateDesc'] def __str__(self): return f"模板{self.id}-{self.UserID}" class ShangjiaLianjie(QModel): """商家链接存储表 - 存储生成的派单链接""" # 主键ID(自动递增) id = models.AutoField(primary_key=True, verbose_name='链接ID') # 关联字段 UserID = models.CharField(max_length=7, db_index=True, verbose_name='用户ID') ProductTypeID = models.PositiveIntegerField(db_index=True, verbose_name='商品类型ID') TemplateID = models.PositiveIntegerField(db_index=True, verbose_name='模板ID') # 链接核心数据 LinkURL = models.CharField(max_length=500, unique=True, verbose_name='链接地址') # 订单关联(生成订单后更新) OrderID = models.CharField(max_length=32, null=True, blank=True, db_index=True, verbose_name='订单ID') # 使用状态 is_used = models.BooleanField(default=False, verbose_name='是否已使用', db_index=True) # 使用者信息 UserIP = models.CharField(max_length=50, null=True, blank=True, verbose_name='使用者IP') # 链接控制 ExpireTime = models.DateTimeField(null=True, blank=True, verbose_name='有效截止时间') # 安全字段 LinkToken = models.CharField( max_length=32, unique=True, db_index=True, verbose_name='链接Token', null=True, blank=True ) # 时间字段 CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间') # 上一个链接的ID(可选,记录订单被更换前的链接) PreviousLinkID = models.PositiveIntegerField( null=True, blank=True, db_index=True, verbose_name='上一个链接ID' ) # 上一个订单的ID(可选,记录被更换的旧订单ID) PreviousOrderID = models.CharField( max_length=32, null=True, blank=True, db_index=True, verbose_name='上一个订单ID' ) class Meta: db_table = 'shangjia_lianjie' verbose_name = '商家链接' verbose_name_plural = verbose_name indexes = [ # 高频查询组合索引 models.Index(fields=['UserID', 'TemplateID','ProductTypeID']), models.Index(fields=['LinkToken']), models.Index(fields=['OrderID']), ] def __str__(self): return f"链接{self.id}-{self.UserID}" class TixianQuotaDefault(QModel): """ 默认每日提现限额表 """ id = models.AutoField(primary_key=True) UserType = models.IntegerField( choices=[(1, '打手'), (2, '管事'), (3, '组长'), (4, '考核官'), (5, '打手押金'), (6, '商家余额')], unique=True, verbose_name='用户类型' ) default_quota = models.DecimalField( max_digits=10, decimal_places=2, default=20.00, verbose_name='默认每日提现限额(元)' ) CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间') class Meta: db_table = 'tixian_quota_default' verbose_name = '默认提现限额' verbose_name_plural = verbose_name def __str__(self): return f"{self.get_UserType_display()} 默认限额: {self.default_quota}" class WithdrawConfig(QModel): """ 提现模式配置表 - mode = 1: 自动提现(前端展示收款码模式) - mode = 2: 手动提现(前端展示微信零钱模式) 默认值为 2(手动打款),没有记录时前端也按默认 2 处理 """ MODE_CHOICES = ( (1, '自动提现'), # 对应前端模式一 (2, '手动提现'), # 对应前端模式二 ) mode = models.IntegerField( choices=MODE_CHOICES, default=2, verbose_name='提现模式' ) created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') updated_time = models.DateTimeField(auto_now=True, verbose_name='更新时间') class Meta: db_table = 'withdraw_config' verbose_name = '提现模式配置' verbose_name_plural = verbose_name def __str__(self): return f'提现模式: {"自动" if self.mode == 1 else "手动"}' class AccountPermission(QModel): """账号权限表:记录每个账号拥有的权限及开关状态""" account_id = models.CharField(max_length=11, db_index=True, verbose_name='账号ID') permission_code = models.IntegerField(verbose_name='权限代码') is_enabled = models.BooleanField(default=False, verbose_name='是否开启') class Meta: db_table = 'account_permission' verbose_name = '账号权限' verbose_name_plural = '账号权限' unique_together = [['account_id', 'permission_code']] # 一个账号的同一权限只能有一条记录 def __str__(self): return f"{self.account_id} 权限{self.permission_code}: {'开启' if self.is_enabled else '关闭'}" # apps/dingdan/models.py (新增模型) class DailyIncomeStat(QModel): """ 每日收入统计表 记录平台每天通过微信支付获得的总收入和总笔数 """ # 日期相关字段(便于快速筛选和分组) date = models.DateField(verbose_name='统计日期', db_index=True) club_id = models.CharField( max_length=16, default='xq', db_index=True, verbose_name='所属俱乐部', ) year = models.PositiveSmallIntegerField(verbose_name='年份') month = models.PositiveSmallIntegerField(verbose_name='月份') day = models.PositiveSmallIntegerField(verbose_name='日期') # 收入统计 total_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='总收入金额') total_count = models.PositiveIntegerField(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 = 'daily_income_stat' verbose_name = '每日收入统计' verbose_name_plural = verbose_name indexes = [ models.Index(fields=['date']), models.Index(fields=['year', 'month', 'day']), models.Index(fields=['club_id', 'date']), ] constraints = [ models.UniqueConstraint(fields=['date', 'club_id'], name='uniq_daily_income_club_date'), ] def __str__(self): return f"{self.date} - 收入{self.total_amount}元 - {self.total_count}笔" # apps/dingdan/models.py class DailyPayoutStat(QModel): """ 每日出款统计表 记录平台每天通过提现/结算等方式的出款总额和总笔数 """ date = models.DateField(verbose_name='统计日期', db_index=True) club_id = models.CharField( max_length=16, default='xq', db_index=True, verbose_name='所属俱乐部', ) year = models.PositiveSmallIntegerField(verbose_name='年份') month = models.PositiveSmallIntegerField(verbose_name='月份') day = models.PositiveSmallIntegerField(verbose_name='日期') total_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='出款总额') total_count = models.PositiveIntegerField(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 = 'daily_payout_stat' verbose_name = '每日出款统计' verbose_name_plural = verbose_name indexes = [ models.Index(fields=['date']), models.Index(fields=['year', 'month', 'day']), models.Index(fields=['club_id', 'date']), ] constraints = [ models.UniqueConstraint(fields=['date', 'club_id'], name='uniq_daily_payout_club_date'), ] def __str__(self): return f"{self.date} - 出款{self.total_amount}元 - {self.total_count}笔" class PopupPage(QModel): club_id = models.CharField(max_length=16, default='xq', db_index=True, verbose_name='俱乐部ID') page_key = models.CharField(max_length=50, db_index=True, verbose_name='页面标识') name = models.CharField(max_length=100, verbose_name='页面名称') description = models.TextField(blank=True, verbose_name='描述') is_active = models.BooleanField(default=True, verbose_name='是否启用') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) ignore_user_mute = models.BooleanField(default=False, verbose_name='忽略用户今日屏蔽') class Meta: db_table = 'popup_page' verbose_name = '弹窗页面' verbose_name_plural = '弹窗页面' unique_together = [['club_id', 'page_key']] def __str__(self): return f'{self.name} ({self.page_key})' class PopupConfig(QModel): STRATEGY_CHOICES = ( ('once', '仅一次'), ('daily', '每日'), ('weekly', '每周'), ('monthly', '每月'), ('yearly', '每年'), ('always', '始终'), ('count', '周期内次数限制'), ) page = models.ForeignKey(PopupPage, on_delete=models.CASCADE, related_name='popups') popup_id = models.CharField(max_length=50, verbose_name='弹窗唯一ID') title = models.CharField(max_length=200, blank=True, verbose_name='标题(后台用)') description = models.TextField(blank=True, verbose_name='描述(后台用)') strategy_type = models.CharField(max_length=20, choices=STRATEGY_CHOICES, default='once') max_count = models.PositiveIntegerField(default=1, verbose_name='周期内最大展示次数') reset_interval = models.CharField(max_length=20, blank=True, choices=(('day','天'),('week','周'),('month','月'),('year','年')), verbose_name='重置周期(count类型时使用)') duration = models.PositiveIntegerField(default=0, verbose_name='强制阅读秒数(0=无强制)') force_even_muted = models.BooleanField(default=False, verbose_name='强制弹出(忽略用户今日屏蔽)') sort_order = models.PositiveIntegerField(default=0, verbose_name='展示顺序') is_active = models.BooleanField(default=True, verbose_name='是否启用') start_time = models.DateTimeField(null=True, blank=True, verbose_name='生效开始时间') end_time = models.DateTimeField(null=True, blank=True, verbose_name='生效结束时间') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'popup_config' verbose_name = '弹窗配置' verbose_name_plural = '弹窗配置' unique_together = ('page', 'popup_id') ordering = ['sort_order', 'id'] def __str__(self): return f'{self.page.name} - {self.popup_id}' class PopupImage(QModel): popup_config = models.ForeignKey(PopupConfig, on_delete=models.CASCADE, related_name='images') image_url = models.CharField(max_length=500, verbose_name='图片相对路径') text = models.TextField(blank=True, verbose_name='图片上方文字') sort_order = models.PositiveIntegerField(default=0, verbose_name='展示顺序') created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'popup_image' verbose_name = '弹窗图片' verbose_name_plural = '弹窗图片' ordering = ['sort_order', 'id'] def __str__(self): return f'{self.popup_config.popup_id} - 图片{self.sort_order}'