彻底解决了 create_time 的问题,将所有字段都改为了 CreateTime
This commit is contained in:
1 parent
90e0bde7f1
commit
e64697b64a
35 files changed
+4803
-4872
No files matched your search
@@ -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',
|
||||
|
||||
+18
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
File diff suppressed because it is too large.
Load diff
+260
-260
@@ -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()
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
+8
-8
@@ -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 '',
|
||||
|
||||
@@ -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
@@ -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
@@ -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. 是否有更多数据
|
||||
|
||||
@@ -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',
|
||||
|
||||
+23
@@ -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
@@ -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
@@ -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
@@ -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()
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 '',
|
||||
|
||||
@@ -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
@@ -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'
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
Reference in new issue
Block a user