彻底解决了 create_time 的问题,将所有字段都改为了 CreateTime

This commit is contained in:
TermiNexus committed 2026-06-19 19:19:22 +08:00
1 parent 90e0bde7f1
commit e64697b64a
35 files changed
+4803 -4872

No files matched your search

+9 -9
View File
@@ -28,7 +28,7 @@ class Migration(migrations.Migration):
('request_headers', models.TextField(blank=True, default='', verbose_name='请求头(JSON格式)')),
('attempt_type', models.CharField(blank=True, default='', max_length=50, verbose_name='攻击类型')),
('detail', models.TextField(blank=True, default='', verbose_name='详细描述')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
],
options={
'verbose_name': '异常用户日志',
@@ -105,8 +105,8 @@ class Migration(migrations.Migration):
('perm_code', models.CharField(db_index=True, max_length=100, unique=True, verbose_name='权限编码')),
('perm_name', models.CharField(max_length=100, verbose_name='权限名称')),
('description', models.CharField(blank=True, default='', max_length=200, verbose_name='权限描述')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '权限',
@@ -140,8 +140,8 @@ class Migration(migrations.Migration):
('role_code', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='角色编码')),
('role_name', models.CharField(max_length=50, verbose_name='角色名称')),
('description', models.CharField(blank=True, default='', max_length=200, verbose_name='角色描述')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '角色',
@@ -170,8 +170,8 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('account_id', models.CharField(db_index=True, max_length=11, verbose_name='账号ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='backend.role', verbose_name='角色')),
],
options={
@@ -185,7 +185,7 @@ class Migration(migrations.Migration):
name='RolePermission',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='backend.permission', verbose_name='权限')),
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='backend.role', verbose_name='角色')),
],
@@ -290,7 +290,7 @@ class Migration(migrations.Migration):
),
migrations.AddIndex(
model_name='abnormaluserlog',
index=models.Index(fields=['create_time'], name='abnormal_us_create__ee16da_idx'),
index=models.Index(fields=['CreateTime'], name='abnormal_us_create__ee16da_idx'),
),
migrations.AlterUniqueTogether(
name='userrole',
@@ -0,0 +1,18 @@
# Generated by Django 4.2.27 on 2026-06-19 19:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('backend', '0001_initial'),
]
operations = [
migrations.RenameIndex(
model_name='abnormaluserlog',
new_name='abnormal_us_CreateT_38f96c_idx',
old_name='abnormal_us_create__ee16da_idx',
),
]
+324 -324
View File
@@ -1,324 +1,324 @@
from django.db import models
from gvsdsdk.model_base import QModel
# ==================== 1. 角色表 ====================
class Role(QModel):
"""角色表"""
role_id = models.AutoField(primary_key=True, verbose_name='角色ID')
role_code = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='角色编码')
role_name = models.CharField(max_length=50, verbose_name='角色名称')
description = models.CharField(max_length=200, blank=True, default='', verbose_name='角色描述')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'role'
verbose_name = '角色'
verbose_name_plural = '角色'
managed = True
indexes = [
models.Index(fields=['role_code']),
]
def __str__(self):
return self.role_name
# ==================== 2. 权限表 ====================
class Permission(QModel):
"""权限表"""
perm_id = models.AutoField(primary_key=True, verbose_name='权限ID')
perm_code = models.CharField(max_length=100, unique=True, db_index=True, verbose_name='权限编码')
perm_name = models.CharField(max_length=100, verbose_name='权限名称')
description = models.CharField(max_length=200, blank=True, default='', verbose_name='权限描述')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'permission'
verbose_name = '权限'
verbose_name_plural = '权限'
managed = True
indexes = [
models.Index(fields=['perm_code']),
]
def __str__(self):
return f"{self.perm_name} ({self.perm_code})"
# ==================== 3. 角色-权限关联表 ====================
class RolePermission(QModel):
"""角色权限关联表"""
id = models.AutoField(primary_key=True)
role = models.ForeignKey(Role, on_delete=models.CASCADE, db_index=True, verbose_name='角色')
permission = models.ForeignKey(Permission, on_delete=models.CASCADE, db_index=True, verbose_name='权限')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'role_permission'
verbose_name = '角色权限关联'
verbose_name_plural = '角色权限关联'
managed = True
unique_together = [['role', 'permission']]
def __str__(self):
return f"{self.role.role_name} -> {self.permission.perm_name}"
# ==================== 4. 用户-角色关联表 ====================
class UserRole(QModel):
"""用户角色关联表"""
id = models.AutoField(primary_key=True)
account_id = models.CharField(max_length=11, db_index=True, verbose_name='账号ID')
role = models.ForeignKey(Role, on_delete=models.CASCADE, db_index=True, verbose_name='角色')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'user_role'
verbose_name = '用户角色关联'
verbose_name_plural = '用户角色关联'
managed = True
unique_together = [['account_id', 'role']]
def __str__(self):
return f"{self.account_id} -> {self.role.role_name}"
# ==================== 5. 异常用户日志 ====================
class AbnormalUserLog(QModel):
"""记录恶意尝试越权操作的用户信息"""
account_id = models.CharField(max_length=20, db_index=True, verbose_name='账号ID(phone)')
ip_address = models.GenericIPAddressField(null=True, blank=True, verbose_name='IP地址')
real_ip = models.GenericIPAddressField(null=True, blank=True, verbose_name='真实IP(穿透代理后)')
x_forwarded_for = models.CharField(max_length=255, blank=True, default='', verbose_name='X-Forwarded-For')
user_agent = models.CharField(max_length=500, blank=True, default='', verbose_name='User-Agent')
request_method = models.CharField(max_length=10, blank=True, default='', verbose_name='请求方法')
request_path = models.CharField(max_length=500, blank=True, default='', verbose_name='请求路径')
request_params = models.TextField(blank=True, default='', verbose_name='请求参数(GET/POST)')
request_body = models.TextField(blank=True, default='', verbose_name='请求体(原始)')
request_headers = models.TextField(blank=True, default='', verbose_name='请求头(JSON格式)')
attempt_type = models.CharField(max_length=50, blank=True, default='', verbose_name='攻击类型')
detail = models.TextField(blank=True, default='', verbose_name='详细描述')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'abnormal_user_log'
verbose_name = '异常用户日志'
verbose_name_plural = verbose_name
indexes = [
models.Index(fields=['account_id']),
models.Index(fields=['ip_address']),
models.Index(fields=['create_time']),
]
def __str__(self):
return f"{self.account_id} @ {self.ip_address} - {self.create_time}"
# ==================== 6. 商家每日统计 ====================
class MerchantDailyStats(QModel):
"""商家每日统计表(原 ShangjiaRiTongji)"""
MerchantID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='商家用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
# 派发统计
AssignedOrderCount = models.IntegerField(
default=0, db_column='paifa_dingdan_shu', verbose_name='派发订单总数')
AssignedAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='paifa_jine', verbose_name='派发订单总金额')
# 结算统计
SettledOrderCount = models.IntegerField(
default=0, db_column='jiesuan_dingdan_shu', verbose_name='结算订单总数')
SettledAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='jiesuan_jine', verbose_name='结算总金额')
# 退款统计
RefundOrderCount = models.IntegerField(
default=0, db_column='tuikuan_dingdan_shu', verbose_name='退款订单总数')
RefundAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='tuikuan_jine', verbose_name='退款总金额')
class Meta:
db_table = 'shangjia_ri_tongji'
verbose_name = '商家每日统计'
unique_together = [['MerchantID', 'Date']]
indexes = [
models.Index(fields=['Date', '-AssignedAmount']),
models.Index(fields=['Date', '-SettledAmount']),
models.Index(fields=['Date', '-AssignedOrderCount']),
]
def __str__(self):
return f"商家{self.MerchantID} {self.Date}"
# ==================== 7. 打手每日统计 ====================
class PlayerDailyStats(QModel):
"""打手每日统计表(原 DashouRiTongji)"""
PlayerID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='打手用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
# 接单统计
AcceptedOrderTotal = models.IntegerField(
default=0, db_column='jiedan_zongliang', verbose_name='接单总量')
CompletedOrderTotal = models.IntegerField(
default=0, db_column='chengjiao_zongliang', verbose_name='成交单总量')
# 金额统计
AcceptedAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='jiedan_zonge', verbose_name='接单总金额')
CompletedAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='chengjiao_zonge', verbose_name='成交总金额')
# 退款统计
RefundCount = models.IntegerField(
default=0, db_column='tuikuan_liang', verbose_name='退款订单量')
RefundAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='tuikuan_jine', verbose_name='退款总金额')
class Meta:
db_table = 'dashou_ri_tongji'
verbose_name = '打手每日统计'
unique_together = [['PlayerID', 'Date']]
indexes = [
models.Index(fields=['Date', '-AcceptedOrderTotal']),
models.Index(fields=['Date', '-CompletedOrderTotal']),
models.Index(fields=['Date', '-AcceptedAmount']),
models.Index(fields=['Date', '-CompletedAmount']),
]
def __str__(self):
return f"打手{self.PlayerID} {self.Date}"
# ==================== 8. 组长每日统计 ====================
class LeaderDailyStats(QModel):
"""组长每日统计表(原 ZuzhangRiTongji)"""
LeaderID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='组长用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
InvitedManagerCount = models.IntegerField(
default=0, db_column='yaoqing_guanshi_shu', verbose_name='邀请管事总数')
TotalIncome = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='shouru_zonge', verbose_name='收入总额(分佣)')
CommissionAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='fenyong_jine', verbose_name='分佣金额')
class Meta:
db_table = 'zuzhang_ri_tongji'
verbose_name = '组长每日统计'
unique_together = [['LeaderID', 'Date']]
indexes = [
models.Index(fields=['Date', '-InvitedManagerCount']),
models.Index(fields=['Date', '-TotalIncome']),
]
def __str__(self):
return f"组长{self.LeaderID} {self.Date}"
# ==================== 9. 管事每日统计 ====================
class ManagerDailyStats(QModel):
"""管事每日统计表(原 GuanshiRiTongji)"""
ManagerID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='管事用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
InvitedPlayerCount = models.IntegerField(
default=0, db_column='yaoqing_dashou_shu', verbose_name='邀请打手总数')
RechargedPlayerCount = models.IntegerField(
default=0, db_column='chongzhi_dashou_shu', verbose_name='充值打手数量')
TotalIncome = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='shouru_zonge', verbose_name='收入总额')
class Meta:
db_table = 'guanshi_ri_tongji'
verbose_name = '管事每日统计'
unique_together = [['ManagerID', 'Date']]
indexes = [
models.Index(fields=['Date', '-InvitedPlayerCount']),
models.Index(fields=['Date', '-RechargedPlayerCount']),
models.Index(fields=['Date', '-TotalIncome']),
]
def __str__(self):
return f"管事{self.ManagerID} {self.Date}"
# ==================== 10. 管事续费每日统计 ====================
class ManagerRenewalDailyStats(QModel):
"""管事续费每日统计表(原 GuanshiXufeiRiTongji)"""
ManagerID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='管事用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
RenewalTotal = models.IntegerField(
default=0, db_column='xufei_zongshu', verbose_name='今日续费总数')
RenewalRevenue = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='xufei_shouyi', verbose_name='续费收益金额')
class Meta:
db_table = 'guanshi_xufei_ri_tongji'
verbose_name = '管事续费每日统计'
unique_together = [['ManagerID', 'Date']]
indexes = [
models.Index(fields=['Date', '-RenewalTotal']),
models.Index(fields=['Date', '-RenewalRevenue']),
]
def __str__(self):
return f"管事续费{self.ManagerID} {self.Date}"
# ==================== 11. 提现每日统计 ====================
class WithdrawalDailyStats(QModel):
"""每日提现统计表(原 TixianRiTongji),按身份统计当天提现总额"""
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
WithdrawalType = models.IntegerField(
choices=[(1, '打手'), (2, '管事'), (3, '组长'),
(4, '考核官'), (5, '打手押金'), (6, '商家余额')],
db_column='leixing', verbose_name='用户类型')
total_amount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00, verbose_name='当天提现总额(元)')
class Meta:
db_table = 'tixian_ri_tongji'
verbose_name = '每日提现统计'
unique_together = [['Date', 'WithdrawalType']]
indexes = [models.Index(fields=['Date', 'WithdrawalType'])]
def __str__(self):
return f"{self.Date} - {self.get_WithdrawalType_display()} 提现总额: {self.total_amount}"
# ==================== 兼容别名(供逐步迁移) ====================
ShangjiaRiTongji = MerchantDailyStats
DashouRiTongji = PlayerDailyStats
ZuzhangRiTongji = LeaderDailyStats
GuanshiRiTongji = ManagerDailyStats
GuanshiXufeiRiTongji = ManagerRenewalDailyStats
TixianRiTongji = WithdrawalDailyStats
from django.db import models
from gvsdsdk.model_base import QModel
# ==================== 1. 角色表 ====================
class Role(QModel):
"""角色表"""
role_id = models.AutoField(primary_key=True, verbose_name='角色ID')
role_code = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='角色编码')
role_name = models.CharField(max_length=50, verbose_name='角色名称')
description = models.CharField(max_length=200, blank=True, default='', verbose_name='角色描述')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'role'
verbose_name = '角色'
verbose_name_plural = '角色'
managed = True
indexes = [
models.Index(fields=['role_code']),
]
def __str__(self):
return self.role_name
# ==================== 2. 权限表 ====================
class Permission(QModel):
"""权限表"""
perm_id = models.AutoField(primary_key=True, verbose_name='权限ID')
perm_code = models.CharField(max_length=100, unique=True, db_index=True, verbose_name='权限编码')
perm_name = models.CharField(max_length=100, verbose_name='权限名称')
description = models.CharField(max_length=200, blank=True, default='', verbose_name='权限描述')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'permission'
verbose_name = '权限'
verbose_name_plural = '权限'
managed = True
indexes = [
models.Index(fields=['perm_code']),
]
def __str__(self):
return f"{self.perm_name} ({self.perm_code})"
# ==================== 3. 角色-权限关联表 ====================
class RolePermission(QModel):
"""角色权限关联表"""
id = models.AutoField(primary_key=True)
role = models.ForeignKey(Role, on_delete=models.CASCADE, db_index=True, verbose_name='角色')
permission = models.ForeignKey(Permission, on_delete=models.CASCADE, db_index=True, verbose_name='权限')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'role_permission'
verbose_name = '角色权限关联'
verbose_name_plural = '角色权限关联'
managed = True
unique_together = [['role', 'permission']]
def __str__(self):
return f"{self.role.role_name} -> {self.permission.perm_name}"
# ==================== 4. 用户-角色关联表 ====================
class UserRole(QModel):
"""用户角色关联表"""
id = models.AutoField(primary_key=True)
account_id = models.CharField(max_length=11, db_index=True, verbose_name='账号ID')
role = models.ForeignKey(Role, on_delete=models.CASCADE, db_index=True, verbose_name='角色')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'user_role'
verbose_name = '用户角色关联'
verbose_name_plural = '用户角色关联'
managed = True
unique_together = [['account_id', 'role']]
def __str__(self):
return f"{self.account_id} -> {self.role.role_name}"
# ==================== 5. 异常用户日志 ====================
class AbnormalUserLog(QModel):
"""记录恶意尝试越权操作的用户信息"""
account_id = models.CharField(max_length=20, db_index=True, verbose_name='账号ID(phone)')
ip_address = models.GenericIPAddressField(null=True, blank=True, verbose_name='IP地址')
real_ip = models.GenericIPAddressField(null=True, blank=True, verbose_name='真实IP(穿透代理后)')
x_forwarded_for = models.CharField(max_length=255, blank=True, default='', verbose_name='X-Forwarded-For')
user_agent = models.CharField(max_length=500, blank=True, default='', verbose_name='User-Agent')
request_method = models.CharField(max_length=10, blank=True, default='', verbose_name='请求方法')
request_path = models.CharField(max_length=500, blank=True, default='', verbose_name='请求路径')
request_params = models.TextField(blank=True, default='', verbose_name='请求参数(GET/POST)')
request_body = models.TextField(blank=True, default='', verbose_name='请求体(原始)')
request_headers = models.TextField(blank=True, default='', verbose_name='请求头(JSON格式)')
attempt_type = models.CharField(max_length=50, blank=True, default='', verbose_name='攻击类型')
detail = models.TextField(blank=True, default='', verbose_name='详细描述')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'abnormal_user_log'
verbose_name = '异常用户日志'
verbose_name_plural = verbose_name
indexes = [
models.Index(fields=['account_id']),
models.Index(fields=['ip_address']),
models.Index(fields=['CreateTime']),
]
def __str__(self):
return f"{self.account_id} @ {self.ip_address} - {self.CreateTime}"
# ==================== 6. 商家每日统计 ====================
class MerchantDailyStats(QModel):
"""商家每日统计表(原 ShangjiaRiTongji)"""
MerchantID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='商家用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
# 派发统计
AssignedOrderCount = models.IntegerField(
default=0, db_column='paifa_dingdan_shu', verbose_name='派发订单总数')
AssignedAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='paifa_jine', verbose_name='派发订单总金额')
# 结算统计
SettledOrderCount = models.IntegerField(
default=0, db_column='jiesuan_dingdan_shu', verbose_name='结算订单总数')
SettledAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='jiesuan_jine', verbose_name='结算总金额')
# 退款统计
RefundOrderCount = models.IntegerField(
default=0, db_column='tuikuan_dingdan_shu', verbose_name='退款订单总数')
RefundAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='tuikuan_jine', verbose_name='退款总金额')
class Meta:
db_table = 'shangjia_ri_tongji'
verbose_name = '商家每日统计'
unique_together = [['MerchantID', 'Date']]
indexes = [
models.Index(fields=['Date', '-AssignedAmount']),
models.Index(fields=['Date', '-SettledAmount']),
models.Index(fields=['Date', '-AssignedOrderCount']),
]
def __str__(self):
return f"商家{self.MerchantID} {self.Date}"
# ==================== 7. 打手每日统计 ====================
class PlayerDailyStats(QModel):
"""打手每日统计表(原 DashouRiTongji)"""
PlayerID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='打手用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
# 接单统计
AcceptedOrderTotal = models.IntegerField(
default=0, db_column='jiedan_zongliang', verbose_name='接单总量')
CompletedOrderTotal = models.IntegerField(
default=0, db_column='chengjiao_zongliang', verbose_name='成交单总量')
# 金额统计
AcceptedAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='jiedan_zonge', verbose_name='接单总金额')
CompletedAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='chengjiao_zonge', verbose_name='成交总金额')
# 退款统计
RefundCount = models.IntegerField(
default=0, db_column='tuikuan_liang', verbose_name='退款订单量')
RefundAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='tuikuan_jine', verbose_name='退款总金额')
class Meta:
db_table = 'dashou_ri_tongji'
verbose_name = '打手每日统计'
unique_together = [['PlayerID', 'Date']]
indexes = [
models.Index(fields=['Date', '-AcceptedOrderTotal']),
models.Index(fields=['Date', '-CompletedOrderTotal']),
models.Index(fields=['Date', '-AcceptedAmount']),
models.Index(fields=['Date', '-CompletedAmount']),
]
def __str__(self):
return f"打手{self.PlayerID} {self.Date}"
# ==================== 8. 组长每日统计 ====================
class LeaderDailyStats(QModel):
"""组长每日统计表(原 ZuzhangRiTongji)"""
LeaderID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='组长用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
InvitedManagerCount = models.IntegerField(
default=0, db_column='yaoqing_guanshi_shu', verbose_name='邀请管事总数')
TotalIncome = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='shouru_zonge', verbose_name='收入总额(分佣)')
CommissionAmount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='fenyong_jine', verbose_name='分佣金额')
class Meta:
db_table = 'zuzhang_ri_tongji'
verbose_name = '组长每日统计'
unique_together = [['LeaderID', 'Date']]
indexes = [
models.Index(fields=['Date', '-InvitedManagerCount']),
models.Index(fields=['Date', '-TotalIncome']),
]
def __str__(self):
return f"组长{self.LeaderID} {self.Date}"
# ==================== 9. 管事每日统计 ====================
class ManagerDailyStats(QModel):
"""管事每日统计表(原 GuanshiRiTongji)"""
ManagerID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='管事用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
InvitedPlayerCount = models.IntegerField(
default=0, db_column='yaoqing_dashou_shu', verbose_name='邀请打手总数')
RechargedPlayerCount = models.IntegerField(
default=0, db_column='chongzhi_dashou_shu', verbose_name='充值打手数量')
TotalIncome = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='shouru_zonge', verbose_name='收入总额')
class Meta:
db_table = 'guanshi_ri_tongji'
verbose_name = '管事每日统计'
unique_together = [['ManagerID', 'Date']]
indexes = [
models.Index(fields=['Date', '-InvitedPlayerCount']),
models.Index(fields=['Date', '-RechargedPlayerCount']),
models.Index(fields=['Date', '-TotalIncome']),
]
def __str__(self):
return f"管事{self.ManagerID} {self.Date}"
# ==================== 10. 管事续费每日统计 ====================
class ManagerRenewalDailyStats(QModel):
"""管事续费每日统计表(原 GuanshiXufeiRiTongji)"""
ManagerID = models.CharField(
max_length=7, db_index=True, db_column='yonghuid', verbose_name='管事用户ID')
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
RenewalTotal = models.IntegerField(
default=0, db_column='xufei_zongshu', verbose_name='今日续费总数')
RenewalRevenue = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00,
db_column='xufei_shouyi', verbose_name='续费收益金额')
class Meta:
db_table = 'guanshi_xufei_ri_tongji'
verbose_name = '管事续费每日统计'
unique_together = [['ManagerID', 'Date']]
indexes = [
models.Index(fields=['Date', '-RenewalTotal']),
models.Index(fields=['Date', '-RenewalRevenue']),
]
def __str__(self):
return f"管事续费{self.ManagerID} {self.Date}"
# ==================== 11. 提现每日统计 ====================
class WithdrawalDailyStats(QModel):
"""每日提现统计表(原 TixianRiTongji),按身份统计当天提现总额"""
Date = models.DateField(
db_index=True, db_column='riqi', verbose_name='日期')
WithdrawalType = models.IntegerField(
choices=[(1, '打手'), (2, '管事'), (3, '组长'),
(4, '考核官'), (5, '打手押金'), (6, '商家余额')],
db_column='leixing', verbose_name='用户类型')
total_amount = models.DecimalField(
max_digits=12, decimal_places=2, default=0.00, verbose_name='当天提现总额(元)')
class Meta:
db_table = 'tixian_ri_tongji'
verbose_name = '每日提现统计'
unique_together = [['Date', 'WithdrawalType']]
indexes = [models.Index(fields=['Date', 'WithdrawalType'])]
def __str__(self):
return f"{self.Date} - {self.get_WithdrawalType_display()} 提现总额: {self.total_amount}"
# ==================== 兼容别名(供逐步迁移) ====================
ShangjiaRiTongji = MerchantDailyStats
DashouRiTongji = PlayerDailyStats
ZuzhangRiTongji = LeaderDailyStats
GuanshiRiTongji = ManagerDailyStats
GuanshiXufeiRiTongji = ManagerRenewalDailyStats
TixianRiTongji = WithdrawalDailyStats
+69 -69
View File
@@ -370,8 +370,8 @@ class GetAdminUserListView(APIView):
'nicheng': user.KefuProfile.nicheng,
'roles': roles_data,
'status': user.KefuProfile.zhuangtai,
'create_time': user.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if hasattr(user, 'UserCreateTime') else '',
'update_time': user.update_time.strftime('%Y-%m-%d %H:%M:%S') if hasattr(user, 'update_time') else '',
'CreateTime': user.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S') if hasattr(user, 'UserCreateTime') else '',
'UpdateTime': user.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if hasattr(user, 'UpdateTime') else '',
})
return Response({
@@ -452,7 +452,7 @@ class GetAdminRolesView(APIView):
users = users.filter(phone__in=user_ids_with_role)
# 排序
users = users.order_by('-create_time')
users = users.order_by('-CreateTime')
# 分页
paginator = Paginator(users, page_size)
@@ -469,8 +469,8 @@ class GetAdminRolesView(APIView):
'nicheng': user.KefuProfile.nicheng,
'roles': roles_data,
'status': user.KefuProfile.zhuangtai,
'create_time': user.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S'),
'update_time': user.update_time.strftime('%Y-%m-%d %H:%M:%S'),
'CreateTime': user.UserCreateTime.strftime('%Y-%m-%d %H:%M:%S'),
'UpdateTime': user.UpdateTime.strftime('%Y-%m-%d %H:%M:%S'),
})
return Response({
@@ -737,7 +737,7 @@ class KefuGetDashouListView(APIView):
# 7. 分页
offset = (page - 1) * page_size
dashou_list = dashou_qs.order_by('-create_time')[offset:offset + page_size]
dashou_list = dashou_qs.order_by('-CreateTime')[offset:offset + page_size]
# 8. 构建返回数据
result = []
@@ -821,7 +821,7 @@ class KefuGetDashouDetailView(APIView):
'dianhua': '',
'wechat': '',
'phone': user_main.Phone or '',
'create_time': user_main.UserCreateTime,
'CreateTime': user_main.UserCreateTime,
'ip': user_main.IP or '',
'jiedanzongliang': 0,
'chengjiaozongliang': 0,
@@ -861,7 +861,7 @@ class KefuGetDashouDetailView(APIView):
'dianhua': dashou.dianhua or '',
'wechat': dashou.wechat or '',
'phone': user_main.Phone or '',
'create_time': user_main.UserCreateTime,
'CreateTime': user_main.UserCreateTime,
'ip': user_main.IP or '',
'jiedanzongliang': dashou.jiedanzongliang,
'chengjiaozongliang': dashou.chengjiaozongliang,
@@ -880,7 +880,7 @@ class KefuGetDashouDetailView(APIView):
# 6. 查询打手已拥有的会员(未过期)
member_records = Huiyuangoumai.query.filter(
yonghu_id=uid
).order_by('-create_time')
).order_by('-CreateTime')
member_list = []
for record in member_records:
# 检查是否过期
@@ -980,7 +980,7 @@ class KefuGetDashouDetailView(APIView):
'dianhua': '',
'wechat': '',
'phone': user_main.Phone or '',
'create_time': user_main.UserCreateTime,
'CreateTime': user_main.UserCreateTime,
'ip': user_main.IP or '',
'jiedanzongliang': 0,
'chengjiaozongliang': 0,
@@ -1016,7 +1016,7 @@ class KefuGetDashouDetailView(APIView):
'dianhua': dashou.dianhua or '',
'wechat': dashou.wechat or '',
'phone': user_main.Phone or '',
'create_time': user_main.UserCreateTime,
'CreateTime': user_main.UserCreateTime,
'ip': user_main.IP or '',
'jiedanzongliang': dashou.jiedanzongliang,
'chengjiaozongliang': dashou.chengjiaozongliang,
@@ -1035,7 +1035,7 @@ class KefuGetDashouDetailView(APIView):
# 5. 查询打手会员信息(仅未过期)
member_records = Huiyuangoumai.query.filter(
yonghu_id=uid
).order_by('-create_time')
).order_by('-CreateTime')
member_list = []
for record in member_records:
@@ -1473,7 +1473,7 @@ class KefuGetShangjiaListView(APIView):
# 6. 分页
offset = (page - 1) * page_size
shangjia_list = shangjia_qs.order_by('-create_time')[offset:offset + page_size]
shangjia_list = shangjia_qs.order_by('-CreateTime')[offset:offset + page_size]
# 7. 构建返回数据
result = []
@@ -1560,7 +1560,7 @@ class KefuGetShangjiaDetailView(APIView):
'jinriliushui': str(shangjia.jinriliushui),
'jinyuedingdan': shangjia.jinyuedingdan,
'jinyueliushui': str(shangjia.jinyueliushui),
'create_time': shangjia.create_time.isoformat() if shangjia.create_time else None,
'CreateTime': shangjia.CreateTime.isoformat() if shangjia.CreateTime else None,
}
return Response({'code': 0, 'data': data})
@@ -1850,7 +1850,7 @@ class GetProductListView(APIView):
else:
qs = qs.order_by(f'-{sort_field}')
else:
qs = qs.order_by('-create_time') # 默认按创建时间倒序
qs = qs.order_by('-CreateTime') # 默认按创建时间倒序
# 分页
total = qs.count()
@@ -2052,7 +2052,7 @@ class GetProductListView(APIView):
else:
qs = qs.order_by(f'-{sort_field}')
else:
qs = qs.order_by('-create_time') # 默认按创建时间倒序
qs = qs.order_by('-CreateTime') # 默认按创建时间倒序
# 分页
total = qs.count()
@@ -2465,7 +2465,7 @@ class GetProductDetailView(APIView):
'tupian_url': product.tupian_url,
'kaioi_ewai_PlayerCommission': product.kaioi_ewai_dashou_fencheng,
'ewai_PlayerCommission': str(product.ewai_dashou_fencheng) if product.ewai_dashou_fencheng is not None else '0',
'create_time': product.create_time.isoformat() if product.create_time else None,
'CreateTime': product.CreateTime.isoformat() if product.CreateTime else None,
'shenhezhuangtai': product.shenhezhuangtai,
}
@@ -2685,7 +2685,7 @@ class GetMemberListView(APIView):
if '3300a' not in permissions:
return Response({'code': 403, 'msg': '无权限查看会员列表'})
members = Huiyuan.query.all().order_by('-create_time')
members = Huiyuan.query.all().order_by('-CreateTime')
member_list = []
for m in members:
member_list.append({
@@ -2696,8 +2696,8 @@ class GetMemberListView(APIView):
'guanshifc': str(m.guanshifc),
'zuzhangfc': str(m.zuzhangfc),
'goumai_cishu': m.goumai_cishu,
'create_time': m.create_time.isoformat() if m.create_time else None,
'update_time': m.update_time.isoformat() if m.update_time else None,
'CreateTime': m.CreateTime.isoformat() if m.CreateTime else None,
'UpdateTime': m.UpdateTime.isoformat() if m.UpdateTime else None,
})
return Response({'code': 0, 'data': {'list': member_list}})
@@ -3034,7 +3034,7 @@ class GetGuanliDetailView(APIView):
'jinrichongzhi': guanshi.jinrichongzhi,
'jinyuechongzhi': guanshi.jinyuechongzhi,
'chongzhifenrun': str(guanshi.chongzhifenrun),
'create_time': guanshi.create_time.isoformat() if guanshi.create_time else None,
'CreateTime': guanshi.CreateTime.isoformat() if guanshi.CreateTime else None,
}
# 余额提现相关
@@ -3726,7 +3726,7 @@ class GetZuzhangDetailView(APIView):
'jinri_fenyong': str(zuzhang.jinri_fenyong),
'jinyue_fenyong': str(zuzhang.jinyue_fenyong),
'fenyong_zonge': str(zuzhang.fenyong_zonge),
'create_time': zuzhang.create_time.isoformat() if zuzhang.create_time else None,
'CreateTime': zuzhang.CreateTime.isoformat() if zuzhang.CreateTime else None,
}
# 余额提现相关
@@ -5567,8 +5567,8 @@ class ProductListView(APIView):
'yongjin': p.yongjin,
'kaioi_ewai_PlayerCommission': p.kaioi_ewai_dashou_fencheng,
'ewai_PlayerCommission': p.ewai_dashou_fencheng,
'create_time': p.create_time.isoformat() if p.create_time else '',
'update_time': p.update_time.isoformat() if p.update_time else '',
'CreateTime': p.CreateTime.isoformat() if p.CreateTime else '',
'UpdateTime': p.UpdateTime.isoformat() if p.UpdateTime else '',
'paixu': p.paixu,
'dianpu_id': p.dianpu_id,
'dianpu_name': p.dianpu.dianpu_mingcheng if p.dianpu else '',
@@ -5873,7 +5873,7 @@ class FaKuanLieBiaoView(APIView):
'zhengju_tupian': zhengju_map.get(r.id, []),
'shensu_tupian': shensu_map.get(r.id, []),
'creat_time': r.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if r.CreateTime else '',
'update_time': r.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if r.UpdateTime else '',
'UpdateTime': r.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if r.UpdateTime else '',
})
return Response({
@@ -6278,7 +6278,7 @@ class HqbkxxView(APIView):
bankuai_list.append({
'bankuai_id': bk.bankuai_id,
'mingcheng': bk.mingcheng,
'create_time': bk.create_time.strftime('%Y-%m-%d %H:%M:%S') if bk.create_time else ''
'CreateTime': bk.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if bk.CreateTime else ''
})
# 6. 查询所有商品类型
@@ -6514,8 +6514,8 @@ class CaiwuView(APIView):
# 今日充值(会员充值,leixing=1, zhuangtai=3)
today_chongzhi = Czjilu.query.filter(
create_time__gte=today_start,
create_time__lt=today_end,
CreateTime__gte=today_start,
CreateTime__lt=today_end,
leixing=1,
zhuangtai=3
)
@@ -6524,8 +6524,8 @@ class CaiwuView(APIView):
# 今日新增会员:从购买记录表统计今天创建的用户(去重)
new_huiyuan_user_ids = Huiyuangoumai.query.filter(
create_time__gte=today_start,
create_time__lt=today_end
CreateTime__gte=today_start,
CreateTime__lt=today_end
).values_list('yonghu_id', flat=True).distinct()
today_new_huiyuan = len(new_huiyuan_user_ids)
@@ -6533,8 +6533,8 @@ class CaiwuView(APIView):
today_new_huiyuan_amount = 0.0
if new_huiyuan_user_ids:
amount_sum = Czjilu.query.filter(
create_time__gte=today_start,
create_time__lt=today_end,
CreateTime__gte=today_start,
CreateTime__lt=today_end,
UserUID__in=new_huiyuan_user_ids,
leixing=1,
zhuangtai=3
@@ -6685,7 +6685,7 @@ class HybkjtsjView(APIView):
end_date = date(year + 1, 1, 1)
else:
end_date = date(year, month + 1, 1)
trunc_func = TruncDate('create_time')
trunc_func = TruncDate('CreateTime')
if not summary_date:
summary_date = now.strftime('%Y-%m-%d')
summary_q = datetime.strptime(summary_date, '%Y-%m-%d').date()
@@ -6694,7 +6694,7 @@ class HybkjtsjView(APIView):
return Response({'code': 1, 'msg': '按月统计需要年份'}, status=400)
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncMonth('create_time')
trunc_func = TruncMonth('CreateTime')
if not summary_date:
summary_date = now.strftime('%Y-%m')
summary_q = datetime.strptime(summary_date + '-01', '%Y-%m-%d').date()
@@ -6702,7 +6702,7 @@ class HybkjtsjView(APIView):
year = year or now.year
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncYear('create_time')
trunc_func = TruncYear('CreateTime')
if not summary_date:
summary_date = str(year)
summary_q = date(year, 1, 1)
@@ -6718,15 +6718,15 @@ class HybkjtsjView(APIView):
'huiyuan_id': huiyuan_id, # 会员ID筛选
'leixing': 1,
'zhuangtai': 3,
'create_time__gte': start_dt,
'create_time__lt': end_dt
'CreateTime__gte': start_dt,
'CreateTime__lt': end_dt
}
# ---------- 分红过滤 ----------
fenhong_filter = {
'huiyuan_id': huiyuan_id, # 分红表会员ID筛选
'create_time__gte': start_dt,
'create_time__lt': end_dt
'CreateTime__gte': start_dt,
'CreateTime__lt': end_dt
}
# 充值分组查询
@@ -6787,12 +6787,12 @@ class HybkjtsjView(APIView):
# ---------- 汇总数据 ----------
summary_chongzhi_filter = chongzhi_filter.copy()
if granularity == 'day':
summary_chongzhi_filter['create_time__date'] = summary_q
summary_chongzhi_filter['CreateTime__date'] = summary_q
elif granularity == 'month':
summary_chongzhi_filter['create_time__year'] = summary_q.year
summary_chongzhi_filter['create_time__month'] = summary_q.month
summary_chongzhi_filter['CreateTime__year'] = summary_q.year
summary_chongzhi_filter['CreateTime__month'] = summary_q.month
else:
summary_chongzhi_filter['create_time__year'] = summary_q.year
summary_chongzhi_filter['CreateTime__year'] = summary_q.year
summary_chongzhi = Czjilu.query.filter(**summary_chongzhi_filter).aggregate(
total_count=Count('id'),
@@ -6806,12 +6806,12 @@ class HybkjtsjView(APIView):
if include_guanshi or include_zuzhang:
summary_fenhong_filter = fenhong_filter.copy()
if granularity == 'day':
summary_fenhong_filter['create_time__date'] = summary_q
summary_fenhong_filter['CreateTime__date'] = summary_q
elif granularity == 'month':
summary_fenhong_filter['create_time__year'] = summary_q.year
summary_fenhong_filter['create_time__month'] = summary_q.month
summary_fenhong_filter['CreateTime__year'] = summary_q.year
summary_fenhong_filter['CreateTime__month'] = summary_q.month
else:
summary_fenhong_filter['create_time__year'] = summary_q.year
summary_fenhong_filter['CreateTime__year'] = summary_q.year
fenhong_agg = {}
if include_guanshi:
@@ -7261,7 +7261,7 @@ class CwqtczhqView(APIView):
return Response({'code': 1, 'msg': '按日统计需要年份和月份'}, status=400)
start_date = date(year, month, 1)
end_date = date(year, month + 1, 1) if month < 12 else date(year + 1, 1, 1)
trunc_func = TruncDate('create_time')
trunc_func = TruncDate('CreateTime')
# 默认汇总日期
if not summary_date:
summary_date = now.strftime('%Y-%m-%d')
@@ -7271,7 +7271,7 @@ class CwqtczhqView(APIView):
return Response({'code': 1, 'msg': '按月统计需要年份'}, status=400)
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncMonth('create_time')
trunc_func = TruncMonth('CreateTime')
if not summary_date:
summary_date = now.strftime('%Y-%m')
summary_q = datetime.strptime(summary_date + '-01', '%Y-%m-%d').date()
@@ -7279,7 +7279,7 @@ class CwqtczhqView(APIView):
year = year or now.year
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncYear('create_time')
trunc_func = TruncYear('CreateTime')
if not summary_date:
summary_date = str(year)
summary_q = date(year, 1, 1)
@@ -7301,8 +7301,8 @@ class CwqtczhqView(APIView):
cz_types = [t for t in types if t in [2, 3, 4, 5]]
if cz_types:
cz_qs = Czjilu.query.filter(
create_time__gte=start_dt,
create_time__lt=end_dt,
CreateTime__gte=start_dt,
CreateTime__lt=end_dt,
leixing__in=cz_types,
zhuangtai=3 # 只统计支付成功的
).annotate(
@@ -7382,12 +7382,12 @@ class CwqtczhqView(APIView):
'zhuangtai': 3,
}
if granularity == 'day':
filter_kwargs['create_time__date'] = summary_q
filter_kwargs['CreateTime__date'] = summary_q
elif granularity == 'month':
filter_kwargs['create_time__year'] = summary_q.year
filter_kwargs['create_time__month'] = summary_q.month
filter_kwargs['CreateTime__year'] = summary_q.year
filter_kwargs['CreateTime__month'] = summary_q.month
else:
filter_kwargs['create_time__year'] = summary_q.year
filter_kwargs['CreateTime__year'] = summary_q.year
agg = Czjilu.query.filter(**filter_kwargs).aggregate(count=Count('id'), amount=Sum('jine'))
count = agg['count'] or 0
amount = float(agg['amount'] or 0)
@@ -7496,7 +7496,7 @@ class CwqtczhqView(APIView):
return Response({'code': 1, 'msg': '按日统计需要年份和月份'}, status=400)
start_date = date(year, month, 1)
end_date = date(year, month + 1, 1) if month < 12 else date(year + 1, 1, 1)
trunc_func = TruncDate('create_time')
trunc_func = TruncDate('CreateTime')
# 默认汇总日期
if not summary_date:
summary_date = now.strftime('%Y-%m-%d')
@@ -7506,7 +7506,7 @@ class CwqtczhqView(APIView):
return Response({'code': 1, 'msg': '按月统计需要年份'}, status=400)
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncMonth('create_time')
trunc_func = TruncMonth('CreateTime')
if not summary_date:
summary_date = now.strftime('%Y-%m')
summary_q = datetime.strptime(summary_date + '-01', '%Y-%m-%d').date()
@@ -7514,7 +7514,7 @@ class CwqtczhqView(APIView):
year = year or now.year
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncYear('create_time')
trunc_func = TruncYear('CreateTime')
if not summary_date:
summary_date = str(year)
summary_q = date(year, 1, 1)
@@ -7536,8 +7536,8 @@ class CwqtczhqView(APIView):
cz_types = [t for t in types if t in [2, 3, 4, 5]]
if cz_types:
cz_qs = Czjilu.query.filter(
create_time__gte=start_dt,
create_time__lt=end_dt,
CreateTime__gte=start_dt,
CreateTime__lt=end_dt,
leixing__in=cz_types,
zhuangtai=3 # 只统计支付成功的
).annotate(
@@ -7639,12 +7639,12 @@ class CwqtczhqView(APIView):
'zhuangtai': 3,
}
if granularity == 'day':
filter_kwargs['create_time__date'] = summary_q
filter_kwargs['CreateTime__date'] = summary_q
elif granularity == 'month':
filter_kwargs['create_time__year'] = summary_q.year
filter_kwargs['create_time__month'] = summary_q.month
filter_kwargs['CreateTime__year'] = summary_q.year
filter_kwargs['CreateTime__month'] = summary_q.month
else:
filter_kwargs['create_time__year'] = summary_q.year
filter_kwargs['CreateTime__year'] = summary_q.year
agg = Czjilu.query.filter(**filter_kwargs).aggregate(count=Count('id'), amount=Sum('jine'))
count = agg['count'] or 0
amount = float(agg['amount'] or 0)
@@ -7760,7 +7760,7 @@ class KhpzhqView(APIView):
'bankuai_id': ch.bankuai_id,
'tubiao_url': ch.tubiao_url or '',
'texiao_miaoshu': ch.texiao_miaoshu or '',
'create_time': ch.create_time.strftime('%Y-%m-%d %H:%M:%S') if ch.create_time else '',
'CreateTime': ch.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if ch.CreateTime else '',
'kaohe_guize': ch.kaohe_guize or '',
'kaioi_jinpai': ch.kaioi_jinpai,
'feiyong': feiyong_dict, # {1:100.0, 2:200.0}
@@ -8016,7 +8016,7 @@ class KhgglView(APIView):
total = queryset.count()
start = (page - 1) * page_size
end = start + page_size
shenheguan_list = queryset.order_by('-create_time')[start:end]
shenheguan_list = queryset.order_by('-CreateTime')[start:end]
# ---------- 预计算每个板块的打手数量 ----------
bankuai_dashou_count_map = {}
@@ -8074,8 +8074,8 @@ class KhgglView(APIView):
'tongguo_zongshu': sg.tongguo_zongshu,
'yue': float(sg.yue),
'zonge': float(sg.zonge),
'create_time': sg.create_time.strftime('%Y-%m-%d %H:%M:%S') if sg.create_time else '',
'update_time': sg.update_time.strftime('%Y-%m-%d %H:%M:%S') if sg.update_time else '',
'CreateTime': sg.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if sg.CreateTime else '',
'UpdateTime': sg.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if sg.UpdateTime else '',
'bankuai': bankuai_info,
'nicheng': dashou_nick,
'is_renzheng': sg.is_renzheng,
+20 -20
View File
@@ -17,8 +17,8 @@ class Migration(migrations.Migration):
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('leixing', models.IntegerField(blank=True, null=True, verbose_name='公告类型')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('jieshao', models.TextField(blank=True, null=True, verbose_name='公告介绍')),
],
options={
@@ -33,8 +33,8 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('tupian_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='轮播图片URL')),
('leixing', models.IntegerField(blank=True, null=True, verbose_name='图片类型:1:轮播2:个人中心背景')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
],
options={
'verbose_name': '轮播',
@@ -91,8 +91,8 @@ class Migration(migrations.Migration):
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('peizhiid', models.IntegerField(blank=True, null=True, verbose_name='群类型:1.打手 2.管事')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('neirong', models.CharField(blank=True, max_length=200, null=True, verbose_name='群介绍')),
('qunid', models.CharField(blank=True, max_length=100, null=True, verbose_name='群id')),
('jieshao', models.CharField(blank=True, max_length=200, null=True, verbose_name='介绍')),
@@ -110,8 +110,8 @@ class Migration(migrations.Migration):
('zongzc', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='总支出')),
('jrzc', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日支出')),
('jrls', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日流水')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
],
options={
'verbose_name': '收支记录',
@@ -125,8 +125,8 @@ class Migration(migrations.Migration):
('id', models.AutoField(primary_key=True, serialize=False)),
('leixing', models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '组长'), (4, '考核官'), (5, '打手押金'), (6, '商家余额')], unique=True, verbose_name='用户类型')),
('default_quota', models.DecimalField(decimal_places=2, default=20.0, max_digits=10, verbose_name='默认每日提现限额(元)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '默认提现限额',
@@ -140,8 +140,8 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('tupian', models.CharField(blank=True, max_length=500, null=True, verbose_name='配置图片URL')),
('leixing', models.PositiveIntegerField(blank=True, null=True, verbose_name='提现类型1:打手规则图片2:默认头像图片')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('fangwen_cishu', models.PositiveIntegerField(default=0, verbose_name='访问次数')),
],
options={
@@ -176,8 +176,8 @@ class Migration(migrations.Migration):
('yongjin_qiangdan', models.BooleanField(default=False, verbose_name='是否开启佣金抢单')),
('yongjin_jiage', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='佣金价格')),
('chenghao_id', models.IntegerField(blank=True, null=True, verbose_name='关联称号ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '商家订单模板',
@@ -200,8 +200,8 @@ class Migration(migrations.Migration):
('shiyongzhe_ip', models.CharField(blank=True, max_length=50, null=True, verbose_name='使用者IP')),
('youxiao_shijian', models.DateTimeField(blank=True, null=True, verbose_name='有效截止时间')),
('lianjie_token', models.CharField(blank=True, db_index=True, max_length=32, null=True, unique=True, verbose_name='链接Token')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('previous_lianjie_id', models.PositiveIntegerField(blank=True, db_index=True, null=True, verbose_name='上一个链接ID')),
('previous_dingdan_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='上一个订单ID')),
],
@@ -244,8 +244,8 @@ class Migration(migrations.Migration):
('day', models.PositiveSmallIntegerField(verbose_name='日期')),
('total_amount', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='出款总额')),
('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='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '每日出款统计',
@@ -264,8 +264,8 @@ class Migration(migrations.Migration):
('day', models.PositiveSmallIntegerField(verbose_name='日期')),
('total_amount', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='总收入金额')),
('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='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '每日收入统计',
+20 -20
View File
@@ -6,8 +6,8 @@ class Lunbo(QModel):
ImageURL = models.CharField(max_length=500, null=True, blank=True, verbose_name='轮播图片URL')
ImageType = models.IntegerField(null=True, blank=True, verbose_name='图片类型:1:轮播2:个人中心背景')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更改时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更改时间')
class Meta:
db_table = 'lunbo'
verbose_name = '轮播'
@@ -17,8 +17,8 @@ class Lunbo(QModel):
class Gonggao(QModel):
NoticeType = models.IntegerField(null=True, blank=True, verbose_name='公告类型')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更改时间')
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'
@@ -28,8 +28,8 @@ class Gonggao(QModel):
class Qunpeizhi(QModel):
GroupType = models.IntegerField(null=True, blank=True, verbose_name='群类型:1.打手 2.管事')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更改时间')
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='介绍')
@@ -39,8 +39,8 @@ class Qunpeizhi(QModel):
class Tupianpeizhi(QModel):
ImageURL = models.CharField(max_length=500, null=True, blank=True, verbose_name='配置图片URL')
ImageType = models.PositiveIntegerField(null=True, blank=True, verbose_name='提现类型1:打手规则图片2:默认头像图片')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更改时间')
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'
@@ -55,8 +55,8 @@ class Szjilu(QModel):
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='今日流水')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, 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 = '收支记录'
@@ -93,8 +93,8 @@ class ShangjiaMoban(QModel):
# 时间字段
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'shangjia_moban'
@@ -152,8 +152,8 @@ class ShangjiaLianjie(QModel):
)
# 时间字段
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
# 上一个链接的ID(可选,记录订单被更换前的链接)
PreviousLinkID = models.PositiveIntegerField(
@@ -206,8 +206,8 @@ class TixianQuotaDefault(QModel):
default=20.00,
verbose_name='默认每日提现限额(元)'
)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, 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'
@@ -287,8 +287,8 @@ class DailyIncomeStat(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='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'daily_income_stat'
@@ -318,8 +318,8 @@ class DailyPayoutStat(QModel):
total_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='出款总额')
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='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'daily_payout_stat'
+1 -1
View File
@@ -53,7 +53,7 @@ def daily_sz_reset_task():
# 清零今日字段
szjilu.DailyExpense = Decimal('0.00')
szjilu.DailyFlow = Decimal('0.00')
szjilu.save(update_fields=['DailyExpense', 'DailyFlow', 'update_time'])
szjilu.save(update_fields=['DailyExpense', 'DailyFlow', 'UpdateTime'])
logger.info(f"收支记录清零完成,今日支出原值: {old_jrzc},今日流水原值: {old_jrls}")
+12 -12
View File
@@ -1038,7 +1038,7 @@ class GetAdminZhanghaoView(APIView):
LEFT JOIN xiugaijilu xjl ON um.phone = xjl.xiugaiid
WHERE um.UserType = 'admin'
GROUP BY um.id, um.phone, um.yonghuid, um.UserType
ORDER BY um.create_time DESC
ORDER BY um.CreateTime DESC
"""
cursor.execute(sql)
@@ -1194,12 +1194,12 @@ class GetXiugaiJiluView(APIView):
xjl.huiyuants, -- IntegerField
xjl.huiyuan_id, -- CharField
xjl.qitashuoming, -- TextField
xjl.create_time, -- DateTimeField
xjl.CreateTime, -- DateTimeField
um.avatar -- CharField
FROM xiugaijilu xjl
LEFT JOIN user_main um ON xjl.yonghuid = um.yonghuid
WHERE xjl.xiugaiid = %s
ORDER BY xjl.create_time DESC
ORDER BY xjl.CreateTime DESC
LIMIT %s OFFSET %s
"""
@@ -1390,7 +1390,7 @@ class ShangjiaMobanListView(APIView):
'labelId': moban.TitleID,
'labelName': label_name,
'texiaoJson': texiao_json,
'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S') if moban.create_time else ''
'createTime': moban.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if moban.CreateTime else ''
})
return Response({'code': 200, 'msg': '搜索成功', 'data': {'list': formatted, 'total': len(formatted), 'hasMore': False}})
@@ -1423,7 +1423,7 @@ class ShangjiaMobanListView(APIView):
'labelId': moban.TitleID,
'labelName': label_name,
'texiaoJson': texiao_json,
'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S') if moban.create_time else ''
'createTime': moban.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if moban.CreateTime else ''
})
has_more = current_page.has_next()
@@ -1561,7 +1561,7 @@ class ShangjiaTianjiaMobanView(APIView):
'jieshao': moban.TemplateDesc,
'jiage': str(moban.Price),
'fabushuliang': moban.PublishedCount,
'createTime': moban.create_time.strftime('%Y-%m-%d %H:%M:%S'),
'createTime': moban.CreateTime.strftime('%Y-%m-%d %H:%M:%S'),
'commissionEnabled': moban.CommissionGrabEnabled,
'commissionValue': str(moban.CommissionPrice) if moban.CommissionPrice is not None else None,
'labelId': moban.TitleID
@@ -1730,7 +1730,7 @@ class ShangjiaGengxinMobanView(APIView):
'commissionEnabled': moban.CommissionGrabEnabled,
'commissionValue': str(moban.CommissionPrice) if moban.CommissionPrice else None,
'labelId': moban.TitleID,
'updateTime': moban.update_time.strftime('%Y-%m-%d %H:%M:%S')
'updateTime': moban.UpdateTime.strftime('%Y-%m-%d %H:%M:%S')
}
})
@@ -1947,7 +1947,7 @@ class ShangjiaLianjieListView(APIView):
UserID=yonghu_id,
TemplateID=moban_id,
is_used=(used == 1)
).order_by('-create_time')
).order_by('-CreateTime')
paginator = Paginator(links, page_size)
if page < 1 or page > paginator.num_pages:
@@ -1963,7 +1963,7 @@ class ShangjiaLianjieListView(APIView):
'is_used': link.is_used,
'dingdan_id': link.OrderID,
'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')
'CreateTime': link.CreateTime.strftime('%Y-%m-%d %H:%M:%S')
})
return Response({
@@ -2581,7 +2581,7 @@ class KehuTianxieDingdanView(APIView):
# 14. 返回成功响应
response_data = {
#'dingdan_id': dingdan_obj.dingdan_id,
#'create_time': dingdan_obj.create_time.strftime('%Y-%m-%d %H:%M:%S'),
#'CreateTime': dingdan_obj.CreateTime.strftime('%Y-%m-%d %H:%M:%S'),
#'shangpin_mingcheng': dingdan_obj.jieshao[:50] if dingdan_obj.jieshao else '', # 截取前50字符
#'jiage': str(dingdan_obj.jine) if dingdan_obj.jine else '0.00',
'shangjia_mingcheng': shangjia_mingcheng,
@@ -2714,8 +2714,8 @@ class GuanZhuAListView(APIView):
# 获取所有图片的相对URL
images = list(qs.values_list('ImageURL', flat=True))
# 获取最新更新时间(取所有记录的update_time最大值)
last_update = qs.aggregate(update_time__max=Max('update_time'))['update_time__max']
# 获取最新更新时间(取所有记录的UpdateTime最大值)
last_update = qs.aggregate(UpdateTime__max=Max('UpdateTime'))['UpdateTime__max']
last_update_str = last_update.strftime('%Y-%m-%d %H:%M:%S') if last_update else None
# 原子性增加访问次数
+352 -352
View File
@@ -1,352 +1,352 @@
"""模块:分佣 SAAS 数据模型
SAAS 级分佣引擎——事件驱动、规则外置、参与方可配置。
子服务只管说"发生了什么",SAAS 负责"怎么分"。"""
import uuid
import datetime
from django.db import models
from gvsdsdk.model_base import QModel
from gvsdsdk.models import UUIDField
class CommissionEvent(QModel):
"""分佣事件表——子服务触发的分佣事件
子服务在业务发生时(订单完成、会员购买、充值到账等)
调用 CommissionEngine.Dispatch() 写入此表。
"""
EVT_ORDER_COMPLETE = 'order_complete'
EVT_MEMBER_PURCHASE = 'member_purchase'
EVT_RECHARGE = 'recharge'
EVT_PENALTY = 'penalty'
EVT_REGISTER = 'register'
EVT_CUSTOM = 'custom'
EVT_TYPE_CHOICES = [
(EVT_ORDER_COMPLETE, '订单完成'),
(EVT_MEMBER_PURCHASE, '会员购买'),
(EVT_RECHARGE, '充值到账'),
(EVT_PENALTY, '罚款缴纳'),
(EVT_REGISTER, '用户注册'),
(EVT_CUSTOM, '自定义事件'),
]
EVT_PENDING = 0
EVT_PROCESSING = 1
EVT_SETTLED = 2
EVT_FAILED = 3
EVT_STATUS_CHOICES = [
(EVT_PENDING, '待处理'),
(EVT_PROCESSING, '处理中'),
(EVT_SETTLED, '已结算'),
(EVT_FAILED, '结算失败'),
]
EventUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
EventType = models.CharField(max_length=32, choices=EVT_TYPE_CHOICES)
EventKey = models.CharField(max_length=128)
TotalAmount = models.DecimalField(max_digits=18, decimal_places=4, default=0)
SourceUserUUID = UUIDField(null=True, blank=True)
EventPayload = models.JSONField(default=dict)
Participants = models.JSONField(default=dict)
EventStatus = models.SmallIntegerField(default=EVT_PENDING, choices=EVT_STATUS_CHOICES)
EventTime = models.DateTimeField(default=datetime.datetime.utcnow)
ProcessTime = models.DateTimeField(null=True, blank=True)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
class Meta:
db_table = 'CommissionEvent'
app_label = 'gvsdsdk'
verbose_name = '分佣事件'
verbose_name_plural = '分佣事件'
unique_together = [('TenantUUID', 'EventKey')]
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'EventType', 'EventStatus'], name='idx_cmevt_tenant_type_status'),
models.Index(fields=['EventKey'], name='idx_cmevt_event_key'),
models.Index(fields=['CreateTime'], name='idx_cmevt_create_time'),
]
def __str__(self):
return f'{self.EventType}:{self.EventKey}'
@property
def IsSettled(self):
return self.EventStatus == self.EVT_SETTLED
def MarkProcessing(self):
self.EventStatus = self.EVT_PROCESSING
self.save(update_fields=['EventStatus'])
def MarkSettled(self):
self.EventStatus = self.EVT_SETTLED
self.ProcessTime = datetime.datetime.utcnow()
self.save(update_fields=['EventStatus', 'ProcessTime'])
def MarkFailed(self):
self.EventStatus = self.EVT_FAILED
self.ProcessTime = datetime.datetime.utcnow()
self.save(update_fields=['EventStatus', 'ProcessTime'])
class RateTable(QModel):
"""费率表——可复用的费率配置
每个租户可创建多张费率表,不同事件类型绑定不同的表。
例如:打手分成费率表、提现手续费率表、罚款分红费率表。
"""
RateTableUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
TableCode = models.CharField(max_length=64)
TableName = models.CharField(max_length=128)
TableDescription = models.CharField(max_length=512, default='')
TableStatus = models.SmallIntegerField(default=1)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
UpdateTime = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'CommissionRateTable'
app_label = 'gvsdsdk'
verbose_name = '费率表'
verbose_name_plural = '费率表'
unique_together = [('TenantUUID', 'TableCode')]
managed = False
indexes = [
models.Index(fields=['TenantUUID'], name='idx_cmrate_tenant'),
]
def __str__(self):
return f'{self.TableCode}:{self.TableName}'
def GetRate(self, key):
try:
entry = self.Entries.get(RateKey=key, EntryStatus=1)
return entry.RateValue
except RateEntry.DoesNotExist:
return None
def GetRates(self):
return {
e.RateKey: e.RateValue
for e in self.Entries.filter(EntryStatus=1)
}
class RateEntry(QModel):
"""费率条目——费率表中的一行"""
EntryUUID = UUIDField(primary_key=True)
RateTable = models.ForeignKey(
RateTable, on_delete=models.CASCADE,
related_name='Entries',
)
RateKey = models.CharField(max_length=64)
RateLabel = models.CharField(max_length=128, default='')
RateValue = models.DecimalField(max_digits=10, decimal_places=6)
EntryStatus = models.SmallIntegerField(default=1)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
class Meta:
db_table = 'CommissionRateEntry'
app_label = 'gvsdsdk'
verbose_name = '费率条目'
verbose_name_plural = '费率条目'
unique_together = [('RateTable', 'RateKey')]
managed = False
indexes = [
models.Index(fields=['RateTable', 'RateKey'], name='idx_cmrentry_table_key'),
]
def __str__(self):
return f'{self.RateKey}={self.RateValue}'
class CommissionRule(QModel):
"""分佣规则表——定义"怎么分"
每条规则绑定一种事件类型,定义参与者如何分账。
支持比例分账、固定金额、阶梯分账、剩余归平台四种 SplitType。
"""
SPLT_PERCENTAGE = 'percentage'
SPLT_FIXED = 'fixed'
SPLT_TIERED = 'tiered'
SPLT_REMAINDER = 'remainder'
SPLT_TYPE_CHOICES = [
(SPLT_PERCENTAGE, '比例分账'),
(SPLT_FIXED, '固定金额'),
(SPLT_TIERED, '阶梯分账'),
(SPLT_REMAINDER, '剩余归平台'),
]
RuleUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
EventType = models.CharField(max_length=32, choices=CommissionEvent.EVT_TYPE_CHOICES)
RuleName = models.CharField(max_length=128)
RuleDescription = models.CharField(max_length=512, default='')
ParticipantRules = models.JSONField(default=list)
RateTable = models.ForeignKey(
RateTable, on_delete=models.SET_NULL,
null=True, blank=True, related_name='rules',
)
MaxInviteLevel = models.SmallIntegerField(default=2)
RulePriority = models.IntegerField(default=0)
RuleStatus = models.SmallIntegerField(default=1)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
UpdateTime = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'CommissionRule'
app_label = 'gvsdsdk'
verbose_name = '分佣规则'
verbose_name_plural = '分佣规则'
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'EventType', 'RuleStatus'], name='idx_cmrule_tenant_type_status'),
models.Index(fields=['RulePriority'], name='idx_cmrule_priority'),
]
def __str__(self):
return f'{self.RuleName}({self.EventType})'
def FindParticipantRule(self, role):
for pr in self.ParticipantRules:
if pr.get('role') == role:
return pr
return None
class CommissionRecord(QModel):
"""分佣记录表——不可变分账流水
每条记录代表一次分账结果:谁、从哪个事件、按什么规则、分了多少。
生成后即冻结,规则变更不影响历史记录。
"""
REC_PENDING = 0
REC_SETTLED = 1
REC_WITHDRAWN = 2
REC_CANCELLED = 3
REC_STATUS_CHOICES = [
(REC_PENDING, '待结算'),
(REC_SETTLED, '已结算'),
(REC_WITHDRAWN, '已提现'),
(REC_CANCELLED, '已取消'),
]
RecordUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
Event = models.ForeignKey(
CommissionEvent, on_delete=models.CASCADE,
related_name='records',
)
Rule = models.ForeignKey(
CommissionRule, on_delete=models.SET_NULL,
null=True, related_name='records',
)
ParticipantID = models.CharField(max_length=128)
ParticipantRole = models.CharField(max_length=64)
SplitType = models.CharField(max_length=16)
Amount = models.DecimalField(max_digits=18, decimal_places=4)
RuleSnapshot = models.JSONField(default=dict)
Status = models.SmallIntegerField(default=REC_PENDING, choices=REC_STATUS_CHOICES)
TierIndex = models.IntegerField(default=0)
SettleTime = models.DateTimeField(null=True, blank=True)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
class Meta:
db_table = 'CommissionRecord'
app_label = 'gvsdsdk'
verbose_name = '分佣记录'
verbose_name_plural = '分佣记录'
ordering = ['-CreateTime']
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'ParticipantID', 'Status'], name='idx_cmrec_tenant_part_status'),
models.Index(fields=['Event'], name='idx_cmrec_event'),
models.Index(fields=['CreateTime'], name='idx_cmrec_create_time'),
]
def __str__(self):
return f'{self.ParticipantRole}:{self.ParticipantID}={self.Amount}'
@property
def IsSettled(self):
return self.Status >= self.REC_SETTLED
def Settle(self):
self.Status = self.REC_SETTLED
self.SettleTime = datetime.datetime.utcnow()
self.save(update_fields=['Status', 'SettleTime'])
def Cancel(self):
self.Status = self.REC_CANCELLED
self.save(update_fields=['Status'])
class PreSettlement(QModel):
"""预结算表——跨平台订单待确认款项
当订单涉及外部平台时,打手分成先挂预结算,
对方确认后转为正式 CommissionRecord。
"""
PST_PENDING = 0
PST_CONFIRMED = 1
PST_REJECTED = 2
PST_STATUS_CHOICES = [
(PST_PENDING, '待确认'),
(PST_CONFIRMED, '已确认'),
(PST_REJECTED, '已拒绝'),
]
SettlementUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
EventKey = models.CharField(max_length=128)
ExternalPlatform = models.CharField(max_length=64, default='')
ExternalOrderID = models.CharField(max_length=128, default='')
ParticipantID = models.CharField(max_length=128)
ParticipantRole = models.CharField(max_length=64, default='worker')
Amount = models.DecimalField(max_digits=18, decimal_places=4)
OrderAmount = models.DecimalField(max_digits=18, decimal_places=4, default=0)
Status = models.SmallIntegerField(default=PST_PENDING, choices=PST_STATUS_CHOICES)
ConfirmedBy = models.CharField(max_length=128, default='')
ConfirmDeadline = models.DateTimeField(null=True, blank=True)
ConfirmedAt = models.DateTimeField(null=True, blank=True)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
UpdateTime = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'CommissionPreSettlement'
app_label = 'gvsdsdk'
verbose_name = '预结算'
verbose_name_plural = '预结算'
unique_together = [('EventKey', 'ParticipantID')]
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'Status'], name='idx_cmpst_tenant_status'),
models.Index(fields=['EventKey'], name='idx_cmpst_event_key'),
models.Index(fields=['ExternalOrderID'], name='idx_cmpst_ext_order'),
]
def __str__(self):
return f'预结算:{self.EventKey}->{self.ParticipantID}={self.Amount}'
def Confirm(self, confirmed_by=''):
self.Status = self.PST_CONFIRMED
self.ConfirmedBy = confirmed_by
self.ConfirmedAt = datetime.datetime.utcnow()
self.save(update_fields=['Status', 'ConfirmedBy', 'ConfirmedAt'])
def Reject(self, confirmed_by=''):
self.Status = self.PST_REJECTED
self.ConfirmedBy = confirmed_by
self.ConfirmedAt = datetime.datetime.utcnow()
self.save(update_fields=['Status', 'ConfirmedBy', 'ConfirmedAt'])
"""模块:分佣 SAAS 数据模型
SAAS 级分佣引擎——事件驱动、规则外置、参与方可配置。
子服务只管说"发生了什么",SAAS 负责"怎么分"。"""
import uuid
import datetime
from django.db import models
from gvsdsdk.model_base import QModel
from gvsdsdk.models import UUIDField
class CommissionEvent(QModel):
"""分佣事件表——子服务触发的分佣事件
子服务在业务发生时(订单完成、会员购买、充值到账等)
调用 CommissionEngine.Dispatch() 写入此表。
"""
EVT_ORDER_COMPLETE = 'order_complete'
EVT_MEMBER_PURCHASE = 'member_purchase'
EVT_RECHARGE = 'recharge'
EVT_PENALTY = 'penalty'
EVT_REGISTER = 'register'
EVT_CUSTOM = 'custom'
EVT_TYPE_CHOICES = [
(EVT_ORDER_COMPLETE, '订单完成'),
(EVT_MEMBER_PURCHASE, '会员购买'),
(EVT_RECHARGE, '充值到账'),
(EVT_PENALTY, '罚款缴纳'),
(EVT_REGISTER, '用户注册'),
(EVT_CUSTOM, '自定义事件'),
]
EVT_PENDING = 0
EVT_PROCESSING = 1
EVT_SETTLED = 2
EVT_FAILED = 3
EVT_STATUS_CHOICES = [
(EVT_PENDING, '待处理'),
(EVT_PROCESSING, '处理中'),
(EVT_SETTLED, '已结算'),
(EVT_FAILED, '结算失败'),
]
EventUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
EventType = models.CharField(max_length=32, choices=EVT_TYPE_CHOICES)
EventKey = models.CharField(max_length=128)
TotalAmount = models.DecimalField(max_digits=18, decimal_places=4, default=0)
SourceUserUUID = UUIDField(null=True, blank=True)
EventPayload = models.JSONField(default=dict)
Participants = models.JSONField(default=dict)
EventStatus = models.SmallIntegerField(default=EVT_PENDING, choices=EVT_STATUS_CHOICES)
EventTime = models.DateTimeField(default=datetime.datetime.utcnow)
ProcessTime = models.DateTimeField(null=True, blank=True)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
class Meta:
db_table = 'CommissionEvent'
app_label = 'gvsdsdk'
verbose_name = '分佣事件'
verbose_name_plural = '分佣事件'
unique_together = [('TenantUUID', 'EventKey')]
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'EventType', 'EventStatus'], name='idx_cmevt_tenant_type_status'),
models.Index(fields=['EventKey'], name='idx_cmevt_event_key'),
models.Index(fields=['CreateTime'], name='idx_cmevt_CreateTime'),
]
def __str__(self):
return f'{self.EventType}:{self.EventKey}'
@property
def IsSettled(self):
return self.EventStatus == self.EVT_SETTLED
def MarkProcessing(self):
self.EventStatus = self.EVT_PROCESSING
self.save(update_fields=['EventStatus'])
def MarkSettled(self):
self.EventStatus = self.EVT_SETTLED
self.ProcessTime = datetime.datetime.utcnow()
self.save(update_fields=['EventStatus', 'ProcessTime'])
def MarkFailed(self):
self.EventStatus = self.EVT_FAILED
self.ProcessTime = datetime.datetime.utcnow()
self.save(update_fields=['EventStatus', 'ProcessTime'])
class RateTable(QModel):
"""费率表——可复用的费率配置
每个租户可创建多张费率表,不同事件类型绑定不同的表。
例如:打手分成费率表、提现手续费率表、罚款分红费率表。
"""
RateTableUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
TableCode = models.CharField(max_length=64)
TableName = models.CharField(max_length=128)
TableDescription = models.CharField(max_length=512, default='')
TableStatus = models.SmallIntegerField(default=1)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
UpdateTime = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'CommissionRateTable'
app_label = 'gvsdsdk'
verbose_name = '费率表'
verbose_name_plural = '费率表'
unique_together = [('TenantUUID', 'TableCode')]
managed = False
indexes = [
models.Index(fields=['TenantUUID'], name='idx_cmrate_tenant'),
]
def __str__(self):
return f'{self.TableCode}:{self.TableName}'
def GetRate(self, key):
try:
entry = self.Entries.get(RateKey=key, EntryStatus=1)
return entry.RateValue
except RateEntry.DoesNotExist:
return None
def GetRates(self):
return {
e.RateKey: e.RateValue
for e in self.Entries.filter(EntryStatus=1)
}
class RateEntry(QModel):
"""费率条目——费率表中的一行"""
EntryUUID = UUIDField(primary_key=True)
RateTable = models.ForeignKey(
RateTable, on_delete=models.CASCADE,
related_name='Entries',
)
RateKey = models.CharField(max_length=64)
RateLabel = models.CharField(max_length=128, default='')
RateValue = models.DecimalField(max_digits=10, decimal_places=6)
EntryStatus = models.SmallIntegerField(default=1)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
class Meta:
db_table = 'CommissionRateEntry'
app_label = 'gvsdsdk'
verbose_name = '费率条目'
verbose_name_plural = '费率条目'
unique_together = [('RateTable', 'RateKey')]
managed = False
indexes = [
models.Index(fields=['RateTable', 'RateKey'], name='idx_cmrentry_table_key'),
]
def __str__(self):
return f'{self.RateKey}={self.RateValue}'
class CommissionRule(QModel):
"""分佣规则表——定义"怎么分"
每条规则绑定一种事件类型,定义参与者如何分账。
支持比例分账、固定金额、阶梯分账、剩余归平台四种 SplitType。
"""
SPLT_PERCENTAGE = 'percentage'
SPLT_FIXED = 'fixed'
SPLT_TIERED = 'tiered'
SPLT_REMAINDER = 'remainder'
SPLT_TYPE_CHOICES = [
(SPLT_PERCENTAGE, '比例分账'),
(SPLT_FIXED, '固定金额'),
(SPLT_TIERED, '阶梯分账'),
(SPLT_REMAINDER, '剩余归平台'),
]
RuleUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
EventType = models.CharField(max_length=32, choices=CommissionEvent.EVT_TYPE_CHOICES)
RuleName = models.CharField(max_length=128)
RuleDescription = models.CharField(max_length=512, default='')
ParticipantRules = models.JSONField(default=list)
RateTable = models.ForeignKey(
RateTable, on_delete=models.SET_NULL,
null=True, blank=True, related_name='rules',
)
MaxInviteLevel = models.SmallIntegerField(default=2)
RulePriority = models.IntegerField(default=0)
RuleStatus = models.SmallIntegerField(default=1)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
UpdateTime = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'CommissionRule'
app_label = 'gvsdsdk'
verbose_name = '分佣规则'
verbose_name_plural = '分佣规则'
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'EventType', 'RuleStatus'], name='idx_cmrule_tenant_type_status'),
models.Index(fields=['RulePriority'], name='idx_cmrule_priority'),
]
def __str__(self):
return f'{self.RuleName}({self.EventType})'
def FindParticipantRule(self, role):
for pr in self.ParticipantRules:
if pr.get('role') == role:
return pr
return None
class CommissionRecord(QModel):
"""分佣记录表——不可变分账流水
每条记录代表一次分账结果:谁、从哪个事件、按什么规则、分了多少。
生成后即冻结,规则变更不影响历史记录。
"""
REC_PENDING = 0
REC_SETTLED = 1
REC_WITHDRAWN = 2
REC_CANCELLED = 3
REC_STATUS_CHOICES = [
(REC_PENDING, '待结算'),
(REC_SETTLED, '已结算'),
(REC_WITHDRAWN, '已提现'),
(REC_CANCELLED, '已取消'),
]
RecordUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
Event = models.ForeignKey(
CommissionEvent, on_delete=models.CASCADE,
related_name='records',
)
Rule = models.ForeignKey(
CommissionRule, on_delete=models.SET_NULL,
null=True, related_name='records',
)
ParticipantID = models.CharField(max_length=128)
ParticipantRole = models.CharField(max_length=64)
SplitType = models.CharField(max_length=16)
Amount = models.DecimalField(max_digits=18, decimal_places=4)
RuleSnapshot = models.JSONField(default=dict)
Status = models.SmallIntegerField(default=REC_PENDING, choices=REC_STATUS_CHOICES)
TierIndex = models.IntegerField(default=0)
SettleTime = models.DateTimeField(null=True, blank=True)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
class Meta:
db_table = 'CommissionRecord'
app_label = 'gvsdsdk'
verbose_name = '分佣记录'
verbose_name_plural = '分佣记录'
ordering = ['-CreateTime']
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'ParticipantID', 'Status'], name='idx_cmrec_tenant_part_status'),
models.Index(fields=['Event'], name='idx_cmrec_event'),
models.Index(fields=['CreateTime'], name='idx_cmrec_CreateTime'),
]
def __str__(self):
return f'{self.ParticipantRole}:{self.ParticipantID}={self.Amount}'
@property
def IsSettled(self):
return self.Status >= self.REC_SETTLED
def Settle(self):
self.Status = self.REC_SETTLED
self.SettleTime = datetime.datetime.utcnow()
self.save(update_fields=['Status', 'SettleTime'])
def Cancel(self):
self.Status = self.REC_CANCELLED
self.save(update_fields=['Status'])
class PreSettlement(QModel):
"""预结算表——跨平台订单待确认款项
当订单涉及外部平台时,打手分成先挂预结算,
对方确认后转为正式 CommissionRecord。
"""
PST_PENDING = 0
PST_CONFIRMED = 1
PST_REJECTED = 2
PST_STATUS_CHOICES = [
(PST_PENDING, '待确认'),
(PST_CONFIRMED, '已确认'),
(PST_REJECTED, '已拒绝'),
]
SettlementUUID = UUIDField(primary_key=True)
TenantUUID = UUIDField()
EventKey = models.CharField(max_length=128)
ExternalPlatform = models.CharField(max_length=64, default='')
ExternalOrderID = models.CharField(max_length=128, default='')
ParticipantID = models.CharField(max_length=128)
ParticipantRole = models.CharField(max_length=64, default='worker')
Amount = models.DecimalField(max_digits=18, decimal_places=4)
OrderAmount = models.DecimalField(max_digits=18, decimal_places=4, default=0)
Status = models.SmallIntegerField(default=PST_PENDING, choices=PST_STATUS_CHOICES)
ConfirmedBy = models.CharField(max_length=128, default='')
ConfirmDeadline = models.DateTimeField(null=True, blank=True)
ConfirmedAt = models.DateTimeField(null=True, blank=True)
CreateTime = models.DateTimeField(default=datetime.datetime.utcnow)
UpdateTime = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'CommissionPreSettlement'
app_label = 'gvsdsdk'
verbose_name = '预结算'
verbose_name_plural = '预结算'
unique_together = [('EventKey', 'ParticipantID')]
managed = False
indexes = [
models.Index(fields=['TenantUUID', 'Status'], name='idx_cmpst_tenant_status'),
models.Index(fields=['EventKey'], name='idx_cmpst_event_key'),
models.Index(fields=['ExternalOrderID'], name='idx_cmpst_ext_order'),
]
def __str__(self):
return f'预结算:{self.EventKey}->{self.ParticipantID}={self.Amount}'
def Confirm(self, confirmed_by=''):
self.Status = self.PST_CONFIRMED
self.ConfirmedBy = confirmed_by
self.ConfirmedAt = datetime.datetime.utcnow()
self.save(update_fields=['Status', 'ConfirmedBy', 'ConfirmedAt'])
def Reject(self, confirmed_by=''):
self.Status = self.PST_REJECTED
self.ConfirmedBy = confirmed_by
self.ConfirmedAt = datetime.datetime.utcnow()
self.save(update_fields=['Status', 'ConfirmedBy', 'ConfirmedAt'])
+924 -924
View File
File diff suppressed because it is too large. Load diff
@@ -1,20 +0,0 @@
# Generated by Django 4.2.27 on 2026-06-19 01:54
from django.db import migrations
import gvsdsdk.models
import uuid
class Migration(migrations.Migration):
dependencies = [
('gvsdsdk', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='user',
name='UserUUID',
field=gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='用户UUID'),
),
]
@@ -1,90 +0,0 @@
# Generated by Django 6.0.5 on 2026-06-13 12:29
import datetime
import gvsdsdk.models
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gvsdsdk', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Position',
fields=[
('PositionUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PositionUUID', primary_key=True, serialize=False)),
('CompanyUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='CompanyUUID')),
('PositionName', models.CharField(db_column='PositionName', max_length=128)),
('PositionCode', models.CharField(db_column='PositionCode', default='', max_length=64)),
('PositionLevel', models.SmallIntegerField(db_column='PositionLevel', default=0)),
('PositionStatus', models.SmallIntegerField(db_column='PositionStatus', default=1)),
('PositionDesc', models.CharField(db_column='PositionDesc', default='', max_length=512)),
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
('UpdateTime', models.DateTimeField(db_column='UpdateTime', default=datetime.datetime.utcnow)),
],
options={
'verbose_name': '职务',
'verbose_name_plural': '职务',
'db_table': 'Position',
'managed': True,
},
),
migrations.CreateModel(
name='RolePosition',
fields=[
('RolePositionUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RolePositionUUID', primary_key=True, serialize=False)),
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID')),
('PositionUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PositionUUID')),
('IsMainPosition', models.SmallIntegerField(db_column='IsMainPosition', default=0)),
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
],
options={
'verbose_name': '角色职务关联',
'verbose_name_plural': '角色职务关联',
'db_table': 'RolePosition',
'managed': True,
},
),
migrations.CreateModel(
name='RoleShop',
fields=[
('RoleShopUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleShopUUID', primary_key=True, serialize=False)),
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID')),
('ShopUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='ShopUUID')),
('IsMainShop', models.SmallIntegerField(db_column='IsMainShop', default=0)),
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
],
options={
'verbose_name': '角色商铺关联',
'verbose_name_plural': '角色商铺关联',
'db_table': 'RoleShop',
'managed': True,
},
),
migrations.CreateModel(
name='Shop',
fields=[
('ShopUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='ShopUUID', primary_key=True, serialize=False)),
('CompanyUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='CompanyUUID')),
('ShopName', models.CharField(db_column='ShopName', max_length=128)),
('ShopCode', models.CharField(db_column='ShopCode', default='', max_length=64)),
('ShopType', models.SmallIntegerField(db_column='ShopType', default=0)),
('ShopStatus', models.SmallIntegerField(db_column='ShopStatus', default=1)),
('ShopAddress', models.CharField(db_column='ShopAddress', default='', max_length=512)),
('ShopContact', models.CharField(db_column='ShopContact', default='', max_length=128)),
('ShopPhone', models.CharField(db_column='ShopPhone', default='', max_length=32)),
('ShopDesc', models.CharField(db_column='ShopDesc', default='', max_length=512)),
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
('UpdateTime', models.DateTimeField(db_column='UpdateTime', default=datetime.datetime.utcnow)),
],
options={
'verbose_name': '商铺',
'verbose_name_plural': '商铺',
'db_table': 'Shop',
'managed': True,
},
),
]
+540 -540
View File
File diff suppressed because it is too large. Load diff
+260 -260
View File
@@ -1,260 +1,260 @@
#!/usr/bin/env python3
"""
migrate_to_gvsdsdk_user.py — 将 UserMain 用户体系迁移到 gvsdsdk.User + RBAC
使用方式:
cd /opt/.../django
python manage.py shell < migrate_to_gvsdsdk_user.py
或:
python manage.py shell
>>> exec(open('migrate_to_gvsdsdk_user.py').read())
"""
import uuid
import datetime
from django.db import transaction
from django.conf import settings
# === 配置 ===
TENANT_UUID = uuid.uuid4().bytes # 本租户 UUID(所有角色共用)
COMPANY_UUID = uuid.uuid4().bytes # 默认公司 UUID
# 角色映射:user_type → (RoleName, RoleDesc)
ROLE_MAP = {
'normal': ('消费者', '普通消费者/老板'),
'dashou': ('打手', '接单打手'),
'shop': ('商家', '发布订单的商家'),
'guanshi': ('负责人', '管事/负责人'),
'admin': ('管理员', '系统管理员'),
'kefu': ('客服', '客服人员'),
'zuzhang': ('组长', '组长'),
'shenheguan': ('审核官', '审核官'),
}
# 权限映射:每个角色拥有的权限码
PERMISSION_MAP = {
'消费者': ['view_orders', 'create_order', 'view_own_profile'],
'打手': ['view_orders', 'accept_order', 'view_own_profile', 'withdraw'],
'商家': ['view_orders', 'create_order', 'view_own_profile', 'withdraw', 'manage_own_orders'],
'负责人': ['view_orders', 'view_own_profile', 'withdraw', 'invite_dashou', 'view_dashou_stats'],
'管理员': ['admin_access', 'manage_users', 'view_all_orders', 'manage_orders', 'view_stats', 'manage_fines'],
'客服': ['kefu_access', 'view_orders', 'manage_orders', 'apply_fine', 'view_stats'],
'组长': ['view_orders', 'view_own_profile', 'withdraw', 'invite_dashou'],
'审核官': ['view_orders', 'review_orders', 'view_own_profile', 'withdraw'],
}
def run_migration():
from gvsdsdk.models import Role, Permission, UserRole, RolePermission
from users.business_models import User
from users.models import (
UserMain, UserBoss, UserDashou, UserShangjia, UserGuanshi,
UserZuzhang, UserShenheguan, AdminProfile, UserKefu,
UserSensitiveData
)
print("=" * 60)
print("开始迁移 UserMain → gvsdsdk.User + RBAC")
print("=" * 60)
# ========== 第1步:创建租户下的角色和权限 ==========
print("\n[1/6] 创建角色和权限...")
created_roles = {}
created_perms = {}
for user_type, (role_name, role_desc) in ROLE_MAP.items():
# 创建角色
role, created = Role.objects.get_or_create(
RoleName=role_name,
TenantUUID=TENANT_UUID,
defaults={
'RoleUUID': uuid.uuid4().bytes,
'RoleDesc': role_desc,
'RoleStatus': 1,
'AssignScope': 0,
}
)
if created:
print(f" 创建角色: {role_name}")
created_roles[user_type] = role
# 创建该角色的权限
perm_codes = PERMISSION_MAP.get(role_name, [])
for perm_code in perm_codes:
perm, perm_created = Permission.objects.get_or_create(
PermCode=perm_code,
TenantUUID=TENANT_UUID,
defaults={
'PermUUID': uuid.uuid4().bytes,
'PermName': perm_code,
'PermCategory': role_name,
'PermStatus': 1,
}
)
if perm_created:
print(f" 创建权限: {perm_code}")
created_perms[perm_code] = perm
# 关联角色-权限
RolePermission.objects.get_or_create(
RoleUUID=role.RoleUUID,
PermUUID=perm.PermUUID,
defaults={
'RolePermUUID': uuid.uuid4().bytes,
}
)
# ========== 第2步:迁移用户 ==========
print("\n[2/6] 迁移用户数据...")
user_main_qs = UserMain.objects.all()
total = user_main_qs.count()
print(f" 共 {total} 个用户待迁移")
# 构建 yonghuid → UserUUID 映射
uid_map = {} # yonghuid → UserUUID (bytes)
for i, um in enumerate(user_main_qs):
if (i + 1) % 100 == 0:
print(f" 进度: {i+1}/{total}")
user_uuid = uuid.uuid4().bytes
# 创建 gvsdsdk User
user = User.objects.create(
UserUUID=user_uuid,
UserName=um.yonghuid, # 用 yonghuid 作为用户名
UserUID=um.yonghuid,
OpenID=um.openid or '',
UnionID=um.unionid or '',
Avatar=um.avatar or 'a_long/morentouxiang.jpg',
Phone=um.phone or '',
PhoneVerified=um.shoujihao_renzheng or False,
IP=um.ip or '',
UserAccountLicense=1,
UserPositionStatus=0,
UserCreateTime=um.create_time or datetime.datetime.utcnow(),
UserLastLoginDate=um.last_login_time or datetime.datetime.utcnow(),
IsStaff=(um.user_type == 'admin'),
IsSuperuser=(um.user_type == 'admin'),
)
uid_map[um.yonghuid] = user_uuid
# 创建 UserRole
user_type = um.user_type or 'normal'
role = created_roles.get(user_type)
if role:
UserRole.objects.create(
UserRoleUUID=uuid.uuid4().bytes,
UserUUID=user_uuid,
RoleUUID=role.RoleUUID,
CompanyUUID=COMPANY_UUID,
)
# 创建 UserSensitiveData
UserSensitiveData.objects.create(
user_uuid_id=user_uuid,
password=um.password or '',
zhifu=um.zhifu or '',
skzhanghao=um.skzhanghao or '',
shoujihao_renzheng=um.shoujihao_renzheng or False,
)
print(f" 用户迁移完成: {len(uid_map)} 个")
# ========== 第3步:迁移扩展表 FK ==========
print("\n[3/6] 迁移扩展表 FK...")
ext_tables = [
('UserBoss', UserBoss, 'boss_profile'),
('UserDashou', UserDashou, 'dashou_profile'),
('UserShangjia', UserShangjia, 'shop_profile'),
('UserGuanshi', UserGuanshi, 'guanshi_profile'),
('UserZuzhang', UserZuzhang, 'zuzhang_profile'),
('UserShenheguan', UserShenheguan, 'shenheguan_profile'),
('AdminProfile', AdminProfile, 'admin_profile'),
('UserKefu', UserKefu, 'kefu_profile'),
]
for table_name, model, _ in ext_tables:
count = 0
for obj in model.objects.all():
old_user_id = obj.user_id # 旧 FK (UserMain.id)
# 通过旧 UserMain 查找 yonghuid → 新 UserUUID
try:
old_user = UserMain.objects.get(id=old_user_id)
new_uuid = uid_map.get(old_user.yonghuid)
if new_uuid:
obj.user_id = new_uuid # 更新 FK 为新 UserUUID
obj.save(update_fields=['user_id'])
count += 1
except UserMain.DoesNotExist:
pass
print(f" {table_name}: 迁移 {count} 条")
# ========== 第4步:迁移其他引用 yonghuid 的表 ==========
print("\n[4/6] 迁移其他表的 yonghuid 引用...")
# Tixianjilu, TixianShenheJilu, TixianAutoRecord, Xiugaijilu, RankingRecord
# 这些表使用 yonghuid 字符串字段,不需要修改(UserUID 保留相同值)
print(" 这些表使用 yonghuid 字符串字段,值不变,无需迁移")
# ========== 第5步:迁移 backend.UserRole ==========
print("\n[5/6] 迁移 backend.UserRole...")
from backend.models import UserRole as BackendUserRole
count = 0
for bur in BackendUserRole.objects.all():
# account_id 是手机号,查找对应的 UserMain → 新 UserUUID
try:
um = UserMain.objects.get(phone=bur.account_id)
new_uuid = uid_map.get(um.yonghuid)
if new_uuid:
# 查找对应的新角色
old_role = bur.role
# 尝试匹配角色名
role_name_map = {
'客服': 'kefu', '打手': 'dashou', '商家': 'shop',
'管事': 'guanshi', '管理员': 'admin', '组长': 'zuzhang',
'审核官': 'shenheguan', '消费者': 'normal',
}
new_role = None
for ut, r in created_roles.items():
if old_role.role_name in r.RoleName or old_role.role_code in ut:
new_role = r
break
if new_role:
UserRole.objects.get_or_create(
UserUUID=new_uuid,
RoleUUID=new_role.RoleUUID,
CompanyUUID=COMPANY_UUID,
defaults={'UserRoleUUID': uuid.uuid4().bytes}
)
count += 1
except UserMain.DoesNotExist:
pass
print(f" 迁移 {count} 条 backend.UserRole")
# ========== 第6步:验证 ==========
print("\n[6/6] 验证迁移结果...")
new_user_count = User.objects.count()
new_role_count = Role.objects.filter(TenantUUID=TENANT_UUID).count()
new_perm_count = Permission.objects.filter(TenantUUID=TENANT_UUID).count()
new_ur_count = UserRole.objects.count()
print(f" gvsdsdk.User: {new_user_count}")
print(f" Role: {new_role_count}")
print(f" Permission: {new_perm_count}")
print(f" UserRole: {new_ur_count}")
print(f" UserSensitiveData: {UserSensitiveData.objects.count()}")
print("\n" + "=" * 60)
print("迁移完成!")
print(f"TENANT_UUID = {uuid.UUID(bytes=TENANT_UUID)}")
print(f"COMPANY_UUID = {uuid.UUID(bytes=COMPANY_UUID)}")
print("请将这两个 UUID 保存到 settings.py 中")
print("=" * 60)
if __name__ == '__main__':
run_migration()
#!/usr/bin/env python3
"""
migrate_to_gvsdsdk_user.py — 将 UserMain 用户体系迁移到 gvsdsdk.User + RBAC
使用方式:
cd /opt/.../django
python manage.py shell < migrate_to_gvsdsdk_user.py
或:
python manage.py shell
>>> exec(open('migrate_to_gvsdsdk_user.py').read())
"""
import uuid
import datetime
from django.db import transaction
from django.conf import settings
# === 配置 ===
TENANT_UUID = uuid.uuid4().bytes # 本租户 UUID(所有角色共用)
COMPANY_UUID = uuid.uuid4().bytes # 默认公司 UUID
# 角色映射:user_type → (RoleName, RoleDesc)
ROLE_MAP = {
'normal': ('消费者', '普通消费者/老板'),
'dashou': ('打手', '接单打手'),
'shop': ('商家', '发布订单的商家'),
'guanshi': ('负责人', '管事/负责人'),
'admin': ('管理员', '系统管理员'),
'kefu': ('客服', '客服人员'),
'zuzhang': ('组长', '组长'),
'shenheguan': ('审核官', '审核官'),
}
# 权限映射:每个角色拥有的权限码
PERMISSION_MAP = {
'消费者': ['view_orders', 'create_order', 'view_own_profile'],
'打手': ['view_orders', 'accept_order', 'view_own_profile', 'withdraw'],
'商家': ['view_orders', 'create_order', 'view_own_profile', 'withdraw', 'manage_own_orders'],
'负责人': ['view_orders', 'view_own_profile', 'withdraw', 'invite_dashou', 'view_dashou_stats'],
'管理员': ['admin_access', 'manage_users', 'view_all_orders', 'manage_orders', 'view_stats', 'manage_fines'],
'客服': ['kefu_access', 'view_orders', 'manage_orders', 'apply_fine', 'view_stats'],
'组长': ['view_orders', 'view_own_profile', 'withdraw', 'invite_dashou'],
'审核官': ['view_orders', 'review_orders', 'view_own_profile', 'withdraw'],
}
def run_migration():
from gvsdsdk.models import Role, Permission, UserRole, RolePermission
from users.business_models import User
from users.models import (
UserMain, UserBoss, UserDashou, UserShangjia, UserGuanshi,
UserZuzhang, UserShenheguan, AdminProfile, UserKefu,
UserSensitiveData
)
print("=" * 60)
print("开始迁移 UserMain → gvsdsdk.User + RBAC")
print("=" * 60)
# ========== 第1步:创建租户下的角色和权限 ==========
print("\n[1/6] 创建角色和权限...")
created_roles = {}
created_perms = {}
for user_type, (role_name, role_desc) in ROLE_MAP.items():
# 创建角色
role, created = Role.objects.get_or_create(
RoleName=role_name,
TenantUUID=TENANT_UUID,
defaults={
'RoleUUID': uuid.uuid4().bytes,
'RoleDesc': role_desc,
'RoleStatus': 1,
'AssignScope': 0,
}
)
if created:
print(f" 创建角色: {role_name}")
created_roles[user_type] = role
# 创建该角色的权限
perm_codes = PERMISSION_MAP.get(role_name, [])
for perm_code in perm_codes:
perm, perm_created = Permission.objects.get_or_create(
PermCode=perm_code,
TenantUUID=TENANT_UUID,
defaults={
'PermUUID': uuid.uuid4().bytes,
'PermName': perm_code,
'PermCategory': role_name,
'PermStatus': 1,
}
)
if perm_created:
print(f" 创建权限: {perm_code}")
created_perms[perm_code] = perm
# 关联角色-权限
RolePermission.objects.get_or_create(
RoleUUID=role.RoleUUID,
PermUUID=perm.PermUUID,
defaults={
'RolePermUUID': uuid.uuid4().bytes,
}
)
# ========== 第2步:迁移用户 ==========
print("\n[2/6] 迁移用户数据...")
user_main_qs = UserMain.objects.all()
total = user_main_qs.count()
print(f" 共 {total} 个用户待迁移")
# 构建 yonghuid → UserUUID 映射
uid_map = {} # yonghuid → UserUUID (bytes)
for i, um in enumerate(user_main_qs):
if (i + 1) % 100 == 0:
print(f" 进度: {i+1}/{total}")
user_uuid = uuid.uuid4().bytes
# 创建 gvsdsdk User
user = User.objects.create(
UserUUID=user_uuid,
UserName=um.yonghuid, # 用 yonghuid 作为用户名
UserUID=um.yonghuid,
OpenID=um.openid or '',
UnionID=um.unionid or '',
Avatar=um.avatar or 'a_long/morentouxiang.jpg',
Phone=um.phone or '',
PhoneVerified=um.shoujihao_renzheng or False,
IP=um.ip or '',
UserAccountLicense=1,
UserPositionStatus=0,
UserCreateTime=um.CreateTime or datetime.datetime.utcnow(),
UserLastLoginDate=um.last_login_time or datetime.datetime.utcnow(),
IsStaff=(um.user_type == 'admin'),
IsSuperuser=(um.user_type == 'admin'),
)
uid_map[um.yonghuid] = user_uuid
# 创建 UserRole
user_type = um.user_type or 'normal'
role = created_roles.get(user_type)
if role:
UserRole.objects.create(
UserRoleUUID=uuid.uuid4().bytes,
UserUUID=user_uuid,
RoleUUID=role.RoleUUID,
CompanyUUID=COMPANY_UUID,
)
# 创建 UserSensitiveData
UserSensitiveData.objects.create(
user_uuid_id=user_uuid,
password=um.password or '',
zhifu=um.zhifu or '',
skzhanghao=um.skzhanghao or '',
shoujihao_renzheng=um.shoujihao_renzheng or False,
)
print(f" 用户迁移完成: {len(uid_map)} 个")
# ========== 第3步:迁移扩展表 FK ==========
print("\n[3/6] 迁移扩展表 FK...")
ext_tables = [
('UserBoss', UserBoss, 'boss_profile'),
('UserDashou', UserDashou, 'dashou_profile'),
('UserShangjia', UserShangjia, 'shop_profile'),
('UserGuanshi', UserGuanshi, 'guanshi_profile'),
('UserZuzhang', UserZuzhang, 'zuzhang_profile'),
('UserShenheguan', UserShenheguan, 'shenheguan_profile'),
('AdminProfile', AdminProfile, 'admin_profile'),
('UserKefu', UserKefu, 'kefu_profile'),
]
for table_name, model, _ in ext_tables:
count = 0
for obj in model.objects.all():
old_user_id = obj.user_id # 旧 FK (UserMain.id)
# 通过旧 UserMain 查找 yonghuid → 新 UserUUID
try:
old_user = UserMain.objects.get(id=old_user_id)
new_uuid = uid_map.get(old_user.yonghuid)
if new_uuid:
obj.user_id = new_uuid # 更新 FK 为新 UserUUID
obj.save(update_fields=['user_id'])
count += 1
except UserMain.DoesNotExist:
pass
print(f" {table_name}: 迁移 {count} 条")
# ========== 第4步:迁移其他引用 yonghuid 的表 ==========
print("\n[4/6] 迁移其他表的 yonghuid 引用...")
# Tixianjilu, TixianShenheJilu, TixianAutoRecord, Xiugaijilu, RankingRecord
# 这些表使用 yonghuid 字符串字段,不需要修改(UserUID 保留相同值)
print(" 这些表使用 yonghuid 字符串字段,值不变,无需迁移")
# ========== 第5步:迁移 backend.UserRole ==========
print("\n[5/6] 迁移 backend.UserRole...")
from backend.models import UserRole as BackendUserRole
count = 0
for bur in BackendUserRole.objects.all():
# account_id 是手机号,查找对应的 UserMain → 新 UserUUID
try:
um = UserMain.objects.get(phone=bur.account_id)
new_uuid = uid_map.get(um.yonghuid)
if new_uuid:
# 查找对应的新角色
old_role = bur.role
# 尝试匹配角色名
role_name_map = {
'客服': 'kefu', '打手': 'dashou', '商家': 'shop',
'管事': 'guanshi', '管理员': 'admin', '组长': 'zuzhang',
'审核官': 'shenheguan', '消费者': 'normal',
}
new_role = None
for ut, r in created_roles.items():
if old_role.role_name in r.RoleName or old_role.role_code in ut:
new_role = r
break
if new_role:
UserRole.objects.get_or_create(
UserUUID=new_uuid,
RoleUUID=new_role.RoleUUID,
CompanyUUID=COMPANY_UUID,
defaults={'UserRoleUUID': uuid.uuid4().bytes}
)
count += 1
except UserMain.DoesNotExist:
pass
print(f" 迁移 {count} 条 backend.UserRole")
# ========== 第6步:验证 ==========
print("\n[6/6] 验证迁移结果...")
new_user_count = User.objects.count()
new_role_count = Role.objects.filter(TenantUUID=TENANT_UUID).count()
new_perm_count = Permission.objects.filter(TenantUUID=TENANT_UUID).count()
new_ur_count = UserRole.objects.count()
print(f" gvsdsdk.User: {new_user_count}")
print(f" Role: {new_role_count}")
print(f" Permission: {new_perm_count}")
print(f" UserRole: {new_ur_count}")
print(f" UserSensitiveData: {UserSensitiveData.objects.count()}")
print("\n" + "=" * 60)
print("迁移完成!")
print(f"TENANT_UUID = {uuid.UUID(bytes=TENANT_UUID)}")
print(f"COMPANY_UUID = {uuid.UUID(bytes=COMPANY_UUID)}")
print("请将这两个 UUID 保存到 settings.py 中")
print("=" * 60)
if __name__ == '__main__':
run_migration()
+26 -26
View File
@@ -25,8 +25,8 @@ class Migration(migrations.Migration):
('bhliyou', models.TextField(blank=True, null=True, verbose_name='驳回处罚理由')),
('jifen', models.IntegerField(default=0, verbose_name='扣除打手积分')),
('dingdan_id', models.CharField(db_index=True, max_length=32, null=True, verbose_name='订单ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'db_table': 'chufajilu',
@@ -39,8 +39,8 @@ class Migration(migrations.Migration):
('dingdan_id', models.CharField(db_index=True, max_length=32, null=True, verbose_name='订单ID')),
('yonghuid', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='用户ID')),
('tupian', models.CharField(blank=True, max_length=500, null=True, verbose_name='证据图片URL')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'db_table': 'chufatupian',
@@ -53,8 +53,8 @@ class Migration(migrations.Migration):
('dingdan_id', models.CharField(db_index=True, max_length=32, null=True, verbose_name='订单ID')),
('dashou', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='接单打手ID')),
('tupian', models.CharField(blank=True, max_length=500, null=True, verbose_name='打手提交图片URL')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'db_table': 'dashoutupian',
@@ -88,8 +88,8 @@ class Migration(migrations.Migration):
('auto_expire_at', models.DateTimeField(blank=True, null=True, verbose_name='计划过期时间')),
('pending_dispatch', models.BooleanField(db_index=True, default=False, verbose_name='待调度标记')),
('status_8_time', models.DateTimeField(blank=True, null=True, verbose_name='状态变为8的时间')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('clkf', models.CharField(db_index=True, max_length=20, null=True, verbose_name='处理客服')),
('tkly', models.CharField(blank=True, max_length=500, null=True, verbose_name='退款/拒绝理由')),
('wechat_transaction_id', models.CharField(blank=True, db_index=True, max_length=64, null=True, verbose_name='微信支付订单号')),
@@ -119,8 +119,8 @@ class Migration(migrations.Migration):
('peihu2_fenhong', models.CharField(blank=True, max_length=10, null=True, verbose_name='陪护2分红比例')),
('zhiding_peihu1', models.CharField(blank=True, max_length=32, null=True, verbose_name='指定陪护1 ID')),
('zhiding_peihu2', models.CharField(blank=True, max_length=32, null=True, verbose_name='指定陪护2 ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '陪护订单',
@@ -180,8 +180,8 @@ class Migration(migrations.Migration):
('shensuliyou', models.TextField(blank=True, null=True, verbose_name='申诉理由')),
('tongyi_chufaliyou', models.TextField(blank=True, null=True, verbose_name='同意处罚理由')),
('bohuiliyou', models.TextField(blank=True, null=True, verbose_name='驳回理由')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('shenqingren_shenfen', models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')], default=1, verbose_name='申请处罚人身份')),
('chulizhe_shenfen', models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员')], default=2, verbose_name='处理者身份')),
('chulizhe', models.CharField(blank=True, max_length=20, null=True, verbose_name='处理者')),
@@ -198,8 +198,8 @@ class Migration(migrations.Migration):
fields=[
('shenfen', models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')], primary_key=True, serialize=False, verbose_name='申请处罚人身份')),
('lilv', models.DecimalField(decimal_places=4, default=0.0, max_digits=5, verbose_name='分红费率')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '罚款分红费率配置',
@@ -213,8 +213,8 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lilu', models.DecimalField(decimal_places=4, max_digits=5, null=True, verbose_name='平台分成利率,1是平台,2是商家')),
('fadanpingtai', models.CharField(max_length=10, null=True, verbose_name='订单所属平台,(商家或平台)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'db_table': 'lilubiao',
@@ -255,8 +255,8 @@ class Migration(migrations.Migration):
('jieshao', models.TextField(blank=True, null=True, verbose_name='订单介绍')),
('beizhu', models.TextField(blank=True, null=True, verbose_name='订单备注')),
('nicheng', models.CharField(blank=True, max_length=50, null=True, verbose_name='游戏昵称')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'db_table': 'tuikuanjilu',
@@ -270,8 +270,8 @@ class Migration(migrations.Migration):
('dashou', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='接单打手ID')),
('zongfen', models.PositiveIntegerField(default=0, verbose_name='总分')),
('cishu', models.PositiveIntegerField(default=0, verbose_name='评分次数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '评分表',
@@ -287,7 +287,7 @@ class Migration(migrations.Migration):
('dashou_id', models.CharField(db_index=True, max_length=7, verbose_name='打手ID')),
('times', models.PositiveSmallIntegerField(verbose_name='第几次接单(从1开始)')),
('operator', models.CharField(max_length=11, verbose_name='操作客服ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
],
options={
'verbose_name': '订单打手变更历史',
@@ -304,8 +304,8 @@ class Migration(migrations.Migration):
('user2_id', models.CharField(db_index=True, max_length=30, verbose_name='用户2标识')),
('dingdan_id', models.CharField(max_length=32, unique=True, verbose_name='订单ID')),
('zhuangtai', models.IntegerField(choices=[(1, '开启中'), (0, '已关闭')], db_index=True, default=1, verbose_name='聊天状态')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'db_table': 'liaotian',
@@ -318,7 +318,7 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('beichufa_id', models.CharField(db_index=True, max_length=7, verbose_name='被处罚用户ID')),
('tupian_url', models.CharField(max_length=500, verbose_name='图片相对URL')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('yongtu', models.IntegerField(choices=[(1, '处罚证据图片'), (2, '申诉图片')], default=2, verbose_name='图片用途')),
('fadan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shensu_tupians', to='orders.fadan', verbose_name='关联罚单')),
],
@@ -339,8 +339,8 @@ class Migration(migrations.Migration):
('fenhong_cishu', models.IntegerField(default=0, verbose_name='分红次数')),
('is_individual_rate', models.BooleanField(default=False, verbose_name='是否单独开启分红利率')),
('yingde_lilv', models.DecimalField(decimal_places=4, default=0.0, max_digits=5, verbose_name='分红应得利率')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '罚款分红',
@@ -18,8 +18,8 @@ class Migration(migrations.Migration):
('User2ID', models.CharField(db_column='user2_id', db_index=True, max_length=30, verbose_name='用户2标识')),
('OrderID', models.CharField(db_column='dingdan_id', max_length=32, unique=True, verbose_name='订单ID')),
('Status', models.IntegerField(choices=[(1, '开启中'), (0, '已关闭')], db_column='zhuangtai', db_index=True, default=1, verbose_name='聊天状态')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'db_table': 'liaotian',
@@ -31,8 +31,8 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('Rate', models.DecimalField(db_column='lilu', decimal_places=4, max_digits=5, null=True, verbose_name='平台分成利率')),
('Platform', models.CharField(db_column='fadanpingtai', max_length=10, null=True, verbose_name='订单所属平台')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'db_table': 'lilubiao',
@@ -57,8 +57,8 @@ class Migration(migrations.Migration):
('Escort2BonusRate', models.CharField(blank=True, db_column='peihu2_fenhong', max_length=10, null=True, verbose_name='陪护2分红比例')),
('AssignedEscort1', models.CharField(blank=True, db_column='zhiding_peihu1', max_length=32, null=True, verbose_name='指定陪护1 ID')),
('AssignedEscort2', models.CharField(blank=True, db_column='zhiding_peihu2', max_length=32, null=True, verbose_name='指定陪护2 ID')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'verbose_name': '陪护订单',
@@ -112,8 +112,8 @@ class Migration(migrations.Migration):
('AutoExpireAt', models.DateTimeField(blank=True, db_column='auto_expire_at', null=True, verbose_name='计划过期时间')),
('PendingDispatch', models.BooleanField(db_column='pending_dispatch', db_index=True, default=False, verbose_name='待调度标记')),
('SettlementTime', models.DateTimeField(blank=True, db_column='status_8_time', null=True, verbose_name='状态变为8的时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
('AssignedCS', models.CharField(db_column='clkf', db_index=True, max_length=20, null=True, verbose_name='处理客服')),
('RefundReason', models.CharField(blank=True, db_column='tkly', max_length=500, null=True, verbose_name='退款/拒绝理由')),
('WechatTransactionID', models.CharField(blank=True, db_column='wechat_transaction_id', db_index=True, max_length=64, null=True, verbose_name='微信支付订单号')),
@@ -132,7 +132,7 @@ class Migration(migrations.Migration):
('PlayerID', models.CharField(db_column='dashou_id', db_index=True, max_length=7, verbose_name='打手ID')),
('Times', models.PositiveSmallIntegerField(verbose_name='第几次接单(从1开始)')),
('Operator', models.CharField(db_column='operator', max_length=11, verbose_name='操作客服ID')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
],
options={
'verbose_name': '订单打手变更历史',
@@ -155,8 +155,8 @@ class Migration(migrations.Migration):
('AppealReason', models.TextField(blank=True, db_column='shensuliyou', null=True, verbose_name='申诉理由')),
('ApproveReason', models.TextField(blank=True, db_column='tongyi_chufaliyou', null=True, verbose_name='同意处罚理由')),
('RejectReason', models.TextField(blank=True, db_column='bohuiliyou', null=True, verbose_name='驳回理由')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
('ApplicantIdentity', models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')], db_column='shenqingren_shenfen', default=1, verbose_name='申请处罚人身份')),
('ProcessorIdentity', models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员')], db_column='chulizhe_shenfen', default=2, verbose_name='处理者身份')),
('ProcessorID', models.CharField(blank=True, db_column='chulizhe', max_length=20, null=True, verbose_name='处理者')),
@@ -174,7 +174,7 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('PenalizedUserID', models.CharField(db_column='beichufa_id', db_index=True, max_length=7, verbose_name='被处罚用户ID')),
('ImageURL', models.CharField(db_column='tupian_url', max_length=500, verbose_name='图片相对URL')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('Purpose', models.IntegerField(choices=[(1, '处罚证据图片'), (2, '申诉图片')], db_column='yongtu', default=2, verbose_name='图片用途')),
],
options={
@@ -194,8 +194,8 @@ class Migration(migrations.Migration):
('BonusCount', models.IntegerField(db_column='fenhong_cishu', default=0, verbose_name='分红次数')),
('IsIndividualRate', models.BooleanField(db_column='is_individual_rate', default=False, verbose_name='是否单独开启分红利率')),
('IndividualRate', models.DecimalField(db_column='yingde_lilv', decimal_places=4, default=0.0, max_digits=5, verbose_name='分红应得利率')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'verbose_name': '罚款分红',
@@ -208,8 +208,8 @@ class Migration(migrations.Migration):
fields=[
('Identity', models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')], db_column='shenfen', primary_key=True, serialize=False, verbose_name='申请处罚人身份')),
('Rate', models.DecimalField(db_column='lilv', decimal_places=4, default=0.0, max_digits=5, verbose_name='分红费率')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'verbose_name': '罚款分红费率配置',
@@ -224,8 +224,8 @@ class Migration(migrations.Migration):
('OrderID', models.CharField(db_column='dingdan_id', db_index=True, max_length=32, null=True, verbose_name='订单ID')),
('UserID', models.CharField(blank=True, db_column='yonghuid', db_index=True, max_length=32, null=True, verbose_name='用户ID')),
('ImageURL', models.CharField(blank=True, db_column='tupian', max_length=500, null=True, verbose_name='证据图片URL')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'db_table': 'chufatupian',
@@ -244,8 +244,8 @@ class Migration(migrations.Migration):
('RejectReason', models.TextField(blank=True, db_column='bhliyou', null=True, verbose_name='驳回处罚理由')),
('DeductedPoints', models.IntegerField(db_column='jifen', default=0, verbose_name='扣除打手积分')),
('OrderID', models.CharField(db_column='dingdan_id', db_index=True, max_length=32, null=True, verbose_name='订单ID')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'db_table': 'chufajilu',
@@ -296,8 +296,8 @@ class Migration(migrations.Migration):
('OrderID', models.CharField(db_column='dingdan_id', db_index=True, max_length=32, null=True, verbose_name='订单ID')),
('PlayerID', models.CharField(blank=True, db_column='dashou', db_index=True, max_length=32, null=True, verbose_name='接单打手ID')),
('ImageURL', models.CharField(blank=True, db_column='tupian', max_length=500, null=True, verbose_name='打手提交图片URL')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'db_table': 'dashoutupian',
@@ -310,8 +310,8 @@ class Migration(migrations.Migration):
('PlayerID', models.CharField(blank=True, db_column='dashou', db_index=True, max_length=32, null=True, verbose_name='接单打手ID')),
('TotalScore', models.PositiveIntegerField(db_column='zongfen', default=0, verbose_name='总分')),
('RatingCount', models.PositiveIntegerField(db_column='cishu', default=0, verbose_name='评分次数')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'verbose_name': '评分表',
@@ -334,8 +334,8 @@ class Migration(migrations.Migration):
('Description', models.TextField(blank=True, db_column='jieshao', null=True, verbose_name='订单介绍')),
('Remark', models.TextField(blank=True, db_column='beizhu', null=True, verbose_name='订单备注')),
('Nickname', models.CharField(blank=True, db_column='nicheng', max_length=50, null=True, verbose_name='游戏昵称')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='create_time', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='update_time', verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, db_column='CreateTime', verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, db_column='UpdateTime', verbose_name='更新时间')),
],
options={
'db_table': 'tuikuanjilu',
+1027 -1027
View File
File diff suppressed because it is too large. Load diff
+8 -8
View File
@@ -1497,7 +1497,7 @@ class DingdanXiangqingView2(APIView):
zhuangtai = order.Status or 0
jiedan_dashou_id = order.PlayerID or ''
dashou_liuyan = order.PlayerRemark or ''
update_time = order.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if order.UpdateTime else ''
UpdateTime = order.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if order.UpdateTime else ''
# 交付图片
dashoujiaofu_list = list(
@@ -1551,7 +1551,7 @@ class DingdanXiangqingView2(APIView):
'dashou_touxiang': dashou_touxiang,
'dashouliuyan': dashou_liuyan,
'dashoujiaofu': dashoujiaofu_list,
'update_time': update_time,
'UpdateTime': UpdateTime,
'jiedan_time': jiedan_time,
'tijiao_time': tijiao_time,
'laoban_pingjia': laoban_pingjia,
@@ -2128,7 +2128,7 @@ class ShangjiaDingdanHuoquView(APIView):
'leixing_id': order.ProductTypeID,
'tupian': order.ImageURL or '',
'jiedan_dashou_id': order.PlayerID or '',
'create_time': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else ''
'CreateTime': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else ''
}
order_list.append(order_data)
@@ -2246,8 +2246,8 @@ class ShangjiaDingdanXiangqingView(APIView):
'shensuliyou': fadan_obj.AppealReason or '',
'tongyi_chufaliyou': fadan_obj.ApproveReason or '',
'bohuiliyou': fadan_obj.RejectReason or '',
'create_time': fadan_obj.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if fadan_obj.CreateTime else '',
'update_time': fadan_obj.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if fadan_obj.UpdateTime else '',
'CreateTime': fadan_obj.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if fadan_obj.CreateTime else '',
'UpdateTime': fadan_obj.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if fadan_obj.UpdateTime else '',
}
# 7. 商家自己的分红利率(用于罚款分红计算)
@@ -2285,7 +2285,7 @@ class ShangjiaDingdanXiangqingView(APIView):
'jieshao': order.Description or '',
'beizhu': order.Remark or '',
'nicheng': order.Nickname or '',
'create_time': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else '',
'CreateTime': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else '',
# 打手信息
'dashou_yonghuid': dashou_yonghuid,
@@ -3774,7 +3774,7 @@ class DashouDingdanHuoquView1(APIView):
'jieshao': order.Description or '',
'tupian': order.ImageURL or '',
'nicheng': order.Nickname or '',
'create_time': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else ''
'CreateTime': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else ''
}
order_list.append(order_data)
@@ -4306,7 +4306,7 @@ class DashouDingdanXiangqingView(APIView):
'tupian': dingdan.ImageURL or '',
'nicheng': dingdan.Nickname or '',
'beizhu': dingdan.Remark or '',
'create_time': dingdan.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if dingdan.CreateTime else '',
'CreateTime': dingdan.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if dingdan.CreateTime else '',
'tuikuan_liyou':dingdan.RefundReason or '',
'dashou_liuyan': dingdan.PlayerRemark or '',
'fuwudashou_id': dingdan.PlayerID or '',
+14 -14
View File
@@ -22,8 +22,8 @@ class Migration(migrations.Migration):
('jine', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='订单金额')),
('leixing', models.IntegerField(blank=True, null=True, verbose_name='充值类型,1:会员,2:押金,3:积分,4:商家')),
('shuoming', models.CharField(blank=True, max_length=100, null=True, verbose_name='订单说明')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '充值记录订单',
@@ -40,8 +40,8 @@ class Migration(migrations.Migration):
('cishu', models.PositiveIntegerField(verbose_name='分红次数')),
('guanshi_fenhong', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='管事分红金额')),
('zuzhang_fenhong', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='组长分红金额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '多次分红配置',
@@ -64,8 +64,8 @@ class Migration(migrations.Migration):
('zuzhang_fenhong', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='组长分红金额')),
('fenhong_leixing', models.PositiveSmallIntegerField(choices=[(1, '会员分红'), (2, '押金分红'), (3, '商家订单分红')], default=1, verbose_name='分红类型')),
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '管事分红记录',
@@ -84,8 +84,8 @@ class Migration(migrations.Migration):
('guanshifc', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='管事分成')),
('zuzhangfc', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='组长分成')),
('goumai_cishu', models.PositiveIntegerField(default=0, verbose_name='购买次数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '会员',
@@ -102,8 +102,8 @@ class Migration(migrations.Migration):
('huiyuan_zhuangtai', models.PositiveIntegerField(default=1, verbose_name='会员状态')),
('jieshao', models.CharField(max_length=30, null=True, verbose_name='会员介绍')),
('daoqi_time', models.DateTimeField(verbose_name='会员到期时间')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '用户购买会员',
@@ -131,8 +131,8 @@ class Migration(migrations.Migration):
('kaioi_ewai_dashou_fencheng', models.BooleanField(default=False, verbose_name='是否开启打手额外分成')),
('ewai_dashou_fencheng', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='打手额外分成金额')),
('tupian_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='商品图片URL')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更改时间')),
('paixu', models.IntegerField(default=0, verbose_name='排序权重')),
('shenhezhuangtai', models.IntegerField(default=1, help_text='1=正常, 2=审核专用', verbose_name='审核状态')),
('shangjia_zhuangtai', models.BooleanField(default=True, verbose_name='是否上架')),
@@ -179,8 +179,8 @@ class Migration(migrations.Migration):
('tuikuan_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='退款总额')),
('pingtai_shouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='平台收益')),
('dianpu_zongshouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='店铺总收益')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '商品每日统计',
+363 -363
View File
@@ -1,364 +1,364 @@
from django.db import models
from gvsdsdk.model_base import QModel
from django.utils import timezone
class Shangpin(QModel):
"""商品表 - 100-1000条数据"""
id = models.AutoField(primary_key=True, verbose_name='商品ID')
biaoqian = models.CharField(max_length=45,null=True, blank=True, verbose_name='商品标题') # 15汉字
jiage = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='商品价格')
kucun = models.PositiveIntegerField(default=0, verbose_name='商品库存')
leixing_id = models.PositiveIntegerField(null=True, blank=True,verbose_name='商品类型ID') # 直接存数字
zhuanqu_id = models.PositiveIntegerField(null=True, blank=True,verbose_name='商品专区ID') # 直接存数字
zhenshi_xiaoliang = models.PositiveIntegerField(default=0, verbose_name='商品真实销量')
duiwai_xiaoliang = models.PositiveIntegerField(default=0, verbose_name='商品对外销量')
jieshao = models.TextField(null=True, blank=True, verbose_name='商品介绍')
# 新增字段
xiadan_xuzhi = models.TextField(null=True, blank=True, verbose_name='下单须知') # 支持500字,可换行
guize_tupian = models.CharField(max_length=500, null=True, blank=True, verbose_name='规则图片URL')
yaoqiuleixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='抢单要求类型')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
yongjin = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='佣金要求')
# 🔥 新增:是否开启打手额外分成
kaioi_ewai_dashou_fencheng = models.BooleanField(default=False, verbose_name='是否开启打手额外分成')
# 🔥 新增:打手额外分成金额(开启时使用此值,否则按利率计算)
ewai_dashou_fencheng = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='打手额外分成金额')
# 原有图片URL
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='商品图片URL')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更改时间')
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用')
dianpu = models.ForeignKey(
'shop.Dianpu', # 🔥 跨应用完整路径
on_delete=models.CASCADE,
null=True,
blank=True,
db_index=True,
verbose_name='所属店铺'
)
dianpu_leixing = models.ForeignKey(
'shop.ShangpinLeixingDianpu',
on_delete=models.SET_NULL,
null=True,
blank=True,
db_index=True,
verbose_name='店铺商品类型'
)
shangjia_zhuangtai = models.BooleanField(default=True, verbose_name='是否上架')
fengjin_zhuangtai = models.BooleanField(default=True, verbose_name='是否封禁')
shenhe_zhuangtai = models.BooleanField(default=False, verbose_name='平台审核状态',help_text='True=审核通过,False=未审核')
class Meta:
db_table = 'shangpin'
verbose_name = '商品'
verbose_name_plural = '商品'
# 不要索引!数据量太小
def __str__(self):
return f"商品{self.id}:{self.biaoqian}"
class ShangpinLeixing(QModel):
"""商品类型表 - <10条数据"""
id = models.AutoField(primary_key=True, verbose_name='类型ID')
yaoqiuleixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='抢单要求类型')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
yongjin = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='佣金要求')
jieshao = models.CharField(max_length=45, null=True, blank=True, verbose_name='类型介绍') # 15汉字
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='类型图片URL') # 用CharField
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用')
bankuai = models.ForeignKey(
'rank.Bankuai',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name='所属板块'
)
class Meta:
db_table = 'shangpin_leixing'
verbose_name = '商品类型'
verbose_name_plural = '商品类型'
def __str__(self):
return f"{self.jieshao}"
class ShangpinZhuanqu(QModel):
"""商品专区表 - <50条数据"""
id = models.AutoField(primary_key=True, verbose_name='专区ID')
mingzi = models.CharField(max_length=45, null=True, blank=True, verbose_name='专区名称') # 15汉字
leixing_id = models.PositiveIntegerField(verbose_name='类型ID') # 直接存数字,不关联
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用')
dianpu = models.ForeignKey(
'shop.Dianpu', # 🔥 跨应用完整路径
on_delete=models.CASCADE,
null=True,
blank=True,
db_index=True,
verbose_name='所属店铺'
)
dianpu_leixing = models.ForeignKey(
'shop.ShangpinLeixingDianpu',
on_delete=models.SET_NULL,
null=True,
blank=True,
db_index=True,
verbose_name='店铺商品类型'
)
shangjia_zhuangtai = models.BooleanField(default=True, verbose_name='是否上架')
fengjin_zhuangtai = models.BooleanField(default=True, verbose_name='是否封禁')
class Meta:
db_table = 'shangpin_zhuanqu'
verbose_name = '商品专区'
verbose_name_plural = '商品专区'
def __str__(self):
return f"{self.mingzi}"
class Huiyuan(QModel):
huiyuan_id = models.CharField(max_length=6, unique=True, verbose_name='会员ID')
jieshao = models.CharField(max_length=30, verbose_name='会员介绍')
jtjieshao = models.TextField(null=True, blank=True, verbose_name='会员规则介绍')
jiage = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='会员价格')
guanshifc = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='管事分成')
zuzhangfc = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='组长分成')
goumai_cishu = models.PositiveIntegerField(default=0, verbose_name='购买次数')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
bankuai = models.ForeignKey(
'rank.Bankuai',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name='所属板块'
)
class Meta:
db_table = 'huiyuan'
verbose_name = '会员'
verbose_name_plural = '会员'
def __str__(self):
return f"会员{self.huiyuan_id}:{self.jieshao}"
class Huiyuangoumai(QModel):
id = models.AutoField(primary_key=True, verbose_name='购买记录ID')
huiyuan_id = models.CharField(max_length=6, db_index=True, verbose_name='会员ID')
yonghu_id = models.CharField(max_length=32, db_index=True, verbose_name='用户ID')
huiyuan_zhuangtai = models.PositiveIntegerField(default=1, verbose_name='会员状态')
jieshao = models.CharField(max_length=30,null=True,verbose_name='会员介绍')
daoqi_time = models.DateTimeField(verbose_name='会员到期时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'huiyuangoumai'
verbose_name = '用户购买会员'
verbose_name_plural = '用户购买会员'
# 添加这个联合唯一约束
unique_together = [['yonghu_id', 'huiyuan_id']]
# 顺便优化索引(可选的,建议加)
indexes = [
models.Index(fields=['yonghu_id']),
models.Index(fields=['huiyuan_id']),
models.Index(fields=['yonghu_id', 'huiyuan_id']), # 复合索引加速查询
]
def __str__(self):
return f"用户{self.yonghu_id}-会员{self.huiyuan_id}"
def jiance_shifou_daoqi(self):
# 使用Django的timezone,它会自动处理时区
now = timezone.now()
if now > self.daoqi_time:
# 过期了
if self.huiyuan_zhuangtai != 0:
self.huiyuan_zhuangtai = 0
self.save()
return True
else:
# 没过期
if self.huiyuan_zhuangtai != 1:
self.huiyuan_zhuangtai = 1
self.save()
return False
class Czjilu(QModel):
dingdan_id = models.CharField(max_length=32, unique=True, db_index=True, verbose_name='订单ID')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
zhuangtai = models.IntegerField(null=True, blank=True, verbose_name='订单状态')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单金额')
leixing = models.IntegerField(null=True, blank=True, verbose_name='充值类型,1:会员,2:押金,3:积分,4:商家')
shuoming = models.CharField(max_length=100, null=True, blank=True, verbose_name='订单说明')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'czjilu'
verbose_name = '充值记录订单'
verbose_name_plural = '充值记录订单'
# 为高频查询字段添加索引
indexes = [
models.Index(fields=['dingdan_id']),
models.Index(fields=['yonghuid']),
]
class Gsfenhong(QModel):
dingdan_id = models.CharField(max_length=32, unique=True, verbose_name='订单ID')
guanshi = models.CharField(max_length=7, db_index=True, verbose_name='管事ID')
dashouid = models.CharField(max_length=7, db_index=True,verbose_name='打手ID')
shuoming = models.CharField(max_length=100, null=True, blank=True, verbose_name='订单说明')
fenhong = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单分红金额')
avatar = models.CharField(max_length=500, null=True, blank=True, verbose_name='打手头像')
nicheng = models.CharField(max_length=50, null=True, verbose_name='打手昵称')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
zuzhang_id = models.CharField(max_length=7, null=True, blank=True, db_index=True, verbose_name='组长ID')
zuzhang_fenhong = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='组长分红金额')
fenhong_leixing = models.PositiveSmallIntegerField(
default=1,
choices=[(1, '会员分红'), (2, '押金分红'), (3, '商家订单分红')],
verbose_name='分红类型'
)
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'gsfenhong'
verbose_name = '管事分红记录'
verbose_name_plural = '管事分红记录'
# 为高频查询字段添加索引
indexes = [
models.Index(fields=['guanshi']),
models.Index(fields=['dashouid']),
]
class DuociFenhong(QModel):
"""
多次分红配置表
用于配置不同次数下管事和组长的分红金额
"""
huiyuan = models.CharField(max_length=10, verbose_name='会员ID')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='管事ID')
cishu = models.PositiveIntegerField(verbose_name='分红次数')
guanshi_fenhong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='管事分红金额')
zuzhang_fenhong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='组长分红金额')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'duoci_fenhong'
verbose_name = '多次分红配置'
verbose_name_plural = '多次分红配置'
unique_together = ('huiyuan', 'yonghuid', 'cishu') # 同一管事、同一会员、同一次数唯一
indexes = [
models.Index(fields=['yonghuid']),
]
def __str__(self):
return f"会员{self.huiyuan_id} 用户{self.yonghuid} 次数{self.cishu}"
class ShangpinMeiriTongji(QModel):
"""
商品每日统计表
按商品 + 日期维度记录点单、成交、退款及收益数据
日期精确到天,冗余年月日字段便于分组查询
"""
shangpin = models.ForeignKey(
'products.Shangpin',
on_delete=models.CASCADE,
db_index=True,
verbose_name='商品ID'
)
riqi = models.DateField(db_index=True, verbose_name='统计日期')
nian = models.PositiveSmallIntegerField(verbose_name='年份')
yue = models.PositiveSmallIntegerField(verbose_name='月份')
ri = models.PositiveSmallIntegerField(verbose_name='日')
# 点单统计(下单即累加)
diandan_zongliang = models.PositiveIntegerField(default=0, verbose_name='点单总量')
diandan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='点单总额')
# 成交统计(订单完成时累加)
chengjiao_zongliang = models.PositiveIntegerField(default=0, verbose_name='成交总量')
chengjiao_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='成交总额')
# 退款统计
tuikuan_zongliang = models.PositiveIntegerField(default=0, verbose_name='退款总量')
tuikuan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='退款总额')
# 收益统计(新增)
pingtai_shouyi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='平台收益')
dianpu_zongshouyi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='店铺总收益')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'shangpin_meiri_tongji'
verbose_name = '商品每日统计'
verbose_name_plural = verbose_name
# 每天每个商品唯一记录
unique_together = [['shangpin', 'riqi']]
indexes = [
models.Index(fields=['shangpin', 'riqi']),
models.Index(fields=['nian', 'yue', 'ri']),
]
def __str__(self):
return f"{self.shangpin.biaoqian} - {self.riqi}"
def clean(self):
"""保存前自动填充年月日冗余字段"""
if self.riqi:
self.nian = self.riqi.year
self.yue = self.riqi.month
self.ri = self.riqi.day
super().clean()
def save(self, *args, **kwargs):
self.clean()
from django.db import models
from gvsdsdk.model_base import QModel
from django.utils import timezone
class Shangpin(QModel):
"""商品表 - 100-1000条数据"""
id = models.AutoField(primary_key=True, verbose_name='商品ID')
biaoqian = models.CharField(max_length=45,null=True, blank=True, verbose_name='商品标题') # 15汉字
jiage = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='商品价格')
kucun = models.PositiveIntegerField(default=0, verbose_name='商品库存')
leixing_id = models.PositiveIntegerField(null=True, blank=True,verbose_name='商品类型ID') # 直接存数字
zhuanqu_id = models.PositiveIntegerField(null=True, blank=True,verbose_name='商品专区ID') # 直接存数字
zhenshi_xiaoliang = models.PositiveIntegerField(default=0, verbose_name='商品真实销量')
duiwai_xiaoliang = models.PositiveIntegerField(default=0, verbose_name='商品对外销量')
jieshao = models.TextField(null=True, blank=True, verbose_name='商品介绍')
# 新增字段
xiadan_xuzhi = models.TextField(null=True, blank=True, verbose_name='下单须知') # 支持500字,可换行
guize_tupian = models.CharField(max_length=500, null=True, blank=True, verbose_name='规则图片URL')
yaoqiuleixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='抢单要求类型')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
yongjin = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='佣金要求')
# 🔥 新增:是否开启打手额外分成
kaioi_ewai_dashou_fencheng = models.BooleanField(default=False, verbose_name='是否开启打手额外分成')
# 🔥 新增:打手额外分成金额(开启时使用此值,否则按利率计算)
ewai_dashou_fencheng = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='打手额外分成金额')
# 原有图片URL
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='商品图片URL')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更改时间')
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用')
dianpu = models.ForeignKey(
'shop.Dianpu', # 🔥 跨应用完整路径
on_delete=models.CASCADE,
null=True,
blank=True,
db_index=True,
verbose_name='所属店铺'
)
dianpu_leixing = models.ForeignKey(
'shop.ShangpinLeixingDianpu',
on_delete=models.SET_NULL,
null=True,
blank=True,
db_index=True,
verbose_name='店铺商品类型'
)
shangjia_zhuangtai = models.BooleanField(default=True, verbose_name='是否上架')
fengjin_zhuangtai = models.BooleanField(default=True, verbose_name='是否封禁')
shenhe_zhuangtai = models.BooleanField(default=False, verbose_name='平台审核状态',help_text='True=审核通过,False=未审核')
class Meta:
db_table = 'shangpin'
verbose_name = '商品'
verbose_name_plural = '商品'
# 不要索引!数据量太小
def __str__(self):
return f"商品{self.id}:{self.biaoqian}"
class ShangpinLeixing(QModel):
"""商品类型表 - <10条数据"""
id = models.AutoField(primary_key=True, verbose_name='类型ID')
yaoqiuleixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='抢单要求类型')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
yongjin = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='佣金要求')
jieshao = models.CharField(max_length=45, null=True, blank=True, verbose_name='类型介绍') # 15汉字
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='类型图片URL') # 用CharField
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用')
bankuai = models.ForeignKey(
'rank.Bankuai',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name='所属板块'
)
class Meta:
db_table = 'shangpin_leixing'
verbose_name = '商品类型'
verbose_name_plural = '商品类型'
def __str__(self):
return f"{self.jieshao}"
class ShangpinZhuanqu(QModel):
"""商品专区表 - <50条数据"""
id = models.AutoField(primary_key=True, verbose_name='专区ID')
mingzi = models.CharField(max_length=45, null=True, blank=True, verbose_name='专区名称') # 15汉字
leixing_id = models.PositiveIntegerField(verbose_name='类型ID') # 直接存数字,不关联
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用')
dianpu = models.ForeignKey(
'shop.Dianpu', # 🔥 跨应用完整路径
on_delete=models.CASCADE,
null=True,
blank=True,
db_index=True,
verbose_name='所属店铺'
)
dianpu_leixing = models.ForeignKey(
'shop.ShangpinLeixingDianpu',
on_delete=models.SET_NULL,
null=True,
blank=True,
db_index=True,
verbose_name='店铺商品类型'
)
shangjia_zhuangtai = models.BooleanField(default=True, verbose_name='是否上架')
fengjin_zhuangtai = models.BooleanField(default=True, verbose_name='是否封禁')
class Meta:
db_table = 'shangpin_zhuanqu'
verbose_name = '商品专区'
verbose_name_plural = '商品专区'
def __str__(self):
return f"{self.mingzi}"
class Huiyuan(QModel):
huiyuan_id = models.CharField(max_length=6, unique=True, verbose_name='会员ID')
jieshao = models.CharField(max_length=30, verbose_name='会员介绍')
jtjieshao = models.TextField(null=True, blank=True, verbose_name='会员规则介绍')
jiage = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='会员价格')
guanshifc = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='管事分成')
zuzhangfc = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='组长分成')
goumai_cishu = models.PositiveIntegerField(default=0, verbose_name='购买次数')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
bankuai = models.ForeignKey(
'rank.Bankuai',
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name='所属板块'
)
class Meta:
db_table = 'huiyuan'
verbose_name = '会员'
verbose_name_plural = '会员'
def __str__(self):
return f"会员{self.huiyuan_id}:{self.jieshao}"
class Huiyuangoumai(QModel):
id = models.AutoField(primary_key=True, verbose_name='购买记录ID')
huiyuan_id = models.CharField(max_length=6, db_index=True, verbose_name='会员ID')
yonghu_id = models.CharField(max_length=32, db_index=True, verbose_name='用户ID')
huiyuan_zhuangtai = models.PositiveIntegerField(default=1, verbose_name='会员状态')
jieshao = models.CharField(max_length=30,null=True,verbose_name='会员介绍')
daoqi_time = models.DateTimeField(verbose_name='会员到期时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'huiyuangoumai'
verbose_name = '用户购买会员'
verbose_name_plural = '用户购买会员'
# 添加这个联合唯一约束
unique_together = [['yonghu_id', 'huiyuan_id']]
# 顺便优化索引(可选的,建议加)
indexes = [
models.Index(fields=['yonghu_id']),
models.Index(fields=['huiyuan_id']),
models.Index(fields=['yonghu_id', 'huiyuan_id']), # 复合索引加速查询
]
def __str__(self):
return f"用户{self.yonghu_id}-会员{self.huiyuan_id}"
def jiance_shifou_daoqi(self):
# 使用Django的timezone,它会自动处理时区
now = timezone.now()
if now > self.daoqi_time:
# 过期了
if self.huiyuan_zhuangtai != 0:
self.huiyuan_zhuangtai = 0
self.save()
return True
else:
# 没过期
if self.huiyuan_zhuangtai != 1:
self.huiyuan_zhuangtai = 1
self.save()
return False
class Czjilu(QModel):
dingdan_id = models.CharField(max_length=32, unique=True, db_index=True, verbose_name='订单ID')
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
zhuangtai = models.IntegerField(null=True, blank=True, verbose_name='订单状态')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单金额')
leixing = models.IntegerField(null=True, blank=True, verbose_name='充值类型,1:会员,2:押金,3:积分,4:商家')
shuoming = models.CharField(max_length=100, null=True, blank=True, verbose_name='订单说明')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'czjilu'
verbose_name = '充值记录订单'
verbose_name_plural = '充值记录订单'
# 为高频查询字段添加索引
indexes = [
models.Index(fields=['dingdan_id']),
models.Index(fields=['yonghuid']),
]
class Gsfenhong(QModel):
dingdan_id = models.CharField(max_length=32, unique=True, verbose_name='订单ID')
guanshi = models.CharField(max_length=7, db_index=True, verbose_name='管事ID')
dashouid = models.CharField(max_length=7, db_index=True,verbose_name='打手ID')
shuoming = models.CharField(max_length=100, null=True, blank=True, verbose_name='订单说明')
fenhong = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单分红金额')
avatar = models.CharField(max_length=500, null=True, blank=True, verbose_name='打手头像')
nicheng = models.CharField(max_length=50, null=True, verbose_name='打手昵称')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
zuzhang_id = models.CharField(max_length=7, null=True, blank=True, db_index=True, verbose_name='组长ID')
zuzhang_fenhong = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,verbose_name='组长分红金额')
fenhong_leixing = models.PositiveSmallIntegerField(
default=1,
choices=[(1, '会员分红'), (2, '押金分红'), (3, '商家订单分红')],
verbose_name='分红类型'
)
huiyuan_id = models.CharField(max_length=6, 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 = 'gsfenhong'
verbose_name = '管事分红记录'
verbose_name_plural = '管事分红记录'
# 为高频查询字段添加索引
indexes = [
models.Index(fields=['guanshi']),
models.Index(fields=['dashouid']),
]
class DuociFenhong(QModel):
"""
多次分红配置表
用于配置不同次数下管事和组长的分红金额
"""
huiyuan = models.CharField(max_length=10, verbose_name='会员ID')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='管事ID')
cishu = models.PositiveIntegerField(verbose_name='分红次数')
guanshi_fenhong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='管事分红金额')
zuzhang_fenhong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='组长分红金额')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'duoci_fenhong'
verbose_name = '多次分红配置'
verbose_name_plural = '多次分红配置'
unique_together = ('huiyuan', 'yonghuid', 'cishu') # 同一管事、同一会员、同一次数唯一
indexes = [
models.Index(fields=['yonghuid']),
]
def __str__(self):
return f"会员{self.huiyuan_id} 用户{self.yonghuid} 次数{self.cishu}"
class ShangpinMeiriTongji(QModel):
"""
商品每日统计表
按商品 + 日期维度记录点单、成交、退款及收益数据
日期精确到天,冗余年月日字段便于分组查询
"""
shangpin = models.ForeignKey(
'products.Shangpin',
on_delete=models.CASCADE,
db_index=True,
verbose_name='商品ID'
)
riqi = models.DateField(db_index=True, verbose_name='统计日期')
nian = models.PositiveSmallIntegerField(verbose_name='年份')
yue = models.PositiveSmallIntegerField(verbose_name='月份')
ri = models.PositiveSmallIntegerField(verbose_name='日')
# 点单统计(下单即累加)
diandan_zongliang = models.PositiveIntegerField(default=0, verbose_name='点单总量')
diandan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='点单总额')
# 成交统计(订单完成时累加)
chengjiao_zongliang = models.PositiveIntegerField(default=0, verbose_name='成交总量')
chengjiao_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='成交总额')
# 退款统计
tuikuan_zongliang = models.PositiveIntegerField(default=0, verbose_name='退款总量')
tuikuan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='退款总额')
# 收益统计(新增)
pingtai_shouyi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='平台收益')
dianpu_zongshouyi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='店铺总收益')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'shangpin_meiri_tongji'
verbose_name = '商品每日统计'
verbose_name_plural = verbose_name
# 每天每个商品唯一记录
unique_together = [['shangpin', 'riqi']]
indexes = [
models.Index(fields=['shangpin', 'riqi']),
models.Index(fields=['nian', 'yue', 'ri']),
]
def __str__(self):
return f"{self.shangpin.biaoqian} - {self.riqi}"
def clean(self):
"""保存前自动填充年月日冗余字段"""
if self.riqi:
self.nian = self.riqi.year
self.yue = self.riqi.month
self.ri = self.riqi.day
super().clean()
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
+28 -28
View File
@@ -2904,8 +2904,8 @@ class GuanshiFenhongListAPI(APIView):
# 查询当前页数据,按创建时间倒序排列
fenhong_list = Gsfenhong.query.filter(query) \
.order_by('-create_time') \
.values('dashouid', 'avatar', 'nicheng', 'fenhong', 'create_time')[offset:offset + page_size]
.order_by('-CreateTime') \
.values('dashouid', 'avatar', 'nicheng', 'fenhong', 'CreateTime')[offset:offset + page_size]
# 格式化数据
formatted_list = []
@@ -2915,7 +2915,7 @@ class GuanshiFenhongListAPI(APIView):
'avatar': item['avatar'] or '', # 打手头像
'nicheng': item['nicheng'] or '未知用户', # 打手昵称
'fenhong': str(item['fenhong']), # 分红金额
'create_time': item['create_time'].strftime('%Y-%m-%d %H:%M:%S') if item['create_time'] else ''
'CreateTime': item['CreateTime'].strftime('%Y-%m-%d %H:%M:%S') if item['CreateTime'] else ''
})
# 返回数据
@@ -3904,7 +3904,7 @@ class AdHuiyuanHqView(APIView):
# === 2. 查询会员表数据 ===
# 查询所有会员数据,按创建时间倒序排列
huiyuan_queryset = Huiyuan.query.all().order_by('-create_time')
huiyuan_queryset = Huiyuan.query.all().order_by('-CreateTime')
# 构建会员数据列表
huiyuan_list = []
@@ -3916,9 +3916,9 @@ class AdHuiyuanHqView(APIView):
'jiage': str(huiyuan.jiage), # 会员价格(转换为字符串,避免Decimal序列化问题)
'guanshifc': str(huiyuan.guanshifc), # 管事分成(转换为字符串)
'goumai_cishu': huiyuan.goumai_cishu, # 购买次数(销量)
'create_time': huiyuan.create_time.strftime('%Y-%m-%d %H:%M:%S') if huiyuan.create_time else None,
'CreateTime': huiyuan.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if huiyuan.CreateTime else None,
# 创建时间
'update_time': huiyuan.update_time.strftime('%Y-%m-%d %H:%M:%S') if huiyuan.update_time else None
'UpdateTime': huiyuan.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if huiyuan.UpdateTime else None
# 更新时间
}
huiyuan_list.append(huiyuan_data)
@@ -4112,10 +4112,10 @@ class HuiyuanXiugaiView(APIView):
'jiage': str(huiyuan_obj.jiage),
'guanshifc': str(huiyuan_obj.guanshifc),
'goumai_cishu': huiyuan_obj.goumai_cishu,
'create_time': huiyuan_obj.create_time.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.create_time else None,
'update_time': huiyuan_obj.update_time.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.update_time else None
'CreateTime': huiyuan_obj.CreateTime.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.CreateTime else None,
'UpdateTime': huiyuan_obj.UpdateTime.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.UpdateTime else None
}
# 返回成功响应
@@ -4292,10 +4292,10 @@ class AdHuiyuanFbView(APIView):
'jiage': str(huiyuan_obj.jiage),
'guanshifc': str(huiyuan_obj.guanshifc),
'goumai_cishu': huiyuan_obj.goumai_cishu,
'create_time': huiyuan_obj.create_time.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.create_time else None,
'update_time': huiyuan_obj.update_time.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.update_time else None
'CreateTime': huiyuan_obj.CreateTime.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.CreateTime else None,
'UpdateTime': huiyuan_obj.UpdateTime.strftime(
'%Y-%m-%d %H:%M:%S') if huiyuan_obj.UpdateTime else None
}
# 返回成功响应
@@ -5110,10 +5110,10 @@ class AdShangpinNeiRongHuoQu(APIView):
'guizetupian_url': shangpin_obj.guize_tupian or '', # 规则图片相对URL
'yajin': str(shangpin_obj.yajin) if hasattr(shangpin_obj, 'yajin') and shangpin_obj.yajin else None,
# 押金(可能不存在)
'chuangjianshijian': shangpin_obj.create_time.strftime(
'%Y-%m-%d %H:%M:%S') if shangpin_obj.create_time else '',
'genggaishijian': shangpin_obj.update_time.strftime(
'%Y-%m-%d %H:%M:%S') if shangpin_obj.update_time else '',
'chuangjianshijian': shangpin_obj.CreateTime.strftime(
'%Y-%m-%d %H:%M:%S') if shangpin_obj.CreateTime else '',
'genggaishijian': shangpin_obj.UpdateTime.strftime(
'%Y-%m-%d %H:%M:%S') if shangpin_obj.UpdateTime else '',
# 额外字段,前端可能不需要但可以保留
'leixing_id': shangpin_obj.leixing_id,
'zhuanqu_id': shangpin_obj.zhuanqu_id,
@@ -5381,8 +5381,8 @@ class AdShangpinXiuGai(APIView):
'duiwaixiaoliang': shangpin_obj.duiwai_xiaoliang,
'xiadanxuzhi': shangpin_obj.xiadan_xuzhi or '',
'yajin': str(shangpin_obj.yongjin) if shangpin_obj.yongjin else None,
'genggaishijian': shangpin_obj.update_time.strftime(
'%Y-%m-%d %H:%M:%S') if shangpin_obj.update_time else '',
'genggaishijian': shangpin_obj.UpdateTime.strftime(
'%Y-%m-%d %H:%M:%S') if shangpin_obj.UpdateTime else '',
}
return Response({
@@ -5589,7 +5589,7 @@ class HuiyuanTypeListView(APIView):
}, status=status.HTTP_401_UNAUTHORIZED)
# 🔥 2. 获取所有会员类型
huiyuan_list = Huiyuan.query.all().order_by('create_time')
huiyuan_list = Huiyuan.query.all().order_by('CreateTime')
# 🔥 3. 构建返回数据
huiyuan_data = []
@@ -5599,7 +5599,7 @@ class HuiyuanTypeListView(APIView):
'jieshao': huiyuan.jieshao, # 会员介绍
'jiage': str(huiyuan.jiage), # 价格
'goumai_cishu': huiyuan.goumai_cishu, # 购买次数
'create_time': huiyuan.create_time.strftime('%Y-%m-%d %H:%M:%S') if huiyuan.create_time else None
'CreateTime': huiyuan.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if huiyuan.CreateTime else None
})
return Response({
@@ -5710,7 +5710,7 @@ class HuiyuanRecordListView(APIView):
hg.huiyuan_id,
hg.jieshao,
hg.daoqi_time,
hg.create_time,
hg.CreateTime,
um.avatar,
ud.nicheng
FROM huiyuangoumai hg
@@ -5728,7 +5728,7 @@ class HuiyuanRecordListView(APIView):
record_sql += " AND hg.daoqi_time <= %s"
record_params.append(now)
record_sql += " ORDER BY hg.create_time DESC LIMIT %s OFFSET %s"
record_sql += " ORDER BY hg.CreateTime DESC LIMIT %s OFFSET %s"
record_params.extend([pagesize, offset])
cursor.execute(record_sql, record_params)
@@ -5743,7 +5743,7 @@ class HuiyuanRecordListView(APIView):
'huiyuan_id': record[2],
'jieshao': record[3],
'daoqi_time': record[4].strftime('%Y-%m-%d %H:%M:%S') if record[4] else None,
'create_time': record[5].strftime('%Y-%m-%d %H:%M:%S') if record[5] else None,
'CreateTime': record[5].strftime('%Y-%m-%d %H:%M:%S') if record[5] else None,
'touxiang': record[6], # 头像相对URL
'nicheng': record[7] or record[1], # 昵称或用户ID
'yonghu_type': 2 # 🔥 默认打手类型(实际应该根据user_type判断)
@@ -5874,7 +5874,7 @@ class ZuzhangFenhongView(APIView):
yaoqing_guanshi = UserGuanshi.query.filter(yaoqingren=current_user.UserUID).count()
# 3.3 分红次数(总记录数)
base_queryset = Gsfenhong.query.filter(zuzhang_id=current_user.UserUID).order_by('-create_time')
base_queryset = Gsfenhong.query.filter(zuzhang_id=current_user.UserUID).order_by('-CreateTime')
fenhong_cishu = base_queryset.count()
# 4. 分页查询
@@ -5907,7 +5907,7 @@ class ZuzhangFenhongView(APIView):
fenhong_str = str(fenhong.quantize(decimal.Decimal('0.00')))
# 时间格式化
create_time = rec.create_time.strftime('%Y-%m-%d %H:%M:%S') if rec.create_time else ''
CreateTime = rec.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if rec.CreateTime else ''
list_data.append({
'dashou_avatar': dashou_avatar,
@@ -5917,7 +5917,7 @@ class ZuzhangFenhongView(APIView):
'guanshi_nicheng': guanshi_nicheng,
'guanshi_yonghuid': guanshi_id,
'fenhong': fenhong_str,
'create_time': create_time,
'CreateTime': CreateTime,
})
# 7. 是否有更多数据
+12 -12
View File
@@ -20,7 +20,7 @@ class Migration(migrations.Migration):
fields=[
('bankuai_id', models.AutoField(primary_key=True, serialize=False, verbose_name='板块ID')),
('mingcheng', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='板块名称')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
],
options={
'verbose_name': '板块',
@@ -36,7 +36,7 @@ class Migration(migrations.Migration):
('leixing', models.CharField(choices=[('dashou', '打手'), ('boss', '老板'), ('shangjia', '商家'), ('guanshi', '管事'), ('zuzhang', '组长')], max_length=10, verbose_name='称号类型')),
('tubiao_url', models.CharField(blank=True, max_length=200, null=True, verbose_name='称号图标相对URL')),
('texiao_miaoshu', models.TextField(blank=True, null=True, verbose_name='特效描述(JSON)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('kaohe_guize', models.TextField(blank=True, null=True, verbose_name='考核规则')),
('kaioi_jinpai', models.BooleanField(default=False, verbose_name='是否同时开启金牌')),
('bankuai', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块(空=全板块通用)')),
@@ -61,7 +61,7 @@ class Migration(migrations.Migration):
('shenheguan_id', models.CharField(blank=True, max_length=7, verbose_name='指定考核官ID')),
('cishu', models.IntegerField(verbose_name='本次考核次数(预计算)')),
('fee', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='本次费用(分账单位)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
],
options={
'verbose_name': '考核支付临时表',
@@ -78,8 +78,8 @@ class Migration(migrations.Migration):
('zhuangtai', models.IntegerField(choices=[(0, '审核中'), (1, '通过'), (2, '未通过'), (3, '待审核')], default=0, verbose_name='审核状态')),
('cishu', models.IntegerField(default=1, verbose_name='第几次审核')),
('jiaofei_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='缴纳费用')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('jilu_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='记录ID')),
('guize_neirong', models.TextField(blank=True, null=True, verbose_name='规则内容')),
('shenheguan_youxi_id', models.CharField(blank=True, max_length=50, null=True, verbose_name='审核官游戏ID')),
@@ -101,7 +101,7 @@ class Migration(migrations.Migration):
('cishu', models.IntegerField(verbose_name='对应次数')),
('shenheguan_id', models.CharField(max_length=7, verbose_name='考核官用户ID')),
('yuanyin', models.TextField(verbose_name='拒绝原因')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('jilu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.shenhejilu', to_field='jilu_id', verbose_name='审核记录')),
],
options={
@@ -162,8 +162,8 @@ class Migration(migrations.Migration):
('taidu_jingyan', models.DecimalField(decimal_places=2, default=0, max_digits=8, verbose_name='服务态度经验')),
('zonghe_jingyan', models.DecimalField(decimal_places=2, default=0, max_digits=8, verbose_name='综合经验')),
('dingdan_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='关联订单ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('bankuai', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块')),
],
options={
@@ -176,7 +176,7 @@ class Migration(migrations.Migration):
name='DingdanBiaoqian',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('chenghao', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.chenghao', verbose_name='标签')),
('dingdan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='orders.dingdan', to_field='dingdan_id', verbose_name='订单')),
],
@@ -194,7 +194,7 @@ class Migration(migrations.Migration):
('shangxian_sudu', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='上线速度评价(1-5)')),
('fuwu_taidu', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='服务态度评价(1-5)')),
('fanche_cishu', models.PositiveIntegerField(blank=True, null=True, verbose_name='翻车次数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('jiedan_time', models.DateTimeField(blank=True, null=True, verbose_name='接单时间')),
('tijiao_time', models.DateTimeField(blank=True, null=True, verbose_name='提交时间')),
('bankuai', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块')),
@@ -256,7 +256,7 @@ class Migration(migrations.Migration):
),
migrations.AddIndex(
model_name='jingyanjilu',
index=models.Index(fields=['yonghu_id', 'bankuai', 'create_time'], name='jingyan_jil_yonghu__786992_idx'),
index=models.Index(fields=['yonghu_id', 'bankuai', 'CreateTime'], name='jingyan_jil_yonghu__786992_idx'),
),
migrations.AddIndex(
model_name='dingdanbiaoqian',
@@ -268,7 +268,7 @@ class Migration(migrations.Migration):
),
migrations.AddIndex(
model_name='dashoubiaoxian',
index=models.Index(fields=['dashou_id', 'bankuai', 'create_time'], name='dashou_biao_dashou__36e1c3_idx'),
index=models.Index(fields=['dashou_id', 'bankuai', 'CreateTime'], name='dashou_biao_dashou__36e1c3_idx'),
),
migrations.AddIndex(
model_name='chenghao',
@@ -0,0 +1,23 @@
# Generated by Django 4.2.27 on 2026-06-19 19:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('rank', '0002_alter_dashoubiaoxian_dingdan_and_more'),
]
operations = [
migrations.RenameIndex(
model_name='dashoubiaoxian',
new_name='dashou_biao_dashou__502414_idx',
old_name='dashou_biao_dashou__36e1c3_idx',
),
migrations.RenameIndex(
model_name='jingyanjilu',
new_name='jingyan_jil_yonghu__51d881_idx',
old_name='jingyan_jil_yonghu__786992_idx',
),
]
+223 -223
View File
@@ -1,224 +1,224 @@
from django.db import models
from gvsdsdk.model_base import QModel
from django.conf import settings
from orders.models import Order
# ==================== 板块表 ====================
class Bankuai(QModel):
bankuai_id = models.AutoField(primary_key=True, verbose_name='板块ID')
mingcheng = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='板块名称')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'bankuai'
verbose_name = '板块'
verbose_name_plural = verbose_name
def __str__(self):
return self.mingcheng
# ==================== 打手订单表现记录 ====================
class DashouBiaoxian(QModel):
dingdan = models.ForeignKey('orders.Order', to_field='OrderID', on_delete=models.CASCADE, related_name='biaoxian', verbose_name='关联订单', db_index=True)
dashou_id = models.CharField(max_length=32, db_index=True, verbose_name='打手ID')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', verbose_name='所属板块', db_index=True,null=True)
shangxian_sudu = models.PositiveSmallIntegerField(null=True, blank=True, verbose_name='上线速度评价(1-5)')
fuwu_taidu = models.PositiveSmallIntegerField(null=True, blank=True, verbose_name='服务态度评价(1-5)')
fanche_cishu = models.PositiveIntegerField(null=True, blank=True, verbose_name='翻车次数')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
jiedan_time = models.DateTimeField(null=True, blank=True, verbose_name='接单时间')
tijiao_time = models.DateTimeField(null=True, blank=True, verbose_name='提交时间')
class Meta:
db_table = 'dashou_biaoxian'
verbose_name = '打手订单表现'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['dashou_id', 'bankuai', 'create_time'])]
# ==================== 经验变动记录 ====================
class JingyanJilu(QModel):
yonghu_id = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
yonghu_leixing = models.CharField(max_length=10, choices=[('dashou','打手'),('boss','老板'),('shangjia','商家'),('guanshi','管事'),('zuzhang','组长')], verbose_name='用户类型')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', verbose_name='所属板块', db_index=True)
sudu_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='上线速度经验')
shili_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='打手实力经验')
taidu_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='服务态度经验')
zonghe_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='综合经验')
dingdan_id = models.CharField(max_length=32, null=True, blank=True, db_index=True, verbose_name='关联订单ID')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'jingyan_jilu'
verbose_name = '经验变动记录'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['yonghu_id', 'bankuai', 'create_time'])]
# ==================== 称号主表 ====================
class Chenghao(QModel):
mingcheng = models.CharField(max_length=50, unique=True, verbose_name='称号名称')
leixing = models.CharField(max_length=10, choices=[('dashou','打手'),('boss','老板'),('shangjia','商家'),('guanshi','管事'),('zuzhang','组长')], verbose_name='称号类型')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', null=True, blank=True, verbose_name='所属板块(空=全板块通用)')
tubiao_url = models.CharField(max_length=200, null=True, blank=True, verbose_name='称号图标相对URL')
texiao_miaoshu = models.TextField(null=True, blank=True, verbose_name='特效描述(JSON)')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
kaohe_guize = models.TextField(null=True, blank=True, verbose_name='考核规则') # 新增
kaioi_jinpai = models.BooleanField(default=False, verbose_name='是否同时开启金牌')
class Meta:
db_table = 'chenghao'
verbose_name = '称号'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['leixing', 'bankuai'])]
# ==================== 用户 - 称号关联 ====================
class YonghuChenghao(QModel):
yonghu = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chenghao_list', verbose_name='用户', db_index=True)
chenghao = models.ForeignKey(Chenghao, on_delete=models.CASCADE, verbose_name='称号')
huode_time = models.DateTimeField(auto_now_add=True, verbose_name='获得时间')
class Meta:
db_table = 'yonghu_chenghao'
verbose_name = '用户称号关联'
verbose_name_plural = verbose_name
unique_together = ('yonghu', 'chenghao')
# 修复:只索引本表字段
indexes = [models.Index(fields=['yonghu', 'chenghao'])]
class DingdanBiaoqian(QModel):
"""订单需求标签关联表"""
dingdan = models.ForeignKey(
Order,
to_field='OrderID', # 关联到字符串字段 OrderID
on_delete=models.CASCADE,
verbose_name='订单',
db_index=True
)
chenghao = models.ForeignKey('rank.Chenghao', on_delete=models.CASCADE, verbose_name='标签')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'dingdan_biaoqian'
verbose_name = '订单需求标签'
verbose_name_plural = verbose_name
unique_together = ('dingdan', 'chenghao')
indexes = [models.Index(fields=['dingdan'])]
class ShenheJilu(QModel):
"""审核记录表"""
shenqingren_id = models.CharField(max_length=7, verbose_name='申请人用户ID')
shenheguan_id = models.CharField(max_length=7, null = True,verbose_name='审核官用户ID')
zhuangtai = models.IntegerField(choices=[(0, '审核中'), (1, '通过'), (2, '未通过'), (3, '待审核')], default=0, verbose_name='审核状态')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', null=True, blank=True, verbose_name='审核板块')
chenghao = models.ForeignKey(Chenghao, on_delete=models.PROTECT, null=True, blank=True, verbose_name='审核标签')
cishu = models.IntegerField(default=1, verbose_name='第几次审核')
jiaofei_jine = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='缴纳费用')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
jilu_id = models.CharField(max_length=32, unique=True, db_index=True, verbose_name='记录ID') # 新增
guize_neirong = models.TextField(null=True, blank=True, verbose_name='规则内容')
shenheguan_youxi_id = models.CharField(max_length=50, null=True, blank=True, verbose_name='审核官游戏ID')
dashou_youxi_id = models.CharField(max_length=50, null=True, blank=True, verbose_name='打手游戏ID')
dashou_beizhu = models.TextField(null=True, blank=True, verbose_name='打手备注')
class Meta:
db_table = 'shenhe_jilu'
verbose_name = '审核记录'
verbose_name_plural = verbose_name
indexes = [
models.Index(fields=['shenqingren_id', 'zhuangtai']),
models.Index(fields=['shenheguan_id']),
]
class KaohePayTemp(QModel):
"""考核支付临时上下文(仅用于支付成功后回调取参,不删除数据)"""
dingdan_id = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='订单ID')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
tag_id = models.IntegerField(verbose_name='标签ID')
game_nick = models.CharField(max_length=100, verbose_name='游戏昵称')
remark = models.TextField(blank=True, verbose_name='备注')
reapply = models.BooleanField(default=False, verbose_name='是否再次申请')
jilu_id = models.CharField(max_length=32, null=True, blank=True, verbose_name='原记录ID(再次申请时)')
shenheguan_id = models.CharField(max_length=7, blank=True, verbose_name='指定考核官ID')
cishu = models.IntegerField(verbose_name='本次考核次数(预计算)')
fee = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='本次费用(分账单位)')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'kaohe_pay_temp'
verbose_name = '考核支付临时表'
verbose_name_plural = verbose_name
class KaoheCishuFeiyong(QModel):
"""各标签各考核次数所需缴纳金额"""
chenghao = models.ForeignKey(Chenghao, on_delete=models.CASCADE, verbose_name='标签')
cishu = models.IntegerField(verbose_name='第几次考核')
feiyong = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='需缴纳金额')
class Meta:
db_table = 'kaohe_cishu_feiyong'
verbose_name = '考核次数费用'
verbose_name_plural = verbose_name
unique_together = ('chenghao', 'cishu')
indexes = [models.Index(fields=['chenghao', 'cishu'])]
class KaoheJujueJilu(QModel):
"""考核拒绝原因记录"""
jilu = models.ForeignKey(ShenheJilu, on_delete=models.CASCADE, to_field='jilu_id', verbose_name='审核记录')
cishu = models.IntegerField(verbose_name='对应次数')
shenheguan_id = models.CharField(max_length=7, verbose_name='考核官用户ID')
yuanyin = models.TextField(verbose_name='拒绝原因')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'kaohe_jujue_jilu'
verbose_name = '拒绝原因记录'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['jilu_id', 'cishu'])]
class KaoheJiluFeiyong(QModel):
"""每次考核记录实际缴纳的费用明细"""
jilu = models.ForeignKey(ShenheJilu, on_delete=models.CASCADE, to_field='jilu_id', verbose_name='考核记录')
cishu = models.IntegerField(verbose_name='第几次考核')
jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='缴纳金额')
class Meta:
db_table = 'kaohe_jilu_feiyong'
verbose_name = '考核记录费用'
verbose_name_plural = verbose_name
unique_together = ('jilu', 'cishu')
class KaoheguanBankuai(QModel):
"""考核官与板块多对多关联表"""
kaoheguan_id = models.CharField(max_length=7, db_index=True, verbose_name='考核官用户ID')
bankuai = models.ForeignKey(Bankuai, on_delete=models.CASCADE, to_field='bankuai_id', verbose_name='所属板块')
class Meta:
db_table = 'kaoheguan_bankuai'
verbose_name = '考核官板块关联'
verbose_name_plural = verbose_name
unique_together = ('kaoheguan_id', 'bankuai')
from django.db import models
from gvsdsdk.model_base import QModel
from django.conf import settings
from orders.models import Order
# ==================== 板块表 ====================
class Bankuai(QModel):
bankuai_id = models.AutoField(primary_key=True, verbose_name='板块ID')
mingcheng = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='板块名称')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'bankuai'
verbose_name = '板块'
verbose_name_plural = verbose_name
def __str__(self):
return self.mingcheng
# ==================== 打手订单表现记录 ====================
class DashouBiaoxian(QModel):
dingdan = models.ForeignKey('orders.Order', to_field='OrderID', on_delete=models.CASCADE, related_name='biaoxian', verbose_name='关联订单', db_index=True)
dashou_id = models.CharField(max_length=32, db_index=True, verbose_name='打手ID')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', verbose_name='所属板块', db_index=True,null=True)
shangxian_sudu = models.PositiveSmallIntegerField(null=True, blank=True, verbose_name='上线速度评价(1-5)')
fuwu_taidu = models.PositiveSmallIntegerField(null=True, blank=True, verbose_name='服务态度评价(1-5)')
fanche_cishu = models.PositiveIntegerField(null=True, blank=True, verbose_name='翻车次数')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
jiedan_time = models.DateTimeField(null=True, blank=True, verbose_name='接单时间')
tijiao_time = models.DateTimeField(null=True, blank=True, verbose_name='提交时间')
class Meta:
db_table = 'dashou_biaoxian'
verbose_name = '打手订单表现'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['dashou_id', 'bankuai', 'CreateTime'])]
# ==================== 经验变动记录 ====================
class JingyanJilu(QModel):
yonghu_id = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
yonghu_leixing = models.CharField(max_length=10, choices=[('dashou','打手'),('boss','老板'),('shangjia','商家'),('guanshi','管事'),('zuzhang','组长')], verbose_name='用户类型')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', verbose_name='所属板块', db_index=True)
sudu_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='上线速度经验')
shili_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='打手实力经验')
taidu_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='服务态度经验')
zonghe_jingyan = models.DecimalField(max_digits=8, decimal_places=2, default=0, verbose_name='综合经验')
dingdan_id = models.CharField(max_length=32, null=True, blank=True, db_index=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 = 'jingyan_jilu'
verbose_name = '经验变动记录'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['yonghu_id', 'bankuai', 'CreateTime'])]
# ==================== 称号主表 ====================
class Chenghao(QModel):
mingcheng = models.CharField(max_length=50, unique=True, verbose_name='称号名称')
leixing = models.CharField(max_length=10, choices=[('dashou','打手'),('boss','老板'),('shangjia','商家'),('guanshi','管事'),('zuzhang','组长')], verbose_name='称号类型')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', null=True, blank=True, verbose_name='所属板块(空=全板块通用)')
tubiao_url = models.CharField(max_length=200, null=True, blank=True, verbose_name='称号图标相对URL')
texiao_miaoshu = models.TextField(null=True, blank=True, verbose_name='特效描述(JSON)')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
kaohe_guize = models.TextField(null=True, blank=True, verbose_name='考核规则') # 新增
kaioi_jinpai = models.BooleanField(default=False, verbose_name='是否同时开启金牌')
class Meta:
db_table = 'chenghao'
verbose_name = '称号'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['leixing', 'bankuai'])]
# ==================== 用户 - 称号关联 ====================
class YonghuChenghao(QModel):
yonghu = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chenghao_list', verbose_name='用户', db_index=True)
chenghao = models.ForeignKey(Chenghao, on_delete=models.CASCADE, verbose_name='称号')
huode_time = models.DateTimeField(auto_now_add=True, verbose_name='获得时间')
class Meta:
db_table = 'yonghu_chenghao'
verbose_name = '用户称号关联'
verbose_name_plural = verbose_name
unique_together = ('yonghu', 'chenghao')
# 修复:只索引本表字段
indexes = [models.Index(fields=['yonghu', 'chenghao'])]
class DingdanBiaoqian(QModel):
"""订单需求标签关联表"""
dingdan = models.ForeignKey(
Order,
to_field='OrderID', # 关联到字符串字段 OrderID
on_delete=models.CASCADE,
verbose_name='订单',
db_index=True
)
chenghao = models.ForeignKey('rank.Chenghao', on_delete=models.CASCADE, verbose_name='标签')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'dingdan_biaoqian'
verbose_name = '订单需求标签'
verbose_name_plural = verbose_name
unique_together = ('dingdan', 'chenghao')
indexes = [models.Index(fields=['dingdan'])]
class ShenheJilu(QModel):
"""审核记录表"""
shenqingren_id = models.CharField(max_length=7, verbose_name='申请人用户ID')
shenheguan_id = models.CharField(max_length=7, null = True,verbose_name='审核官用户ID')
zhuangtai = models.IntegerField(choices=[(0, '审核中'), (1, '通过'), (2, '未通过'), (3, '待审核')], default=0, verbose_name='审核状态')
bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', null=True, blank=True, verbose_name='审核板块')
chenghao = models.ForeignKey(Chenghao, on_delete=models.PROTECT, null=True, blank=True, verbose_name='审核标签')
cishu = models.IntegerField(default=1, verbose_name='第几次审核')
jiaofei_jine = 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='更新时间')
jilu_id = models.CharField(max_length=32, unique=True, db_index=True, verbose_name='记录ID') # 新增
guize_neirong = models.TextField(null=True, blank=True, verbose_name='规则内容')
shenheguan_youxi_id = models.CharField(max_length=50, null=True, blank=True, verbose_name='审核官游戏ID')
dashou_youxi_id = models.CharField(max_length=50, null=True, blank=True, verbose_name='打手游戏ID')
dashou_beizhu = models.TextField(null=True, blank=True, verbose_name='打手备注')
class Meta:
db_table = 'shenhe_jilu'
verbose_name = '审核记录'
verbose_name_plural = verbose_name
indexes = [
models.Index(fields=['shenqingren_id', 'zhuangtai']),
models.Index(fields=['shenheguan_id']),
]
class KaohePayTemp(QModel):
"""考核支付临时上下文(仅用于支付成功后回调取参,不删除数据)"""
dingdan_id = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='订单ID')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
tag_id = models.IntegerField(verbose_name='标签ID')
game_nick = models.CharField(max_length=100, verbose_name='游戏昵称')
remark = models.TextField(blank=True, verbose_name='备注')
reapply = models.BooleanField(default=False, verbose_name='是否再次申请')
jilu_id = models.CharField(max_length=32, null=True, blank=True, verbose_name='原记录ID(再次申请时)')
shenheguan_id = models.CharField(max_length=7, blank=True, verbose_name='指定考核官ID')
cishu = models.IntegerField(verbose_name='本次考核次数(预计算)')
fee = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='本次费用(分账单位)')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'kaohe_pay_temp'
verbose_name = '考核支付临时表'
verbose_name_plural = verbose_name
class KaoheCishuFeiyong(QModel):
"""各标签各考核次数所需缴纳金额"""
chenghao = models.ForeignKey(Chenghao, on_delete=models.CASCADE, verbose_name='标签')
cishu = models.IntegerField(verbose_name='第几次考核')
feiyong = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='需缴纳金额')
class Meta:
db_table = 'kaohe_cishu_feiyong'
verbose_name = '考核次数费用'
verbose_name_plural = verbose_name
unique_together = ('chenghao', 'cishu')
indexes = [models.Index(fields=['chenghao', 'cishu'])]
class KaoheJujueJilu(QModel):
"""考核拒绝原因记录"""
jilu = models.ForeignKey(ShenheJilu, on_delete=models.CASCADE, to_field='jilu_id', verbose_name='审核记录')
cishu = models.IntegerField(verbose_name='对应次数')
shenheguan_id = models.CharField(max_length=7, verbose_name='考核官用户ID')
yuanyin = models.TextField(verbose_name='拒绝原因')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'kaohe_jujue_jilu'
verbose_name = '拒绝原因记录'
verbose_name_plural = verbose_name
indexes = [models.Index(fields=['jilu_id', 'cishu'])]
class KaoheJiluFeiyong(QModel):
"""每次考核记录实际缴纳的费用明细"""
jilu = models.ForeignKey(ShenheJilu, on_delete=models.CASCADE, to_field='jilu_id', verbose_name='考核记录')
cishu = models.IntegerField(verbose_name='第几次考核')
jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='缴纳金额')
class Meta:
db_table = 'kaohe_jilu_feiyong'
verbose_name = '考核记录费用'
verbose_name_plural = verbose_name
unique_together = ('jilu', 'cishu')
class KaoheguanBankuai(QModel):
"""考核官与板块多对多关联表"""
kaoheguan_id = models.CharField(max_length=7, db_index=True, verbose_name='考核官用户ID')
bankuai = models.ForeignKey(Bankuai, on_delete=models.CASCADE, to_field='bankuai_id', verbose_name='所属板块')
class Meta:
db_table = 'kaoheguan_bankuai'
verbose_name = '考核官板块关联'
verbose_name_plural = verbose_name
unique_together = ('kaoheguan_id', 'bankuai')
indexes = [models.Index(fields=['kaoheguan_id'])]
+11 -11
View File
@@ -244,7 +244,7 @@ class ShenheDatingDataView(APIView):
total = query.count()
offset = (page - 1) * page_size
jilu_list = query.select_related('bankuai', 'chenghao').order_by('-create_time')[
jilu_list = query.select_related('bankuai', 'chenghao').order_by('-CreateTime')[
offset:offset + page_size]
records = []
@@ -274,7 +274,7 @@ class ShenheDatingDataView(APIView):
'chenghao_texiao_json': texiao_json,
'guize_neirong': jl.guize_neirong or '',
'kaohe_feiyong': kaohe_feiyong, # 新增
'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S') if jl.create_time else '',
'CreateTime': jl.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if jl.CreateTime else '',
})
has_more = (page * page_size) < total
@@ -416,7 +416,7 @@ class ShenheXiangqingView(APIView):
last_fail = KaoheJujueJilu.objects.filter(
jilu=jl,
cishu=jl.cishu - 1
).order_by('-create_time').first()
).order_by('-CreateTime').first()
if last_fail:
last_fail_reason = last_fail.yuanyin
@@ -435,7 +435,7 @@ class ShenheXiangqingView(APIView):
'daishou_fei': daishou_fei, # 新增:待收考核费
'last_fail_reason': last_fail_reason,
'is_jinpai': is_jinpai,
'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S') if jl.create_time else '',
'CreateTime': jl.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if jl.CreateTime else '',
})
has_more = (page * page_size) < total
@@ -685,7 +685,7 @@ class KaoheJiluView(APIView):
)
total = query.count()
records = query.order_by('-create_time')[(page-1)*page_size : page*page_size]
records = query.order_by('-CreateTime')[(page-1)*page_size : page*page_size]
data = []
for jl in records:
@@ -695,7 +695,7 @@ class KaoheJiluView(APIView):
)['total'] or 0.00
# 上次拒绝原因(最近一条)
last_fail = KaoheJujueJilu.objects.filter(jilu=jl).order_by('-create_time').first()
last_fail = KaoheJujueJilu.objects.filter(jilu=jl).order_by('-CreateTime').first()
fail_reason = last_fail.yuanyin if last_fail else ''
# 考核官头像
@@ -716,7 +716,7 @@ class KaoheJiluView(APIView):
'cishu': jl.cishu,
'total_fee': float(total_fee),
'last_fail_reason': fail_reason,
'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S'),
'CreateTime': jl.CreateTime.strftime('%Y-%m-%d %H:%M:%S'),
# 为再次申请预留标签对象数据(前端可能用到)
'tag_obj': {
'id': jl.chenghao_id,
@@ -849,7 +849,7 @@ class KaoheJiluListView(APIView):
# 4. 计数与分页
total = base_query.count()
offset = (page - 1) * page_size
jilu_list = base_query.order_by('-create_time')[offset:offset + page_size]
jilu_list = base_query.order_by('-CreateTime')[offset:offset + page_size]
# 5. 预取关联数据,减少查询次数
jilu_list = jilu_list.select_related('bankuai', 'chenghao')
@@ -875,7 +875,7 @@ class KaoheJiluListView(APIView):
reject_dict[rej.jilu_id].append({
'cishu': rej.cishu,
'yuanyin': rej.yuanyin,
'create_time': rej.create_time.strftime('%Y-%m-%d %H:%M:%S') if rej.create_time else ''
'CreateTime': rej.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if rej.CreateTime else ''
})
# 6. 批量获取申请人信息(昵称和头像)
@@ -927,8 +927,8 @@ class KaoheJiluListView(APIView):
'dashou_beizhu': jl.dashou_beizhu or '',
'shenheguan_youxi_id': jl.shenheguan_youxi_id or '',
'guize_neirong': jl.guize_neirong or '',
'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S') if jl.create_time else '',
'update_time': jl.update_time.strftime('%Y-%m-%d %H:%M:%S') if jl.update_time else '',
'CreateTime': jl.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if jl.CreateTime else '',
'UpdateTime': jl.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if jl.UpdateTime else '',
'fee_list': fee_items,
'reject_list': reject_dict.get(jl.jilu_id, []),
})
+122 -122
View File
@@ -1,122 +1,122 @@
import os
import re
ROOT_DIR = r"d:\ALONGF\Django"
EXCLUDE_DIRS = {"migrations", "__pycache__", ".git", "node_modules", ".venv", "idea"}
EXCLUDE_FILES = {"migrate_to_gvsdsdk_user.py", "rp.py", "refactor_replace.py"}
SAFE_REPLACEMENTS = {
"shoujihao_renzheng": "PhoneVerified",
"last_login_time": "UserLastLoginDate",
"openid": "OpenID",
"user_type": "UserType",
"dashou_profile": "DashouProfile",
"shop_profile": "ShopProfile",
"guanshi_profile": "GuanshiProfile",
"boss_profile": "BossProfile",
"admin_profile": "AdminProfile",
"kefu_profile": "KefuProfile",
"zuzhang_profile": "ZuzhangProfile",
"shenheguan_profile": "ShenheguanProfile",
"has_role": "HasRole",
}
UNSAFE_REPLACEMENTS = {
"yonghuid": "UserUID",
"avatar": "Avatar",
"phone": "Phone",
"ip": "IP",
"create_time": "UserCreateTime",
"zhifu": "PaymentQRCode",
"skzhanghao": "PaymentAccount",
}
NON_USER_VARS = {
"record", "tixian_record", "tixian", "audit",
"item", "items",
"shangjia", "product", "guanshi", "zuzhang",
"bk", "ch", "sg", "p", "m",
"huiyuan", "huiyuan_obj", "shangbin_obj", "shangpin_obj",
"moban", "link", "dingdan_obj",
"jl", "rej", "dianpu", "shop",
"r", "rec", "chufa", "auto_record",
"um", "hg", "xjl", "Dingdan",
"obj", "tixian_obj",
"sensitive_data", "self",
"boss_profile", "dashou_profile", "guanshi_profile", "shop_profile",
"kefu_profile", "admin_profile", "zuzhang_profile", "shenheguan_profile",
"BossProfile", "DashouProfile", "GuanshiProfile", "ShopProfile",
"KefuProfile", "AdminProfile", "ZuzhangProfile", "ShenheguanProfile",
"shangjia_profile",
"dingdan", "order", "tixian_shenhe",
}
def should_skip_dir(dirpath):
for excl in EXCLUDE_DIRS:
if excl in dirpath:
return True
return False
def process_content(content):
# 1. Safe replacements: global .old -> .new
for old, new in SAFE_REPLACEMENTS.items():
pattern = r"\." + re.escape(old) + r"\b"
content = re.sub(pattern, "." + new, content)
# 2. Unsafe replacements: targeted, only on User instance variables
for old, new in UNSAFE_REPLACEMENTS.items():
def make_replacer(new_name):
def replacer(m):
var = m.group(1)
if var in NON_USER_VARS:
return m.group(0)
return var + "." + new_name
return replacer
pattern = r"(?<!\w)(\w+)\." + re.escape(old) + r"\b"
content = re.sub(pattern, make_replacer(new), content)
# 3. hasattr string replacements
all_replacements = {**SAFE_REPLACEMENTS, **UNSAFE_REPLACEMENTS}
for old, new in all_replacements.items():
def make_hasattr_replacer(new_name, old_name):
def replacer(m):
var = m.group(1)
if old_name in UNSAFE_REPLACEMENTS and var in NON_USER_VARS:
return m.group(0)
return "hasattr(" + var + ", '" + new_name + "')"
return replacer
pattern = r"hasattr\((\w+),\s*['\"]" + re.escape(old) + r"['\"]\)"
content = re.sub(pattern, make_hasattr_replacer(new, old), content)
return content
def main():
total_mod = 0
for root, dirs, files in os.walk(ROOT_DIR):
if should_skip_dir(root):
continue
for fname in files:
if not fname.endswith(".py"):
continue
if fname in EXCLUDE_FILES:
continue
file_path = os.path.join(root, fname)
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
new_content = process_content(content)
if new_content != content:
with open(file_path, "w", encoding="utf-8") as f:
f.write(new_content)
print("modified: " + file_path)
total_mod += 1
except Exception as err:
print("error " + file_path + ": " + str(err))
print("\ndone, modified " + str(total_mod) + " files")
if __name__ == "__main__":
main()
import os
import re
ROOT_DIR = r"d:\ALONGF\Django"
EXCLUDE_DIRS = {"migrations", "__pycache__", ".git", "node_modules", ".venv", "idea"}
EXCLUDE_FILES = {"migrate_to_gvsdsdk_user.py", "rp.py", "refactor_replace.py"}
SAFE_REPLACEMENTS = {
"shoujihao_renzheng": "PhoneVerified",
"last_login_time": "UserLastLoginDate",
"openid": "OpenID",
"user_type": "UserType",
"dashou_profile": "DashouProfile",
"shop_profile": "ShopProfile",
"guanshi_profile": "GuanshiProfile",
"boss_profile": "BossProfile",
"admin_profile": "AdminProfile",
"kefu_profile": "KefuProfile",
"zuzhang_profile": "ZuzhangProfile",
"shenheguan_profile": "ShenheguanProfile",
"has_role": "HasRole",
}
UNSAFE_REPLACEMENTS = {
"yonghuid": "UserUID",
"avatar": "Avatar",
"phone": "Phone",
"ip": "IP",
"CreateTime": "UserCreateTime",
"zhifu": "PaymentQRCode",
"skzhanghao": "PaymentAccount",
}
NON_USER_VARS = {
"record", "tixian_record", "tixian", "audit",
"item", "items",
"shangjia", "product", "guanshi", "zuzhang",
"bk", "ch", "sg", "p", "m",
"huiyuan", "huiyuan_obj", "shangbin_obj", "shangpin_obj",
"moban", "link", "dingdan_obj",
"jl", "rej", "dianpu", "shop",
"r", "rec", "chufa", "auto_record",
"um", "hg", "xjl", "Dingdan",
"obj", "tixian_obj",
"sensitive_data", "self",
"boss_profile", "dashou_profile", "guanshi_profile", "shop_profile",
"kefu_profile", "admin_profile", "zuzhang_profile", "shenheguan_profile",
"BossProfile", "DashouProfile", "GuanshiProfile", "ShopProfile",
"KefuProfile", "AdminProfile", "ZuzhangProfile", "ShenheguanProfile",
"shangjia_profile",
"dingdan", "order", "tixian_shenhe",
}
def should_skip_dir(dirpath):
for excl in EXCLUDE_DIRS:
if excl in dirpath:
return True
return False
def process_content(content):
# 1. Safe replacements: global .old -> .new
for old, new in SAFE_REPLACEMENTS.items():
pattern = r"\." + re.escape(old) + r"\b"
content = re.sub(pattern, "." + new, content)
# 2. Unsafe replacements: targeted, only on User instance variables
for old, new in UNSAFE_REPLACEMENTS.items():
def make_replacer(new_name):
def replacer(m):
var = m.group(1)
if var in NON_USER_VARS:
return m.group(0)
return var + "." + new_name
return replacer
pattern = r"(?<!\w)(\w+)\." + re.escape(old) + r"\b"
content = re.sub(pattern, make_replacer(new), content)
# 3. hasattr string replacements
all_replacements = {**SAFE_REPLACEMENTS, **UNSAFE_REPLACEMENTS}
for old, new in all_replacements.items():
def make_hasattr_replacer(new_name, old_name):
def replacer(m):
var = m.group(1)
if old_name in UNSAFE_REPLACEMENTS and var in NON_USER_VARS:
return m.group(0)
return "hasattr(" + var + ", '" + new_name + "')"
return replacer
pattern = r"hasattr\((\w+),\s*['\"]" + re.escape(old) + r"['\"]\)"
content = re.sub(pattern, make_hasattr_replacer(new, old), content)
return content
def main():
total_mod = 0
for root, dirs, files in os.walk(ROOT_DIR):
if should_skip_dir(root):
continue
for fname in files:
if not fname.endswith(".py"):
continue
if fname in EXCLUDE_FILES:
continue
file_path = os.path.join(root, fname)
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
new_content = process_content(content)
if new_content != content:
with open(file_path, "w", encoding="utf-8") as f:
f.write(new_content)
print("modified: " + file_path)
total_mod += 1
except Exception as err:
print("error " + file_path + ": " + str(err))
print("\ndone, modified " + str(total_mod) + " files")
if __name__ == "__main__":
main()
+12 -12
View File
@@ -21,8 +21,8 @@ class Migration(migrations.Migration):
('id', models.PositiveSmallIntegerField(default=1, editable=False, primary_key=True, serialize=False)),
('moren_choucheng_feilv', models.DecimalField(decimal_places=4, default=0.1, max_digits=5, verbose_name='默认订单抽成费率(小数,0.1000=10%)')),
('moren_tixian_xiane', models.DecimalField(decimal_places=2, default=1000.0, max_digits=10, verbose_name='默认可提现限额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '店铺默认配置',
@@ -35,8 +35,8 @@ class Migration(migrations.Migration):
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('kaiqi_shenhe', models.BooleanField(default=False, verbose_name='是否开启商品审核模式')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '商品审核模式配置',
@@ -52,8 +52,8 @@ class Migration(migrations.Migration):
('zhanghao', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='登录账号')),
('mima', models.CharField(max_length=255, verbose_name='密码')),
('is_active', models.BooleanField(default=True, verbose_name='是否启用')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '用户认证凭证',
@@ -77,8 +77,8 @@ class Migration(migrations.Migration):
('tuikuan_zongliang', models.PositiveIntegerField(default=0, verbose_name='退款总量')),
('tuikuan_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='退款总额')),
('shouyi_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='收益总额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('shangji_fenhong_cishu', models.PositiveIntegerField(default=0, verbose_name='作为上级获得分红次数')),
('shangji_fenhong_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='作为上级获得分红总额')),
('shangji_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='当天对应的上级店铺ID(若无则为空)')),
@@ -104,8 +104,8 @@ class Migration(migrations.Migration):
('zhuangtai', models.IntegerField(choices=[(0, '封禁'), (1, '正常')], default=1, verbose_name='店铺状态')),
('bangding_yonghushu', models.PositiveIntegerField(default=0, verbose_name='绑定用户总数')),
('erweima_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='店铺二维码相对URL')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('kaiqi_shouyi_choucheng', models.BooleanField(default=False, verbose_name='是否开启店铺订单收益抽成')),
('shouyi_choucheng_feilv', models.DecimalField(blank=True, decimal_places=4, default=0.0, max_digits=5, null=True, verbose_name='店铺订单收益抽成费率(小数,如0.1000=10%)')),
('ketixian_yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='店铺可提现余额')),
@@ -128,8 +128,8 @@ class Migration(migrations.Migration):
name='YonghuDianpuBangding',
fields=[
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='绑定自增ID')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('dianpu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.dianpu', verbose_name='关联店铺ID')),
('yonghu', models.ForeignKey(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户ID')),
],
+224 -224
View File
@@ -1,224 +1,224 @@
from django.db import models
from gvsdsdk.model_base import QModel
class YonghuPingzheng(QModel):
id = models.AutoField(primary_key=True, verbose_name='自增主键ID')
yonghu = models.CharField(
max_length=7,
unique=True, # 确保一个用户只有一条凭证记录
db_index=True,
verbose_name='关联用户ID'
)
zhanghao = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='登录账号')
mima = models.CharField(max_length=255, verbose_name='密码')
is_active = models.BooleanField(default=True, verbose_name='是否启用')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'yonghu_pingzheng'
verbose_name = '用户认证凭证'
verbose_name_plural = verbose_name
class Dianpu(QModel):
id = models.AutoField(primary_key=True, verbose_name='店铺自增ID')
pingzheng = models.OneToOneField(
'shop.YonghuPingzheng', # 同应用内可简写,但完整路径更清晰
on_delete=models.CASCADE,
db_index=True,
verbose_name='关联用户凭证'
)
dianpu_mingcheng = models.CharField(max_length=50, verbose_name='店铺名称')
dianpu_touxiang = models.CharField(max_length=500, null=True, blank=True, verbose_name='店铺头像URL')
lianxi_dianhua = models.CharField(max_length=20, null=True, blank=True, verbose_name='联系电话')
weixinhao = models.CharField(max_length=50, null=True, blank=True, verbose_name='微信号')
zhuangtai = models.IntegerField(choices=[(0, '封禁'), (1, '正常')], default=1, verbose_name='店铺状态')
bangding_yonghushu = models.PositiveIntegerField(default=0, verbose_name='绑定用户总数')
erweima_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='店铺二维码相对URL')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
kaiqi_shouyi_choucheng = models.BooleanField(default=False, verbose_name='是否开启店铺订单收益抽成')
shouyi_choucheng_feilv = models.DecimalField(max_digits=5, decimal_places=4, null=True, blank=True, default=0.0000,
verbose_name='店铺订单收益抽成费率(小数,如0.1000=10%)')
ketixian_yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='店铺可提现余额')
zhengqu_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='店铺赚取总额')
meiri_tixian_xiane = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, default=0.00,
verbose_name='店铺每日提现限额')
kaiqi_meiri_xiane = models.BooleanField(default=False, verbose_name='是否开启每日提现限额')
yaoqing_dianpu_id = models.PositiveIntegerField(null=True, blank=True, db_index=True,
verbose_name='邀请人店铺ID(上级)')
fenhong_choucheng_feilv = models.DecimalField(max_digits=5, decimal_places=4, null=True, blank=True, default=0.0500,
verbose_name='上级分红抽成费率(默认5%)')
shangji_fenhong_leiji = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='作为上级累计获得分红')
shangji_ketixian_fenhong = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='作为上级可提现分红余额')
class Meta:
db_table = 'dianpu'
verbose_name = '平台商家店铺'
verbose_name_plural = verbose_name
class DianpuMorenPeizhi(QModel):
id = models.PositiveSmallIntegerField(primary_key=True, default=1, editable=False)
moren_choucheng_feilv = models.DecimalField(max_digits=5, decimal_places=4, default=0.1000, verbose_name='默认订单抽成费率(小数,0.1000=10%)')
moren_tixian_xiane = models.DecimalField(max_digits=10, decimal_places=2, default=1000.00, verbose_name='默认可提现限额')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'dianpu_moren_peizhi'
verbose_name = '店铺默认配置'
verbose_name_plural = verbose_name
def __str__(self):
return f"默认配置 - 费率:{self.moren_choucheng_feilv} 限额:{self.moren_tixian_xiane}"
def save(self, *args, **kwargs):
self.id = 1
super().save(*args, **kwargs)
class DianpuShouzhiMeiriTongji(QModel):
dianpu_id = models.PositiveIntegerField(db_index=True, verbose_name='店铺ID')
riqi = models.DateField(db_index=True, verbose_name='统计日期')
nian = models.PositiveSmallIntegerField(verbose_name='年份')
yue = models.PositiveSmallIntegerField(verbose_name='月份')
ri = models.PositiveSmallIntegerField(verbose_name='日')
xiadan_zongliang = models.PositiveIntegerField(default=0, verbose_name='下单总量')
xiadan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='下单总额')
chengjiao_zongliang = models.PositiveIntegerField(default=0, verbose_name='成交总量')
chengjiao_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='成交总额')
tuikuan_zongliang = models.PositiveIntegerField(default=0, verbose_name='退款总量')
tuikuan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='退款总额')
shouyi_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='收益总额')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
shangji_fenhong_cishu = models.PositiveIntegerField(default=0, verbose_name='作为上级获得分红次数')
shangji_fenhong_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='作为上级获得分红总额')
# ---------- 作为下级,给上级的分红记录 ----------
shangji_id = models.PositiveIntegerField(null=True, blank=True, verbose_name='当天对应的上级店铺ID(若无则为空)')
gei_shangji_cishu = models.PositiveIntegerField(default=0, verbose_name='给上级分红次数')
gei_shangji_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='给上级分红总额')
class Meta:
db_table = 'dianpu_shouzhi_meiri_tongji'
verbose_name = '店铺每日收支统计'
verbose_name_plural = verbose_name
unique_together = [['dianpu_id', 'riqi']]
indexes = [
models.Index(fields=['dianpu_id', 'riqi']),
models.Index(fields=['nian', 'yue', 'ri']),
]
def __str__(self):
return f"店铺ID:{self.dianpu_id} - {self.riqi}"
def clean(self):
if self.riqi:
self.nian = self.riqi.year
self.yue = self.riqi.month
self.ri = self.riqi.day
super().clean()
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
class YonghuDianpuBangding(QModel):
id = models.AutoField(primary_key=True, verbose_name='绑定自增ID')
yonghu = models.ForeignKey(
'users.User',
on_delete=models.CASCADE,
db_column='UserUUID',
db_index=True,
verbose_name='用户ID'
)
dianpu = models.ForeignKey('Dianpu', on_delete=models.CASCADE, db_index=True, verbose_name='关联店铺ID')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'yonghu_dianpu_bangding'
verbose_name = '用户店铺绑定关系'
verbose_name_plural = verbose_name
unique_together = [['yonghu', 'dianpu']]
class ShangpinLeixingDianpu(QModel):
"""
店铺级商品类型映射表
与公共商品类型表 ShangpinLeixing 强制关联,用于店铺自定义类型
"""
id = models.AutoField(primary_key=True, verbose_name='类型自增ID')
dianpu = models.ForeignKey(
'shop.Dianpu',
on_delete=models.CASCADE,
db_index=True,
verbose_name='所属店铺'
)
# 🔥 强制映射到公共商品类型,不可为空
gonggong_leixing = models.ForeignKey(
'products.ShangpinLeixing',
on_delete=models.CASCADE,
db_index=True,
verbose_name='映射的公共商品类型'
)
jieshao = models.CharField(max_length=45, verbose_name='类型介绍')
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='类型图片URL')
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shangjia_zhuangtai = models.BooleanField(default=True, verbose_name='是否上架')
fengjin_zhuangtai = models.BooleanField(default=False, verbose_name='是否封禁')
shenhe_zhuangtai = models.BooleanField(default=False, verbose_name='平台审核状态',help_text='True=审核通过,False=未审核')
class Meta:
db_table = 'shangdian_shangpin_leixing'
verbose_name = '店铺商品类型映射'
verbose_name_plural = verbose_name
indexes = [
models.Index(fields=['dianpu']),
models.Index(fields=['gonggong_leixing']),
]
def __str__(self):
return f"{self.dianpu.dianpu_mingcheng} - {self.jieshao}"
# shangdian/models.py 或独立应用 models.py
class DianpuShangpinShenheShezhi(QModel):
"""店铺商品审核模式全局配置(仅一条记录)"""
kaiqi_shenhe = models.BooleanField(default=False, verbose_name='是否开启商品审核模式')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'dianpu_shangpin_shenhe_shezhi'
verbose_name = '商品审核模式配置'
verbose_name_plural = verbose_name
def save(self, *args, **kwargs):
self.pk = 1 # 强制使用 ID=1 保证唯一
super().save(*args, **kwargs)
from django.db import models
from gvsdsdk.model_base import QModel
class YonghuPingzheng(QModel):
id = models.AutoField(primary_key=True, verbose_name='自增主键ID')
yonghu = models.CharField(
max_length=7,
unique=True, # 确保一个用户只有一条凭证记录
db_index=True,
verbose_name='关联用户ID'
)
zhanghao = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='登录账号')
mima = models.CharField(max_length=255, verbose_name='密码')
is_active = models.BooleanField(default=True, verbose_name='是否启用')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'yonghu_pingzheng'
verbose_name = '用户认证凭证'
verbose_name_plural = verbose_name
class Dianpu(QModel):
id = models.AutoField(primary_key=True, verbose_name='店铺自增ID')
pingzheng = models.OneToOneField(
'shop.YonghuPingzheng', # 同应用内可简写,但完整路径更清晰
on_delete=models.CASCADE,
db_index=True,
verbose_name='关联用户凭证'
)
dianpu_mingcheng = models.CharField(max_length=50, verbose_name='店铺名称')
dianpu_touxiang = models.CharField(max_length=500, null=True, blank=True, verbose_name='店铺头像URL')
lianxi_dianhua = models.CharField(max_length=20, null=True, blank=True, verbose_name='联系电话')
weixinhao = models.CharField(max_length=50, null=True, blank=True, verbose_name='微信号')
zhuangtai = models.IntegerField(choices=[(0, '封禁'), (1, '正常')], default=1, verbose_name='店铺状态')
bangding_yonghushu = models.PositiveIntegerField(default=0, verbose_name='绑定用户总数')
erweima_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='店铺二维码相对URL')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
kaiqi_shouyi_choucheng = models.BooleanField(default=False, verbose_name='是否开启店铺订单收益抽成')
shouyi_choucheng_feilv = models.DecimalField(max_digits=5, decimal_places=4, null=True, blank=True, default=0.0000,
verbose_name='店铺订单收益抽成费率(小数,如0.1000=10%)')
ketixian_yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='店铺可提现余额')
zhengqu_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='店铺赚取总额')
meiri_tixian_xiane = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, default=0.00,
verbose_name='店铺每日提现限额')
kaiqi_meiri_xiane = models.BooleanField(default=False, verbose_name='是否开启每日提现限额')
yaoqing_dianpu_id = models.PositiveIntegerField(null=True, blank=True, db_index=True,
verbose_name='邀请人店铺ID(上级)')
fenhong_choucheng_feilv = models.DecimalField(max_digits=5, decimal_places=4, null=True, blank=True, default=0.0500,
verbose_name='上级分红抽成费率(默认5%)')
shangji_fenhong_leiji = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='作为上级累计获得分红')
shangji_ketixian_fenhong = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='作为上级可提现分红余额')
class Meta:
db_table = 'dianpu'
verbose_name = '平台商家店铺'
verbose_name_plural = verbose_name
class DianpuMorenPeizhi(QModel):
id = models.PositiveSmallIntegerField(primary_key=True, default=1, editable=False)
moren_choucheng_feilv = models.DecimalField(max_digits=5, decimal_places=4, default=0.1000, verbose_name='默认订单抽成费率(小数,0.1000=10%)')
moren_tixian_xiane = models.DecimalField(max_digits=10, decimal_places=2, default=1000.00, verbose_name='默认可提现限额')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'dianpu_moren_peizhi'
verbose_name = '店铺默认配置'
verbose_name_plural = verbose_name
def __str__(self):
return f"默认配置 - 费率:{self.moren_choucheng_feilv} 限额:{self.moren_tixian_xiane}"
def save(self, *args, **kwargs):
self.id = 1
super().save(*args, **kwargs)
class DianpuShouzhiMeiriTongji(QModel):
dianpu_id = models.PositiveIntegerField(db_index=True, verbose_name='店铺ID')
riqi = models.DateField(db_index=True, verbose_name='统计日期')
nian = models.PositiveSmallIntegerField(verbose_name='年份')
yue = models.PositiveSmallIntegerField(verbose_name='月份')
ri = models.PositiveSmallIntegerField(verbose_name='日')
xiadan_zongliang = models.PositiveIntegerField(default=0, verbose_name='下单总量')
xiadan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='下单总额')
chengjiao_zongliang = models.PositiveIntegerField(default=0, verbose_name='成交总量')
chengjiao_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='成交总额')
tuikuan_zongliang = models.PositiveIntegerField(default=0, verbose_name='退款总量')
tuikuan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='退款总额')
shouyi_zonge = models.DecimalField(max_digits=12, 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='更新时间')
shangji_fenhong_cishu = models.PositiveIntegerField(default=0, verbose_name='作为上级获得分红次数')
shangji_fenhong_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='作为上级获得分红总额')
# ---------- 作为下级,给上级的分红记录 ----------
shangji_id = models.PositiveIntegerField(null=True, blank=True, verbose_name='当天对应的上级店铺ID(若无则为空)')
gei_shangji_cishu = models.PositiveIntegerField(default=0, verbose_name='给上级分红次数')
gei_shangji_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
verbose_name='给上级分红总额')
class Meta:
db_table = 'dianpu_shouzhi_meiri_tongji'
verbose_name = '店铺每日收支统计'
verbose_name_plural = verbose_name
unique_together = [['dianpu_id', 'riqi']]
indexes = [
models.Index(fields=['dianpu_id', 'riqi']),
models.Index(fields=['nian', 'yue', 'ri']),
]
def __str__(self):
return f"店铺ID:{self.dianpu_id} - {self.riqi}"
def clean(self):
if self.riqi:
self.nian = self.riqi.year
self.yue = self.riqi.month
self.ri = self.riqi.day
super().clean()
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
class YonghuDianpuBangding(QModel):
id = models.AutoField(primary_key=True, verbose_name='绑定自增ID')
yonghu = models.ForeignKey(
'users.User',
on_delete=models.CASCADE,
db_column='UserUUID',
db_index=True,
verbose_name='用户ID'
)
dianpu = models.ForeignKey('Dianpu', on_delete=models.CASCADE, db_index=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 = 'yonghu_dianpu_bangding'
verbose_name = '用户店铺绑定关系'
verbose_name_plural = verbose_name
unique_together = [['yonghu', 'dianpu']]
class ShangpinLeixingDianpu(QModel):
"""
店铺级商品类型映射表
与公共商品类型表 ShangpinLeixing 强制关联,用于店铺自定义类型
"""
id = models.AutoField(primary_key=True, verbose_name='类型自增ID')
dianpu = models.ForeignKey(
'shop.Dianpu',
on_delete=models.CASCADE,
db_index=True,
verbose_name='所属店铺'
)
# 🔥 强制映射到公共商品类型,不可为空
gonggong_leixing = models.ForeignKey(
'products.ShangpinLeixing',
on_delete=models.CASCADE,
db_index=True,
verbose_name='映射的公共商品类型'
)
jieshao = models.CharField(max_length=45, verbose_name='类型介绍')
tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='类型图片URL')
paixu = models.IntegerField(default=0, verbose_name='排序权重')
shangjia_zhuangtai = models.BooleanField(default=True, verbose_name='是否上架')
fengjin_zhuangtai = models.BooleanField(default=False, verbose_name='是否封禁')
shenhe_zhuangtai = models.BooleanField(default=False, verbose_name='平台审核状态',help_text='True=审核通过,False=未审核')
class Meta:
db_table = 'shangdian_shangpin_leixing'
verbose_name = '店铺商品类型映射'
verbose_name_plural = verbose_name
indexes = [
models.Index(fields=['dianpu']),
models.Index(fields=['gonggong_leixing']),
]
def __str__(self):
return f"{self.dianpu.dianpu_mingcheng} - {self.jieshao}"
# shangdian/models.py 或独立应用 models.py
class DianpuShangpinShenheShezhi(QModel):
"""店铺商品审核模式全局配置(仅一条记录)"""
kaiqi_shenhe = models.BooleanField(default=False, verbose_name='是否开启商品审核模式')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'dianpu_shangpin_shenhe_shezhi'
verbose_name = '商品审核模式配置'
verbose_name_plural = verbose_name
def save(self, *args, **kwargs):
self.pk = 1 # 强制使用 ID=1 保证唯一
super().save(*args, **kwargs)
+4 -4
View File
@@ -170,7 +170,7 @@ def verify_shop_permission(request, frontend_user_id=None):
dianpu = Dianpu.objects.select_for_update().get(id=dianpu_id)
dianpu.ketixian_yue = F('ketixian_yue') + dianpu_shouyi
dianpu.zhengqu_zonge = F('zhengqu_zonge') + dianpu_shouyi
dianpu.save(update_fields=['ketixian_yue', 'zhengqu_zonge', 'update_time'])
dianpu.save(update_fields=['ketixian_yue', 'zhengqu_zonge', 'UpdateTime'])
except Dianpu.DoesNotExist:
logger.error(f"结算时店铺ID {dianpu_id} 不存在,但已校验过,此处不应发生")
raise
@@ -383,7 +383,7 @@ def update_dianpu_daily_stat(
dianpu_locked = Dianpu.objects.select_for_update().get(id=dianpu_id)
dianpu_locked.ketixian_yue = F('ketixian_yue') + dianpu_shouyi
dianpu_locked.zhengqu_zonge = F('zhengqu_zonge') + dianpu_shouyi
dianpu_locked.save(update_fields=['ketixian_yue', 'zhengqu_zonge', 'update_time'])
dianpu_locked.save(update_fields=['ketixian_yue', 'zhengqu_zonge', 'UpdateTime'])
except Dianpu.DoesNotExist:
logger.error(f"结算时店铺 {dianpu_id} 不存在")
raise
@@ -466,13 +466,13 @@ def _update_shangji_gain_stat_within_tx(shangji_dianpu_id, fenhong_jine):
# 更新上级店铺的“作为上级获得”字段
tongji_shangji.shangji_fenhong_cishu = F('shangji_fenhong_cishu') + 1
tongji_shangji.shangji_fenhong_zonge = F('shangji_fenhong_zonge') + fenhong_jine
tongji_shangji.save(update_fields=['shangji_fenhong_cishu', 'shangji_fenhong_zonge', 'update_time'])
tongji_shangji.save(update_fields=['shangji_fenhong_cishu', 'shangji_fenhong_zonge', 'UpdateTime'])
# 更新上级店铺主表的分红余额和累计分红
shangji = Dianpu.objects.select_for_update().get(id=shangji_dianpu_id)
shangji.shangji_fenhong_leiji = F('shangji_fenhong_leiji') + fenhong_jine
shangji.shangji_ketixian_fenhong = F('shangji_ketixian_fenhong') + fenhong_jine
shangji.save(update_fields=['shangji_fenhong_leiji', 'shangji_ketixian_fenhong', 'update_time'])
shangji.save(update_fields=['shangji_fenhong_leiji', 'shangji_ketixian_fenhong', 'UpdateTime'])
logger.info(f"上级店铺 {shangji_dianpu_id} 获得分红 +{fenhong_jine}")
+13 -13
View File
@@ -440,8 +440,8 @@ class ShopOverviewView(APIView):
'zhuangtai': dianpu.zhuangtai,
'bangding_yonghushu': dianpu.bangding_yonghushu,
'erweima_url': dianpu.erweima_url or '',
'create_time': dianpu.create_time.isoformat() if dianpu.create_time else '',
'update_time': dianpu.update_time.isoformat() if dianpu.update_time else '',
'CreateTime': dianpu.CreateTime.isoformat() if dianpu.CreateTime else '',
'UpdateTime': dianpu.UpdateTime.isoformat() if dianpu.UpdateTime else '',
# 新增字段
'kaiqi_shouyi_choucheng': dianpu.kaiqi_shouyi_choucheng,
'shouyi_choucheng_feilv': float(dianpu.shouyi_choucheng_feilv) if dianpu.shouyi_choucheng_feilv else 0.0,
@@ -729,7 +729,7 @@ class ShopQrcodeView(APIView):
# 更新数据库
with transaction.atomic():
dianpu.erweima_url = relative_path
dianpu.save(update_fields=['erweima_url', 'update_time'])
dianpu.save(update_fields=['erweima_url', 'UpdateTime'])
return Response({
'code': 0,
@@ -1281,7 +1281,7 @@ class ShopProductListView(APIView):
'guize_tupian', 'yaoqiuleixing', 'huiyuan_id', 'yongjin',
'tupian_url', 'ewai_dashou_fencheng', 'paixu',
'dianpu_leixing_id', 'shangjia_zhuangtai', 'fengjin_zhuangtai',
'shenhe_zhuangtai', 'create_time', 'update_time'
'shenhe_zhuangtai', 'CreateTime', 'UpdateTime'
)
# 筛选
@@ -1342,8 +1342,8 @@ class ShopProductListView(APIView):
'shangjia_zhuangtai': p.shangjia_zhuangtai,
'fengjin_zhuangtai': p.fengjin_zhuangtai,
'shenhe_zhuangtai': p.shenhe_zhuangtai,
'create_time': p.create_time.isoformat() if p.create_time else '',
'update_time': p.update_time.isoformat() if p.update_time else '',
'CreateTime': p.CreateTime.isoformat() if p.CreateTime else '',
'UpdateTime': p.UpdateTime.isoformat() if p.UpdateTime else '',
})
return Response({
@@ -1589,7 +1589,7 @@ class ShopProductModifyView1(APIView):
update_fields.append('shenhe_zhuangtai')
if update_fields:
product.save(update_fields=update_fields + ['update_time'])
product.save(update_fields=update_fields + ['UpdateTime'])
return Response({'code': 0, 'msg': '商品修改成功'})
# ---------- 添加商品(增强会员/佣金默认逻辑) ----------
@@ -1823,7 +1823,7 @@ class SubShopListView(APIView):
pass
# 5. 排序:按创建时间倒序
queryset = queryset.order_by('-create_time')
queryset = queryset.order_by('-CreateTime')
# 6. 分页
try:
@@ -1844,8 +1844,8 @@ class SubShopListView(APIView):
'bangding_yonghushu': shop.bangding_yonghushu,
'zhengqu_zonge': str(shop.zhengqu_zonge),
'ketixian_yue': str(shop.ketixian_yue),
'create_time': shop.create_time.strftime('%Y-%m-%d %H:%M:%S') if shop.create_time else '',
'update_time': shop.update_time.strftime('%Y-%m-%d %H:%M:%S') if shop.update_time else '',
'CreateTime': shop.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if shop.CreateTime else '',
'UpdateTime': shop.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if shop.UpdateTime else '',
'erweima_url': shop.erweima_url or '',
'fenhong_choucheng_feilv': str(shop.fenhong_choucheng_feilv) if shop.fenhong_choucheng_feilv else '0.0000',
})
@@ -1998,7 +1998,7 @@ class SubShopModifyView(APIView):
except (ValueError, TypeError):
return Response({'code': 400, 'msg': '分红费率格式错误'})
sub_dianpu.save(update_fields=['zhuangtai', 'fenhong_choucheng_feilv', 'update_time'])
sub_dianpu.save(update_fields=['zhuangtai', 'fenhong_choucheng_feilv', 'UpdateTime'])
return Response({'code': 200, 'msg': '修改成功'})
except Dianpu.DoesNotExist:
@@ -2486,8 +2486,8 @@ class ShopOrderManageView(APIView):
'beizhu': order.Remark or '',
'nicheng': order.Nickname or '',
'leixing_id': order.ProductTypeID,
'create_time': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else '',
'update_time': order.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if order.UpdateTime else '',
'CreateTime': order.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if order.CreateTime else '',
'UpdateTime': order.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if order.UpdateTime else '',
'pingtai_kuozhan': {
'laoban_id': ext.BossID or '',
'laoban_pingjia': ext.BossReview or '',
+23 -23
View File
@@ -33,8 +33,8 @@ class Migration(migrations.Migration):
('ip', models.CharField(blank=True, max_length=50, null=True, verbose_name='来访用户ip')),
('last_login_time', models.DateTimeField(blank=True, null=True, verbose_name='最后登录时间')),
('user_type', models.CharField(choices=[('normal', '普通用户'), ('dashou', '打手'), ('shop', '商家'), ('guanshi', '管事'), ('admin', '管理员')], default='normal', max_length=10, verbose_name='用户类型')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '用户主表',
@@ -112,8 +112,8 @@ class Migration(migrations.Migration):
('huiyuants', models.IntegerField(default=0, verbose_name='添加会员天数')),
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
('qitashuoming', models.TextField(blank=True, null=True, verbose_name='其他说明')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '修改记录表',
@@ -139,8 +139,8 @@ class Migration(migrations.Migration):
('kaioi_ewai_tixian', models.BooleanField(default=False, verbose_name='开启额外提现')),
('kaioi_ewai_fenhong', models.BooleanField(default=False, verbose_name='开启额外分红')),
('ewai_fenhong_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外分红金额(元)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ZuzhangProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
@@ -160,8 +160,8 @@ class Migration(migrations.Migration):
('tongguo_zongshu', models.IntegerField(default=0, verbose_name='通过总数')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='赚取总额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ShenheguanProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
@@ -186,7 +186,7 @@ class Migration(migrations.Migration):
('jinriliushui', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家今日流水')),
('jinyuedingdan', models.IntegerField(default=0, verbose_name='商家今月订单总量')),
('jinyueliushui', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家今月流水')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ShopProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
@@ -203,8 +203,8 @@ class Migration(migrations.Migration):
('zhifu', models.CharField(blank=True, max_length=500, null=True, verbose_name='收款码图片')),
('skzhanghao', models.CharField(blank=True, max_length=11, null=True, verbose_name='收款账号')),
('shoujihao_renzheng', models.BooleanField(default=False, verbose_name='手机号是否已认证')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user_uuid', models.OneToOneField(db_column='user_uuid_id', on_delete=django.db.models.deletion.CASCADE, related_name='sensitive_data', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
@@ -223,8 +223,8 @@ class Migration(migrations.Migration):
('jinrichuli', models.IntegerField(default=0, verbose_name='今日处理订单数')),
('jinyuechuli', models.IntegerField(default=0, verbose_name='本月处理订单数')),
('zongchuli', models.IntegerField(default=0, verbose_name='累计处理订单数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='KefuProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
@@ -248,7 +248,7 @@ class Migration(migrations.Migration):
('jinyuechongzhi', models.IntegerField(default=0, verbose_name='今月充值打手数量')),
('chongzhifenrun', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='充值分佣总额')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('fenhong_yici', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='首次分红金额')),
('fenghong_erci_enabled', models.BooleanField(default=False, verbose_name='开启二次分红')),
('fenghong_erci', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='二次分红金额')),
@@ -288,7 +288,7 @@ class Migration(migrations.Migration):
('jinyueshouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今月收益金额')),
('jifen', models.IntegerField(default=0, verbose_name='打手积分')),
('yajin', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='打手押金')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('last_tixian_date', models.DateField(blank=True, null=True, verbose_name='最近提现日期')),
('jinritixian_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日已提现金额')),
('kaioi_ewai_xiane', models.BooleanField(default=False, verbose_name='是否开启额外提现限额')),
@@ -309,7 +309,7 @@ class Migration(migrations.Migration):
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='消费总额')),
('alldingdan', models.IntegerField(default=0, verbose_name='订单总数')),
('alltui', models.IntegerField(default=0, verbose_name='退款总数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='BossProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
@@ -337,8 +337,8 @@ class Migration(migrations.Migration):
('tixian_auto_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='最近一次打款单号(非唯一,重试收款会更新)')),
('fail_reason', models.TextField(blank=True, null=True, verbose_name='微信打款失败原因')),
('dakuan_mode', models.PositiveSmallIntegerField(db_index=True, default=1, verbose_name='打款方式(1手动2自动)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '提现审核记录',
@@ -365,8 +365,8 @@ class Migration(migrations.Migration):
('bhliyou', models.TextField(blank=True, null=True, verbose_name='驳回理由')),
('shenhe_jilu_id', models.IntegerField(blank=True, db_index=True, null=True, verbose_name='关联提现审核记录ID(TixianShenheJilu.id)')),
('shenhe_danhao', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='关联提现审核单号')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '提现记录表',
@@ -391,8 +391,8 @@ class Migration(migrations.Migration):
('wechat_package', models.TextField(blank=True, null=True, verbose_name='微信返回的package_info(JSON)')),
('fail_reason', models.TextField(blank=True, null=True, verbose_name='失败原因')),
('shenhe_danhao', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='关联审核单号')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('UpdateTime', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
options={
'verbose_name': '自动提现记录',
@@ -430,7 +430,7 @@ class Migration(migrations.Migration):
('password', models.CharField(max_length=255, verbose_name='密码')),
('wechat', models.CharField(blank=True, max_length=50, verbose_name='管理员微信')),
('yaoqingma', models.CharField(db_index=True, max_length=20, null=True, verbose_name='管理员邀请码')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('CreateTime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='AdminProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
+24 -24
View File
@@ -43,8 +43,8 @@ class UserMain(AbstractBaseUser, QModel):
# 状态和时间字段
#is_active = models.BooleanField(default=True, verbose_name='是否激活')
#last_login = models.DateTimeField(blank=True, null=True, verbose_name='最后登录时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
# 邀请码字段
#yaoqingma = models.CharField(max_length=20, blank=True, null=True, verbose_name='邀请码')
@@ -63,7 +63,7 @@ class UserMain(AbstractBaseUser, QModel):
models.Index(fields=['openid']),
#models.Index(fields=['phone']),
models.Index(fields=['user_type']),
#models.Index(fields=['create_time']),
#models.Index(fields=['CreateTime']),
]
def __str__(self):
@@ -97,7 +97,7 @@ class UserBoss(QModel):
zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='消费总额')
alldingdan = models.IntegerField(default=0, verbose_name='订单总数')
alltui = models.IntegerField(default=0, verbose_name='退款总数')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'user_boss'
@@ -130,7 +130,7 @@ class UserDashou(QModel):
jinyueshouyi = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今月收益金额')
jifen = models.IntegerField(default=0, verbose_name='打手积分')
yajin= models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='打手押金')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
last_tixian_date = models.DateField(null=True, blank=True, verbose_name='最近提现日期') # 用于重置今日提现金额
jinritixian_jine = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日已提现金额')
@@ -167,7 +167,7 @@ class UserShangjia(QModel):
jinriliushui = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='商家今日流水')
jinyuedingdan = models.IntegerField(default=0, verbose_name='商家今月订单总量')
jinyueliushui = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='商家今月流水')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'user_shangjia'
@@ -194,7 +194,7 @@ class UserGuanshi(QModel):
jinyuechongzhi = models.IntegerField(default=0, verbose_name='今月充值打手数量')
chongzhifenrun = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='充值分佣总额')
yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='可提现余额')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
# 新增:首次分红金额(针对特殊用户)
fenhong_yici = models.DecimalField(max_digits=10,decimal_places=2,default=0.00,verbose_name='首次分红金额')
@@ -260,9 +260,9 @@ class UserZuzhang(QModel):
# 额外分红金额
ewai_fenhong_jine = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='额外分红金额(元)')
# 创建时间
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
# 更新时间
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'user_zuzhang'
@@ -286,8 +286,8 @@ class UserShenheguan(QModel):
tongguo_zongshu = models.IntegerField(default=0, verbose_name='通过总数')
yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='可提现余额')
zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='赚取总额')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'user_shenheguan'
@@ -303,7 +303,7 @@ class AdminProfile(QModel):
password = models.CharField(max_length=255, verbose_name='密码')
wechat = models.CharField(max_length=50, blank=True, verbose_name='管理员微信')
yaoqingma = models.CharField(max_length=20, null=True, db_index=True,verbose_name='管理员邀请码') # 🟢 新增字段
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'admin_profile'
@@ -320,8 +320,8 @@ class UserKefu(QModel):
jinrichuli = models.IntegerField(default=0, verbose_name='今日处理订单数')
jinyuechuli = models.IntegerField(default=0, verbose_name='本月处理订单数')
zongchuli = models.IntegerField(default=0, verbose_name='累计处理订单数')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'user_kefu'
@@ -362,8 +362,8 @@ class Tixianjilu(QModel):
max_length=32, null=True, blank=True, db_index=True,
verbose_name='关联提现审核单号'
)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'tixianjilu'
@@ -425,8 +425,8 @@ class TixianShenheJilu(QModel):
dakuan_mode = models.PositiveSmallIntegerField(
default=1, db_index=True, verbose_name='打款方式(1手动2自动)'
)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'tixian_shenhe_jilu'
@@ -481,8 +481,8 @@ class TixianAutoRecord(QModel):
shenhe_danhao = models.CharField(
max_length=32, null=True, blank=True, db_index=True, verbose_name='关联审核单号'
)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'tixian_auto_record'
@@ -536,8 +536,8 @@ class Xiugaijilu(QModel):
# 其他字段
qitashuoming = models.TextField(null=True, blank=True, verbose_name='其他说明')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'xiugaijilu'
@@ -614,8 +614,8 @@ class UserSensitiveData(QModel):
zhifu = models.CharField(max_length=500, null=True, blank=True, verbose_name='收款码图片')
skzhanghao = models.CharField(max_length=11, blank=True, null=True, verbose_name='收款账号')
shoujihao_renzheng = models.BooleanField(default=False, verbose_name='手机号是否已认证')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'user_sensitive_data'
+12 -12
View File
@@ -439,7 +439,7 @@ def _get_active_auto_record(shenhe_danhao):
shenhe_danhao=shenhe_danhao,
zhuangtai__in=[0, 1],
)
.order_by('-create_time')
.order_by('-CreateTime')
.first()
)
@@ -731,7 +731,7 @@ def _quota_already_reserved_for_record(auto_record):
other_sum = TixianAutoRecord.query.filter(
leixing=auto_record.leixing,
zhuangtai__in=[0, 1],
create_time__date=today,
CreateTime__date=today,
).exclude(tixian_id=auto_record.tixian_id).aggregate(
total=Sum('shijidaozhang'),
)['total'] or decimal.Decimal('0.00')
@@ -912,7 +912,7 @@ def sync_audit_and_jilu_status(audit, new_status, **extra_fields):
setattr(audit, k, v)
audit.save()
if audit.tixianjilu_id:
update_fields = {'zhuangtai': new_status, 'update_time': timezone.now()}
update_fields = {'zhuangtai': new_status, 'UpdateTime': timezone.now()}
if 'bhliyou' in extra_fields:
update_fields['bhliyou'] = extra_fields['bhliyou']
Tixianjilu.query.filter(id=audit.tixianjilu_id).update(**update_fields)
@@ -925,7 +925,7 @@ def _close_auto_record_failed(auto_record, fail_reason):
reason = (fail_reason or '打款失败')[:500]
auto_record.zhuangtai = 2
auto_record.fail_reason = reason
auto_record.save(update_fields=['zhuangtai', 'fail_reason', 'update_time'])
auto_record.save(update_fields=['zhuangtai', 'fail_reason', 'UpdateTime'])
release_collect_quota_for_record(auto_record)
@@ -1059,7 +1059,7 @@ def mark_transfer_success(auto_record, *, wechat_transfer_no=None, with_accounti
return False
ar.zhuangtai = 1
update_fields = ['zhuangtai', 'update_time']
update_fields = ['zhuangtai', 'UpdateTime']
if wechat_transfer_no:
ar.wechat_transfer_no = wechat_transfer_no
update_fields.append('wechat_transfer_no')
@@ -1087,7 +1087,7 @@ def mark_transfer_success(auto_record, *, wechat_transfer_no=None, with_accounti
def _sync_record_from_wx_query(auto_record, wx_data):
"""根据微信查单结果修正本地打款记录,返回 (action, payload)"""
if wx_data.get('_not_found'):
age = timezone.now() - auto_record.create_time
age = timezone.now() - auto_record.CreateTime
if auto_record.zhuangtai == 0 and age < timedelta(minutes=PENDING_QUERY_GRACE_MINUTES):
return RECONCILE_PENDING, {
'msg': '有收款处理中,请稍后再试',
@@ -1096,7 +1096,7 @@ def _sync_record_from_wx_query(auto_record, wx_data):
if auto_record.zhuangtai == 0:
auto_record.zhuangtai = 2
auto_record.fail_reason = '微信未找到该打款单,请重新发起收款'
auto_record.save(update_fields=['zhuangtai', 'fail_reason', 'update_time'])
auto_record.save(update_fields=['zhuangtai', 'fail_reason', 'UpdateTime'])
release_collect_quota_for_record(auto_record)
return RECONCILE_ALLOW_NEW, {}
@@ -1118,7 +1118,7 @@ def _sync_record_from_wx_query(auto_record, wx_data):
}
if auto_record.zhuangtai == 0:
auto_record.wechat_package = json.dumps(package, ensure_ascii=False)
auto_record.save(update_fields=['wechat_package', 'update_time'])
auto_record.save(update_fields=['wechat_package', 'UpdateTime'])
wx_cfg = settings.WECHAT_PAY_V3_CONFIG
return RECONCILE_WAIT_CONFIRM, {
'tixian_id': auto_record.tixian_id,
@@ -1143,7 +1143,7 @@ def _sync_record_from_wx_query(auto_record, wx_data):
if auto_record.zhuangtai != 1:
auto_record.zhuangtai = 2
auto_record.fail_reason = fail_reason
auto_record.save(update_fields=['zhuangtai', 'fail_reason', 'update_time'])
auto_record.save(update_fields=['zhuangtai', 'fail_reason', 'UpdateTime'])
release_collect_quota_for_record(auto_record)
if auto_record.shenhe_danhao:
try:
@@ -1171,14 +1171,14 @@ def get_auto_record_for_collect(shenhe_danhao):
"""
pending = (
TixianAutoRecord.query.filter(shenhe_danhao=shenhe_danhao, zhuangtai=0)
.order_by('-create_time')
.order_by('-CreateTime')
.first()
)
if pending:
return pending
return (
TixianAutoRecord.query.filter(shenhe_danhao=shenhe_danhao)
.order_by('-create_time')
.order_by('-CreateTime')
.first()
)
@@ -1190,7 +1190,7 @@ def reconcile_shenhe_wechat_bills(shenhe_danhao):
返回 (action, payload)
"""
records = list(
TixianAutoRecord.query.filter(shenhe_danhao=shenhe_danhao).order_by('-create_time')
TixianAutoRecord.query.filter(shenhe_danhao=shenhe_danhao).order_by('-CreateTime')
)
if any(r.zhuangtai == 1 for r in records):
+2 -2
View File
@@ -91,7 +91,7 @@ def _mark_auto_record_failed(tixian_id, fail_reason):
TixianAutoRecord.query.filter(tixian_id=tixian_id, zhuangtai=0).update(
zhuangtai=2,
fail_reason=(fail_reason or '打款失败')[:500],
update_time=timezone.now(),
UpdateTime=timezone.now(),
)
@@ -307,7 +307,7 @@ def process_audit_collect(request):
shenhe_danhao=shenhe_danhao,
)
audit.tixian_auto_id = tixian_id
audit.save(update_fields=['tixian_auto_id', 'update_time'])
audit.save(update_fields=['tixian_auto_id', 'UpdateTime'])
body = _build_wx_transfer_body(
wx_cfg, tixian_id, user_main.OpenID, yonghuid, leixing, shijidaozhang,
+57 -57
View File
@@ -1512,7 +1512,7 @@ class GuanshiYaoqingDashouListView(APIView):
pass
# 6. 排序和分页
base_qs = base_qs.order_by('-create_time')
base_qs = base_qs.order_by('-CreateTime')
paginator = Paginator(base_qs, page_size)
try:
page_obj = paginator.page(page)
@@ -1980,7 +1980,7 @@ class TixianShenqingView(APIView):
'jine': str(jine.quantize(decimal.Decimal('0.01'))),
'fangshi': fangshi,
'zhuangtai': 1,
'create_time': tixian_record.create_time.strftime('%Y-%m-%d %H:%M:%S'),
'CreateTime': tixian_record.CreateTime.strftime('%Y-%m-%d %H:%M:%S'),
'current_rate': str(current_rate.quantize(decimal.Decimal('0.0000'))),
'shouxufei': str(shouxufei.quantize(decimal.Decimal('0.01'))),
'shijidaozhang': str(shijidaozhang.quantize(decimal.Decimal('0.01'))),
@@ -2175,10 +2175,10 @@ class TixianJiluHuoquViewV2(APIView):
# 自动提现:含新审核关联记录;zhuangtai>0 时按状态筛选
if zhuangtai_filter > 0:
qs = qs.filter(zhuangtai=zhuangtai_filter)
qs = qs.order_by('-create_time')
qs = qs.order_by('-CreateTime')
records_queryset = qs.values(
'id', 'leixing', 'jine', 'zhuangtai', 'create_time', 'fangshi',
'id', 'leixing', 'jine', 'zhuangtai', 'CreateTime', 'fangshi',
'phone', 'skzhanghao', 'zhifu', 'bhliyou',
'shenhe_jilu_id', 'shenhe_danhao',
)[offset:offset + limit + 1]
@@ -2202,7 +2202,7 @@ class TixianJiluHuoquViewV2(APIView):
if danhao_list:
for ar in TixianAutoRecord.query.filter(
shenhe_danhao__in=danhao_list, zhuangtai=2
).order_by('-create_time').values('shenhe_danhao', 'fail_reason'):
).order_by('-CreateTime').values('shenhe_danhao', 'fail_reason'):
if ar['shenhe_danhao'] not in auto_fail_map:
auto_fail_map[ar['shenhe_danhao']] = ar['fail_reason']
@@ -2227,7 +2227,7 @@ class TixianJiluHuoquViewV2(APIView):
'leixing': record['leixing'],
'jine': jine_val,
'zhuangtai': record['zhuangtai'],
'create': record['create_time'].strftime('%Y-%m-%d %H:%M:%S'),
'create': record['CreateTime'].strftime('%Y-%m-%d %H:%M:%S'),
'fangshi': record['fangshi'],
'txdianhua': record['phone'] or '',
'txzh': record['skzhanghao'] or '',
@@ -2484,7 +2484,7 @@ class AdminFinancialDataView(APIView):
# 如果需要汇总多条记录,可以使用aggregate进行聚合查询
# 方法1:获取最新的一条记录(假设表中只有一条汇总记录)
shouzhijilu = Szjilu.query.order_by('-create_time').first()
shouzhijilu = Szjilu.query.order_by('-CreateTime').first()
# 方法2:如果表中可能有多条记录,需要汇总,可以使用以下方式:
# from django.db.models Sum
@@ -3150,7 +3150,7 @@ class AdGuanLiYongHu(APIView):
total_count = queryset.count()
# 获取当前页的数据
users = list(queryset.order_by('-create_time')[offset:offset + limit])
users = list(queryset.order_by('-CreateTime')[offset:offset + limit])
# 计算是否有更多数据
current_count = len(users)
@@ -3193,7 +3193,7 @@ class AdGuanLiYongHu(APIView):
total_count = queryset.count()
# 获取当前页的数据
dashou_list = list(queryset.order_by('-create_time')[offset:offset + limit])
dashou_list = list(queryset.order_by('-CreateTime')[offset:offset + limit])
# 计算是否有更多数据
current_count = len(dashou_list)
@@ -3237,7 +3237,7 @@ class AdGuanLiYongHu(APIView):
total_count = queryset.count()
# 获取当前页的数据
guanshi_list = list(queryset.order_by('-create_time')[offset:offset + limit])
guanshi_list = list(queryset.order_by('-CreateTime')[offset:offset + limit])
# 计算是否有更多数据
current_count = len(guanshi_list)
@@ -3280,7 +3280,7 @@ class AdGuanLiYongHu(APIView):
total_count = queryset.count()
# 获取当前页的数据
shangjia_list = list(queryset.order_by('-create_time')[offset:offset + limit])
shangjia_list = list(queryset.order_by('-CreateTime')[offset:offset + limit])
# 计算是否有更多数据
current_count = len(shangjia_list)
@@ -3487,8 +3487,8 @@ class CfGuanLi(APIView):
'bhliyou': chufa.RejectReason,
'jifen': chufa.DeductedPoints,
'dingdan_id': chufa.OrderID,
'create_time': chufa.create_time,
'update_time': chufa.update_time,
'CreateTime': chufa.CreateTime,
'UpdateTime': chufa.UpdateTime,
# 🔴【新增】申诉理由字段
'ssliyou': chufa.AppealReason or '',
# 🔴【新增】商家证据图片
@@ -3863,8 +3863,8 @@ class AdckyhxqView(APIView):
'avatar': user_main.Avatar,
'phone': user_main.Phone,
'ip': user_main.IP,
'create_time': user_main.UserCreateTime,
'update_time': user_main.UserCreateTime,
'CreateTime': user_main.UserCreateTime,
'UpdateTime': user_main.UserCreateTime,
'user_type': user_type
}
@@ -3879,7 +3879,7 @@ class AdckyhxqView(APIView):
'zonge': boss_profile.zonge,
'alldingdan': boss_profile.alldingdan,
'alltui': boss_profile.alltui,
'create_time_boss': boss_profile.create_time
'CreateTime_boss': boss_profile.CreateTime
})
elif user_type == 2: # 打手
@@ -3910,14 +3910,14 @@ class AdckyhxqView(APIView):
'jinyueshouyi': dashou_profile.jinyueshouyi,
'jifen': dashou_profile.jifen,
'yajin': dashou_profile.yajin,
'create_time_dashou': dashou_profile.create_time
'CreateTime_dashou': dashou_profile.CreateTime
})
# 查询打手的会员信息(只返回未过期的)
# 使用select_related预取huiyuan信息(如果有关联的话)
member_records = Huiyuangoumai.query.filter(
yonghu_id=uid
).order_by('-create_time')
).order_by('-CreateTime')
member_list = []
for record in member_records:
@@ -3936,7 +3936,7 @@ class AdckyhxqView(APIView):
'huiyuan_name': huiyuan.jieshao,
'daoqi_time': record.daoqi_time,
'is_active': record.huiyuan_zhuangtai == 1,
'create_time': record.create_time
'CreateTime': record.CreateTime
})
response_data['member_list'] = member_list
@@ -3957,7 +3957,7 @@ class AdckyhxqView(APIView):
'jinyuechongzhi': guanshi_profile.jinyuechongzhi,
'chongzhifenrun': guanshi_profile.chongzhifenrun,
'yue': guanshi_profile.yue, # 管事可提现余额
'create_time_guanshi': guanshi_profile.create_time
'CreateTime_guanshi': guanshi_profile.CreateTime
})
elif user_type == 4: # 商家
@@ -3978,7 +3978,7 @@ class AdckyhxqView(APIView):
'jinriliushui': shop_profile.jinriliushui,
'jinyuedingdan': shop_profile.jinyuedingdan,
'jinyueliushui': shop_profile.jinyueliushui,
'create_time_shop': shop_profile.create_time
'CreateTime_shop': shop_profile.CreateTime
})
# 获取所有会员列表(用于前端下拉选择)
@@ -4092,7 +4092,7 @@ class AdcjxgView(APIView):
'xiugaiid': zhanghao,
'leixing': user_type,
'qitashuoming': '',
'create_time': timezone.now()
'CreateTime': timezone.now()
}
# 标记是否有敏感字段被修改
@@ -4499,7 +4499,7 @@ class AddtxshView(APIView):
query &= Q(yonghuid=search_uid)
# 🔴【修改】排序改为按申请时间升序(最早申请排最前)
queryset = Tixianjilu.query.filter(query).order_by('create_time')
queryset = Tixianjilu.query.filter(query).order_by('CreateTime')
# 🔴【修改】分页逻辑:如果是搜索模式,不分页,返回所有匹配记录
if search_uid:
@@ -4541,8 +4541,8 @@ class AddtxshView(APIView):
'fangshi': record.fangshi,
'shenheid': record.shenheid,
'bhliyou': record.bhliyou,
'create_time': record.create_time,
'update_time': record.update_time
'CreateTime': record.CreateTime,
'UpdateTime': record.UpdateTime
})
return Response({
@@ -4628,7 +4628,7 @@ class AdtixianqkView(APIView):
if result == 3: # 拒绝
withdrawal.bhliyou = reason
withdrawal.update_time = timezone.now()
withdrawal.UpdateTime = timezone.now()
withdrawal.save()
# 🟢 新增:如果同意提现(result=2),更新收支记录表
@@ -4646,7 +4646,7 @@ class AdtixianqkView(APIView):
szjilu_record.TotalIncome -= tixian_jine # 总收益减去提现金额
szjilu_record.TotalExpense += tixian_jine # 总支出加上提现金额
szjilu_record.DailyExpense += tixian_jine # 今日支出加上提现金额
szjilu_record.update_time = timezone.now()
szjilu_record.UpdateTime = timezone.now()
szjilu_record.save()
except Szjilu.DoesNotExist:
@@ -4668,7 +4668,7 @@ class AdtixianqkView(APIView):
'id': withdrawal.id,
'zhuangtai': withdrawal.zhuangtai,
'shenheid': withdrawal.shenheid,
'update_time': withdrawal.update_time
'UpdateTime': withdrawal.UpdateTime
}
}, status=status.HTTP_200_OK)
@@ -6224,8 +6224,8 @@ class ChufaJiluHuoquView(APIView):
'sqzhuangtai': record.ApplyStatus or 0,
'ssliyou': record.AppealReason or '',
'jifen': record.DeductedPoints or 0,
'create_time': record.create_time.strftime('%Y-%m-%d %H:%M:%S') if record.create_time else '',
'update_time': record.update_time.strftime('%Y-%m-%d %H:%M:%S') if record.update_time else '',
'CreateTime': record.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if record.CreateTime else '',
'UpdateTime': record.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if record.UpdateTime else '',
'zhengju_tupian': zhengju_tupian, # 商家上传的证据图片
'shensu_tupian': shensu_tupian, # 打手上传的申诉图片
}
@@ -6402,8 +6402,8 @@ class DashouShensuView(APIView):
'shensu_liyou': shensu_liyou,
'shensu_tupian_urls': saved_tupian_urls,
'sqzhuangtai': chufa_record.ApplyStatus,
'update_time': chufa_record.update_time.strftime(
'%Y-%m-%d %H:%M:%S') if chufa_record.update_time else ''
'UpdateTime': chufa_record.UpdateTime.strftime(
'%Y-%m-%d %H:%M:%S') if chufa_record.UpdateTime else ''
}
# 记录操作日志
@@ -6652,8 +6652,8 @@ class ShangjiaChufaJiluHuoquView(APIView):
'sqzhuangtai': record.ApplyStatus or 0,
'ssliyou': record.AppealReason or '',
'jifen': record.DeductedPoints or 0,
'create_time': record.create_time.strftime('%Y-%m-%d %H:%M:%S') if record.create_time else '',
'update_time': record.update_time.strftime('%Y-%m-%d %H:%M:%S') if record.update_time else '',
'CreateTime': record.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if record.CreateTime else '',
'UpdateTime': record.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if record.UpdateTime else '',
'zhengju_tupian': zhengju_tupian, # 商家自己上传的证据图片
'shensu_tupian': shensu_tupian, # 打手上传的申诉图片
}
@@ -8481,7 +8481,7 @@ class KefuGetDashouListView(APIView):
# 4. 计算总数并分页
total = queryset.count()
offset = (page - 1) * page_size
dashou_list = queryset.order_by('-create_time')[offset:offset + page_size]
dashou_list = queryset.order_by('-CreateTime')[offset:offset + page_size]
# 5. 构建返回数据(只取需要的字段)
result = []
@@ -8584,7 +8584,7 @@ class KefuGetDashouDetailView(APIView):
'dianhua': '',
'wechat': '',
'phone': user_main.Phone or '',
'create_time': user_main.UserCreateTime,
'CreateTime': user_main.UserCreateTime,
'ip': user_main.IP or '',
'jiedanzongliang': 0,
'chengjiaozongliang': 0,
@@ -8620,7 +8620,7 @@ class KefuGetDashouDetailView(APIView):
'dianhua': dashou.dianhua or '',
'wechat': dashou.wechat or '',
'phone': user_main.Phone or '',
'create_time': user_main.UserCreateTime,
'CreateTime': user_main.UserCreateTime,
'ip': user_main.IP or '',
'jiedanzongliang': dashou.jiedanzongliang,
'chengjiaozongliang': dashou.chengjiaozongliang,
@@ -8639,7 +8639,7 @@ class KefuGetDashouDetailView(APIView):
# 5. 查询打手会员信息(仅未过期)
member_records = Huiyuangoumai.query.filter(
yonghu_id=uid
).order_by('-create_time')
).order_by('-CreateTime')
member_list = []
for record in member_records:
@@ -9047,8 +9047,8 @@ class KefuPunishmentListView(APIView):
'qingqiuid': item.ApplicantID,
'cfliyou': item.PenaltyReason,
'sqzhuangtai': item.ApplyStatus,
'create_time': item.CreateTime,
'update_time': item.UpdateTime,
'CreateTime': item.CreateTime,
'UpdateTime': item.UpdateTime,
# 其他字段按需添加
})
@@ -9282,8 +9282,8 @@ class KefuPunishmentDetailView(APIView):
'ssliyou': record.AppealReason or '',
'zhengju_tupian': zhengju_images,
'shensu_tupian': shensu_images,
'create_time': record.CreateTime,
'update_time': record.UpdateTime,
'CreateTime': record.CreateTime,
'UpdateTime': record.UpdateTime,
}
return Response({'code': 0, 'data': data})
@@ -9619,7 +9619,7 @@ if not kefu_txsh_list_logger.handlers:
_TIXIAN_LIST_BASE_FIELDS = (
'id', 'yonghuid', 'avatar', 'phone', 'nicheng', 'leixing',
'zhifu', 'skzhanghao', 'jine', 'zhuangtai', 'fangshi',
'shenheid', 'bhliyou', 'create_time', 'update_time',
'shenheid', 'bhliyou', 'CreateTime', 'UpdateTime',
)
_TIXIAN_LIST_AUDIT_FIELDS = ('shenhe_jilu_id', 'shenhe_danhao')
@@ -9773,7 +9773,7 @@ class KefuWithdrawListView(APIView):
q &= Q(yonghuid=search_uid)
if date_filter:
q &= Q(update_time__date=date_filter)
q &= Q(UpdateTime__date=date_filter)
if min_amount is not None and str(min_amount).strip() != '':
try:
@@ -9821,7 +9821,7 @@ class KefuWithdrawListView(APIView):
'total_amount': str(round(float(total_amount), 2)),
}
queryset = base_qs.order_by('create_time')
queryset = base_qs.order_by('CreateTime')
total = queryset.count()
records = list(queryset[(page - 1) * page_size: page * page_size])
@@ -9865,8 +9865,8 @@ class KefuWithdrawListView(APIView):
'dakuan_mode': self._resolve_row_dakuan_mode(item, audit_mode_map, shenhe_field_ok),
'shenheid': item.shenheid or '',
'bhliyou': item.bhliyou or '',
'create_time': item.create_time.strftime('%Y-%m-%d %H:%M:%S') if item.create_time else '',
'update_time': item.update_time.strftime('%Y-%m-%d %H:%M:%S') if item.update_time else '',
'CreateTime': item.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if item.CreateTime else '',
'UpdateTime': item.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if item.UpdateTime else '',
})
return Response({
@@ -9973,8 +9973,8 @@ class KefuWithdrawDetailView(APIView):
'fangshi': record.fangshi,
'shenheid': record.shenheid or '',
'bhliyou': record.bhliyou or '',
'create_time': record.create_time,
'update_time': record.update_time,
'CreateTime': record.CreateTime,
'UpdateTime': record.UpdateTime,
}
# 根据提现类型添加扩展信息
@@ -10145,11 +10145,11 @@ class KefuWithdrawActionView(APIView):
refund_balance(user, audit.leixing, audit.shijidaozhang)
tixian.shenheid = kefu_user.UserUID
tixian.bhliyou = limit_msg
tixian.save(update_fields=['shenheid', 'bhliyou', 'update_time'])
tixian.save(update_fields=['shenheid', 'bhliyou', 'UpdateTime'])
raise ValueError(f'提现记录{tixian_id}:{limit_msg},已自动驳回并退款')
sync_audit_and_jilu_status(audit, 6, shenhe_ren_id=kefu_user.UserUID)
tixian.shenheid = kefu_user.UserUID
tixian.save(update_fields=['shenheid', 'update_time'])
tixian.save(update_fields=['shenheid', 'UpdateTime'])
else:
sync_audit_and_jilu_status(
audit, 5,
@@ -10160,7 +10160,7 @@ class KefuWithdrawActionView(APIView):
refund_balance(user, audit.leixing, audit.shijidaozhang)
tixian.shenheid = kefu_user.UserUID
tixian.bhliyou = reason
tixian.save(update_fields=['shenheid', 'bhliyou', 'update_time'])
tixian.save(update_fields=['shenheid', 'bhliyou', 'UpdateTime'])
def _process_manual_item(self, item, action, reason, phone):
"""手动打款单条处理(原逻辑,须在 transaction.atomic 内调用)"""
@@ -10195,7 +10195,7 @@ class KefuWithdrawActionView(APIView):
szjilu.TotalIncome -= tixian.jine
szjilu.TotalExpense += tixian.jine
szjilu.DailyExpense += tixian.jine
szjilu.update_time = timezone.now()
szjilu.UpdateTime = timezone.now()
szjilu.save()
except Exception as e:
logger.error(f'更新收支记录失败: {e}')
@@ -10208,7 +10208,7 @@ class KefuWithdrawActionView(APIView):
tixian.bhliyou = reason
tixian.shenheid = phone
tixian.update_time = timezone.now()
tixian.UpdateTime = timezone.now()
tixian.save()
def post(self, request):
@@ -11482,7 +11482,7 @@ class DaShouFaKuanLieBiaoView(APIView):
yingxiang_qiangdan, shensuliyou, bohuiliyou,
zhengju_tupian: [...], // 证据图片(yongtu=1)
shensu_tupian: [...], // 申诉图片(yongtu=2)
create_time, update_time
CreateTime, UpdateTime
}],
has_more, page, page_size
}
@@ -11565,8 +11565,8 @@ class DaShouFaKuanLieBiaoView(APIView):
'bohuiliyou': r.RejectReason or '',
'zhengju_tupian': zhengju_map.get(rid, []), # 证据图片
'shensu_tupian': shensu_map.get(rid, []), # 申诉图片
'create_time': r.create_time.strftime('%Y-%m-%d %H:%M:%S') if r.create_time else '',
'update_time': r.update_time.strftime('%Y-%m-%d %H:%M:%S') if r.update_time else '',
'CreateTime': r.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if r.CreateTime else '',
'UpdateTime': r.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if r.UpdateTime else '',
}
chufa_list.append(item)