试点修复了 config 模型的拼音字段

This commit is contained in:
2026-06-19 11:41:18 +08:00
parent 6f6af7553a
commit 7df8a1a1d2
10 changed files with 930 additions and 815 deletions

View File

@@ -3349,13 +3349,13 @@ class GetWithdrawSettingsView(APIView):
# 2. 个人每日限额 (leixing=1,2,3) # 2. 个人每日限额 (leixing=1,2,3)
quota_map = {} quota_map = {}
for leixing in [1, 2, 3]: for leixing in [1, 2, 3]:
obj = TixianQuotaDefault.query.filter(leixing=leixing).first() obj = TixianQuotaDefault.query.filter(UserType=leixing).first()
quota_map[leixing] = float(obj.default_quota) if obj else 20.0 quota_map[leixing] = float(obj.default_quota) if obj else 20.0
# 3. 每日总限额提现类型1~6 → 配置表4~9 # 3. 每日总限额提现类型1~6 → 配置表4~9
total_limit_map = {} total_limit_map = {}
for withdraw_leixing, quota_leixing in [(1, 4), (2, 5), (3, 6), (4, 7), (5, 8), (6, 9)]: for withdraw_leixing, quota_leixing in [(1, 4), (2, 5), (3, 6), (4, 7), (5, 8), (6, 9)]:
obj = TixianQuotaDefault.query.filter(leixing=quota_leixing).first() obj = TixianQuotaDefault.query.filter(UserType=quota_leixing).first()
total_limit_map[withdraw_leixing] = float(obj.default_quota) if obj else 0.0 total_limit_map[withdraw_leixing] = float(obj.default_quota) if obj else 0.0
# 4. 当日已提现总额(按提现类型 leixing 1~6 # 4. 当日已提现总额(按提现类型 leixing 1~6
@@ -3491,7 +3491,7 @@ class UpdateWithdrawSettingsView(APIView):
if val is not None: if val is not None:
quota = Decimal(str(val)) quota = Decimal(str(val))
obj, created = TixianQuotaDefault.objects.select_for_update().get_or_create( obj, created = TixianQuotaDefault.objects.select_for_update().get_or_create(
leixing=role, UserType=role,
defaults={'default_quota': quota} defaults={'default_quota': quota}
) )
if not created: if not created:
@@ -3505,7 +3505,7 @@ class UpdateWithdrawSettingsView(APIView):
limit = Decimal(str(val)) limit = Decimal(str(val))
code = total_code_map[role] code = total_code_map[role]
obj, created = TixianQuotaDefault.objects.select_for_update().get_or_create( obj, created = TixianQuotaDefault.objects.select_for_update().get_or_create(
leixing=code, UserType=code,
defaults={'default_quota': limit} defaults={'default_quota': limit}
) )
if not created: if not created:
@@ -8220,7 +8220,7 @@ class ZxkfghdsView(APIView):
# 获取原链接用于模板ID等 # 获取原链接用于模板ID等
try: try:
old_lianjie = ShangjiaLianjie.query.get(dingdan_id=OrderID) old_lianjie = ShangjiaLianjie.query.get(OrderID=OrderID)
except ShangjiaLianjie.DoesNotExist: except ShangjiaLianjie.DoesNotExist:
logger.error(f"原链接记录不存在,订单: {OrderID}") logger.error(f"原链接记录不存在,订单: {OrderID}")
return Response({'code': 500, 'msg': '链接数据异常'}) return Response({'code': 500, 'msg': '链接数据异常'})
@@ -8306,7 +8306,7 @@ class ZxkfghdsView(APIView):
salt = secrets.token_hex(8) salt = secrets.token_hex(8)
raw = f"{timestamp}:{dd_id}:{uid}:{salt}" raw = f"{timestamp}:{dd_id}:{uid}:{salt}"
token = hashlib.sha256(raw.encode()).hexdigest()[:24] token = hashlib.sha256(raw.encode()).hexdigest()[:24]
if ShangjiaLianjie.query.filter(lianjie_token=token).exists(): if ShangjiaLianjie.query.filter(LinkToken=token).exists():
return generate_secure_token(dd_id, uid) return generate_secure_token(dd_id, uid)
return token return token
@@ -8346,16 +8346,16 @@ class ZxkfghdsView(APIView):
# ---- 6.4 生成新链接并关联旧链接信息 ---- # ---- 6.4 生成新链接并关联旧链接信息 ----
link_url = generate_link_url(secure_token) link_url = generate_link_url(secure_token)
new_lianjie = ShangjiaLianjie.query.create( new_lianjie = ShangjiaLianjie.query.create(
yonghu_id=shangjia_id, UserID=shangjia_id,
leixing_id=old_lianjie.leixing_id, ProductTypeID=old_lianjie.ProductTypeID,
moban_id=old_lianjie.moban_id, TemplateID=old_lianjie.TemplateID,
lianjie=link_url, LinkURL=link_url,
lianjie_token=secure_token, LinkToken=secure_token,
dingdan_id=new_OrderID, OrderID=new_OrderID,
is_used=True, # 直接标记已使用 is_used=True, # 直接标记已使用
youxiao_shijian=timezone.now() + timezone.timedelta(days=1), ExpireTime=timezone.now() + timezone.timedelta(days=1),
previous_lianjie_id=old_lianjie.id, # 记录旧链接ID PreviousLinkID=old_lianjie.id, # 记录旧链接ID
previous_dingdan_id=old_order.OrderID, # 记录旧订单ID PreviousOrderID=old_order.OrderID, # 记录旧订单ID
) )
# ---- 6.5 异步通知(广播新订单、跨平台同步) ---- # ---- 6.5 异步通知(广播新订单、跨平台同步) ----

View File

@@ -0,0 +1,64 @@
# Generated manually to rename pinyin fields to PascalCase
# db_column is preserved, so these are no-ops at the database level
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('config', '0001_initial'),
]
operations = [
# Lunbo
migrations.RenameField(model_name='lunbo', old_name='tupian_url', new_name='ImageURL'),
migrations.RenameField(model_name='lunbo', old_name='leixing', new_name='ImageType'),
# Gonggao
migrations.RenameField(model_name='gonggao', old_name='leixing', new_name='NoticeType'),
migrations.RenameField(model_name='gonggao', old_name='jieshao', new_name='Content'),
# Qunpeizhi
migrations.RenameField(model_name='qunpeizhi', old_name='peizhiid', new_name='GroupType'),
migrations.RenameField(model_name='qunpeizhi', old_name='neirong', new_name='GroupContent'),
migrations.RenameField(model_name='qunpeizhi', old_name='qunid', new_name='GroupID'),
migrations.RenameField(model_name='qunpeizhi', old_name='jieshao', new_name='Description'),
# Tupianpeizhi
migrations.RenameField(model_name='tupianpeizhi', old_name='tupian', new_name='ImageURL'),
migrations.RenameField(model_name='tupianpeizhi', old_name='leixing', new_name='ImageType'),
migrations.RenameField(model_name='tupianpeizhi', old_name='fangwen_cishu', new_name='AccessCount'),
# Szjilu
migrations.RenameField(model_name='szjilu', old_name='zongsy', new_name='TotalIncome'),
migrations.RenameField(model_name='szjilu', old_name='zongls', new_name='TotalFlow'),
migrations.RenameField(model_name='szjilu', old_name='zongzc', new_name='TotalExpense'),
migrations.RenameField(model_name='szjilu', old_name='jrzc', new_name='DailyExpense'),
migrations.RenameField(model_name='szjilu', old_name='jrls', new_name='DailyFlow'),
# ShangjiaMoban
migrations.RenameField(model_name='shangjiamoban', old_name='yonghu_id', new_name='UserID'),
migrations.RenameField(model_name='shangjiamoban', old_name='leixing_id', new_name='ProductTypeID'),
migrations.RenameField(model_name='shangjiamoban', old_name='moban_jieshao', new_name='TemplateDesc'),
migrations.RenameField(model_name='shangjiamoban', old_name='jiage', new_name='Price'),
migrations.RenameField(model_name='shangjiamoban', old_name='fabu_shuliang', new_name='PublishedCount'),
migrations.RenameField(model_name='shangjiamoban', old_name='yongjin_qiangdan', new_name='CommissionGrabEnabled'),
migrations.RenameField(model_name='shangjiamoban', old_name='yongjin_jiage', new_name='CommissionPrice'),
migrations.RenameField(model_name='shangjiamoban', old_name='chenghao_id', new_name='TitleID'),
# ShangjiaLianjie
migrations.RenameField(model_name='shangjialianjie', old_name='yonghu_id', new_name='UserID'),
migrations.RenameField(model_name='shangjialianjie', old_name='leixing_id', new_name='ProductTypeID'),
migrations.RenameField(model_name='shangjialianjie', old_name='moban_id', new_name='TemplateID'),
migrations.RenameField(model_name='shangjialianjie', old_name='lianjie', new_name='LinkURL'),
migrations.RenameField(model_name='shangjialianjie', old_name='dingdan_id', new_name='OrderID'),
migrations.RenameField(model_name='shangjialianjie', old_name='shiyongzhe_ip', new_name='UserIP'),
migrations.RenameField(model_name='shangjialianjie', old_name='youxiao_shijian', new_name='ExpireTime'),
migrations.RenameField(model_name='shangjialianjie', old_name='lianjie_token', new_name='LinkToken'),
migrations.RenameField(model_name='shangjialianjie', old_name='previous_lianjie_id', new_name='PreviousLinkID'),
migrations.RenameField(model_name='shangjialianjie', old_name='previous_dingdan_id', new_name='PreviousOrderID'),
# TixianQuotaDefault
migrations.RenameField(model_name='tixianquotadefault', old_name='leixing', new_name='UserType'),
]

View File

