进行了 backend 的重构,实验中
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-17 17:17
|
||||
# Generated by Django 4.2.27 on 2026-06-18 03:51
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@@ -11,173 +12,6 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Permission',
|
||||
fields=[
|
||||
('perm_id', models.AutoField(primary_key=True, serialize=False, verbose_name='权限ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '权限',
|
||||
'verbose_name_plural': '权限',
|
||||
'db_table': 'permission',
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Role',
|
||||
fields=[
|
||||
('role_id', models.AutoField(primary_key=True, serialize=False, verbose_name='角色ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '角色',
|
||||
'verbose_name_plural': '角色',
|
||||
'db_table': 'role',
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RolePermission',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '角色权限关联',
|
||||
'verbose_name_plural': '角色权限关联',
|
||||
'db_table': 'role_permission',
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserRole',
|
||||
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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户角色关联',
|
||||
'verbose_name_plural': '用户角色关联',
|
||||
'db_table': 'user_role',
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ZuzhangRiTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='组长用户ID')),
|
||||
('riqi', models.DateField(db_index=True, verbose_name='日期')),
|
||||
('yaoqing_guanshi_shu', models.IntegerField(default=0, verbose_name='邀请管事总数')),
|
||||
('shouru_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='收入总额(分佣)')),
|
||||
('fenyong_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='分佣金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '组长每日统计',
|
||||
'db_table': 'zuzhang_ri_tongji',
|
||||
'indexes': [models.Index(fields=['riqi', '-yaoqing_guanshi_shu'], name='zuzhang_ri__riqi_87169e_idx'), models.Index(fields=['riqi', '-shouru_zonge'], name='zuzhang_ri__riqi_1d7e51_idx')],
|
||||
'unique_together': {('yonghuid', 'riqi')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TixianRiTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('riqi', models.DateField(db_index=True, verbose_name='日期')),
|
||||
('leixing', models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '组长'), (4, '考核官'), (5, '打手押金'), (6, '商家余额')], verbose_name='用户类型')),
|
||||
('total_amount', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='当天提现总额(元)')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '每日提现统计',
|
||||
'db_table': 'tixian_ri_tongji',
|
||||
'indexes': [models.Index(fields=['riqi', 'leixing'], name='tixian_ri_t_riqi_c18bb2_idx')],
|
||||
'unique_together': {('riqi', 'leixing')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangjiaRiTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='商家用户ID')),
|
||||
('riqi', models.DateField(db_index=True, verbose_name='日期')),
|
||||
('paifa_dingdan_shu', models.IntegerField(default=0, verbose_name='派发订单总数')),
|
||||
('paifa_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='派发订单总金额')),
|
||||
('jiesuan_dingdan_shu', models.IntegerField(default=0, verbose_name='结算订单总数')),
|
||||
('jiesuan_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='结算总金额')),
|
||||
('tuikuan_dingdan_shu', models.IntegerField(default=0, verbose_name='退款订单总数')),
|
||||
('tuikuan_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='退款总金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家每日统计',
|
||||
'db_table': 'shangjia_ri_tongji',
|
||||
'indexes': [models.Index(fields=['riqi', '-paifa_jine'], name='shangjia_ri_riqi_d00f7f_idx'), models.Index(fields=['riqi', '-jiesuan_jine'], name='shangjia_ri_riqi_25772a_idx'), models.Index(fields=['riqi', '-paifa_dingdan_shu'], name='shangjia_ri_riqi_e05c54_idx')],
|
||||
'unique_together': {('yonghuid', 'riqi')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GuanshiXufeiRiTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='管事用户ID')),
|
||||
('riqi', models.DateField(db_index=True, verbose_name='日期')),
|
||||
('xufei_zongshu', models.IntegerField(default=0, verbose_name='今日续费总数')),
|
||||
('xufei_shouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='续费收益金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '管事续费每日统计',
|
||||
'db_table': 'guanshi_xufei_ri_tongji',
|
||||
'indexes': [models.Index(fields=['riqi', '-xufei_zongshu'], name='guanshi_xuf_riqi_7c128f_idx'), models.Index(fields=['riqi', '-xufei_shouyi'], name='guanshi_xuf_riqi_8f09b5_idx')],
|
||||
'unique_together': {('yonghuid', 'riqi')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GuanshiRiTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='管事用户ID')),
|
||||
('riqi', models.DateField(db_index=True, verbose_name='日期')),
|
||||
('yaoqing_dashou_shu', models.IntegerField(default=0, verbose_name='邀请打手总数')),
|
||||
('chongzhi_dashou_shu', models.IntegerField(default=0, verbose_name='充值打手数量')),
|
||||
('shouru_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='收入总额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '管事每日统计',
|
||||
'db_table': 'guanshi_ri_tongji',
|
||||
'indexes': [models.Index(fields=['riqi', '-yaoqing_dashou_shu'], name='guanshi_ri__riqi_075e1a_idx'), models.Index(fields=['riqi', '-chongzhi_dashou_shu'], name='guanshi_ri__riqi_78a79d_idx'), models.Index(fields=['riqi', '-shouru_zonge'], name='guanshi_ri__riqi_334f52_idx')],
|
||||
'unique_together': {('yonghuid', 'riqi')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DashouRiTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='打手用户ID')),
|
||||
('riqi', models.DateField(db_index=True, verbose_name='日期')),
|
||||
('jiedan_zongliang', models.IntegerField(default=0, verbose_name='接单总量')),
|
||||
('chengjiao_zongliang', models.IntegerField(default=0, verbose_name='成交单总量')),
|
||||
('jiedan_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='接单总金额')),
|
||||
('chengjiao_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='成交总金额')),
|
||||
('tuikuan_liang', models.IntegerField(default=0, verbose_name='退款订单量')),
|
||||
('tuikuan_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='退款总金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '打手每日统计',
|
||||
'db_table': 'dashou_ri_tongji',
|
||||
'indexes': [models.Index(fields=['riqi', '-jiedan_zongliang'], name='dashou_ri_t_riqi_95a785_idx'), models.Index(fields=['riqi', '-chengjiao_zongliang'], name='dashou_ri_t_riqi_ad9c1a_idx'), models.Index(fields=['riqi', '-jiedan_zonge'], name='dashou_ri_t_riqi_5da703_idx'), models.Index(fields=['riqi', '-chengjiao_zonge'], name='dashou_ri_t_riqi_0a3156_idx')],
|
||||
'unique_together': {('yonghuid', 'riqi')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AbnormalUserLog',
|
||||
fields=[
|
||||
@@ -200,7 +34,270 @@ class Migration(migrations.Migration):
|
||||
'verbose_name': '异常用户日志',
|
||||
'verbose_name_plural': '异常用户日志',
|
||||
'db_table': 'abnormal_user_log',
|
||||
'indexes': [models.Index(fields=['account_id'], name='abnormal_us_account_425899_idx'), models.Index(fields=['ip_address'], name='abnormal_us_ip_addr_3d612b_idx'), models.Index(fields=['create_time'], name='abnormal_us_create__ee16da_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LeaderDailyStats',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('LeaderID', models.CharField(db_column='yonghuid', db_index=True, max_length=7, verbose_name='组长用户ID')),
|
||||
('Date', models.DateField(db_column='riqi', db_index=True, verbose_name='日期')),
|
||||
('InvitedManagerCount', models.IntegerField(db_column='yaoqing_guanshi_shu', default=0, verbose_name='邀请管事总数')),
|
||||
('TotalIncome', models.DecimalField(db_column='shouru_zonge', decimal_places=2, default=0.0, max_digits=12, verbose_name='收入总额(分佣)')),
|
||||
('CommissionAmount', models.DecimalField(db_column='fenyong_jine', decimal_places=2, default=0.0, max_digits=12, verbose_name='分佣金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '组长每日统计',
|
||||
'db_table': 'zuzhang_ri_tongji',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ManagerDailyStats',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('ManagerID', models.CharField(db_column='yonghuid', db_index=True, max_length=7, verbose_name='管事用户ID')),
|
||||
('Date', models.DateField(db_column='riqi', db_index=True, verbose_name='日期')),
|
||||
('InvitedPlayerCount', models.IntegerField(db_column='yaoqing_dashou_shu', default=0, verbose_name='邀请打手总数')),
|
||||
('RechargedPlayerCount', models.IntegerField(db_column='chongzhi_dashou_shu', default=0, verbose_name='充值打手数量')),
|
||||
('TotalIncome', models.DecimalField(db_column='shouru_zonge', decimal_places=2, default=0.0, max_digits=12, verbose_name='收入总额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '管事每日统计',
|
||||
'db_table': 'guanshi_ri_tongji',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ManagerRenewalDailyStats',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('ManagerID', models.CharField(db_column='yonghuid', db_index=True, max_length=7, verbose_name='管事用户ID')),
|
||||
('Date', models.DateField(db_column='riqi', db_index=True, verbose_name='日期')),
|
||||
('RenewalTotal', models.IntegerField(db_column='xufei_zongshu', default=0, verbose_name='今日续费总数')),
|
||||
('RenewalRevenue', models.DecimalField(db_column='xufei_shouyi', decimal_places=2, default=0.0, max_digits=12, verbose_name='续费收益金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '管事续费每日统计',
|
||||
'db_table': 'guanshi_xufei_ri_tongji',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='MerchantDailyStats',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('MerchantID', models.CharField(db_column='yonghuid', db_index=True, max_length=7, verbose_name='商家用户ID')),
|
||||
('Date', models.DateField(db_column='riqi', db_index=True, verbose_name='日期')),
|
||||
('AssignedOrderCount', models.IntegerField(db_column='paifa_dingdan_shu', default=0, verbose_name='派发订单总数')),
|
||||
('AssignedAmount', models.DecimalField(db_column='paifa_jine', decimal_places=2, default=0.0, max_digits=12, verbose_name='派发订单总金额')),
|
||||
('SettledOrderCount', models.IntegerField(db_column='jiesuan_dingdan_shu', default=0, verbose_name='结算订单总数')),
|
||||
('SettledAmount', models.DecimalField(db_column='jiesuan_jine', decimal_places=2, default=0.0, max_digits=12, verbose_name='结算总金额')),
|
||||
('RefundOrderCount', models.IntegerField(db_column='tuikuan_dingdan_shu', default=0, verbose_name='退款订单总数')),
|
||||
('RefundAmount', models.DecimalField(db_column='tuikuan_jine', decimal_places=2, default=0.0, max_digits=12, verbose_name='退款总金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家每日统计',
|
||||
'db_table': 'shangjia_ri_tongji',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Permission',
|
||||
fields=[
|
||||
('perm_id', models.AutoField(primary_key=True, serialize=False, verbose_name='权限ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '权限',
|
||||
'verbose_name_plural': '权限',
|
||||
'db_table': 'permission',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PlayerDailyStats',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('PlayerID', models.CharField(db_column='yonghuid', db_index=True, max_length=7, verbose_name='打手用户ID')),
|
||||
('Date', models.DateField(db_column='riqi', db_index=True, verbose_name='日期')),
|
||||
('AcceptedOrderTotal', models.IntegerField(db_column='jiedan_zongliang', default=0, verbose_name='接单总量')),
|
||||
('CompletedOrderTotal', models.IntegerField(db_column='chengjiao_zongliang', default=0, verbose_name='成交单总量')),
|
||||
('AcceptedAmount', models.DecimalField(db_column='jiedan_zonge', decimal_places=2, default=0.0, max_digits=12, verbose_name='接单总金额')),
|
||||
('CompletedAmount', models.DecimalField(db_column='chengjiao_zonge', decimal_places=2, default=0.0, max_digits=12, verbose_name='成交总金额')),
|
||||
('RefundCount', models.IntegerField(db_column='tuikuan_liang', default=0, verbose_name='退款订单量')),
|
||||
('RefundAmount', models.DecimalField(db_column='tuikuan_jine', decimal_places=2, default=0.0, max_digits=12, verbose_name='退款总金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '打手每日统计',
|
||||
'db_table': 'dashou_ri_tongji',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Role',
|
||||
fields=[
|
||||
('role_id', models.AutoField(primary_key=True, serialize=False, verbose_name='角色ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '角色',
|
||||
'verbose_name_plural': '角色',
|
||||
'db_table': 'role',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='WithdrawalDailyStats',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('Date', models.DateField(db_column='riqi', db_index=True, verbose_name='日期')),
|
||||
('WithdrawalType', models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '组长'), (4, '考核官'), (5, '打手押金'), (6, '商家余额')], db_column='leixing', verbose_name='用户类型')),
|
||||
('total_amount', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='当天提现总额(元)')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '每日提现统计',
|
||||
'db_table': 'tixian_ri_tongji',
|
||||
'indexes': [models.Index(fields=['Date', 'WithdrawalType'], name='tixian_ri_t_riqi_c18bb2_idx')],
|
||||
'unique_together': {('Date', 'WithdrawalType')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserRole',
|
||||
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='更新时间')),
|
||||
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='backend.role', verbose_name='角色')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户角色关联',
|
||||
'verbose_name_plural': '用户角色关联',
|
||||
'db_table': 'user_role',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RolePermission',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('create_time', 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='角色')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '角色权限关联',
|
||||
'verbose_name_plural': '角色权限关联',
|
||||
'db_table': 'role_permission',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='role',
|
||||
index=models.Index(fields=['role_code'], name='role_role_co_b9f497_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='playerdailystats',
|
||||
index=models.Index(fields=['Date', '-AcceptedOrderTotal'], name='dashou_ri_t_riqi_95a785_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='playerdailystats',
|
||||
index=models.Index(fields=['Date', '-CompletedOrderTotal'], name='dashou_ri_t_riqi_ad9c1a_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='playerdailystats',
|
||||
index=models.Index(fields=['Date', '-AcceptedAmount'], name='dashou_ri_t_riqi_5da703_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='playerdailystats',
|
||||
index=models.Index(fields=['Date', '-CompletedAmount'], name='dashou_ri_t_riqi_0a3156_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='playerdailystats',
|
||||
unique_together={('PlayerID', 'Date')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='permission',
|
||||
index=models.Index(fields=['perm_code'], name='permission_perm_co_56cbe3_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='merchantdailystats',
|
||||
index=models.Index(fields=['Date', '-AssignedAmount'], name='shangjia_ri_riqi_d00f7f_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='merchantdailystats',
|
||||
index=models.Index(fields=['Date', '-SettledAmount'], name='shangjia_ri_riqi_25772a_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='merchantdailystats',
|
||||
index=models.Index(fields=['Date', '-AssignedOrderCount'], name='shangjia_ri_riqi_e05c54_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='merchantdailystats',
|
||||
unique_together={('MerchantID', 'Date')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='managerrenewaldailystats',
|
||||
index=models.Index(fields=['Date', '-RenewalTotal'], name='guanshi_xuf_riqi_7c128f_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='managerrenewaldailystats',
|
||||
index=models.Index(fields=['Date', '-RenewalRevenue'], name='guanshi_xuf_riqi_8f09b5_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='managerrenewaldailystats',
|
||||
unique_together={('ManagerID', 'Date')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='managerdailystats',
|
||||
index=models.Index(fields=['Date', '-InvitedPlayerCount'], name='guanshi_ri__riqi_075e1a_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='managerdailystats',
|
||||
index=models.Index(fields=['Date', '-RechargedPlayerCount'], name='guanshi_ri__riqi_78a79d_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='managerdailystats',
|
||||
index=models.Index(fields=['Date', '-TotalIncome'], name='guanshi_ri__riqi_334f52_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='managerdailystats',
|
||||
unique_together={('ManagerID', 'Date')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='leaderdailystats',
|
||||
index=models.Index(fields=['Date', '-InvitedManagerCount'], name='zuzhang_ri__riqi_87169e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='leaderdailystats',
|
||||
index=models.Index(fields=['Date', '-TotalIncome'], name='zuzhang_ri__riqi_1d7e51_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='leaderdailystats',
|
||||
unique_together={('LeaderID', 'Date')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='abnormaluserlog',
|
||||
index=models.Index(fields=['account_id'], name='abnormal_us_account_425899_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='abnormaluserlog',
|
||||
index=models.Index(fields=['ip_address'], name='abnormal_us_ip_addr_3d612b_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='abnormaluserlog',
|
||||
index=models.Index(fields=['create_time'], name='abnormal_us_create__ee16da_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userrole',
|
||||
unique_together={('account_id', 'role')},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='rolepermission',
|
||||
unique_together={('role', 'permission')},
|
||||
),
|
||||
]
|
||||
|
||||
@@ -17,7 +17,7 @@ class Role(QModel):
|
||||
db_table = 'role'
|
||||
verbose_name = '角色'
|
||||
verbose_name_plural = '角色'
|
||||
managed = False
|
||||
managed = True
|
||||
indexes = [
|
||||
models.Index(fields=['role_code']),
|
||||
]
|
||||
@@ -40,7 +40,7 @@ class Permission(QModel):
|
||||
db_table = 'permission'
|
||||
verbose_name = '权限'
|
||||
verbose_name_plural = '权限'
|
||||
managed = False
|
||||
managed = True
|
||||
indexes = [
|
||||
models.Index(fields=['perm_code']),
|
||||
]
|
||||
@@ -61,8 +61,8 @@ class RolePermission(QModel):
|
||||
db_table = 'role_permission'
|
||||
verbose_name = '角色权限关联'
|
||||
verbose_name_plural = '角色权限关联'
|
||||
managed = False
|
||||
unique_together = [['role', 'permission']] # 防止重复授权
|
||||
managed = True
|
||||
unique_together = [['role', 'permission']]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.role.role_name} -> {self.permission.perm_name}"
|
||||
@@ -72,7 +72,7 @@ class RolePermission(QModel):
|
||||
class UserRole(QModel):
|
||||
"""用户角色关联表"""
|
||||
id = models.AutoField(primary_key=True)
|
||||
account_id = models.CharField(max_length=11, db_index=True, verbose_name='账号ID') # 对应 UserMain 的 phone 字段
|
||||
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='更新时间')
|
||||
@@ -81,37 +81,28 @@ class UserRole(QModel):
|
||||
db_table = 'user_role'
|
||||
verbose_name = '用户角色关联'
|
||||
verbose_name_plural = '用户角色关联'
|
||||
managed = False
|
||||
unique_together = [['account_id', 'role']] # 同一用户同一角色只能有一条
|
||||
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')
|
||||
|
||||
# 地理位置信息(需借助第三方API,这里只存储请求时的IP,后续可离线解析)
|
||||
# 但我们可以存储更多请求细节
|
||||
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:
|
||||
@@ -128,148 +119,206 @@ class AbnormalUserLog(QModel):
|
||||
return f"{self.account_id} @ {self.ip_address} - {self.create_time}"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ShangjiaRiTongji(QModel):
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='商家用户ID')
|
||||
riqi = models.DateField(db_index=True, verbose_name='日期') # 年月日
|
||||
# ==================== 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='日期')
|
||||
|
||||
# 派发统计
|
||||
paifa_dingdan_shu = models.IntegerField(default=0, verbose_name='派发订单总数')
|
||||
paifa_jine = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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='派发订单总金额')
|
||||
|
||||
# 结算统计(成交)
|
||||
jiesuan_dingdan_shu = models.IntegerField(default=0, verbose_name='结算订单总数')
|
||||
jiesuan_jine = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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='结算总金额')
|
||||
|
||||
# 退款统计(可选)
|
||||
tuikuan_dingdan_shu = models.IntegerField(default=0, verbose_name='退款订单总数')
|
||||
tuikuan_jine = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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 = [['yonghuid', 'riqi']] # 每人每天一条记录
|
||||
unique_together = [['MerchantID', 'Date']]
|
||||
indexes = [
|
||||
models.Index(fields=['riqi', '-paifa_jine']),
|
||||
models.Index(fields=['riqi', '-jiesuan_jine']),
|
||||
models.Index(fields=['riqi', '-paifa_dingdan_shu']),
|
||||
models.Index(fields=['Date', '-AssignedAmount']),
|
||||
models.Index(fields=['Date', '-SettledAmount']),
|
||||
models.Index(fields=['Date', '-AssignedOrderCount']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"商家{self.MerchantID} {self.Date}"
|
||||
|
||||
|
||||
|
||||
|
||||
class DashouRiTongji(QModel):
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='打手用户ID')
|
||||
riqi = models.DateField(db_index=True, verbose_name='日期') # 年月日
|
||||
# ==================== 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='日期')
|
||||
|
||||
# 接单统计
|
||||
jiedan_zongliang = models.IntegerField(default=0, verbose_name='接单总量')
|
||||
chengjiao_zongliang = models.IntegerField(default=0, verbose_name='成交单总量')
|
||||
AcceptedOrderTotal = models.IntegerField(
|
||||
default=0, db_column='jiedan_zongliang', verbose_name='接单总量')
|
||||
CompletedOrderTotal = models.IntegerField(
|
||||
default=0, db_column='chengjiao_zongliang', verbose_name='成交单总量')
|
||||
|
||||
# 金额统计
|
||||
jiedan_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='接单总金额')
|
||||
chengjiao_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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='成交总金额')
|
||||
|
||||
# 退款统计
|
||||
tuikuan_liang = models.IntegerField(default=0, verbose_name='退款订单量')
|
||||
tuikuan_jine = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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 = [['yonghuid', 'riqi']]
|
||||
unique_together = [['PlayerID', 'Date']]
|
||||
indexes = [
|
||||
models.Index(fields=['riqi', '-jiedan_zongliang']),
|
||||
models.Index(fields=['riqi', '-chengjiao_zongliang']),
|
||||
models.Index(fields=['riqi', '-jiedan_zonge']),
|
||||
models.Index(fields=['riqi', '-chengjiao_zonge']),
|
||||
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}"
|
||||
|
||||
|
||||
class ZuzhangRiTongji(QModel):
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='组长用户ID')
|
||||
riqi = models.DateField(db_index=True, verbose_name='日期') # 年月日
|
||||
# ==================== 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='日期')
|
||||
|
||||
yaoqing_guanshi_shu = models.IntegerField(default=0, verbose_name='邀请管事总数')
|
||||
shouru_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='收入总额(分佣)')
|
||||
|
||||
# 可选明细
|
||||
fenyong_jine = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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 = [['yonghuid', 'riqi']]
|
||||
unique_together = [['LeaderID', 'Date']]
|
||||
indexes = [
|
||||
models.Index(fields=['riqi', '-yaoqing_guanshi_shu']),
|
||||
models.Index(fields=['riqi', '-shouru_zonge']),
|
||||
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='日期')
|
||||
|
||||
class GuanshiRiTongji(QModel):
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='管事用户ID')
|
||||
riqi = models.DateField(db_index=True, verbose_name='日期') # 年月日
|
||||
|
||||
yaoqing_dashou_shu = models.IntegerField(default=0, verbose_name='邀请打手总数')
|
||||
chongzhi_dashou_shu = models.IntegerField(default=0, verbose_name='充值打手数量')
|
||||
shouru_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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 = [['yonghuid', 'riqi']]
|
||||
unique_together = [['ManagerID', 'Date']]
|
||||
indexes = [
|
||||
models.Index(fields=['riqi', '-yaoqing_dashou_shu']),
|
||||
models.Index(fields=['riqi', '-chongzhi_dashou_shu']),
|
||||
models.Index(fields=['riqi', '-shouru_zonge']),
|
||||
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='日期')
|
||||
|
||||
class GuanshiXufeiRiTongji(QModel):
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='管事用户ID')
|
||||
riqi = models.DateField(db_index=True, verbose_name='日期') # 年月日
|
||||
|
||||
xufei_zongshu = models.IntegerField(default=0, verbose_name='今日续费总数') # 续费订单数(或续费打手数)
|
||||
xufei_shouyi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, 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 = [['yonghuid', 'riqi']]
|
||||
unique_together = [['ManagerID', 'Date']]
|
||||
indexes = [
|
||||
models.Index(fields=['riqi', '-xufei_zongshu']),
|
||||
models.Index(fields=['riqi', '-xufei_shouyi']),
|
||||
models.Index(fields=['Date', '-RenewalTotal']),
|
||||
models.Index(fields=['Date', '-RenewalRevenue']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"管事续费{self.ManagerID} {self.Date}"
|
||||
|
||||
|
||||
# models.py 中添加
|
||||
|
||||
class TixianRiTongji(QModel):
|
||||
"""
|
||||
每日提现统计表(按身份统计当天提现总额)
|
||||
"""
|
||||
riqi = models.DateField(db_index=True, verbose_name='日期')
|
||||
leixing = models.IntegerField(
|
||||
# ==================== 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, '商家余额')],
|
||||
verbose_name='用户类型'
|
||||
)
|
||||
total_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='当天提现总额(元)')
|
||||
(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 = [['riqi', 'leixing']] # 每天每个身份一条记录
|
||||
indexes = [models.Index(fields=['riqi', 'leixing'])]
|
||||
unique_together = [['Date', 'WithdrawalType']]
|
||||
indexes = [models.Index(fields=['Date', 'WithdrawalType'])]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.riqi} - {self.get_leixing_display()} 提现总额: {self.total_amount}"
|
||||
return f"{self.Date} - {self.get_WithdrawalType_display()} 提现总额: {self.total_amount}"
|
||||
|
||||
|
||||
# ==================== 兼容别名(供逐步迁移) ====================
|
||||
ShangjiaRiTongji = MerchantDailyStats
|
||||
DashouRiTongji = PlayerDailyStats
|
||||
ZuzhangRiTongji = LeaderDailyStats
|
||||
GuanshiRiTongji = ManagerDailyStats
|
||||
GuanshiXufeiRiTongji = ManagerRenewalDailyStats
|
||||
TixianRiTongji = WithdrawalDailyStats
|
||||
|
||||
231
backend/utils.py
231
backend/utils.py
@@ -5,8 +5,8 @@ from functools import lru_cache
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q
|
||||
from rest_framework.response import Response
|
||||
from .models import AbnormalUserLog, UserRole, Permission, DashouRiTongji, ShangjiaRiTongji, \
|
||||
GuanshiXufeiRiTongji, GuanshiRiTongji, ZuzhangRiTongji, TixianRiTongji
|
||||
from .models import AbnormalUserLog, UserRole, Permission, PlayerDailyStats, MerchantDailyStats, \
|
||||
ManagerRenewalDailyStats, ManagerDailyStats, LeaderDailyStats, WithdrawalDailyStats
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models import F
|
||||
@@ -129,36 +129,36 @@ def update_dashou_daily_by_action(yonghuid, amount, action):
|
||||
today = date.today()
|
||||
|
||||
with transaction.atomic():
|
||||
stat, created = DashouRiTongji.objects.select_for_update().get_or_create(
|
||||
yonghuid=yonghuid,
|
||||
riqi=today,
|
||||
stat, created = PlayerDailyStats.objects.select_for_update().get_or_create(
|
||||
PlayerID=yonghuid,
|
||||
Date=today,
|
||||
defaults={
|
||||
'yonghuid': yonghuid,
|
||||
'riqi': today,
|
||||
'jiedan_zongliang': 0,
|
||||
'jiedan_zonge': Decimal('0.00'),
|
||||
'chengjiao_zongliang': 0,
|
||||
'chengjiao_zonge': Decimal('0.00'),
|
||||
'tuikuan_liang': 0,
|
||||
'tuikuan_jine': Decimal('0.00'),
|
||||
'PlayerID': yonghuid,
|
||||
'Date': today,
|
||||
'AcceptedOrderTotal': 0,
|
||||
'AcceptedAmount': Decimal('0.00'),
|
||||
'CompletedOrderTotal': 0,
|
||||
'CompletedAmount': Decimal('0.00'),
|
||||
'RefundCount': 0,
|
||||
'RefundAmount': Decimal('0.00'),
|
||||
}
|
||||
)
|
||||
|
||||
update_fields = {}
|
||||
if action == 1: # 接单
|
||||
update_fields['jiedan_zongliang'] = F('jiedan_zongliang') + 1
|
||||
update_fields['jiedan_zonge'] = F('jiedan_zonge') + amount
|
||||
update_fields['AcceptedOrderTotal'] = F('AcceptedOrderTotal') + 1
|
||||
update_fields['AcceptedAmount'] = F('AcceptedAmount') + amount
|
||||
elif action == 2: # 成交
|
||||
update_fields['chengjiao_zongliang'] = F('chengjiao_zongliang') + 1
|
||||
update_fields['chengjiao_zonge'] = F('chengjiao_zonge') + amount
|
||||
update_fields['CompletedOrderTotal'] = F('CompletedOrderTotal') + 1
|
||||
update_fields['CompletedAmount'] = F('CompletedAmount') + amount
|
||||
elif action == 3: # 退款
|
||||
update_fields['tuikuan_liang'] = F('tuikuan_liang') + 1
|
||||
update_fields['tuikuan_jine'] = F('tuikuan_jine') + amount
|
||||
update_fields['RefundCount'] = F('RefundCount') + 1
|
||||
update_fields['RefundAmount'] = F('RefundAmount') + amount
|
||||
else:
|
||||
return # 无效行为
|
||||
|
||||
if update_fields:
|
||||
DashouRiTongji.query.filter(id=stat.id).update(**update_fields)
|
||||
PlayerDailyStats.query.filter(id=stat.id).update(**update_fields)
|
||||
|
||||
|
||||
def update_shangjia_daily(yonghuid, amount, action):
|
||||
@@ -183,38 +183,38 @@ def update_shangjia_daily(yonghuid, amount, action):
|
||||
|
||||
with transaction.atomic():
|
||||
# 获取或创建当天统计记录,同时加锁防止并发
|
||||
stat, created = ShangjiaRiTongji.objects.select_for_update().get_or_create(
|
||||
yonghuid=yonghuid,
|
||||
riqi=today,
|
||||
stat, created = MerchantDailyStats.objects.select_for_update().get_or_create(
|
||||
MerchantID=yonghuid,
|
||||
Date=today,
|
||||
defaults={
|
||||
'yonghuid': yonghuid,
|
||||
'riqi': today,
|
||||
'paifa_dingdan_shu': 0,
|
||||
'paifa_jine': Decimal('0.00'),
|
||||
'jiesuan_dingdan_shu': 0,
|
||||
'jiesuan_jine': Decimal('0.00'),
|
||||
'tuikuan_dingdan_shu': 0,
|
||||
'tuikuan_jine': Decimal('0.00'),
|
||||
'MerchantID': yonghuid,
|
||||
'Date': today,
|
||||
'AssignedOrderCount': 0,
|
||||
'AssignedAmount': Decimal('0.00'),
|
||||
'SettledOrderCount': 0,
|
||||
'SettledAmount': Decimal('0.00'),
|
||||
'RefundOrderCount': 0,
|
||||
'RefundAmount': Decimal('0.00'),
|
||||
}
|
||||
)
|
||||
|
||||
# 构建本次更新的字段,使用 F 表达式进行原子累加
|
||||
update_fields = {}
|
||||
if action == 1: # 派发
|
||||
update_fields['paifa_dingdan_shu'] = F('paifa_dingdan_shu') + 1
|
||||
update_fields['paifa_jine'] = F('paifa_jine') + amount
|
||||
update_fields['AssignedOrderCount'] = F('AssignedOrderCount') + 1
|
||||
update_fields['AssignedAmount'] = F('AssignedAmount') + amount
|
||||
elif action == 2: # 结算(成交)
|
||||
update_fields['jiesuan_dingdan_shu'] = F('jiesuan_dingdan_shu') + 1
|
||||
update_fields['jiesuan_jine'] = F('jiesuan_jine') + amount
|
||||
update_fields['SettledOrderCount'] = F('SettledOrderCount') + 1
|
||||
update_fields['SettledAmount'] = F('SettledAmount') + amount
|
||||
elif action == 3: # 退款
|
||||
update_fields['tuikuan_dingdan_shu'] = F('tuikuan_dingdan_shu') + 1
|
||||
update_fields['tuikuan_jine'] = F('tuikuan_jine') + amount
|
||||
update_fields['RefundOrderCount'] = F('RefundOrderCount') + 1
|
||||
update_fields['RefundAmount'] = F('RefundAmount') + amount
|
||||
else:
|
||||
# 无效的行为类型,直接返回
|
||||
return
|
||||
|
||||
# 执行原子更新
|
||||
ShangjiaRiTongji.query.filter(id=stat.id).update(**update_fields)
|
||||
MerchantDailyStats.query.filter(id=stat.id).update(**update_fields)
|
||||
|
||||
|
||||
|
||||
@@ -226,26 +226,26 @@ def update_guanshi_daily_by_action(yonghuid, action, amount=Decimal('0.00')):
|
||||
today = date.today()
|
||||
|
||||
with transaction.atomic():
|
||||
stat, created = GuanshiRiTongji.objects.select_for_update().get_or_create(
|
||||
yonghuid=yonghuid,
|
||||
riqi=today,
|
||||
stat, created = ManagerDailyStats.objects.select_for_update().get_or_create(
|
||||
ManagerID=yonghuid,
|
||||
Date=today,
|
||||
defaults={
|
||||
'yonghuid': yonghuid,
|
||||
'riqi': today,
|
||||
'yaoqing_dashou_shu': 0,
|
||||
'chongzhi_dashou_shu': 0,
|
||||
'shouru_zonge': Decimal('0.00'),
|
||||
'ManagerID': yonghuid,
|
||||
'Date': today,
|
||||
'InvitedPlayerCount': 0,
|
||||
'RechargedPlayerCount': 0,
|
||||
'TotalIncome': Decimal('0.00'),
|
||||
}
|
||||
)
|
||||
|
||||
if action == 1:
|
||||
# 邀请打手:无论新创建还是已存在,直接 +1
|
||||
if created:
|
||||
stat.yaoqing_dashou_shu = 1
|
||||
stat.InvitedPlayerCount = 1
|
||||
stat.save()
|
||||
else:
|
||||
GuanshiRiTongji.query.filter(id=stat.id).update(
|
||||
yaoqing_dashou_shu=F('yaoqing_dashou_shu') + 1
|
||||
ManagerDailyStats.query.filter(id=stat.id).update(
|
||||
InvitedPlayerCount=F('InvitedPlayerCount') + 1
|
||||
)
|
||||
|
||||
elif action == 2:
|
||||
@@ -253,13 +253,13 @@ def update_guanshi_daily_by_action(yonghuid, action, amount=Decimal('0.00')):
|
||||
if amount <= 0:
|
||||
return
|
||||
if created:
|
||||
stat.chongzhi_dashou_shu = 1
|
||||
stat.shouru_zonge = amount
|
||||
stat.RechargedPlayerCount = 1
|
||||
stat.TotalIncome = amount
|
||||
stat.save()
|
||||
else:
|
||||
GuanshiRiTongji.query.filter(id=stat.id).update(
|
||||
chongzhi_dashou_shu=F('chongzhi_dashou_shu') + 1,
|
||||
shouru_zonge=F('shouru_zonge') + amount
|
||||
ManagerDailyStats.query.filter(id=stat.id).update(
|
||||
RechargedPlayerCount=F('RechargedPlayerCount') + 1,
|
||||
TotalIncome=F('TotalIncome') + amount
|
||||
)
|
||||
|
||||
elif action in (3, 4):
|
||||
@@ -267,70 +267,13 @@ def update_guanshi_daily_by_action(yonghuid, action, amount=Decimal('0.00')):
|
||||
if amount <= 0:
|
||||
return
|
||||
if created:
|
||||
stat.shouru_zonge = amount
|
||||
stat.TotalIncome = amount
|
||||
stat.save()
|
||||
else:
|
||||
GuanshiRiTongji.query.filter(id=stat.id).update(
|
||||
shouru_zonge=F('shouru_zonge') + amount
|
||||
ManagerDailyStats.query.filter(id=stat.id).update(
|
||||
TotalIncome=F('TotalIncome') + amount
|
||||
)
|
||||
|
||||
'''def update_guanshi_daily_by_action(yonghuid, action, amount=Decimal('0.00')):
|
||||
"""
|
||||
根据操作行为更新管事每日统计(邀请打手、充值会员)
|
||||
|
||||
参数:
|
||||
yonghuid: 管事用户ID
|
||||
action: 操作类型
|
||||
1 = 邀请打手(次数自动+1,无需传其他参数)
|
||||
2 = 充值会员(需要传 amount 参数)
|
||||
amount: 充值金额(Decimal),仅在 action=2 时有效
|
||||
|
||||
说明:
|
||||
- 每次调用只代表一次操作,不会批量处理。
|
||||
- 使用 select_for_update + F() 保证原子性和并发安全。
|
||||
"""
|
||||
today = date.today()
|
||||
|
||||
# 邀请打手:次数+1,金额不变
|
||||
if action == 1:
|
||||
count_field = 'yaoqing_dashou_shu'
|
||||
amount = Decimal('0.00')
|
||||
|
||||
# 充值会员:次数+1,金额累加
|
||||
elif action == 2:
|
||||
amount = Decimal(str(amount)) if amount else Decimal('0.00')
|
||||
if amount <= 0:
|
||||
return
|
||||
count_field = 'chongzhi_dashou_shu'
|
||||
|
||||
else:
|
||||
return # 无效行为,直接返回
|
||||
|
||||
with transaction.atomic():
|
||||
stat, created = GuanshiRiTongji.objects.select_for_update().get_or_create(
|
||||
yonghuid=yonghuid,
|
||||
riqi=today,
|
||||
defaults={
|
||||
'yonghuid': yonghuid,
|
||||
'riqi': today,
|
||||
'yaoqing_dashou_shu': 0,
|
||||
'chongzhi_dashou_shu': 0,
|
||||
'shouru_zonge': Decimal('0.00'),
|
||||
}
|
||||
)
|
||||
|
||||
if created:
|
||||
# 新记录直接赋初值
|
||||
if action == 1:
|
||||
stat.yaoqing_dashou_shu = 1
|
||||
else:
|
||||
# 已存在记录,使用 F 表达式原子累加次数
|
||||
update_fields = {count_field: F(count_field) + 1}
|
||||
|
||||
if action == 2:
|
||||
update_fields['shouru_zonge'] = F('shouru_zonge') + amount
|
||||
|
||||
GuanshiRiTongji.query.filter(id=stat.id).update(**update_fields)'''
|
||||
|
||||
def update_guanshi_xufei_daily(yonghuid, xufei_jine=Decimal('0.00')):
|
||||
"""
|
||||
@@ -339,20 +282,20 @@ def update_guanshi_xufei_daily(yonghuid, xufei_jine=Decimal('0.00')):
|
||||
"""
|
||||
today = date.today()
|
||||
with transaction.atomic():
|
||||
stat, created = GuanshiXufeiRiTongji.objects.select_for_update().get_or_create(
|
||||
yonghuid=yonghuid,
|
||||
riqi=today,
|
||||
stat, created = ManagerRenewalDailyStats.objects.select_for_update().get_or_create(
|
||||
ManagerID=yonghuid,
|
||||
Date=today,
|
||||
defaults={
|
||||
'yonghuid': yonghuid,
|
||||
'riqi': today,
|
||||
'xufei_zongshu': 1,
|
||||
'xufei_shouyi': xufei_jine,
|
||||
'ManagerID': yonghuid,
|
||||
'Date': today,
|
||||
'RenewalTotal': 1,
|
||||
'RenewalRevenue': xufei_jine,
|
||||
}
|
||||
)
|
||||
if not created:
|
||||
GuanshiXufeiRiTongji.query.filter(id=stat.id).update(
|
||||
xufei_zongshu=F('xufei_zongshu') + 1,
|
||||
xufei_shouyi=F('xufei_shouyi') + xufei_jine
|
||||
ManagerRenewalDailyStats.query.filter(id=stat.id).update(
|
||||
RenewalTotal=F('RenewalTotal') + 1,
|
||||
RenewalRevenue=F('RenewalRevenue') + xufei_jine
|
||||
)
|
||||
|
||||
|
||||
@@ -370,39 +313,39 @@ def update_zuzhang_daily_by_action(yonghuid, action, amount=Decimal('0.00')):
|
||||
today = date.today()
|
||||
|
||||
with transaction.atomic():
|
||||
stat, created = ZuzhangRiTongji.objects.select_for_update().get_or_create(
|
||||
yonghuid=yonghuid,
|
||||
riqi=today,
|
||||
stat, created = LeaderDailyStats.objects.select_for_update().get_or_create(
|
||||
LeaderID=yonghuid,
|
||||
Date=today,
|
||||
defaults={
|
||||
'yonghuid': yonghuid,
|
||||
'riqi': today,
|
||||
'yaoqing_guanshi_shu': 0,
|
||||
'shouru_zonge': Decimal('0.00'),
|
||||
'fenyong_jine': Decimal('0.00'),
|
||||
'LeaderID': yonghuid,
|
||||
'Date': today,
|
||||
'InvitedManagerCount': 0,
|
||||
'TotalIncome': Decimal('0.00'),
|
||||
'CommissionAmount': Decimal('0.00'),
|
||||
}
|
||||
)
|
||||
|
||||
if created:
|
||||
# 新记录直接设置初始值
|
||||
if action == 1:
|
||||
stat.yaoqing_guanshi_shu = 1
|
||||
stat.InvitedManagerCount = 1
|
||||
elif action == 2:
|
||||
amount = Decimal(str(amount)) if amount else Decimal('0.00')
|
||||
stat.shouru_zonge = amount
|
||||
stat.fenyong_jine = amount
|
||||
stat.TotalIncome = amount
|
||||
stat.CommissionAmount = amount
|
||||
stat.save()
|
||||
else:
|
||||
# 已存在记录,使用 F 表达式原子累加
|
||||
if action == 1:
|
||||
ZuzhangRiTongji.query.filter(id=stat.id).update(
|
||||
yaoqing_guanshi_shu=F('yaoqing_guanshi_shu') + 1
|
||||
LeaderDailyStats.query.filter(id=stat.id).update(
|
||||
InvitedManagerCount=F('InvitedManagerCount') + 1
|
||||
)
|
||||
elif action == 2:
|
||||
amount = Decimal(str(amount)) if amount else Decimal('0.00')
|
||||
if amount > 0:
|
||||
ZuzhangRiTongji.query.filter(id=stat.id).update(
|
||||
shouru_zonge=F('shouru_zonge') + amount,
|
||||
fenyong_jine=F('fenyong_jine') + amount
|
||||
LeaderDailyStats.query.filter(id=stat.id).update(
|
||||
TotalIncome=F('TotalIncome') + amount,
|
||||
CommissionAmount=F('CommissionAmount') + amount
|
||||
)
|
||||
|
||||
|
||||
@@ -415,13 +358,13 @@ def update_tixian_daily_stat(leixing, amount):
|
||||
"""
|
||||
today = date.today()
|
||||
with transaction.atomic():
|
||||
stat, created = TixianRiTongji.objects.select_for_update().get_or_create(
|
||||
riqi=today,
|
||||
leixing=leixing,
|
||||
stat, created = WithdrawalDailyStats.objects.select_for_update().get_or_create(
|
||||
Date=today,
|
||||
WithdrawalType=leixing,
|
||||
defaults={'total_amount': amount}
|
||||
)
|
||||
if not created:
|
||||
TixianRiTongji.query.filter(id=stat.id).update(
|
||||
WithdrawalDailyStats.query.filter(id=stat.id).update(
|
||||
total_amount=F('total_amount') + amount
|
||||
)
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ from .utils import (
|
||||
|
||||
# models 集中导入
|
||||
## backend
|
||||
from backend.models import Role, Permission, RolePermission, UserRole, TixianRiTongji
|
||||
from backend.models import Role, Permission, RolePermission, UserRole, WithdrawalDailyStats
|
||||
|
||||
## users
|
||||
from users.models import (
|
||||
@@ -3329,10 +3329,10 @@ class GetWithdrawSettingsView(APIView):
|
||||
# 4. 当日已提现总额(按提现类型 leixing 1~6)
|
||||
today = date.today()
|
||||
today_totals = {i: 0.0 for i in range(1, 7)}
|
||||
records = TixianRiTongji.query.filter(riqi=today)
|
||||
records = WithdrawalDailyStats.query.filter(Date=today)
|
||||
for rec in records:
|
||||
if rec.leixing in today_totals:
|
||||
today_totals[rec.leixing] = float(rec.total_amount)
|
||||
if rec.WithdrawalType in today_totals:
|
||||
today_totals[rec.WithdrawalType] = float(rec.total_amount)
|
||||
|
||||
# 🆕 获取提现模式(自动1 / 手动2),默认2
|
||||
config = WithdrawConfig.query.filter(id=1).first()
|
||||
@@ -3358,7 +3358,7 @@ class UpdateWithdrawSettingsView(APIView):
|
||||
- 修改管事相关需要5500b
|
||||
- 修改组长相关需要5500c
|
||||
注意:修改每日总限额时,会联动影响“当日已提现总额”的显示(由前端实时计算),
|
||||
后端不直接修改 TixianRiTongji,该表由提现流程自动累加。
|
||||
后端不直接修改 WithdrawalDailyStats,该表由提现流程自动累加。
|
||||
POST /houtai/htxgtxsz
|
||||
"""
|
||||
permission_classes = []
|
||||
@@ -3491,7 +3491,7 @@ class UpdateWithdrawSettingsView(APIView):
|
||||
defaults={'mode': int(withdraw_mode)}
|
||||
)
|
||||
|
||||
# 注意:TixianRiTongji 表由提现流程自动更新,此处不直接修改
|
||||
# 注意:WithdrawalDailyStats 表由提现流程自动更新,此处不直接修改
|
||||
return Response({'code': 0, 'msg': '设置修改成功'})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user