@@ -0,0 +1,76 @@
# Generated by Django 4.2.27 on 2026-06-19 11:36
# Modified to use SeparateDatabaseAndState for RemoveIndex to bypass
# MySQL backend's _create_missing_fk_index check that fails after RenameField
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('config', '0002_rename_pinyin_to_pascal'),
]
operations = [
# RemoveIndex operations wrapped in SeparateDatabaseAndState
# to bypass MySQL backend's FK index check that references old field names
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.RemoveIndex(
model_name='shangjialianjie',
name='shangjia_li_yonghu__9f2b25_idx',
),
migrations.RemoveIndex(
model_name='shangjialianjie',
name='shangjia_li_lianjie_99014c_idx',
),
migrations.RemoveIndex(
model_name='shangjialianjie',
name='shangjia_li_dingdan_95b682_idx',
),
migrations.RemoveIndex(
model_name='shangjiamoban',
name='shangjia_mo_yonghu__bb287d_idx',
),
migrations.RemoveIndex(
model_name='shangjiamoban',
name='shangjia_mo_yonghu__4240d0_idx',
),
],
database_operations=[
migrations.RunSQL(
sql=[
'DROP INDEX `shangjia_li_yonghu__9f2b25_idx` ON `shangjia_lianjie`',
'DROP INDEX `shangjia_li_lianjie_99014c_idx` ON `shangjia_lianjie`',
'DROP INDEX `shangjia_li_dingdan_95b682_idx` ON `shangjia_lianjie`',
'DROP INDEX `shangjia_mo_yonghu__bb287d_idx` ON `shangjia_moban`',
'DROP INDEX `shangjia_mo_yonghu__4240d0_idx` ON `shangjia_moban`',
],
reverse_sql=[
# No reverse needed - indexes will be recreated by AddIndex
],
),
],
),
# AddIndex operations - these should work fine since fields exist with new names
migrations.AddIndex(
model_name='shangjialianjie',
index=models.Index(fields=['UserID', 'TemplateID', 'ProductTypeID'], name='shangjia_li_UserID_e59d94_idx'),
),
migrations.AddIndex(
model_name='shangjialianjie',
index=models.Index(fields=['LinkToken'], name='shangjia_li_LinkTok_6b32bb_idx'),
),
migrations.AddIndex(
model_name='shangjialianjie',
index=models.Index(fields=['OrderID'], name='shangjia_li_OrderID_e7ddf9_idx'),
),
migrations.AddIndex(
model_name='shangjiamoban',
index=models.Index(fields=['UserID', 'ProductTypeID'], name='shangjia_mo_UserID_abd699_idx'),
),
migrations.AddIndex(
model_name='shangjiamoban',
index=models.Index(fields=['UserID', 'ProductTypeID', 'id'], name='shangjia_mo_UserID_2dcb54_idx'),
),
]

View File

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

View File

@@ -1,85 +1,85 @@
""" """
阿龙电竞 - 收支记录定时任务 阿龙电竞 - 收支记录定时任务
处理收支记录表的每日清零 处理收支记录表的每日清零
固定使用ID=1的记录 固定使用ID=1的记录
""" """
from celery import shared_task from celery import shared_task
from django.db import transaction from django.db import transaction
from django.utils import timezone from django.utils import timezone
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
import logging import logging
# 导入模型 # 导入模型
from config.models import Szjilu from config.models import Szjilu
from utils.celery_utils import log_task_execution, rollback_on_failure from utils.celery_utils import log_task_execution, rollback_on_failure
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@shared_task @shared_task
@rollback_on_failure("收支记录每日清零") @rollback_on_failure("收支记录每日清零")
def daily_sz_reset_task(): def daily_sz_reset_task():
""" """
收支记录每日清零 - 每天凌晨0点5分执行 收支记录每日清零 - 每天凌晨0点5分执行
清零收支记录表的今日相关字段固定使用ID=1的记录 清零收支记录表的今日相关字段固定使用ID=1的记录
""" """
try: try:
with transaction.atomic(): with transaction.atomic():
# 获取今天的日期 # 获取今天的日期
today = datetime.now().strftime('%Y-%m-%d') today = datetime.now().strftime('%Y-%m-%d')
logger.info(f"开始执行收支记录清零任务,日期: {today}") logger.info(f"开始执行收支记录清零任务,日期: {today}")
# 查询ID=1的收支记录如果不存在则创建 # 查询ID=1的收支记录如果不存在则创建
try: try:
szjilu = Szjilu.objects.get(id=1) szjilu = Szjilu.objects.get(id=1)
logger.info(f"找到ID=1的收支记录") logger.info(f"找到ID=1的收支记录")
except Szjilu.DoesNotExist: except Szjilu.DoesNotExist:
# 创建ID=1的初始记录 # 创建ID=1的初始记录
szjilu = Szjilu.objects.create( szjilu = Szjilu.objects.create(
id=1, id=1,
zongsy=Decimal('0.00'), TotalIncome=Decimal('0.00'),
zongls=Decimal('0.00'), TotalFlow=Decimal('0.00'),
zongzc=Decimal('0.00'), TotalExpense=Decimal('0.00'),
jrzc=Decimal('0.00'), DailyExpense=Decimal('0.00'),
jrls=Decimal('0.00') DailyFlow=Decimal('0.00')
) )
logger.info(f"创建ID=1的收支记录") logger.info(f"创建ID=1的收支记录")
# 记录清零前的值(用于日志) # 记录清零前的值(用于日志)
old_jrzc = szjilu.jrzc old_jrzc = szjilu.DailyExpense
old_jrls = szjilu.jrls old_jrls = szjilu.DailyFlow
# 清零今日字段 # 清零今日字段
szjilu.jrzc = Decimal('0.00') szjilu.DailyExpense = Decimal('0.00')
szjilu.jrls = Decimal('0.00') szjilu.DailyFlow = Decimal('0.00')
szjilu.save(update_fields=['jrzc', 'jrls', 'update_time']) szjilu.save(update_fields=['DailyExpense', 'DailyFlow', 'update_time'])
logger.info(f"收支记录清零完成,今日支出原值: {old_jrzc},今日流水原值: {old_jrls}") logger.info(f"收支记录清零完成,今日支出原值: {old_jrzc},今日流水原值: {old_jrls}")
result_msg = f"收支记录清零完成 - 日期: {today}, 记录ID: {szjilu.id}" result_msg = f"收支记录清零完成 - 日期: {today}, 记录ID: {szjilu.id}"
log_task_execution("收支记录每日清零", True, result_msg) log_task_execution("收支记录每日清零", True, result_msg)
return { return {
"success": True, "success": True,
"date": today, "date": today,
"record_id": szjilu.id, "record_id": szjilu.id,
"jrzc_cleared": True, "jrzc_cleared": True,
"jrls_cleared": True, "jrls_cleared": True,
"old_jrzc": str(old_jrzc), "old_jrzc": str(old_jrzc),
"old_jrls": str(old_jrls), "old_jrls": str(old_jrls),
"message": result_msg "message": result_msg
} }
except Exception as e: except Exception as e:
error_msg = f"收支记录每日清零失败: {str(e)}" error_msg = f"收支记录每日清零失败: {str(e)}"
logger.error(error_msg) logger.error(error_msg)
log_task_execution("收支记录每日清零", False, error_msg) log_task_execution("收支记录每日清零", False, error_msg)
return { return {
"success": False, "success": False,
"error": str(e), "error": str(e),
"date": datetime.now().strftime('%Y-%m-%d'), "date": datetime.now().strftime('%Y-%m-%d'),
"message": error_msg "message": error_msg
} }

View File

@@ -132,13 +132,13 @@ class ShangpinGonggaoView(APIView):
try: try:
logger.info("收到商品公告和轮播图请求") logger.info("收到商品公告和轮播图请求")
# 1. 查询公告类型为1 # 1. 查询公告类型为1
gonggao_obj = Gonggao.query.filter(leixing=1).first() gonggao_obj = Gonggao.query.filter(NoticeType=1).first()
# 获取公告内容,如果没有则返回空字符串 # 获取公告内容,如果没有则返回空字符串
gonggao_content = gonggao_obj.jieshao if gonggao_obj else "" gonggao_content = gonggao_obj.Content if gonggao_obj else ""
# 2. 查询轮播图类型为1按显示顺序排序 # 2. 查询轮播图类型为1按显示顺序排序
lunbo_queryset = Lunbo.query.filter(leixing=1) lunbo_queryset = Lunbo.query.filter(ImageType=1)
# 提取轮播图URL列表 # 提取轮播图URL列表
lunbo_urls = [lunbo.tupian_url for lunbo in lunbo_queryset] lunbo_urls = [lunbo.ImageURL for lunbo in lunbo_queryset]
# 3. 构建返回数据 # 3. 构建返回数据
response_data = { response_data = {
"shangpingonggao": gonggao_content, "shangpingonggao": gonggao_content,
@@ -211,18 +211,18 @@ class AdminConfigQueryView(APIView):
}, status=status.HTTP_401_UNAUTHORIZED) }, status=status.HTTP_401_UNAUTHORIZED)
# 查询图片配置 # 查询图片配置
rule_image = Tupianpeizhi.query.filter(leixing=1).first() rule_image = Tupianpeizhi.query.filter(ImageType=1).first()
default_avatar = Tupianpeizhi.query.filter(leixing=2).first() default_avatar = Tupianpeizhi.query.filter(ImageType=2).first()
# 查询群配置 # 查询群配置
qun_configs = Qunpeizhi.query.all() qun_configs = Qunpeizhi.query.all()
qq_groups = [] qq_groups = []
for config in qun_configs: for config in qun_configs:
qq_groups.append({ qq_groups.append({
'peizhiid': config.peizhiid, 'peizhiid': config.GroupType,
'neirong': config.neirong if config.neirong else '', 'neirong': config.GroupContent if config.GroupContent else '',
'qunid': config.qunid if config.qunid else '', 'qunid': config.GroupID if config.GroupID else '',
'jieshao': config.jieshao if config.jieshao else '' 'jieshao': config.Description if config.Description else ''
}) })
# 查询利率配置 # 查询利率配置
@@ -236,8 +236,8 @@ class AdminConfigQueryView(APIView):
# 构建返回数据 # 构建返回数据
data = { data = {
'images': { 'images': {
'rule_image': rule_image.tupian if rule_image and rule_image.tupian else '', 'rule_image': rule_image.ImageURL if rule_image and rule_image.ImageURL else '',
'default_avatar': default_avatar.tupian if default_avatar and default_avatar.tupian else '' 'default_avatar': default_avatar.ImageURL if default_avatar and default_avatar.ImageURL else ''
}, },
'qq_groups': qq_groups, 'qq_groups': qq_groups,
'rates': { 'rates': {
@@ -374,8 +374,8 @@ class AdminUploadImageView(APIView):
# 更新数据库 # 更新数据库
with transaction.atomic(): with transaction.atomic():
# 获取或创建图片配置记录 # 获取或创建图片配置记录
tupian_peizhi, created = Tupianpeizhi.query.get_or_create(leixing=int(leixing)) tupian_peizhi, created = Tupianpeizhi.query.get_or_create(ImageType=int(leixing))
tupian_peizhi.tupian = fixed_relative_url tupian_peizhi.ImageURL = fixed_relative_url
tupian_peizhi.save() tupian_peizhi.save()
return Response({ return Response({
@@ -454,7 +454,7 @@ class AdminUpdateConfigView(APIView):
continue continue
# 🔴 修复使用filter()确保查询到正确的记录 # 🔴 修复使用filter()确保查询到正确的记录
qun_configs = Qunpeizhi.query.filter(peizhiid=peizhiid) qun_configs = Qunpeizhi.query.filter(GroupType=peizhiid)
if qun_configs.exists(): if qun_configs.exists():
# 如果存在多个相同peizhiid的记录取第一个应该只有一个 # 如果存在多个相同peizhiid的记录取第一个应该只有一个
@@ -466,27 +466,27 @@ class AdminUpdateConfigView(APIView):
jieshao = group_data.get('jieshao') jieshao = group_data.get('jieshao')
if neirong is not None: if neirong is not None:
qun_config.neirong = neirong or '' qun_config.GroupContent = neirong or ''
if qunid is not None: if qunid is not None:
qun_config.qunid = qunid or '' qun_config.GroupID = qunid or ''
if jieshao is not None: if jieshao is not None:
qun_config.jieshao = jieshao or '' qun_config.Description = jieshao or ''
qun_config.save() qun_config.save()
else: else:
# 如果不存在创建新的使用提供的peizhiid # 如果不存在创建新的使用提供的peizhiid
qun_config = Qunpeizhi.query.create( qun_config = Qunpeizhi.query.create(
peizhiid=peizhiid, GroupType=peizhiid,
neirong=group_data.get('neirong', '') or '', GroupContent=group_data.get('neirong', '') or '',
qunid=group_data.get('qunid', '') or '', GroupID=group_data.get('qunid', '') or '',
jieshao=group_data.get('jieshao', '') or '' Description=group_data.get('jieshao', '') or ''
) )
updated_groups.append({ updated_groups.append({
'peizhiid': qun_config.peizhiid, 'peizhiid': qun_config.GroupType,
'neirong': qun_config.neirong, 'neirong': qun_config.GroupContent,
'qunid': qun_config.qunid, 'qunid': qun_config.GroupID,
'jieshao': qun_config.jieshao 'jieshao': qun_config.Description
}) })
if updated_groups: if updated_groups:
@@ -1349,45 +1349,45 @@ class ShangjiaMobanListView(APIView):
except (ValueError, TypeError): except (ValueError, TypeError):
label_id = None label_id = None
query = Q(yonghu_id=yonghu_id, leixing_id=leixing_id) query = Q(UserID=yonghu_id, ProductTypeID=leixing_id)
if get_type == 1: # 搜索模式 if get_type == 1: # 搜索模式
if keyword: if keyword:
keyword = str(keyword).strip() keyword = str(keyword).strip()
try: try:
mid = int(keyword) mid = int(keyword)
query &= Q(id=mid) | Q(moban_jieshao__icontains=keyword) query &= Q(id=mid) | Q(TemplateDesc__icontains=keyword)
except ValueError: except ValueError:
query &= Q(moban_jieshao__icontains=keyword) query &= Q(TemplateDesc__icontains=keyword)
if min_price: if min_price:
try: try:
query &= Q(jiage__gte=Decimal(str(min_price))) query &= Q(Price__gte=Decimal(str(min_price)))
except: except:
pass pass
if label_id: if label_id:
query &= Q(chenghao_id=label_id) query &= Q(TitleID=label_id)
mobans = ShangjiaMoban.query.filter(query).order_by('-id') mobans = ShangjiaMoban.query.filter(query).order_by('-id')
formatted = [] formatted = []
for moban in mobans: for moban in mobans:
texiao_json = '' texiao_json = ''
label_name = '' label_name = ''
if moban.chenghao_id: if moban.TitleID:
try: try:
ch = Chenghao.query.get(id=moban.chenghao_id) ch = Chenghao.query.get(id=moban.TitleID)
label_name = ch.mingcheng label_name = ch.mingcheng
texiao_json = ch.texiao_miaoshu or '' texiao_json = ch.texiao_miaoshu or ''
except Chenghao.DoesNotExist: except Chenghao.DoesNotExist:
pass pass
formatted.append({ formatted.append({
'mobanId': moban.id, 'mobanId': moban.id,
'shangpinTypeId': moban.leixing_id, 'shangpinTypeId': moban.ProductTypeID,
'jieshao': moban.moban_jieshao, 'jieshao': moban.TemplateDesc,
'jiage': str(moban.jiage), 'jiage': str(moban.Price),
'fabushuliang': moban.fabu_shuliang, 'fabushuliang': moban.PublishedCount,
'commissionEnabled': moban.yongjin_qiangdan, 'commissionEnabled': moban.CommissionGrabEnabled,
'commissionValue': str(moban.yongjin_jiage) if moban.yongjin_jiage is not None else None, 'commissionValue': str(moban.CommissionPrice) if moban.CommissionPrice is not None else None,
'labelId': moban.chenghao_id, 'labelId': moban.TitleID,
'labelName': label_name, 'labelName': label_name,
'texiaoJson': texiao_json, 'texiaoJson': texiao_json,
'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S') if moban.create_time else '' 'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S') if moban.create_time else ''
@@ -1405,22 +1405,22 @@ class ShangjiaMobanListView(APIView):
for moban in current_page.object_list: for moban in current_page.object_list:
texiao_json = '' texiao_json = ''
label_name = '' label_name = ''
if moban.chenghao_id: if moban.TitleID:
try: try:
ch = Chenghao.query.get(id=moban.chenghao_id) ch = Chenghao.query.get(id=moban.TitleID)
label_name = ch.mingcheng label_name = ch.mingcheng
texiao_json = ch.texiao_miaoshu or '' texiao_json = ch.texiao_miaoshu or ''
except Chenghao.DoesNotExist: except Chenghao.DoesNotExist:
pass pass
formatted.append({ formatted.append({
'mobanId': moban.id, 'mobanId': moban.id,
'shangpinTypeId': moban.leixing_id, 'shangpinTypeId': moban.ProductTypeID,
'jieshao': moban.moban_jieshao, 'jieshao': moban.TemplateDesc,
'jiage': str(moban.jiage), 'jiage': str(moban.Price),
'fabushuliang': moban.fabu_shuliang, 'fabushuliang': moban.PublishedCount,
'commissionEnabled': moban.yongjin_qiangdan, 'commissionEnabled': moban.CommissionGrabEnabled,
'commissionValue': str(moban.yongjin_jiage) if moban.yongjin_jiage is not None else None, 'commissionValue': str(moban.CommissionPrice) if moban.CommissionPrice is not None else None,
'labelId': moban.chenghao_id, 'labelId': moban.TitleID,
'labelName': label_name, 'labelName': label_name,
'texiaoJson': texiao_json, 'texiaoJson': texiao_json,
'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S') if moban.create_time else '' 'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S') if moban.create_time else ''
@@ -1499,17 +1499,17 @@ class ShangjiaTianjiaMobanView(APIView):
return Response({'code': 400, 'msg': '订单介绍不能超过100字', 'data': {}}, status=400) return Response({'code': 400, 'msg': '订单介绍不能超过100字', 'data': {}}, status=400)
# 6. 佣金验证(若启用) # 6. 佣金验证(若启用)
yongjin_qiangdan = False CommissionGrabEnabled = False
yongjin_jiage = None CommissionPrice = None
if commission_enabled: if commission_enabled:
yongjin_qiangdan = True CommissionGrabEnabled = True
if not commission_value: if not commission_value:
return Response({'code': 400, 'msg': '开启佣金时,佣金金额不能为空', 'data': {}}, status=400) return Response({'code': 400, 'msg': '开启佣金时,佣金金额不能为空', 'data': {}}, status=400)
try: try:
comm_decimal = Decimal(str(commission_value)) comm_decimal = Decimal(str(commission_value))
if comm_decimal <= 0: if comm_decimal <= 0:
return Response({'code': 400, 'msg': '佣金必须大于0', 'data': {}}, status=400) return Response({'code': 400, 'msg': '佣金必须大于0', 'data': {}}, status=400)
yongjin_jiage = comm_decimal CommissionPrice = comm_decimal
except (InvalidOperation, ValueError, TypeError): except (InvalidOperation, ValueError, TypeError):
return Response({'code': 400, 'msg': '佣金格式错误', 'data': {}}, status=400) return Response({'code': 400, 'msg': '佣金格式错误', 'data': {}}, status=400)
@@ -1532,23 +1532,23 @@ class ShangjiaTianjiaMobanView(APIView):
# 9. 检查同一用户、同一类型下是否已存在相同介绍的模板 # 9. 检查同一用户、同一类型下是否已存在相同介绍的模板
if ShangjiaMoban.query.filter( if ShangjiaMoban.query.filter(
yonghu_id=yonghu_id, UserID=yonghu_id,
leixing_id=leixing_id, ProductTypeID=leixing_id,
moban_jieshao=jieshao TemplateDesc=jieshao
).exists(): ).exists():
return Response({'code': 400, 'msg': '已存在相同介绍的模板', 'data': {}}, status=400) return Response({'code': 400, 'msg': '已存在相同介绍的模板', 'data': {}}, status=400)
# 10. 执行数据库创建(事务) # 10. 执行数据库创建(事务)
with transaction.atomic(): with transaction.atomic():
moban = ShangjiaMoban.query.create( moban = ShangjiaMoban.query.create(
yonghu_id=yonghu_id, UserID=yonghu_id,
leixing_id=leixing_id, ProductTypeID=leixing_id,
moban_jieshao=jieshao, TemplateDesc=jieshao,
jiage=jiage_decimal, Price=jiage_decimal,
fabu_shuliang=0, PublishedCount=0,
yongjin_qiangdan=yongjin_qiangdan, CommissionGrabEnabled=yongjin_qiangdan,
yongjin_jiage=yongjin_jiage, CommissionPrice=yongjin_jiage,
chenghao_id=cleaned_label_id TitleID=cleaned_label_id
) )
# 11. 返回成功数据(字段与前端对齐) # 11. 返回成功数据(字段与前端对齐)
@@ -1558,13 +1558,13 @@ class ShangjiaTianjiaMobanView(APIView):
'data': { 'data': {
'mobanId': moban.id, 'mobanId': moban.id,
'shangpinTypeId': leixing_id, 'shangpinTypeId': leixing_id,
'jieshao': moban.moban_jieshao, 'jieshao': moban.TemplateDesc,
'jiage': str(moban.jiage), 'jiage': str(moban.Price),
'fabushuliang': moban.fabu_shuliang, 'fabushuliang': moban.PublishedCount,
'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S'), 'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S'),
'commissionEnabled': moban.yongjin_qiangdan, 'commissionEnabled': moban.CommissionGrabEnabled,
'commissionValue': str(moban.yongjin_jiage) if moban.yongjin_jiage is not None else None, 'commissionValue': str(moban.CommissionPrice) if moban.CommissionPrice is not None else None,
'labelId': moban.chenghao_id 'labelId': moban.TitleID
} }
}) })
@@ -1599,7 +1599,7 @@ class ShangjiaShanchuMobanView(APIView):
return Response({'code': 400, 'msg': '参数缺失', 'data': {}}, status=400) return Response({'code': 400, 'msg': '参数缺失', 'data': {}}, status=400)
try: try:
moban = ShangjiaMoban.query.get(id=moban_id, yonghu_id=yonghu_id, leixing_id=leixing_id) moban = ShangjiaMoban.query.get(id=moban_id, UserID=yonghu_id, ProductTypeID=leixing_id)
except ShangjiaMoban.DoesNotExist: except ShangjiaMoban.DoesNotExist:
return Response({'code': 404, 'msg': '模板不存在', 'data': {}}, status=404) return Response({'code': 404, 'msg': '模板不存在', 'data': {}}, status=404)
@@ -1645,8 +1645,8 @@ class ShangjiaGengxinMobanView(APIView):
try: try:
moban = ShangjiaMoban.query.get( moban = ShangjiaMoban.query.get(
id=moban_id, id=moban_id,
yonghu_id=yonghu_id, UserID=yonghu_id,
leixing_id=leixing_id ProductTypeID=leixing_id
) )
except ShangjiaMoban.DoesNotExist: except ShangjiaMoban.DoesNotExist:
return Response({'code': 404, 'msg': '模板不存在或无权修改', 'data': {}}, status=404) return Response({'code': 404, 'msg': '模板不存在或无权修改', 'data': {}}, status=404)
@@ -1657,9 +1657,9 @@ class ShangjiaGengxinMobanView(APIView):
if new_jieshao: if new_jieshao:
if len(new_jieshao) > 100: if len(new_jieshao) > 100:
return Response({'code': 400, 'msg': '订单介绍不能超过100字', 'data': {}}, status=400) return Response({'code': 400, 'msg': '订单介绍不能超过100字', 'data': {}}, status=400)
if new_jieshao != moban.moban_jieshao: if new_jieshao != moban.TemplateDesc:
moban.moban_jieshao = new_jieshao moban.TemplateDesc = new_jieshao
update_fields.append('moban_jieshao') update_fields.append('TemplateDesc')
# 修改价格 # 修改价格
if new_jiage: if new_jiage:
@@ -1667,18 +1667,18 @@ class ShangjiaGengxinMobanView(APIView):
jiage_decimal = Decimal(new_jiage) jiage_decimal = Decimal(new_jiage)
if jiage_decimal <= 0 or jiage_decimal > 10000: if jiage_decimal <= 0 or jiage_decimal > 10000:
return Response({'code': 400, 'msg': '价格必须在0.1-10000元之间', 'data': {}}, status=400) return Response({'code': 400, 'msg': '价格必须在0.1-10000元之间', 'data': {}}, status=400)
if jiage_decimal != moban.jiage: if jiage_decimal != moban.Price:
moban.jiage = jiage_decimal moban.Price = jiage_decimal
update_fields.append('jiage') update_fields.append('Price')
except (InvalidOperation, ValueError, TypeError): except (InvalidOperation, ValueError, TypeError):
return Response({'code': 400, 'msg': '价格格式错误', 'data': {}}, status=400) return Response({'code': 400, 'msg': '价格格式错误', 'data': {}}, status=400)
# 修改标签 # 修改标签
if label_id is not None: # 允许传空字符串或不传传0表示清空 if label_id is not None: # 允许传空字符串或不传传0表示清空
new_label = int(label_id) if label_id else None new_label = int(label_id) if label_id else None
if new_label != moban.chenghao_id: if new_label != moban.TitleID:
moban.chenghao_id = new_label moban.TitleID = new_label
update_fields.append('chenghao_id') update_fields.append('TitleID')
# 修改佣金设置 # 修改佣金设置
if commission_enabled is not None: if commission_enabled is not None:
@@ -1690,27 +1690,27 @@ class ShangjiaGengxinMobanView(APIView):
comm_decimal = Decimal(commission_value) comm_decimal = Decimal(commission_value)
if comm_decimal < 0.1 or comm_decimal > 50: if comm_decimal < 0.1 or comm_decimal > 50:
return Response({'code': 400, 'msg': '佣金需在0.1-50元之间', 'data': {}}, status=400) return Response({'code': 400, 'msg': '佣金需在0.1-50元之间', 'data': {}}, status=400)
if moban.yongjin_qiangdan != True or moban.yongjin_jiage != comm_decimal: if moban.CommissionGrabEnabled != True or moban.CommissionPrice != comm_decimal:
moban.yongjin_qiangdan = True moban.CommissionGrabEnabled = True
moban.yongjin_jiage = comm_decimal moban.CommissionPrice = comm_decimal
update_fields.extend(['yongjin_qiangdan', 'yongjin_jiage']) update_fields.extend(['CommissionGrabEnabled', 'CommissionPrice'])
except (InvalidOperation, ValueError, TypeError): except (InvalidOperation, ValueError, TypeError):
return Response({'code': 400, 'msg': '佣金格式错误', 'data': {}}, status=400) return Response({'code': 400, 'msg': '佣金格式错误', 'data': {}}, status=400)
else: else:
if moban.yongjin_qiangdan != False or moban.yongjin_jiage is not None: if moban.CommissionGrabEnabled != False or moban.CommissionPrice is not None:
moban.yongjin_qiangdan = False moban.CommissionGrabEnabled = False
moban.yongjin_jiage = None moban.CommissionPrice = None
update_fields.extend(['yongjin_qiangdan', 'yongjin_jiage']) update_fields.extend(['CommissionGrabEnabled', 'CommissionPrice'])
if not update_fields: if not update_fields:
return Response({'code': 400, 'msg': '没有修改内容', 'data': {}}, status=400) return Response({'code': 400, 'msg': '没有修改内容', 'data': {}}, status=400)
# 检查介绍唯一性 # 检查介绍唯一性
if 'moban_jieshao' in update_fields: if 'TemplateDesc' in update_fields:
if ShangjiaMoban.query.filter( if ShangjiaMoban.query.filter(
yonghu_id=yonghu_id, UserID=yonghu_id,
leixing_id=leixing_id, ProductTypeID=leixing_id,
moban_jieshao=moban.moban_jieshao TemplateDesc=moban.TemplateDesc
).exclude(id=moban_id).exists(): ).exclude(id=moban_id).exists():
return Response({'code': 400, 'msg': '已存在相同介绍的模板', 'data': {}}, status=400) return Response({'code': 400, 'msg': '已存在相同介绍的模板', 'data': {}}, status=400)
@@ -1723,13 +1723,13 @@ class ShangjiaGengxinMobanView(APIView):
'msg': '模板修改成功', 'msg': '模板修改成功',
'data': { 'data': {
'mobanId': moban.id, 'mobanId': moban.id,
'shangpinTypeId': moban.leixing_id, 'shangpinTypeId': moban.ProductTypeID,
'jieshao': moban.moban_jieshao, 'jieshao': moban.TemplateDesc,
'jiage': str(moban.jiage), 'jiage': str(moban.Price),
'fabushuliang': moban.fabu_shuliang, 'fabushuliang': moban.PublishedCount,
'commissionEnabled': moban.yongjin_qiangdan, 'commissionEnabled': moban.CommissionGrabEnabled,
'commissionValue': str(moban.yongjin_jiage) if moban.yongjin_jiage else None, 'commissionValue': str(moban.CommissionPrice) if moban.CommissionPrice else None,
'labelId': moban.chenghao_id, 'labelId': moban.TitleID,
'updateTime': moban.update_time.strftime('%Y-%m-%d %H:%M:%S') 'updateTime': moban.update_time.strftime('%Y-%m-%d %H:%M:%S')
} }
}) })
@@ -1778,11 +1778,11 @@ class ShangjiaGenerateLinkView(APIView):
# 查询模板 # 查询模板
try: try:
moban = ShangjiaMoban.query.get(id=moban_id, yonghu_id=user.UserUID, leixing_id=shangpin_type_id) moban = ShangjiaMoban.query.get(id=moban_id, UserID=user.UserUID, ProductTypeID=shangpin_type_id)
except ShangjiaMoban.DoesNotExist: except ShangjiaMoban.DoesNotExist:
return Response({'code': 400, 'msg': '模板不存在', 'data': {}}, status=400) return Response({'code': 400, 'msg': '模板不存在', 'data': {}}, status=400)
jiage = moban.jiage jiage = moban.Price
if jiage > shangjia.yue: if jiage > shangjia.yue:
return Response({'code': 400, 'msg': f'余额不足,当前余额{shangjia.yue}', 'data': {}}, status=400) return Response({'code': 400, 'msg': f'余额不足,当前余额{shangjia.yue}', 'data': {}}, status=400)
@@ -1794,10 +1794,10 @@ class ShangjiaGenerateLinkView(APIView):
dashou_fencheng = Decimal(str(round(float(jiage) * lilu, 2))) dashou_fencheng = Decimal(str(round(float(jiage) * lilu, 2)))
# 抢单要求:根据模板是否启用佣金 # 抢单要求:根据模板是否启用佣金
chenghao_id = moban.chenghao_id chenghao_id = moban.TitleID
if moban.yongjin_qiangdan and moban.yongjin_jiage is not None: if moban.CommissionGrabEnabled and moban.CommissionPrice is not None:
final_yaoqiuleixing = 2 # 佣金模式 final_yaoqiuleixing = 2 # 佣金模式
final_yongjin = moban.yongjin_jiage final_yongjin = moban.CommissionPrice
final_huiyuan_id = '' final_huiyuan_id = ''
else: else:
final_yaoqiuleixing = shangpin_leixing.yaoqiuleixing or 1 final_yaoqiuleixing = shangpin_leixing.yaoqiuleixing or 1
@@ -1825,7 +1825,7 @@ class ShangjiaGenerateLinkView(APIView):
raw = f"{timestamp}:{dd_id}:{uid}:{salt}" raw = f"{timestamp}:{dd_id}:{uid}:{salt}"
token = hashlib.sha256(raw.encode()).hexdigest()[:24] token = hashlib.sha256(raw.encode()).hexdigest()[:24]
# 确保唯一性(极小概率重复再试一次) # 确保唯一性(极小概率重复再试一次)
if ShangjiaLianjie.query.filter(lianjie_token=token).exists(): if ShangjiaLianjie.query.filter(LinkToken=token).exists():
return generate_secure_token(dd_id, uid) return generate_secure_token(dd_id, uid)
return token return token
@@ -1848,7 +1848,7 @@ class ShangjiaGenerateLinkView(APIView):
yaoqiuleixing=final_yaoqiuleixing, yaoqiuleixing=final_yaoqiuleixing,
huiyuan_id=final_huiyuan_id, huiyuan_id=final_huiyuan_id,
yongjin=final_yongjin, yongjin=final_yongjin,
Description=moban.moban_jieshao[:2000], Description=moban.TemplateDesc[:2000],
user1_id=f"Sj{user.UserUID}", user1_id=f"Sj{user.UserUID}",
ImageURL=user.Avatar or '', ImageURL=user.Avatar or '',
) )
@@ -1881,18 +1881,18 @@ class ShangjiaGenerateLinkView(APIView):
# 生成链接并保存 # 生成链接并保存
link_url = generate_link_url(secure_token) link_url = generate_link_url(secure_token)
lianjie_obj = ShangjiaLianjie.query.create( lianjie_obj = ShangjiaLianjie.query.create(
yonghu_id=user.UserUID, UserID=user.UserUID,
leixing_id=shangpin_type_id, ProductTypeID=shangpin_type_id,
moban_id=moban_id, TemplateID=moban_id,
lianjie=link_url, LinkURL=link_url,
lianjie_token=secure_token, LinkToken=secure_token,
dingdan_id=dingdan_id, OrderID=dingdan_id,
is_used=False, is_used=False,
youxiao_shijian=timezone.now() + timezone.timedelta(days=1) ExpireTime=timezone.now() + timezone.timedelta(days=1)
) )
# 更新模板发布数量 # 更新模板发布数量
ShangjiaMoban.query.filter(id=moban_id).update(fabu_shuliang=F('fabu_shuliang') + 1) ShangjiaMoban.query.filter(id=moban_id).update(PublishedCount=F('PublishedCount') + 1)
shangjia.refresh_from_db() shangjia.refresh_from_db()
logger.info(f"链接生成成功 - 订单ID: {dingdan_id}, 标签: {label_name}") logger.info(f"链接生成成功 - 订单ID: {dingdan_id}, 标签: {label_name}")
@@ -1904,11 +1904,11 @@ class ShangjiaGenerateLinkView(APIView):
'linkUrl': link_url, 'linkUrl': link_url,
'newBalance': str(shangjia.yue), 'newBalance': str(shangjia.yue),
'dingdanId': dingdan_id, 'dingdanId': dingdan_id,
'dingdanJieshao': moban.moban_jieshao, 'dingdanJieshao': moban.TemplateDesc,
'jiage': str(jiage), 'jiage': str(jiage),
'labelId': chenghao_id, 'labelId': chenghao_id,
'labelName': label_name, 'labelName': label_name,
'youxiaoShijian': lianjie_obj.youxiao_shijian.strftime('%Y-%m-%d %H:%M:%S'), 'youxiaoShijian': lianjie_obj.ExpireTime.strftime('%Y-%m-%d %H:%M:%S'),
} }
}) })
@@ -1939,13 +1939,13 @@ class ShangjiaLianjieListView(APIView):
# 校验模板归属 # 校验模板归属
try: try:
moban = ShangjiaMoban.query.get(id=moban_id, yonghu_id=yonghu_id) moban = ShangjiaMoban.query.get(id=moban_id, UserID=yonghu_id)
except ShangjiaMoban.DoesNotExist: except ShangjiaMoban.DoesNotExist:
return Response({'code': 404, 'msg': '模板不存在或无权查看', 'data': {}}, status=404) return Response({'code': 404, 'msg': '模板不存在或无权查看', 'data': {}}, status=404)
links = ShangjiaLianjie.query.filter( links = ShangjiaLianjie.query.filter(
yonghu_id=yonghu_id, UserID=yonghu_id,
moban_id=moban_id, TemplateID=moban_id,
is_used=(used == 1) is_used=(used == 1)
).order_by('-create_time') ).order_by('-create_time')
@@ -1958,11 +1958,11 @@ class ShangjiaLianjieListView(APIView):
for link in current_page.object_list: for link in current_page.object_list:
data_list.append({ data_list.append({
'id': link.id, 'id': link.id,
'lianjie': link.lianjie, 'lianjie': link.LinkURL,
'lianjie_token': link.lianjie_token, 'LinkToken': link.LinkToken,
'is_used': link.is_used, 'is_used': link.is_used,
'dingdan_id': link.dingdan_id, 'dingdan_id': link.OrderID,
'youxiao_shijian': link.youxiao_shijian.strftime('%Y-%m-%d %H:%M:%S') if link.youxiao_shijian else '', 'ExpireTime': link.ExpireTime.strftime('%Y-%m-%d %H:%M:%S') if link.ExpireTime else '',
'create_time': link.create_time.strftime('%Y-%m-%d %H:%M:%S') 'create_time': link.create_time.strftime('%Y-%m-%d %H:%M:%S')
}) })
@@ -2138,8 +2138,8 @@ class KehuGetDingdanLianjieView(APIView):
# 5. 查询链接记录 # 5. 查询链接记录
try: try:
lianjie_obj = ShangjiaLianjie.query.select_related().get(lianjie_token=token) lianjie_obj = ShangjiaLianjie.query.select_related().get(LinkToken=token)
logger.info(f"找到链接记录 - 链接ID: {lianjie_obj.id}, 商家ID: {lianjie_obj.yonghu_id}") logger.info(f"找到链接记录 - 链接ID: {lianjie_obj.id}, 商家ID: {lianjie_obj.UserID}")
except ShangjiaLianjie.DoesNotExist: except ShangjiaLianjie.DoesNotExist:
logger.warning(f"链接不存在 - Token: {token[:8]}..., IP: {client_ip}") logger.warning(f"链接不存在 - Token: {token[:8]}..., IP: {client_ip}")
return Response({ return Response({
@@ -2157,8 +2157,8 @@ class KehuGetDingdanLianjieView(APIView):
# 6. 更新访问者IP无论是否已使用都记录最新访问IP # 6. 更新访问者IP无论是否已使用都记录最新访问IP
try: try:
lianjie_obj.shiyongzhe_ip = client_ip lianjie_obj.UserIP = client_ip
lianjie_obj.save(update_fields=['shiyongzhe_ip']) lianjie_obj.save(update_fields=['UserIP'])
logger.info(f"更新访问者IP成功: {client_ip}") logger.info(f"更新访问者IP成功: {client_ip}")
except Exception as e: except Exception as e:
logger.warning(f"更新IP失败: {str(e)}") logger.warning(f"更新IP失败: {str(e)}")
@@ -2166,8 +2166,8 @@ class KehuGetDingdanLianjieView(APIView):
# 7. 检查链接有效期 # 7. 检查链接有效期
'''now = timezone.now() '''now = timezone.now()
if lianjie_obj.youxiao_shijian and lianjie_obj.youxiao_shijian < now: if lianjie_obj.ExpireTime and lianjie_obj.ExpireTime < now:
logger.warning(f"链接已过期 - 过期时间: {lianjie_obj.youxiao_shijian}, 当前: {now}") logger.warning(f"链接已过期 - 过期时间: {lianjie_obj.ExpireTime}, 当前: {now}")
return Response({ return Response({
'code': 400, 'code': 400,
'msg': '链接已过期', 'msg': '链接已过期',
@@ -2177,25 +2177,25 @@ class KehuGetDingdanLianjieView(APIView):
# 8. 准备返回数据 # 8. 准备返回数据
response_data = { response_data = {
'is_used': lianjie_obj.is_used, 'is_used': lianjie_obj.is_used,
'dingdan_id': lianjie_obj.dingdan_id or '', 'dingdan_id': lianjie_obj.OrderID or '',
'youxiao_shijian': lianjie_obj.youxiao_shijian.strftime( 'youxiao_shijian': lianjie_obj.ExpireTime.strftime(
'%Y-%m-%d %H:%M:%S') if lianjie_obj.youxiao_shijian else '', '%Y-%m-%d %H:%M:%S') if lianjie_obj.ExpireTime else '',
} }
# 9. 获取订单信息 # 9. 获取订单信息
if lianjie_obj.dingdan_id: if lianjie_obj.OrderID:
try: try:
# 查询订单主表 # 查询订单主表
dingdan_obj = Order.query.get(OrderID=lianjie_obj.dingdan_id) dingdan_obj = Order.query.get(OrderID=lianjie_obj.OrderID)
# 获取商家昵称 # 获取商家昵称
shangjia_nicheng = '' shangjia_nicheng = ''
try: try:
user_main = User.query.get(UserUID=lianjie_obj.yonghu_id) user_main = User.query.get(UserUID=lianjie_obj.UserID)
shangjia_obj = user_main.ShopProfile shangjia_obj = user_main.ShopProfile
shangjia_nicheng = shangjia_obj.nicheng shangjia_nicheng = shangjia_obj.nicheng
except (User.DoesNotExist, UserShangjia.DoesNotExist): except (User.DoesNotExist, UserShangjia.DoesNotExist):
logger.warning(f"商家信息不存在 - 用户ID: {lianjie_obj.yonghu_id}") logger.warning(f"商家信息不存在 - 用户ID: {lianjie_obj.UserID}")
# ========== 新增:确定俱乐部配置 ========== # ========== 新增:确定俱乐部配置 ==========
# 默认头像(相对路径) # 默认头像(相对路径)
@@ -2217,7 +2217,7 @@ class KehuGetDingdanLianjieView(APIView):
'default_avatar': default_avatar, 'default_avatar': default_avatar,
'goeasy_appkey': goeasy_appkey, 'goeasy_appkey': goeasy_appkey,
# 前端用于连接GoEasy的自身用户ID固定B前缀+商家ID # 前端用于连接GoEasy的自身用户ID固定B前缀+商家ID
'self_user_id': f"B{lianjie_obj.yonghu_id}" if lianjie_obj.yonghu_id else '', 'self_user_id': f"B{lianjie_obj.UserID}" if lianjie_obj.UserID else '',
} }
# 如果已使用,返回已填写的信息 # 如果已使用,返回已填写的信息
@@ -2237,14 +2237,14 @@ class KehuGetDingdanLianjieView(APIView):
shangjia_biaoshi = '' shangjia_biaoshi = ''
try: try:
shangjia_kuozhan = MerchantOrderExt.query.select_related('Order').filter( shangjia_kuozhan = MerchantOrderExt.query.select_related('Order').filter(
Order__OrderID=lianjie_obj.dingdan_id Order__OrderID=lianjie_obj.OrderID
).first() ).first()
if shangjia_kuozhan and shangjia_kuozhan.MerchantID: if shangjia_kuozhan and shangjia_kuozhan.MerchantID:
shangjia_biaoshi = f'Sj{shangjia_kuozhan.MerchantID}' shangjia_biaoshi = f'Sj{shangjia_kuozhan.MerchantID}'
logger.info(f"生成商家标识: {shangjia_biaoshi}") logger.info(f"生成商家标识: {shangjia_biaoshi}")
else: else:
logger.info(f"订单 {lianjie_obj.dingdan_id} 没有商家订单扩展信息") logger.info(f"订单 {lianjie_obj.OrderID} 没有商家订单扩展信息")
except Exception as e: except Exception as e:
logger.error(f"查询商家订单扩展异常: {str(e)}", exc_info=True) logger.error(f"查询商家订单扩展异常: {str(e)}", exc_info=True)
@@ -2258,7 +2258,7 @@ class KehuGetDingdanLianjieView(APIView):
response_data.update(dingdan_info) response_data.update(dingdan_info)
except Order.DoesNotExist: except Order.DoesNotExist:
logger.error(f"订单不存在 - 订单ID: {lianjie_obj.dingdan_id}") logger.error(f"订单不存在 - 订单ID: {lianjie_obj.OrderID}")
response_data.update({ response_data.update({
'jieshao': '', 'jieshao': '',
'jiage': '0.00', 'jiage': '0.00',
@@ -2437,9 +2437,9 @@ class KehuTianxieDingdanView(APIView):
# 9. 查询链接记录 # 9. 查询链接记录
try: try:
lianjie_obj = ShangjiaLianjie.query.get(lianjie_token=token) lianjie_obj = ShangjiaLianjie.query.get(LinkToken=token)
logger.info( logger.info(
f"找到链接记录 - 链接ID: {lianjie_obj.id}, 商家ID: {lianjie_obj.yonghu_id}, 是否已使用: {lianjie_obj.is_used}") f"找到链接记录 - 链接ID: {lianjie_obj.id}, 商家ID: {lianjie_obj.UserID}, 是否已使用: {lianjie_obj.is_used}")
except ShangjiaLianjie.DoesNotExist: except ShangjiaLianjie.DoesNotExist:
logger.warning(f"链接不存在 - Token: {token[:8]}..., IP: {client_ip}") logger.warning(f"链接不存在 - Token: {token[:8]}..., IP: {client_ip}")
return Response({ return Response({
@@ -2450,8 +2450,8 @@ class KehuTianxieDingdanView(APIView):
# 10. 检查链接有效期 # 10. 检查链接有效期
now = timezone.now() now = timezone.now()
if lianjie_obj.youxiao_shijian and lianjie_obj.youxiao_shijian < now: if lianjie_obj.ExpireTime and lianjie_obj.ExpireTime < now:
logger.warning(f"链接已过期 - 过期时间: {lianjie_obj.youxiao_shijian}") logger.warning(f"链接已过期 - 过期时间: {lianjie_obj.ExpireTime}")
return Response({ return Response({
'code': 400, 'code': 400,
'msg': '链接已过期', 'msg': '链接已过期',
@@ -2523,17 +2523,17 @@ class KehuTianxieDingdanView(APIView):
try: try:
with transaction.atomic(): with transaction.atomic():
# 更新链接记录 # 更新链接记录
lianjie_obj.shiyongzhe_ip = client_ip lianjie_obj.UserIP = client_ip
lianjie_obj.is_used = True lianjie_obj.is_used = True
lianjie_obj.save(update_fields=['shiyongzhe_ip', 'is_used']) lianjie_obj.save(update_fields=['UserIP', 'is_used'])
logger.info(f"更新链接记录成功 - 链接ID: {lianjie_obj.id}, 设置为已使用") logger.info(f"更新链接记录成功 - 链接ID: {lianjie_obj.id}, 设置为已使用")
# 查询订单 # 查询订单
if not lianjie_obj.dingdan_id: if not lianjie_obj.OrderID:
logger.error(f"链接记录中订单ID为空 - 链接ID: {lianjie_obj.id}") logger.error(f"链接记录中订单ID为空 - 链接ID: {lianjie_obj.id}")
raise ValueError("订单ID为空") raise ValueError("订单ID为空")
dingdan_obj = Order.query.get(OrderID=lianjie_obj.dingdan_id) dingdan_obj = Order.query.get(OrderID=lianjie_obj.OrderID)
# 检查订单状态是否为13灰色状态 # 检查订单状态是否为13灰色状态
if dingdan_obj.Status != 13: if dingdan_obj.Status != 13:
@@ -2571,12 +2571,12 @@ class KehuTianxieDingdanView(APIView):
# 获取商家信息用于返回 # 获取商家信息用于返回
try: try:
user_main = User.query.get(UserUID=lianjie_obj.yonghu_id) user_main = User.query.get(UserUID=lianjie_obj.UserID)
shangjia_obj = user_main.ShopProfile shangjia_obj = user_main.ShopProfile
shangjia_mingcheng = shangjia_obj.nicheng shangjia_mingcheng = shangjia_obj.nicheng
except: except:
shangjia_mingcheng = f"商家{lianjie_obj.yonghu_id}" shangjia_mingcheng = f"商家{lianjie_obj.UserID}"
logger.warning(f"获取商家昵称失败,使用默认 - 用户ID: {lianjie_obj.yonghu_id}") logger.warning(f"获取商家昵称失败,使用默认 - 用户ID: {lianjie_obj.UserID}")
# 14. 返回成功响应 # 14. 返回成功响应
response_data = { response_data = {
@@ -2594,7 +2594,7 @@ class KehuTianxieDingdanView(APIView):
# 新方法(行为驱动,更安全) # 新方法(行为驱动,更安全)
update_shangjia_daily( update_shangjia_daily(
yonghuid=lianjie_obj.yonghu_id, yonghuid=lianjie_obj.UserID,
amount=Decimal(str(dingdan_obj.Amount)), amount=Decimal(str(dingdan_obj.Amount)),
action=1 # 1 = 派发 action=1 # 1 = 派发
) )
@@ -2606,7 +2606,7 @@ class KehuTianxieDingdanView(APIView):
}, status=status.HTTP_200_OK) }, status=status.HTTP_200_OK)
except Order.DoesNotExist: except Order.DoesNotExist:
logger.error(f"订单不存在 - 订单ID: {lianjie_obj.dingdan_id}") logger.error(f"订单不存在 - 订单ID: {lianjie_obj.OrderID}")
return Response({ return Response({
'code': 500, 'code': 500,
'msg': '订单数据异常', 'msg': '订单数据异常',
@@ -2699,7 +2699,7 @@ class GuanZhuAListView(APIView):
def post(self, request): def post(self, request):
try: try:
# 查询类型为3的所有记录 # 查询类型为3的所有记录
qs = Tupianpeizhi.query.filter(leixing=3) qs = Tupianpeizhi.query.filter(ImageType=3)
if not qs.exists(): if not qs.exists():
return Response({ return Response({
'code': 0, 'code': 0,
@@ -2712,7 +2712,7 @@ class GuanZhuAListView(APIView):
}, status=status.HTTP_200_OK) }, status=status.HTTP_200_OK)
# 获取所有图片的相对URL # 获取所有图片的相对URL
images = list(qs.values_list('tupian', flat=True)) images = list(qs.values_list('ImageURL', flat=True))
# 获取最新更新时间取所有记录的update_time最大值 # 获取最新更新时间取所有记录的update_time最大值
last_update = qs.aggregate(Max('update_time'))['update_time__max'] last_update = qs.aggregate(Max('update_time'))['update_time__max']
@@ -2720,8 +2720,8 @@ class GuanZhuAListView(APIView):
# 原子性增加访问次数 # 原子性增加访问次数
# 先更新所有记录,再获取更新后的最大次数 # 先更新所有记录,再获取更新后的最大次数
qs.update(fangwen_cishu=F('fangwen_cishu') + 1) qs.update(AccessCount=F('AccessCount') + 1)
visit_count = qs.aggregate(Max('fangwen_cishu'))['fangwen_cishu__max'] or 0 visit_count = qs.aggregate(Max('AccessCount'))['AccessCount__max'] or 0
return Response({ return Response({
'code': 0, 'code': 0,

View File

@@ -354,18 +354,18 @@ class WechatPayNotifyView(APIView):
szjilu, created = Szjilu.objects.select_for_update().get_or_create( szjilu, created = Szjilu.objects.select_for_update().get_or_create(
id=1, id=1,
defaults={ defaults={
'zongsy': Decimal('0.00'), 'TotalIncome': Decimal('0.00'),
'zongls': Decimal('0.00'), 'TotalFlow': Decimal('0.00'),
'zongzc': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'DailyExpense': Decimal('0.00'),
'jrls': Decimal('0.00') 'DailyFlow': Decimal('0.00')
} }
) )
if created: if created:
logger.info("创建ID=1的收支记录") logger.info("创建ID=1的收支记录")
szjilu.zongsy += jine_decimal szjilu.TotalIncome += jine_decimal
szjilu.zongls += jine_decimal szjilu.TotalFlow += jine_decimal
szjilu.jrls += jine_decimal szjilu.DailyFlow += jine_decimal
szjilu.save() szjilu.save()
logger.info(f"收支记录更新成功,增加金额: {jine}") logger.info(f"收支记录更新成功,增加金额: {jine}")
except Exception as e: except Exception as e:
@@ -628,18 +628,18 @@ class PaymentVerifyView(APIView):
szjilu, created = Szjilu.objects.select_for_update().get_or_create( szjilu, created = Szjilu.objects.select_for_update().get_or_create(
id=1, id=1,
defaults={ defaults={
'zongsy': Decimal('0.00'), 'TotalIncome': Decimal('0.00'),
'zongls': Decimal('0.00'), 'TotalFlow': Decimal('0.00'),
'zongzc': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'DailyExpense': Decimal('0.00'),
'jrls': Decimal('0.00') 'DailyFlow': Decimal('0.00')
} }
) )
if created: if created:
logger.info("创建ID=1的收支记录") logger.info("创建ID=1的收支记录")
szjilu.zongsy += jine_decimal szjilu.TotalIncome += jine_decimal
szjilu.zongls += jine_decimal szjilu.TotalFlow += jine_decimal
szjilu.jrls += jine_decimal szjilu.DailyFlow += jine_decimal
szjilu.save() szjilu.save()
logger.info(f"收支记录更新成功,增加金额: {jine}") logger.info(f"收支记录更新成功,增加金额: {jine}")
except Exception as e: except Exception as e:
@@ -3492,7 +3492,7 @@ class ShangjiaLianjieLiuYanZhuanFaView(APIView):
return Response({'code': 400, 'msg': '缺少参数'}) return Response({'code': 400, 'msg': '缺少参数'})
try: try:
lianjie = ShangjiaLianjie.query.get(lianjie_token=token) lianjie = ShangjiaLianjie.query.get(LinkToken=token)
except ShangjiaLianjie.DoesNotExist: except ShangjiaLianjie.DoesNotExist:
return Response({'code': 404, 'msg': '链接不存在或已失效'}) return Response({'code': 404, 'msg': '链接不存在或已失效'})
@@ -3504,7 +3504,7 @@ class ShangjiaLianjieLiuYanZhuanFaView(APIView):
except Order.DoesNotExist: except Order.DoesNotExist:
return Response({'code': 500, 'msg': '订单数据异常'}) return Response({'code': 500, 'msg': '订单数据异常'})
shangjia_uid = lianjie.yonghu_id shangjia_uid = lianjie.UserID
sender_id = f"B{shangjia_uid}" sender_id = f"B{shangjia_uid}"
sender_name = "老板" sender_name = "老板"
sender_avatar = '' sender_avatar = ''
@@ -5557,9 +5557,9 @@ class AdTongYiTuiKuanPingTai(APIView):
szjilu_obj = Szjilu.query.get(id=1) szjilu_obj = Szjilu.query.get(id=1)
szjilu_obj.zongsy -= jine szjilu_obj.TotalIncome -= jine
szjilu_obj.zongzc += jine szjilu_obj.TotalExpense += jine
szjilu_obj.jrzc += jine szjilu_obj.DailyExpense += jine
szjilu_obj.save() szjilu_obj.save()
except Szjilu.DoesNotExist: except Szjilu.DoesNotExist:
logger.error(f"平台退款:收支记录表(id=1)不存在,跳过") logger.error(f"平台退款:收支记录表(id=1)不存在,跳过")

View File

@@ -689,18 +689,18 @@ class YajinHuitiao(View):
szjilu, created = Szjilu.query.get_or_create( szjilu, created = Szjilu.query.get_or_create(
id=1, id=1,
defaults={ defaults={
'zongsy': Decimal('0.00'), 'TotalIncome': Decimal('0.00'),
'zongls': Decimal('0.00'), 'TotalFlow': Decimal('0.00'),
'zongzc': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'DailyExpense': Decimal('0.00'),
'jrls': Decimal('0.00') 'DailyFlow': Decimal('0.00')
} }
) )
# 更新三个字段 # 更新三个字段
szjilu.zongsy += jine_decimal # 总收益 szjilu.TotalIncome += jine_decimal # 总收益
szjilu.zongls += jine_decimal # 总流水 szjilu.TotalFlow += jine_decimal # 总流水
szjilu.jrls += jine_decimal # 今日流水 szjilu.DailyFlow += jine_decimal # 今日流水
szjilu.save() szjilu.save()
@@ -1204,18 +1204,18 @@ class JifenHuitiao(View):
szjilu, created = Szjilu.query.get_or_create( szjilu, created = Szjilu.query.get_or_create(
id=1, id=1,
defaults={ defaults={
'zongsy': Decimal('0.00'), 'TotalIncome': Decimal('0.00'),
'zongls': Decimal('0.00'), 'TotalFlow': Decimal('0.00'),
'zongzc': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'DailyExpense': Decimal('0.00'),
'jrls': Decimal('0.00') 'DailyFlow': Decimal('0.00')
} }
) )
# 更新三个字段 # 更新三个字段
szjilu.zongsy += jine_decimal # 总收益 szjilu.TotalIncome += jine_decimal # 总收益
szjilu.zongls += jine_decimal # 总流水 szjilu.TotalFlow += jine_decimal # 总流水
szjilu.jrls += jine_decimal # 今日流水 szjilu.DailyFlow += jine_decimal # 今日流水
szjilu.save() szjilu.save()
@@ -1778,12 +1778,12 @@ class HuiyuanHuitiao(View):
szjilu, _ = Szjilu.query.get_or_create( szjilu, _ = Szjilu.query.get_or_create(
id=1, id=1,
defaults={'zongsy': Decimal('0.00'), 'zongls': Decimal('0.00'), 'zongzc': Decimal('0.00'), defaults={'TotalIncome': Decimal('0.00'), 'TotalFlow': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'jrls': Decimal('0.00')} 'DailyExpense': Decimal('0.00'), 'DailyFlow': Decimal('0.00')}
) )
szjilu.zongsy += jine_decimal szjilu.TotalIncome += jine_decimal
szjilu.zongls += jine_decimal szjilu.TotalFlow += jine_decimal
szjilu.jrls += jine_decimal szjilu.DailyFlow += jine_decimal
szjilu.save() szjilu.save()
logger.info(f"收支记录更新成功: 订单{order.dingdan_id}, 金额{jine_decimal}") logger.info(f"收支记录更新成功: 订单{order.dingdan_id}, 金额{jine_decimal}")
except Exception as e: except Exception as e:
@@ -2612,18 +2612,18 @@ class ShangjiaHuitiao(View):
szjilu, created = Szjilu.query.get_or_create( szjilu, created = Szjilu.query.get_or_create(
id=1, id=1,
defaults={ defaults={
'zongsy': Decimal('0.00'), 'TotalIncome': Decimal('0.00'),
'zongls': Decimal('0.00'), 'TotalFlow': Decimal('0.00'),
'zongzc': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'DailyExpense': Decimal('0.00'),
'jrls': Decimal('0.00') 'DailyFlow': Decimal('0.00')
} }
) )
# 更新三个字段 # 更新三个字段
szjilu.zongsy += jine_decimal # 总收益 szjilu.TotalIncome += jine_decimal # 总收益
szjilu.zongls += jine_decimal # 总流水 szjilu.TotalFlow += jine_decimal # 总流水
szjilu.jrls += jine_decimal # 今日流水 szjilu.DailyFlow += jine_decimal # 今日流水
szjilu.save() szjilu.save()
@@ -4362,12 +4362,12 @@ class AdShangpinHuQu(APIView):
) )
# 6. 查询公告数据(类型=1的公告 # 6. 查询公告数据(类型=1的公告
gonggao_obj = Gonggao.query.filter(leixing=1).first() gonggao_obj = Gonggao.query.filter(NoticeType=1).first()
shangpingonggao = gonggao_obj.jieshao if gonggao_obj else '' shangpingonggao = gonggao_obj.Content if gonggao_obj else ''
# 7. 查询轮播图数据(类型=1的轮播图 # 7. 查询轮播图数据(类型=1的轮播图
lunbo_objs = Lunbo.query.filter(leixing=1).values('tupian_url') lunbo_objs = Lunbo.query.filter(ImageType=1).values('ImageURL')
shangpinlunbo = [item['tupian_url'] for item in lunbo_objs] shangpinlunbo = [item['ImageURL'] for item in lunbo_objs]
# 8. 查询商品类型数据 # 8. 查询商品类型数据
shangpinleixing_data = ShangpinLeixing.query.all().values( shangpinleixing_data = ShangpinLeixing.query.all().values(
@@ -4495,14 +4495,14 @@ class AdGonggaoXiuGai(APIView):
) )
# 8. 查询公告表类型为1的公告 # 8. 查询公告表类型为1的公告
gonggao_obj = Gonggao.query.filter(leixing=1).first() gonggao_obj = Gonggao.query.filter(NoticeType=1).first()
# 如果不存在,则创建 # 如果不存在,则创建
if not gonggao_obj: if not gonggao_obj:
gonggao_obj = Gonggao(leixing=1) gonggao_obj = Gonggao(NoticeType=1)
# 9. 更新公告内容 # 9. 更新公告内容
gonggao_obj.jieshao = gonggao_neirong gonggao_obj.Content = gonggao_neirong
gonggao_obj.save() gonggao_obj.save()
# 10. 返回成功响应 # 10. 返回成功响应
@@ -4685,7 +4685,7 @@ class AdLunboXiuGai(APIView):
) )
# 查询轮播图记录 # 查询轮播图记录
lunbo_obj = Lunbo.query.filter(tupian_url=tupian_url, leixing=1).first() lunbo_obj = Lunbo.query.filter(ImageURL=tupian_url, ImageType=1).first()
if not lunbo_obj: if not lunbo_obj:
return Response( return Response(
@@ -4761,15 +4761,15 @@ class AdLunboXiuGai(APIView):
# 创建轮播图记录 # 创建轮播图记录
lunbo_obj = Lunbo.query.create( lunbo_obj = Lunbo.query.create(
tupian_url=oss_file_path, # 存相对路径 ImageURL=oss_file_path, # 存相对路径
leixing=1 ImageType=1
) )
return Response({ return Response({
'code': 0, 'code': 0,
'message': '添加成功', 'message': '添加成功',
'data': { 'data': {
'tupian_url': lunbo_obj.tupian_url 'tupian_url': lunbo_obj.ImageURL
} }
}) })

View File

@@ -415,14 +415,14 @@ def _get_personal_daily_quota(leixing, profile):
if leixing == 1: if leixing == 1:
if profile.kaioi_ewai_xiane and profile.ewai_xiane > 0: if profile.kaioi_ewai_xiane and profile.ewai_xiane > 0:
return profile.ewai_xiane return profile.ewai_xiane
return TixianQuotaDefault.query.get(leixing=1).default_quota return TixianQuotaDefault.query.get(UserType=1).default_quota
if leixing == 2: if leixing == 2:
if profile.kaioi_ewai_xiane and profile.ewai_xiane > 0: if profile.kaioi_ewai_xiane and profile.ewai_xiane > 0:
return profile.ewai_xiane return profile.ewai_xiane
return TixianQuotaDefault.query.get(leixing=2).default_quota return TixianQuotaDefault.query.get(UserType=2).default_quota
if leixing == 3: if leixing == 3:
try: try:
default_quota = TixianQuotaDefault.query.get(leixing=3).default_quota default_quota = TixianQuotaDefault.query.get(UserType=3).default_quota
except TixianQuotaDefault.DoesNotExist: except TixianQuotaDefault.DoesNotExist:
default_quota = decimal.Decimal('0.00') default_quota = decimal.Decimal('0.00')
if profile.kaioi_ewai_tixian and profile.ewai_tixian_xiane > 0: if profile.kaioi_ewai_tixian and profile.ewai_tixian_xiane > 0:
@@ -482,7 +482,7 @@ def _get_platform_daily_limit(leixing):
""" """
quota_leixing = leixing + 3 quota_leixing = leixing + 3
try: try:
return TixianQuotaDefault.query.get(leixing=quota_leixing).default_quota return TixianQuotaDefault.query.get(UserType=quota_leixing).default_quota
except TixianQuotaDefault.DoesNotExist: except TixianQuotaDefault.DoesNotExist:
logger.warning( logger.warning(
'平台每日总限额未配置 leixing=%s(读取quota_leixing=%s)按0处理禁止新增收款', '平台每日总限额未配置 leixing=%s(读取quota_leixing=%s)按0处理禁止新增收款',
@@ -1034,16 +1034,16 @@ def _apply_platform_accounting(auto_record):
update_daily_payout(auto_record.shijidaozhang) update_daily_payout(auto_record.shijidaozhang)
try: try:
szjilu = Szjilu.objects.select_for_update().get(id=1) szjilu = Szjilu.objects.select_for_update().get(id=1)
szjilu.zongsy -= auto_record.shijidaozhang szjilu.TotalIncome -= auto_record.shijidaozhang
szjilu.zongzc += auto_record.shijidaozhang szjilu.TotalExpense += auto_record.shijidaozhang
szjilu.jrzc += auto_record.shijidaozhang szjilu.DailyExpense += auto_record.shijidaozhang
szjilu.save() szjilu.save()
except Szjilu.DoesNotExist: except Szjilu.DoesNotExist:
Szjilu.query.create( Szjilu.query.create(
id=1, id=1,
zongsy=-auto_record.shijidaozhang, TotalIncome=-auto_record.shijidaozhang,
zongzc=auto_record.shijidaozhang, TotalExpense=auto_record.shijidaozhang,
jrzc=auto_record.shijidaozhang, DailyExpense=auto_record.shijidaozhang,
) )

View File

@@ -413,11 +413,11 @@ class WechatMiniProgramLoginView(APIView):
for config in qun_configs: for config in qun_configs:
if config.id == 1: if config.id == 1:
result['dashouqun'] = config.neirong or '' result['dashouqun'] = config.GroupContent or ''
result['dashouqunid'] = config.qunid or '' result['dashouqunid'] = config.GroupID or ''
elif config.id == 2: elif config.id == 2:
result['guanshiqun'] = config.neirong or '' result['guanshiqun'] = config.GroupContent or ''
result['guanshiqunid'] = config.qunid or '' result['guanshiqunid'] = config.GroupID or ''
return result return result
@@ -2489,22 +2489,22 @@ class AdminFinancialDataView(APIView):
# 方法2如果表中可能有多条记录需要汇总可以使用以下方式 # 方法2如果表中可能有多条记录需要汇总可以使用以下方式
# from django.db.models Sum # from django.db.models Sum
# zonghe = Szjilu.query.aggregate( # zonghe = Szjilu.query.aggregate(
# zongliushui=Sum('zongls'), # zongliushui=Sum('TotalFlow'),
# zongshouyi=Sum('zongsy'), # zongshouyi=Sum('TotalIncome'),
# zongzhichu=Sum('zongzc'), # zongzhichu=Sum('TotalExpense'),
# jrls=Sum('jrls'), # DailyFlow=Sum('DailyFlow'),
# jrzc=Sum('jrzc') # DailyExpense=Sum('DailyExpense')
# ) # )
# 准备返回数据 # 准备返回数据
if shouzhijilu: if shouzhijilu:
# 有记录的情况 # 有记录的情况
huizongshuju = { huizongshuju = {
'zongliushui': float(shouzhijilu.zongls or 0), 'zongliushui': float(shouzhijilu.TotalFlow or 0),
'zongshouyi': float(shouzhijilu.zongsy or 0), 'zongshouyi': float(shouzhijilu.TotalIncome or 0),
'zongzhichu': float(shouzhijilu.zongzc or 0), 'zongzhichu': float(shouzhijilu.TotalExpense or 0),
'jrls': float(shouzhijilu.jrls or 0), 'jrls': float(shouzhijilu.DailyFlow or 0),
'jrzc': float(shouzhijilu.jrzc or 0) 'jrzc': float(shouzhijilu.DailyExpense or 0)
} }
else: else:
# 没有记录的情况,返回默认值 # 没有记录的情况,返回默认值
@@ -4643,9 +4643,9 @@ class AdtixianqkView(APIView):
update_daily_payout(tixian_jine) update_daily_payout(tixian_jine)
# 更新收支记录 # 更新收支记录
szjilu_record.zongsy -= tixian_jine # 总收益减去提现金额 szjilu_record.TotalIncome -= tixian_jine # 总收益减去提现金额
szjilu_record.zongzc += tixian_jine # 总支出加上提现金额 szjilu_record.TotalExpense += tixian_jine # 总支出加上提现金额
szjilu_record.jrzc += tixian_jine # 今日支出加上提现金额 szjilu_record.DailyExpense += tixian_jine # 今日支出加上提现金额
szjilu_record.update_time = timezone.now() szjilu_record.update_time = timezone.now()
szjilu_record.save() szjilu_record.save()
@@ -4653,9 +4653,9 @@ class AdtixianqkView(APIView):
# 如果收支记录表不存在id=1的记录创建一个 # 如果收支记录表不存在id=1的记录创建一个
szjilu_record = Szjilu.query.create( szjilu_record = Szjilu.query.create(
id=1, id=1,
zongsy=-tixian_jine if result == 2 else 0, TotalIncome=-tixian_jine if result == 2 else 0,
zongzc=tixian_jine if result == 2 else 0, TotalExpense=tixian_jine if result == 2 else 0,
jrzc=tixian_jine if result == 2 else 0 DailyExpense=tixian_jine if result == 2 else 0
) )
except Exception as e: except Exception as e:
# 如果更新收支记录失败,抛出异常,事务会回滚 # 如果更新收支记录失败,抛出异常,事务会回滚
@@ -5506,11 +5506,11 @@ class WechatLoginAndDashouRegisterView(APIView):
for config in qun_configs: for config in qun_configs:
if config.id == 1: if config.id == 1:
result['dashouqun'] = config.neirong or '' result['dashouqun'] = config.GroupContent or ''
result['dashouqunid'] = config.qunid or '' result['dashouqunid'] = config.GroupID or ''
elif config.id == 2: elif config.id == 2:
result['guanshiqun'] = config.neirong or '' result['guanshiqun'] = config.GroupContent or ''
result['guanshiqunid'] = config.qunid or '' result['guanshiqunid'] = config.GroupID or ''
return result return result
@@ -10098,9 +10098,9 @@ class KefuWithdrawActionView(APIView):
try: try:
update_daily_payout(tixian.jine) update_daily_payout(tixian.jine)
szjilu, _ = Szjilu.query.get_or_create(id=1) szjilu, _ = Szjilu.query.get_or_create(id=1)
szjilu.zongsy -= tixian.jine szjilu.TotalIncome -= tixian.jine
szjilu.zongzc += tixian.jine szjilu.TotalExpense += tixian.jine
szjilu.jrzc += tixian.jine szjilu.DailyExpense += tixian.jine
szjilu.update_time = timezone.now() szjilu.update_time = timezone.now()
szjilu.save() szjilu.save()
except Exception as e: except Exception as e:
@@ -10663,11 +10663,11 @@ class WechatLoginAndGuanshiRegisterView(APIView):
} }
for config in qun_configs: for config in qun_configs:
if config.id == 1: if config.id == 1:
result['dashouqun'] = config.neirong or '' result['dashouqun'] = config.GroupContent or ''
result['dashouqunid'] = config.qunid or '' result['dashouqunid'] = config.GroupID or ''
elif config.id == 2: elif config.id == 2:
result['guanshiqun'] = config.neirong or '' result['guanshiqun'] = config.GroupContent or ''
result['guanshiqunid'] = config.qunid or '' result['guanshiqunid'] = config.GroupID or ''
return result return result
except Exception as e: except Exception as e:
logger.error(f"获取群配置失败: {e}") logger.error(f"获取群配置失败: {e}")
@@ -10890,11 +10890,11 @@ class GuanshiRegisterView(APIView):
} }
for config in qun_configs: for config in qun_configs:
if config.id == 1: if config.id == 1:
result['dashouqun'] = config.neirong or '' result['dashouqun'] = config.GroupContent or ''
result['dashouqunid'] = config.qunid or '' result['dashouqunid'] = config.GroupID or ''
elif config.id == 2: elif config.id == 2:
result['guanshiqun'] = config.neirong or '' result['guanshiqun'] = config.GroupContent or ''
result['guanshiqunid'] = config.qunid or '' result['guanshiqunid'] = config.GroupID or ''
return result return result
except Exception as e: except Exception as e:
logger.error(f"获取群配置失败: {e}") logger.error(f"获取群配置失败: {e}")
@@ -11834,18 +11834,18 @@ class FaKuanHuitiaoView(View):
szjilu, created = Szjilu.query.get_or_create( szjilu, created = Szjilu.query.get_or_create(
id=1, id=1,
defaults={ defaults={
'zongsy': Decimal('0.00'), 'TotalIncome': Decimal('0.00'),
'zongls': Decimal('0.00'), 'TotalFlow': Decimal('0.00'),
'zongzc': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'DailyExpense': Decimal('0.00'),
'jrls': Decimal('0.00') 'DailyFlow': Decimal('0.00')
} }
) )
# 更新三个字段 # 更新三个字段
szjilu.zongsy += jine_decimal # 总收益 szjilu.TotalIncome += jine_decimal # 总收益
szjilu.zongls += jine_decimal # 总流水 szjilu.TotalFlow += jine_decimal # 总流水
szjilu.jrls += jine_decimal # 今日流水 szjilu.DailyFlow += jine_decimal # 今日流水
szjilu.save() szjilu.save()
@@ -12403,18 +12403,18 @@ class KaohePayCallbackView(View):
szjilu, created = Szjilu.query.get_or_create( szjilu, created = Szjilu.query.get_or_create(
id=1, id=1,
defaults={ defaults={
'zongsy': Decimal('0.00'), 'TotalIncome': Decimal('0.00'),
'zongls': Decimal('0.00'), 'TotalFlow': Decimal('0.00'),
'zongzc': Decimal('0.00'), 'TotalExpense': Decimal('0.00'),
'jrzc': Decimal('0.00'), 'DailyExpense': Decimal('0.00'),
'jrls': Decimal('0.00'), 'DailyFlow': Decimal('0.00'),
} }
) )
szjilu.zongsy += jine_decimal szjilu.TotalIncome += jine_decimal
szjilu.zongls += jine_decimal szjilu.TotalFlow += jine_decimal
szjilu.jrls += jine_decimal szjilu.DailyFlow += jine_decimal
szjilu.save() szjilu.save()
logger.info(f"更新收支记录成功: zongsy={szjilu.zongsy}") logger.info(f"更新收支记录成功: zongsy={szjilu.TotalIncome}")
except Exception as e: except Exception as e:
logger.error(f"更新收支记录失败: {str(e)}", exc_info=True) logger.error(f"更新收支记录失败: {str(e)}", exc_info=True)