进行了 GVSDSDK 迁移,可能存在诸多问题
This commit is contained in:
1 parent
72770ad73b
commit
d00f0d08e5
132 files changed
+161593
-4827
No files matched your search
@@ -132,12 +132,13 @@ AUTHENTICATION_BACKENDS = [
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
]
|
||||
|
||||
AUTH_USER_MODEL = 'users.UserMain'
|
||||
AUTH_USER_MODEL = 'gvsdsdk.User'
|
||||
|
||||
# ==================== DRF 配置 ====================
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
||||
'gvsdsdk.auth.elt_auth.ELTAuthentication',
|
||||
),
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
'rest_framework.permissions.IsAuthenticated',
|
||||
|
||||
+206
-296
@@ -1,296 +1,206 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-06 23:31
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="AbnormalUserLog",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"account_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=20, verbose_name="账号ID(phone)"
|
||||
),
|
||||
),
|
||||
(
|
||||
"ip_address",
|
||||
models.GenericIPAddressField(
|
||||
blank=True, null=True, verbose_name="IP地址"
|
||||
),
|
||||
),
|
||||
(
|
||||
"real_ip",
|
||||
models.GenericIPAddressField(
|
||||
blank=True, null=True, verbose_name="真实IP(穿透代理后)"
|
||||
),
|
||||
),
|
||||
(
|
||||
"x_forwarded_for",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=255,
|
||||
verbose_name="X-Forwarded-For",
|
||||
),
|
||||
),
|
||||
(
|
||||
"user_agent",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=500,
|
||||
verbose_name="User-Agent",
|
||||
),
|
||||
),
|
||||
(
|
||||
"request_method",
|
||||
models.CharField(
|
||||
blank=True, default="", max_length=10, verbose_name="请求方法"
|
||||
),
|
||||
),
|
||||
(
|
||||
"request_path",
|
||||
models.CharField(
|
||||
blank=True, default="", max_length=500, 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(
|
||||
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="创建时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "异常用户日志",
|
||||
"verbose_name_plural": "异常用户日志",
|
||||
"db_table": "abnormal_user_log",
|
||||
},
|
||||
),
|
||||
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",
|
||||
},
|
||||
),
|
||||
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",
|
||||
},
|
||||
),
|
||||
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",
|
||||
},
|
||||
),
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="role",
|
||||
index=models.Index(fields=["role_code"], name="role_role_co_b9f497_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="permission",
|
||||
index=models.Index(
|
||||
fields=["perm_code"], name="permission_perm_co_56cbe3_idx"
|
||||
),
|
||||
),
|
||||
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")},
|
||||
),
|
||||
]
|
||||
# Generated by Django 4.2.27 on 2026-06-17 17:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
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=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('account_id', models.CharField(db_index=True, max_length=20, verbose_name='账号ID(phone)')),
|
||||
('ip_address', models.GenericIPAddressField(blank=True, null=True, verbose_name='IP地址')),
|
||||
('real_ip', models.GenericIPAddressField(blank=True, null=True, verbose_name='真实IP(穿透代理后)')),
|
||||
('x_forwarded_for', models.CharField(blank=True, default='', max_length=255, verbose_name='X-Forwarded-For')),
|
||||
('user_agent', models.CharField(blank=True, default='', max_length=500, verbose_name='User-Agent')),
|
||||
('request_method', models.CharField(blank=True, default='', max_length=10, verbose_name='请求方法')),
|
||||
('request_path', models.CharField(blank=True, default='', max_length=500, 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(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='创建时间')),
|
||||
],
|
||||
options={
|
||||
'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')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,339 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-09 14:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("backend", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
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="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")},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,54 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-10 18:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("backend", "0002_zuzhangritongji_shangjiaritongji_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
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, "组长")],
|
||||
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")},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,34 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-15 01:42
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('backend', '0003_tixianritongji'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='rolepermission',
|
||||
name='permission',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='backend.permission', verbose_name='权限'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rolepermission',
|
||||
name='role',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='backend.role', verbose_name='角色'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='tixianritongji',
|
||||
name='leixing',
|
||||
field=models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '组长'), (4, '考核官'), (5, '打手押金'), (6, '商家余额')], verbose_name='用户类型'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='userrole',
|
||||
name='role',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='backend.role', verbose_name='角色'),
|
||||
),
|
||||
]
|
||||
Whitespace-only changes.
@@ -17,6 +17,7 @@ class Role(QModel):
|
||||
db_table = 'role'
|
||||
verbose_name = '角色'
|
||||
verbose_name_plural = '角色'
|
||||
managed = False
|
||||
indexes = [
|
||||
models.Index(fields=['role_code']),
|
||||
]
|
||||
@@ -39,6 +40,7 @@ class Permission(QModel):
|
||||
db_table = 'permission'
|
||||
verbose_name = '权限'
|
||||
verbose_name_plural = '权限'
|
||||
managed = False
|
||||
indexes = [
|
||||
models.Index(fields=['perm_code']),
|
||||
]
|
||||
@@ -59,6 +61,7 @@ class RolePermission(QModel):
|
||||
db_table = 'role_permission'
|
||||
verbose_name = '角色权限关联'
|
||||
verbose_name_plural = '角色权限关联'
|
||||
managed = False
|
||||
unique_together = [['role', 'permission']] # 防止重复授权
|
||||
|
||||
def __str__(self):
|
||||
@@ -78,6 +81,7 @@ class UserRole(QModel):
|
||||
db_table = 'user_role'
|
||||
verbose_name = '用户角色关联'
|
||||
verbose_name_plural = '用户角色关联'
|
||||
managed = False
|
||||
unique_together = [['account_id', 'role']] # 同一用户同一角色只能有一条
|
||||
|
||||
def __str__(self):
|
||||
|
||||
+37
-36
@@ -56,9 +56,10 @@ from backend.models import Role, Permission, RolePermission, UserRole, TixianRiT
|
||||
|
||||
## users
|
||||
from users.models import (
|
||||
UserMain, UserGuanshi, UserBoss, UserZuzhang,
|
||||
UserGuanshi, UserBoss, UserZuzhang,
|
||||
UserKefu, UserDashou, Xiugaijilu, UserShangjia, UserShenheguan
|
||||
)
|
||||
from gvsdsdk.models import User
|
||||
|
||||
## orders
|
||||
from orders.models import (
|
||||
@@ -315,7 +316,7 @@ class GetAdminUserListView(APIView):
|
||||
page = int(request.data.get('page', 1))
|
||||
page_size = int(request.data.get('pageSize', 20))
|
||||
|
||||
users = UserMain.query.filter(
|
||||
users = User.query.filter(
|
||||
user_type='kefu',
|
||||
kefu_profile__isnull=False
|
||||
).select_related('kefu_profile')
|
||||
@@ -420,7 +421,7 @@ class GetAdminRolesView(APIView):
|
||||
page_size = int(request.data.get('pageSize', 20))
|
||||
|
||||
# 基础查询:user_type='kefu' 且存在客服扩展表
|
||||
users = UserMain.query.filter(user_type='kefu', kefu_profile__isnull=False).select_related('kefu_profile')
|
||||
users = User.query.filter(user_type='kefu', kefu_profile__isnull=False).select_related('kefu_profile')
|
||||
if phone:
|
||||
users = users.filter(phone__icontains=phone)
|
||||
if nicheng:
|
||||
@@ -487,9 +488,9 @@ class ModifyAdminUserView(APIView):
|
||||
return Response({'code': 400, 'msg': '缺少目标用户账号'})
|
||||
|
||||
try:
|
||||
target_user = UserMain.query.get(phone=target_phone, user_type='kefu')
|
||||
target_user = User.query.get(phone=target_phone, user_type='kefu')
|
||||
target_kefu = target_user.kefu_profile
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不存在'})
|
||||
except UserKefu.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户扩展信息缺失'})
|
||||
@@ -574,25 +575,25 @@ class AddAdminUserView(APIView):
|
||||
return Response({'code': 400, 'msg': '密码和二级密码至少6位'})
|
||||
|
||||
# 校验手机号是否已被占用(且 user_type='kefu')
|
||||
if UserMain.query.filter(phone=phone, user_type='kefu').exists():
|
||||
if User.query.filter(phone=phone, user_type='kefu').exists():
|
||||
return Response({'code': 400, 'msg': '该账号已存在'})
|
||||
|
||||
# 生成唯一的 yonghuid(7位数字)
|
||||
while True:
|
||||
yonghuid = str(random.randint(1000000, 9999999))
|
||||
if not UserMain.query.filter(yonghuid=yonghuid).exists():
|
||||
if not User.query.filter(yonghuid=yonghuid).exists():
|
||||
break
|
||||
|
||||
# 生成唯一的 openid(格式:admin_{时间戳}_{随机6位})
|
||||
timestamp = str(int(time.time() * 1000))
|
||||
random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
||||
openid = f"admin_{timestamp}_{random_suffix}"
|
||||
while UserMain.query.filter(openid=openid).exists():
|
||||
while User.query.filter(openid=openid).exists():
|
||||
random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
||||
openid = f"admin_{timestamp}_{random_suffix}"
|
||||
|
||||
with transaction.atomic():
|
||||
user_main = UserMain.query.create(
|
||||
user_main = User.query.create(
|
||||
yonghuid=yonghuid,
|
||||
openid=openid,
|
||||
phone=phone,
|
||||
@@ -756,10 +757,10 @@ class KefuGetDashouDetailView(APIView):
|
||||
|
||||
# 4. 查询打手主表和扩展表
|
||||
try:
|
||||
user_main = UserMain.query.select_related('dashou_profile').get(
|
||||
user_main = User.query.select_related('dashou_profile').get(
|
||||
yonghuid=uid
|
||||
)
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '打手不存在'})
|
||||
|
||||
try:
|
||||
@@ -913,10 +914,10 @@ class KefuGetDashouDetailView(APIView):
|
||||
# 3. 查询打手主表和扩展表
|
||||
try:
|
||||
# 使用 select_related 预加载 dashou_profile,减少数据库查询
|
||||
user_main = UserMain.query.select_related('dashou_profile').get(
|
||||
user_main = User.query.select_related('dashou_profile').get(
|
||||
yonghuid=uid
|
||||
)
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '打手不存在'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# 验证用户类型是否为打手(可选,但建议验证)
|
||||
@@ -1063,9 +1064,9 @@ class KefuUpdateDashouView(APIView):
|
||||
|
||||
# 3. 查询打手
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=dashou_id)
|
||||
dashou_profile = dashou_user.dashou_profile
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '打手不存在'})
|
||||
except UserDashou.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '打手扩展信息缺失'})
|
||||
@@ -2837,8 +2838,8 @@ class GetGuanliListView(APIView):
|
||||
invite_count_value = request.data.get('invite_count_value')
|
||||
status = request.data.get('status')
|
||||
|
||||
# 构建查询:从 UserMain 开始,关联 UserGuanshi 和 UserBoss(左连接获取昵称)
|
||||
qs = UserMain.query.filter(
|
||||
# 构建查询:从 User 开始,关联 UserGuanshi 和 UserBoss(左连接获取昵称)
|
||||
qs = User.query.filter(
|
||||
guanshi_profile__isnull=False # 确保是管事
|
||||
).select_related('guanshi_profile').select_related('boss_profile')
|
||||
|
||||
@@ -2967,10 +2968,10 @@ class GetGuanliDetailView(APIView):
|
||||
|
||||
# 查询用户主表和管事扩展表
|
||||
try:
|
||||
user = UserMain.query.select_related('guanshi_profile', 'boss_profile').get(yonghuid=yonghuid)
|
||||
user = User.query.select_related('guanshi_profile', 'boss_profile').get(yonghuid=yonghuid)
|
||||
guanshi = user.guanshi_profile
|
||||
boss = user.boss_profile if hasattr(user, 'boss_profile') else None
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '管事不存在'})
|
||||
except UserGuanshi.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不是管事'})
|
||||
@@ -3088,10 +3089,10 @@ class UpdateGuanliView(APIView):
|
||||
|
||||
# 查询管事对象(不在事务外加锁,事务内加锁)
|
||||
try:
|
||||
user = UserMain.query.get(yonghuid=yonghuid)
|
||||
user = User.query.get(yonghuid=yonghuid)
|
||||
guanshi = user.guanshi_profile
|
||||
boss = user.boss_profile if hasattr(user, 'boss_profile') else None
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不存在'})
|
||||
except UserGuanshi.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不是管事'})
|
||||
@@ -3099,7 +3100,7 @@ class UpdateGuanliView(APIView):
|
||||
# 开始事务,内部使用 select_for_update
|
||||
with transaction.atomic():
|
||||
# 重新获取加锁对象
|
||||
user = UserMain.objects.select_for_update().get(yonghuid=yonghuid)
|
||||
user = User.objects.select_for_update().get(yonghuid=yonghuid)
|
||||
guanshi = user.guanshi_profile
|
||||
boss = user.boss_profile if hasattr(user, 'boss_profile') else None
|
||||
|
||||
@@ -3659,10 +3660,10 @@ class GetZuzhangDetailView(APIView):
|
||||
|
||||
# 查询组长主表、扩展表、老板扩展表(昵称)
|
||||
try:
|
||||
user = UserMain.query.select_related('zuzhang_profile', 'boss_profile').get(yonghuid=yonghuid)
|
||||
user = User.query.select_related('zuzhang_profile', 'boss_profile').get(yonghuid=yonghuid)
|
||||
zuzhang = user.zuzhang_profile
|
||||
boss = user.boss_profile if hasattr(user, 'boss_profile') else None
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '组长不存在'})
|
||||
except UserZuzhang.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不是组长'})
|
||||
@@ -3672,7 +3673,7 @@ class GetZuzhangDetailView(APIView):
|
||||
'yonghuid': user.yonghuid,
|
||||
'nickname': boss.nickname if boss else '',
|
||||
'avatar': user.avatar or '',
|
||||
'dianhua': '', # 组长表无电话字段?组长扩展表没有电话/微信,但前端可能需要,可从UserMain关联?实际上组长表无电话字段,这里留空或从其他表获取
|
||||
'dianhua': '', # 组长表无电话字段?组长扩展表没有电话/微信,但前端可能需要,可从User关联?实际上组长表无电话字段,这里留空或从其他表获取
|
||||
'wechat': '',
|
||||
'zhuangtai': zuzhang.zhuangtai,
|
||||
'yaoqingma': zuzhang.yaoqingma,
|
||||
@@ -3782,10 +3783,10 @@ class UpdateZuzhangView(APIView):
|
||||
|
||||
# 查询组长对象
|
||||
try:
|
||||
user = UserMain.query.get(yonghuid=yonghuid)
|
||||
user = User.query.get(yonghuid=yonghuid)
|
||||
zuzhang = user.zuzhang_profile
|
||||
boss = user.boss_profile if hasattr(user, 'boss_profile') else None
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不存在'})
|
||||
except UserZuzhang.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不是组长'})
|
||||
@@ -3820,7 +3821,7 @@ class UpdateZuzhangView(APIView):
|
||||
if avatar:
|
||||
user.avatar = avatar
|
||||
user.save()
|
||||
# 组长表没有电话/微信字段,如需存储可暂存到UserMain或忽略
|
||||
# 组长表没有电话/微信字段,如需存储可暂存到User或忽略
|
||||
# 这里不处理
|
||||
|
||||
# ---------- 2. 可提现金额修改(加:6600a;减:6600b)----------
|
||||
@@ -5025,7 +5026,7 @@ class ShopModifyView(APIView):
|
||||
return Response({'code': 400, 'msg': '必填字段缺失(用户ID、账号、密码、店铺名称)'})
|
||||
|
||||
# 检查用户是否存在
|
||||
if not UserMain.query.filter(yonghuid=yonghu_id).exists():
|
||||
if not User.query.filter(yonghuid=yonghu_id).exists():
|
||||
return Response({'code': 404, 'msg': '用户不存在'})
|
||||
|
||||
# 检查凭证是否已存在
|
||||
@@ -5961,11 +5962,11 @@ class FaKuanChuangJianView(APIView):
|
||||
|
||||
# 验证用户是否存在对应的扩展表
|
||||
try:
|
||||
user = UserMain.query.get(yonghuid=beichufa_id)
|
||||
user = User.query.get(yonghuid=beichufa_id)
|
||||
profile_attr = SHENFEN_PROFILE_MAP.get(shenfen)
|
||||
if not profile_attr or not hasattr(user, profile_attr):
|
||||
return Response({'code': 400, 'msg': '该用户不是所选身份'})
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '用户不存在'})
|
||||
|
||||
# 处理图片上传
|
||||
@@ -6161,9 +6162,9 @@ class PunishDashouView(APIView):
|
||||
|
||||
# 查询打手
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=dashou_id)
|
||||
dashou = dashou_user.dashou_profile
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 404, 'msg': '打手用户不存在'})
|
||||
except ObjectDoesNotExist:
|
||||
return Response({'code': 400, 'msg': '该用户不是打手'})
|
||||
@@ -8188,7 +8189,7 @@ class ZxkfghdsView(APIView):
|
||||
shangjia_ext = old_order.shangjia_kuozhan
|
||||
shangjia_id = shangjia_ext.shangjia_id
|
||||
# 获取商家昵称用于新订单扩展表
|
||||
shangjia_user = UserMain.query.get(yonghuid=shangjia_id)
|
||||
shangjia_user = User.query.get(yonghuid=shangjia_id)
|
||||
shangjia_nicheng = shangjia_user.shop_profile.nicheng or f"商家{shangjia_id}"
|
||||
except (ObjectDoesNotExist, UserShangjia.DoesNotExist):
|
||||
logger.error(f"商家信息缺失,订单: {dingdan_id}")
|
||||
@@ -8205,12 +8206,12 @@ class ZxkfghdsView(APIView):
|
||||
dashou_id = old_order.jiedan_dashou_id
|
||||
if dashou_id:
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=dashou_id)
|
||||
dashou_profile = dashou_user.dashou_profile
|
||||
dashou_profile.tuikuanliang += 1 # 退款次数+1
|
||||
dashou_profile.zhuangtai = 1 # 设为空闲
|
||||
dashou_profile.save()
|
||||
except (UserMain.DoesNotExist, ObjectDoesNotExist):
|
||||
except (User.DoesNotExist, ObjectDoesNotExist):
|
||||
logger.warning(f"打手 {dashou_id} 不存在,跳过更新")
|
||||
|
||||
# 5.3 更新退款记录表
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
"""检查 user_dashou 中有 user_id 的记录"""
|
||||
import re
|
||||
|
||||
with open('xaio_cheng_xu_backup.sql', 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
pattern = re.compile(r"INSERT\s+INTO\s+`user_dashou`\s+VALUES\s*\((.+?)\)\s*;", re.IGNORECASE | re.DOTALL)
|
||||
matches = list(pattern.finditer(content))
|
||||
|
||||
# 找有 user_id 的记录
|
||||
has_uid = 0
|
||||
no_uid = 0
|
||||
uid_values = []
|
||||
for m in matches:
|
||||
v = m.group(1).rstrip()
|
||||
if v.endswith('NULL'):
|
||||
no_uid += 1
|
||||
else:
|
||||
has_uid += 1
|
||||
# 提取最后一个值(user_id)
|
||||
last_comma = v.rfind(',')
|
||||
uid_val = v[last_comma+1:].strip()
|
||||
uid_values.append(uid_val)
|
||||
|
||||
print(f"有 user_id: {has_uid}, 无 user_id: {no_uid}")
|
||||
print(f"user_id 值样本: {uid_values[:10]}")
|
||||
|
||||
# 检查 user_main 中这些 user_id 是否存在
|
||||
# user_main 的 id 字段是 vals[1]
|
||||
main_pattern = re.compile(r"INSERT\s+INTO\s+`user_main`\s+VALUES\s*\((.+?)\)\s*;", re.IGNORECASE | re.DOTALL)
|
||||
main_ids = set()
|
||||
for m in main_pattern.finditer(content):
|
||||
# 简单提取第二个字段 (id)
|
||||
v = m.group(1)
|
||||
# 找前几个逗号
|
||||
in_q = False
|
||||
commas = []
|
||||
for i, ch in enumerate(v):
|
||||
if ch == "'": in_q = not in_q
|
||||
elif ch == ',' and not in_q:
|
||||
commas.append(i)
|
||||
if len(commas) >= 2: break
|
||||
if len(commas) >= 2:
|
||||
id_val = v[commas[0]+1:commas[1]].strip()
|
||||
main_ids.add(id_val)
|
||||
|
||||
print(f"\nuser_main id 范围: {len(main_ids)} 个")
|
||||
matched = sum(1 for uid in uid_values if uid in main_ids)
|
||||
print(f"user_dashou user_id 匹配 user_main: {matched}/{len(uid_values)}")
|
||||
|
||||
# 也检查 user_type 分布
|
||||
type_pattern = re.compile(r"INSERT\s+INTO\s+`user_main`\s+VALUES\s*\((.+?)\)\s*;", re.IGNORECASE | re.DOTALL)
|
||||
type_counts = {}
|
||||
for m in type_pattern.finditer(content):
|
||||
v = m.group(1)
|
||||
# 找第12个字段 (user_type, index 11)
|
||||
in_q = False
|
||||
commas = []
|
||||
for i, ch in enumerate(v):
|
||||
if ch == "'": in_q = not in_q
|
||||
elif ch == ',' and not in_q:
|
||||
commas.append(i)
|
||||
if len(commas) >= 12: break
|
||||
if len(commas) >= 12:
|
||||
type_val = v[commas[10]+1:commas[11]].strip().strip("'")
|
||||
type_counts[type_val] = type_counts.get(type_val, 0) + 1
|
||||
|
||||
print(f"\nuser_type 分布: {type_counts}")
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
"""检查数据库表行数"""
|
||||
import MySQLdb
|
||||
from app_secrets import DATABASE_HOST, DATABASE_PORT, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME
|
||||
|
||||
conn = MySQLdb.connect(
|
||||
host=DATABASE_HOST, port=int(DATABASE_PORT),
|
||||
user=DATABASE_USER, password=DATABASE_PASSWORD,
|
||||
database=DATABASE_NAME
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(
|
||||
"SELECT TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES "
|
||||
"WHERE TABLE_SCHEMA = %s ORDER BY TABLE_NAME",
|
||||
[DATABASE_NAME]
|
||||
)
|
||||
for row in cursor.fetchall():
|
||||
print(f"{row[0]:40s} {row[1]}")
|
||||
conn.close()
|
||||
@@ -1,92 +1,296 @@
|
||||
# Generated by Django 5.2.10 on 2026-01-14 19:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Gonggao',
|
||||
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='更改时间')),
|
||||
('jieshao', models.TextField(blank=True, null=True, verbose_name='公告介绍')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '公告',
|
||||
'verbose_name_plural': '公告',
|
||||
'db_table': 'gonggao',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Lunbo',
|
||||
fields=[
|
||||
('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='更改时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '轮播',
|
||||
'verbose_name_plural': '轮播',
|
||||
'db_table': 'lunbo',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Qunpeizhi',
|
||||
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='更改时间')),
|
||||
('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='介绍')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'qunpeizhi',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Szjilu',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='记录ID')),
|
||||
('zongsy', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='总收益')),
|
||||
('zongls', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='总流水')),
|
||||
('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='更改时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '收支记录',
|
||||
'verbose_name_plural': '收支记录',
|
||||
'db_table': 'szjilu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Tupianpeizhi',
|
||||
fields=[
|
||||
('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='更改时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '配置图片',
|
||||
'verbose_name_plural': '配置图片',
|
||||
'db_table': 'tupianpeizhi',
|
||||
},
|
||||
),
|
||||
]
|
||||
# Generated by Django 4.2.27 on 2026-06-17 16:31
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Gonggao',
|
||||
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='更改时间')),
|
||||
('jieshao', models.TextField(blank=True, null=True, verbose_name='公告介绍')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '公告',
|
||||
'verbose_name_plural': '公告',
|
||||
'db_table': 'gonggao',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Lunbo',
|
||||
fields=[
|
||||
('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='更改时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '轮播',
|
||||
'verbose_name_plural': '轮播',
|
||||
'db_table': 'lunbo',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PopupConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('popup_id', models.CharField(max_length=50, verbose_name='弹窗唯一ID')),
|
||||
('title', models.CharField(blank=True, max_length=200, verbose_name='标题(后台用)')),
|
||||
('description', models.TextField(blank=True, verbose_name='描述(后台用)')),
|
||||
('strategy_type', models.CharField(choices=[('once', '仅一次'), ('daily', '每日'), ('weekly', '每周'), ('monthly', '每月'), ('yearly', '每年'), ('always', '始终'), ('count', '周期内次数限制')], default='once', max_length=20)),
|
||||
('max_count', models.PositiveIntegerField(default=1, verbose_name='周期内最大展示次数')),
|
||||
('reset_interval', models.CharField(blank=True, choices=[('day', '天'), ('week', '周'), ('month', '月'), ('year', '年')], max_length=20, verbose_name='重置周期(count类型时使用)')),
|
||||
('duration', models.PositiveIntegerField(default=0, verbose_name='强制阅读秒数(0=无强制)')),
|
||||
('force_even_muted', models.BooleanField(default=False, verbose_name='强制弹出(忽略用户今日屏蔽)')),
|
||||
('sort_order', models.PositiveIntegerField(default=0, verbose_name='展示顺序')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='是否启用')),
|
||||
('start_time', models.DateTimeField(blank=True, null=True, verbose_name='生效开始时间')),
|
||||
('end_time', models.DateTimeField(blank=True, null=True, verbose_name='生效结束时间')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '弹窗配置',
|
||||
'verbose_name_plural': '弹窗配置',
|
||||
'db_table': 'popup_config',
|
||||
'ordering': ['sort_order', 'id'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PopupPage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('page_key', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='页面标识')),
|
||||
('name', models.CharField(max_length=100, verbose_name='页面名称')),
|
||||
('description', models.TextField(blank=True, verbose_name='描述')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='是否启用')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('ignore_user_mute', models.BooleanField(default=False, verbose_name='忽略用户今日屏蔽')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '弹窗页面',
|
||||
'verbose_name_plural': '弹窗页面',
|
||||
'db_table': 'popup_page',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Qunpeizhi',
|
||||
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='更改时间')),
|
||||
('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='介绍')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'qunpeizhi',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Szjilu',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='记录ID')),
|
||||
('zongsy', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='总收益')),
|
||||
('zongls', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='总流水')),
|
||||
('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='更改时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '收支记录',
|
||||
'verbose_name_plural': '收支记录',
|
||||
'db_table': 'szjilu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TixianQuotaDefault',
|
||||
fields=[
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '默认提现限额',
|
||||
'verbose_name_plural': '默认提现限额',
|
||||
'db_table': 'tixian_quota_default',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Tupianpeizhi',
|
||||
fields=[
|
||||
('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='更改时间')),
|
||||
('fangwen_cishu', models.PositiveIntegerField(default=0, verbose_name='访问次数')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '配置图片',
|
||||
'verbose_name_plural': '配置图片',
|
||||
'db_table': 'tupianpeizhi',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='WithdrawConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('mode', models.IntegerField(choices=[(1, '自动提现'), (2, '手动提现')], default=2, verbose_name='提现模式')),
|
||||
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('updated_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '提现模式配置',
|
||||
'verbose_name_plural': '提现模式配置',
|
||||
'db_table': 'withdraw_config',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangjiaMoban',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='模板ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('leixing_id', models.PositiveIntegerField(db_index=True, verbose_name='商品类型ID')),
|
||||
('moban_jieshao', models.CharField(max_length=500, verbose_name='模板介绍')),
|
||||
('jiage', models.DecimalField(decimal_places=2, help_text='单位:元', max_digits=10, verbose_name='模板价格')),
|
||||
('fabu_shuliang', models.PositiveIntegerField(default=0, verbose_name='发布数量')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家订单模板',
|
||||
'verbose_name_plural': '商家订单模板',
|
||||
'db_table': 'shangjia_moban',
|
||||
'indexes': [models.Index(fields=['yonghu_id', 'leixing_id'], name='shangjia_mo_yonghu__bb287d_idx'), models.Index(fields=['yonghu_id', 'leixing_id', 'id'], name='shangjia_mo_yonghu__4240d0_idx')],
|
||||
'unique_together': {('yonghu_id', 'leixing_id', 'moban_jieshao')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangjiaLianjie',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='链接ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('leixing_id', models.PositiveIntegerField(db_index=True, verbose_name='商品类型ID')),
|
||||
('moban_id', models.PositiveIntegerField(db_index=True, verbose_name='模板ID')),
|
||||
('lianjie', models.CharField(max_length=500, unique=True, verbose_name='链接地址')),
|
||||
('dingdan_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='订单ID')),
|
||||
('is_used', models.BooleanField(db_index=True, default=False, verbose_name='是否已使用')),
|
||||
('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='更新时间')),
|
||||
('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')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家链接',
|
||||
'verbose_name_plural': '商家链接',
|
||||
'db_table': 'shangjia_lianjie',
|
||||
'indexes': [models.Index(fields=['yonghu_id', 'moban_id', 'leixing_id'], name='shangjia_li_yonghu__9f2b25_idx'), models.Index(fields=['lianjie_token'], name='shangjia_li_lianjie_99014c_idx'), models.Index(fields=['dingdan_id'], name='shangjia_li_dingdan_95b682_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PopupImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image_url', models.CharField(max_length=500, verbose_name='图片相对路径')),
|
||||
('text', models.TextField(blank=True, verbose_name='图片上方文字')),
|
||||
('sort_order', models.PositiveIntegerField(default=0, verbose_name='展示顺序')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('popup_config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='config.popupconfig')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '弹窗图片',
|
||||
'verbose_name_plural': '弹窗图片',
|
||||
'db_table': 'popup_image',
|
||||
'ordering': ['sort_order', 'id'],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='popupconfig',
|
||||
name='page',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='popups', to='config.popuppage'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DailyPayoutStat',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(db_index=True, unique=True, verbose_name='统计日期')),
|
||||
('year', models.PositiveSmallIntegerField(verbose_name='年份')),
|
||||
('month', models.PositiveSmallIntegerField(verbose_name='月份')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '每日出款统计',
|
||||
'verbose_name_plural': '每日出款统计',
|
||||
'db_table': 'daily_payout_stat',
|
||||
'indexes': [models.Index(fields=['date'], name='daily_payou_date_b534ec_idx'), models.Index(fields=['year', 'month', 'day'], name='daily_payou_year_6376ca_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DailyIncomeStat',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(db_index=True, unique=True, verbose_name='统计日期')),
|
||||
('year', models.PositiveSmallIntegerField(verbose_name='年份')),
|
||||
('month', models.PositiveSmallIntegerField(verbose_name='月份')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '每日收入统计',
|
||||
'verbose_name_plural': '每日收入统计',
|
||||
'db_table': 'daily_income_stat',
|
||||
'indexes': [models.Index(fields=['date'], name='daily_incom_date_75e6df_idx'), models.Index(fields=['year', 'month', 'day'], name='daily_incom_year_d85d10_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AccountPermission',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('account_id', models.CharField(db_index=True, max_length=11, verbose_name='账号ID')),
|
||||
('permission_code', models.IntegerField(verbose_name='权限代码')),
|
||||
('is_enabled', models.BooleanField(default=False, verbose_name='是否开启')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '账号权限',
|
||||
'verbose_name_plural': '账号权限',
|
||||
'db_table': 'account_permission',
|
||||
'unique_together': {('account_id', 'permission_code')},
|
||||
},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='popupconfig',
|
||||
unique_together={('page', 'popup_id')},
|
||||
),
|
||||
]
|
||||
@@ -1,56 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-27 12:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ShangjiaMoban',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='模板ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('leixing_id', models.PositiveIntegerField(db_index=True, verbose_name='商品类型ID')),
|
||||
('moban_jieshao', models.CharField(max_length=500, verbose_name='模板介绍')),
|
||||
('jiage', models.DecimalField(decimal_places=2, help_text='单位:元', max_digits=10, verbose_name='模板价格')),
|
||||
('fabu_shuliang', 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家订单模板',
|
||||
'verbose_name_plural': '商家订单模板',
|
||||
'db_table': 'shangjia_moban',
|
||||
'indexes': [models.Index(fields=['yonghu_id', 'leixing_id'], name='shangjia_mo_yonghu__bb287d_idx'), models.Index(fields=['yonghu_id', 'leixing_id', 'id'], name='shangjia_mo_yonghu__4240d0_idx')],
|
||||
'unique_together': {('yonghu_id', 'leixing_id', 'moban_jieshao')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangjiaLianjie',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='链接ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('leixing_id', models.PositiveIntegerField(db_index=True, verbose_name='商品类型ID')),
|
||||
('moban_id', models.PositiveIntegerField(db_index=True, verbose_name='模板ID')),
|
||||
('lianjie', models.CharField(max_length=500, unique=True, verbose_name='链接地址')),
|
||||
('dingdan_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='订单ID')),
|
||||
('is_used', models.BooleanField(db_index=True, default=False, verbose_name='是否已使用')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家链接',
|
||||
'verbose_name_plural': '商家链接',
|
||||
'db_table': 'shangjia_lianjie',
|
||||
'indexes': [models.Index(fields=['yonghu_id', 'moban_id', 'leixing_id'], name='shangjia_li_yonghu__9f2b25_idx'), models.Index(fields=['lianjie_token'], name='shangjia_li_lianjie_99014c_idx'), models.Index(fields=['dingdan_id'], name='shangjia_li_dingdan_95b682_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-16 17:04
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0002_shangjiamoban_shangjialianjie'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='tupianpeizhi',
|
||||
name='fangwen_cishu',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='访问次数'),
|
||||
),
|
||||
]
|
||||
@@ -1,28 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-20 15:50
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0003_tupianpeizhi_fangwen_cishu'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TixianQuotaDefault',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('leixing', models.IntegerField(choices=[(1, '打手'), (2, '管事')], 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '默认提现限额',
|
||||
'verbose_name_plural': '默认提现限额',
|
||||
'db_table': 'tixian_quota_default',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,76 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-24 17:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0004_tixianquotadefault'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='OrderTypeMapping',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('partner_club_id', models.CharField(db_index=True, max_length=6, verbose_name='对方俱乐部ID')),
|
||||
('partner_type_id', models.PositiveIntegerField(verbose_name='对方订单类型ID')),
|
||||
('partner_type_name', models.CharField(max_length=100, verbose_name='对方订单类型名称')),
|
||||
('our_type_id', models.PositiveIntegerField(verbose_name='我方订单类型ID')),
|
||||
('our_type_name', models.CharField(max_length=100, 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': 'order_type_mapping',
|
||||
'unique_together': {('partner_club_id', 'partner_type_id')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DailyDispatchStat',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(db_index=True, verbose_name='统计日期')),
|
||||
('year', models.PositiveSmallIntegerField(verbose_name='年份')),
|
||||
('month', models.PositiveSmallIntegerField(verbose_name='月份')),
|
||||
('day', models.PositiveSmallIntegerField(verbose_name='日期')),
|
||||
('direction', models.PositiveSmallIntegerField(choices=[(1, '我方派单'), (2, '对方派单')], verbose_name='派单方向')),
|
||||
('partner_club_id', models.CharField(db_index=True, max_length=6, verbose_name='对方俱乐部ID')),
|
||||
('dispatch_count', models.PositiveIntegerField(default=0, verbose_name='派单数')),
|
||||
('dispatch_amount', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='派单总额')),
|
||||
('success_count', models.PositiveIntegerField(default=0, verbose_name='成交订单数')),
|
||||
('success_amount', 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '每日派单统计',
|
||||
'verbose_name_plural': '每日派单统计',
|
||||
'db_table': 'daily_dispatch_stat',
|
||||
'indexes': [models.Index(fields=['year', 'month', 'day', 'direction', 'partner_club_id'], name='daily_dispa_year_f98f91_idx'), models.Index(fields=['date'], name='daily_dispa_date_9ac7fe_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Club',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('club_id', models.CharField(db_index=True, max_length=6, verbose_name='本俱乐部ID')),
|
||||
('partner_club_id', models.CharField(max_length=6, unique=True, verbose_name='对方俱乐部ID')),
|
||||
('is_interop_enabled', models.BooleanField(default=False, verbose_name='是否开启平台互通')),
|
||||
('is_receive_enabled', models.BooleanField(default=False, verbose_name='是否同意接收对方订单')),
|
||||
('dashou_rate', models.DecimalField(decimal_places=4, default=1.0, max_digits=5, verbose_name='打手分红费率')),
|
||||
('partner_domain', models.URLField(blank=True, 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': 'club',
|
||||
'indexes': [models.Index(fields=['club_id'], name='club_club_id_e75636_idx'), models.Index(fields=['partner_club_id'], name='club_partner_b76039_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,52 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-01 09:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0005_ordertypemapping_dailydispatchstat_club'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ClubConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('club_id', models.CharField(db_index=True, max_length=6, verbose_name='俱乐部ID')),
|
||||
('club_nickname', models.CharField(blank=True, default='', max_length=50, verbose_name='俱乐部昵称')),
|
||||
('club_avatar', models.CharField(blank=True, default='', max_length=500, verbose_name='俱乐部头像地址')),
|
||||
('backend_domain', models.CharField(blank=True, default='', max_length=200, verbose_name='后台域名')),
|
||||
('chat_api_key', models.CharField(blank=True, default='', max_length=200, verbose_name='聊天API密钥')),
|
||||
('chat_api_id', models.CharField(blank=True, default='', max_length=200, verbose_name='聊天API ID')),
|
||||
('customer_service_api_url', models.CharField(blank=True, default='', max_length=200, verbose_name='客服API URL')),
|
||||
('customer_service_corp_id', models.CharField(blank=True, default='', max_length=100, verbose_name='客服企业ID')),
|
||||
('storage_bucket_domain', models.CharField(blank=True, default='', max_length=500, verbose_name='存储桶域名')),
|
||||
('is_self', models.SmallIntegerField(choices=[(0, '对方'), (1, '我方')], db_index=True, default=0, 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': 'club_config',
|
||||
'unique_together': {('club_id',)},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AccountPermission',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('account_id', models.CharField(db_index=True, max_length=11, verbose_name='账号ID')),
|
||||
('permission_code', models.IntegerField(verbose_name='权限代码')),
|
||||
('is_enabled', models.BooleanField(default=False, verbose_name='是否开启')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '账号权限',
|
||||
'verbose_name_plural': '账号权限',
|
||||
'db_table': 'account_permission',
|
||||
'unique_together': {('account_id', 'permission_code')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,28 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-02 13:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0006_clubconfig_accountpermission'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='club',
|
||||
name='receive_rate',
|
||||
field=models.DecimalField(decimal_places=4, default=1.0, max_digits=5, verbose_name='接收打手分红费率'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dailydispatchstat',
|
||||
name='claimed_amount',
|
||||
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='抢单总额'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dailydispatchstat',
|
||||
name='claimed_count',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='抢单数'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-04 18:51
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0007_club_receive_rate_dailydispatchstat_claimed_amount_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='clubconfig',
|
||||
name='storage_bucket_name',
|
||||
field=models.CharField(blank=True, default='', max_length=100, verbose_name='存储桶名称'),
|
||||
),
|
||||
]
|
||||
@@ -1,53 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-05 13:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0008_clubconfig_storage_bucket_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DailyPayoutStat',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(db_index=True, unique=True, verbose_name='统计日期')),
|
||||
('year', models.PositiveSmallIntegerField(verbose_name='年份')),
|
||||
('month', models.PositiveSmallIntegerField(verbose_name='月份')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '每日出款统计',
|
||||
'verbose_name_plural': '每日出款统计',
|
||||
'db_table': 'daily_payout_stat',
|
||||
'indexes': [models.Index(fields=['date'], name='daily_payou_date_b534ec_idx'), models.Index(fields=['year', 'month', 'day'], name='daily_payou_year_6376ca_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DailyIncomeStat',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(db_index=True, unique=True, verbose_name='统计日期')),
|
||||
('year', models.PositiveSmallIntegerField(verbose_name='年份')),
|
||||
('month', models.PositiveSmallIntegerField(verbose_name='月份')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '每日收入统计',
|
||||
'verbose_name_plural': '每日收入统计',
|
||||
'db_table': 'daily_income_stat',
|
||||
'indexes': [models.Index(fields=['date'], name='daily_incom_date_75e6df_idx'), models.Index(fields=['year', 'month', 'day'], name='daily_incom_year_d85d10_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,84 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-22 11:24
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0009_dailypayoutstat_dailyincomestat'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PopupConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('popup_id', models.CharField(max_length=50, verbose_name='弹窗唯一ID')),
|
||||
('title', models.CharField(blank=True, max_length=200, verbose_name='标题(后台用)')),
|
||||
('description', models.TextField(blank=True, verbose_name='描述(后台用)')),
|
||||
('strategy_type', models.CharField(choices=[('once', '仅一次'), ('daily', '每日'), ('weekly', '每周'), ('monthly', '每月'), ('yearly', '每年'), ('always', '始终'), ('count', '周期内次数限制')], default='once', max_length=20)),
|
||||
('max_count', models.PositiveIntegerField(default=1, verbose_name='周期内最大展示次数')),
|
||||
('reset_interval', models.CharField(blank=True, choices=[('day', '天'), ('week', '周'), ('month', '月'), ('year', '年')], max_length=20, verbose_name='重置周期(count类型时使用)')),
|
||||
('duration', models.PositiveIntegerField(default=0, verbose_name='强制阅读秒数(0=无强制)')),
|
||||
('force_even_muted', models.BooleanField(default=False, verbose_name='强制弹出(忽略用户今日屏蔽)')),
|
||||
('sort_order', models.PositiveIntegerField(default=0, verbose_name='展示顺序')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='是否启用')),
|
||||
('start_time', models.DateTimeField(blank=True, null=True, verbose_name='生效开始时间')),
|
||||
('end_time', models.DateTimeField(blank=True, null=True, verbose_name='生效结束时间')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '弹窗配置',
|
||||
'verbose_name_plural': '弹窗配置',
|
||||
'db_table': 'popup_config',
|
||||
'ordering': ['sort_order', 'id'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PopupPage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('page_key', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='页面标识')),
|
||||
('name', models.CharField(max_length=100, verbose_name='页面名称')),
|
||||
('description', models.TextField(blank=True, verbose_name='描述')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='是否启用')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('ignore_user_mute', models.BooleanField(default=False, verbose_name='忽略用户今日屏蔽')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '弹窗页面',
|
||||
'verbose_name_plural': '弹窗页面',
|
||||
'db_table': 'popup_page',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PopupImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image_url', models.CharField(max_length=500, verbose_name='图片相对路径')),
|
||||
('text', models.TextField(blank=True, verbose_name='图片上方文字')),
|
||||
('sort_order', models.PositiveIntegerField(default=0, verbose_name='展示顺序')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('popup_config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='config.popupconfig')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '弹窗图片',
|
||||
'verbose_name_plural': '弹窗图片',
|
||||
'db_table': 'popup_image',
|
||||
'ordering': ['sort_order', 'id'],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='popupconfig',
|
||||
name='page',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='popups', to='config.popuppage'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='popupconfig',
|
||||
unique_together={('page', 'popup_id')},
|
||||
),
|
||||
]
|
||||
@@ -1,27 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-25 12:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0010_popupconfig_popuppage_popupimage_popupconfig_page_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='WithdrawConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('mode', models.IntegerField(choices=[(1, '自动提现'), (2, '手动提现')], default=2, verbose_name='提现模式')),
|
||||
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('updated_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '提现模式配置',
|
||||
'verbose_name_plural': '提现模式配置',
|
||||
'db_table': 'withdraw_config',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,28 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-17 18:57
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0011_withdrawconfig'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangjiamoban',
|
||||
name='chenghao_id',
|
||||
field=models.IntegerField(blank=True, null=True, verbose_name='关联称号ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangjiamoban',
|
||||
name='yongjin_jiage',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='佣金价格'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangjiamoban',
|
||||
name='yongjin_qiangdan',
|
||||
field=models.BooleanField(default=False, verbose_name='是否开启佣金抢单'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-26 03:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0012_shangjiamoban_chenghao_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangjialianjie',
|
||||
name='previous_dingdan_id',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='上一个订单ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangjialianjie',
|
||||
name='previous_lianjie_id',
|
||||
field=models.PositiveIntegerField(blank=True, db_index=True, null=True, verbose_name='上一个链接ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,30 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-15 01:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('config', '0013_shangjialianjie_previous_dingdan_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='Club',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='ClubConfig',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='DailyDispatchStat',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='OrderTypeMapping',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='tixianquotadefault',
|
||||
name='leixing',
|
||||
field=models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '组长'), (4, '考核官'), (5, '打手押金'), (6, '商家余额')], unique=True, verbose_name='用户类型'),
|
||||
),
|
||||
]
|
||||
+9
-8
@@ -37,9 +37,10 @@ from .models import (
|
||||
)
|
||||
|
||||
from users.models import (
|
||||
UserMain, AdminProfile, UserDashou, UserBoss,
|
||||
AdminProfile, UserDashou, UserBoss,
|
||||
UserShangjia, UserGuanshi, UserZuzhang
|
||||
)
|
||||
from gvsdsdk.models import User
|
||||
|
||||
from orders.models import Lilubiao, Dingdan, DingdanShangjia
|
||||
from orders.notice_tasks import dingdan_guangbo
|
||||
@@ -180,7 +181,7 @@ class AdminConfigQueryView(APIView):
|
||||
'data': None
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 获取当前用户(UserMain实例)
|
||||
# 获取当前用户(User实例)
|
||||
user_main = request.user
|
||||
|
||||
# 验证账号:比较user_main的phone与前端传递的zhanghao
|
||||
@@ -2190,10 +2191,10 @@ class KehuGetDingdanLianjieView(APIView):
|
||||
# 获取商家昵称
|
||||
shangjia_nicheng = ''
|
||||
try:
|
||||
user_main = UserMain.query.get(yonghuid=lianjie_obj.yonghu_id)
|
||||
user_main = User.query.get(yonghuid=lianjie_obj.yonghu_id)
|
||||
shangjia_obj = user_main.shop_profile
|
||||
shangjia_nicheng = shangjia_obj.nicheng
|
||||
except (UserMain.DoesNotExist, UserShangjia.DoesNotExist):
|
||||
except (User.DoesNotExist, UserShangjia.DoesNotExist):
|
||||
logger.warning(f"商家信息不存在 - 用户ID: {lianjie_obj.yonghu_id}")
|
||||
|
||||
# ========== 新增:确定俱乐部配置 ==========
|
||||
@@ -2472,7 +2473,7 @@ class KehuTianxieDingdanView(APIView):
|
||||
# 验证打手是否存在且有效
|
||||
try:
|
||||
# 先查询用户主表
|
||||
dashou_user = UserMain.query.get(yonghuid=zhiding_dashou)
|
||||
dashou_user = User.query.get(yonghuid=zhiding_dashou)
|
||||
logger.info(f"找到打手用户 - 用户ID: {zhiding_dashou}")
|
||||
|
||||
# 通过反向关系获取打手扩展信息
|
||||
@@ -2510,7 +2511,7 @@ class KehuTianxieDingdanView(APIView):
|
||||
'data': None
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
logger.warning(f"指定打手用户不存在 - 用户ID: {zhiding_dashou}")
|
||||
return Response({
|
||||
'code': 400,
|
||||
@@ -2570,7 +2571,7 @@ class KehuTianxieDingdanView(APIView):
|
||||
|
||||
# 获取商家信息用于返回
|
||||
try:
|
||||
user_main = UserMain.query.get(yonghuid=lianjie_obj.yonghu_id)
|
||||
user_main = User.query.get(yonghuid=lianjie_obj.yonghu_id)
|
||||
shangjia_obj = user_main.shop_profile
|
||||
shangjia_mingcheng = shangjia_obj.nicheng
|
||||
except:
|
||||
@@ -3250,7 +3251,7 @@ class CheckPhoneAuthView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
user = request.user # UserMain 实例
|
||||
user = request.user # User 实例
|
||||
|
||||
# 已经认证过手机号,直接放行
|
||||
if user.shoujihao_renzheng:
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import MySQLdb
|
||||
|
||||
conn = MySQLdb.connect(
|
||||
host='gvsds.com', port=50030, user='root',
|
||||
password='sajksh.sdfGH3YUge.wjkd+',
|
||||
database='xaio_cheng_xu', charset='utf8mb4'
|
||||
)
|
||||
cur = conn.cursor()
|
||||
|
||||
# 获取所有表
|
||||
cur.execute("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='xaio_cheng_xu'")
|
||||
tables = [row[0] for row in cur.fetchall()]
|
||||
print(f'共 {len(tables)} 张表')
|
||||
|
||||
# 禁用外键检查,删除所有表
|
||||
cur.execute('SET FOREIGN_KEY_CHECKS = 0')
|
||||
for t in tables:
|
||||
cur.execute(f'DROP TABLE IF EXISTS `{t}`')
|
||||
print(f' 已删除: {t}')
|
||||
cur.execute('SET FOREIGN_KEY_CHECKS = 1')
|
||||
|
||||
conn.commit()
|
||||
print(f'\n已删除全部 {len(tables)} 张表')
|
||||
|
||||
# 验证
|
||||
cur.execute("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='xaio_cheng_xu'")
|
||||
count = cur.fetchone()[0]
|
||||
print(f'剩余表数: {count}')
|
||||
|
||||
cur.close()
|
||||
conn.close()
|
||||
@@ -1,35 +0,0 @@
|
||||
"""
|
||||
修复 django_migrations 表中的旧 app 名称引用。
|
||||
在服务器上执行: python manage.py shell < fix_migration_history.py
|
||||
或: python manage.py shell
|
||||
然后粘贴此脚本内容
|
||||
"""
|
||||
from django.db import connection
|
||||
|
||||
APP_NAME_MAPPINGS = {
|
||||
'houtai': 'backend',
|
||||
'yonghu': 'users',
|
||||
'dingdan': 'orders',
|
||||
'peizhi': 'config',
|
||||
'shangpin': 'products',
|
||||
'shangdian': 'shop',
|
||||
'dengji': 'rank',
|
||||
}
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
for old_name, new_name in APP_NAME_MAPPINGS.items():
|
||||
cursor.execute(
|
||||
"SELECT COUNT(*) FROM django_migrations WHERE app = %s",
|
||||
[old_name]
|
||||
)
|
||||
count = cursor.fetchone()[0]
|
||||
if count > 0:
|
||||
cursor.execute(
|
||||
"UPDATE django_migrations SET app = %s WHERE app = %s",
|
||||
[new_name, old_name]
|
||||
)
|
||||
print(f"已更新 {count} 条记录: {old_name} -> {new_name}")
|
||||
else:
|
||||
print(f"无需更新: {old_name} (无记录)")
|
||||
|
||||
print("\n修复完成!请运行 python manage.py migrate")
|
||||
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python3
|
||||
"""修复 tixianjilu 导入 — 使用指定列名的 INSERT"""
|
||||
import re, sys, time, MySQLdb
|
||||
|
||||
sys.path.insert(0, '.')
|
||||
import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'a_long_dianjing.settings')
|
||||
import django; django.setup()
|
||||
from app_secrets import DATABASE_HOST, DATABASE_PORT, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME
|
||||
|
||||
SQL_FILE = os.path.join(os.path.dirname(__file__), 'xaio_cheng_xu_backup.sql')
|
||||
|
||||
with open(SQL_FILE, 'r', encoding='utf-8') as f:
|
||||
sql_content = f.read()
|
||||
|
||||
# 旧表字段顺序(SQL INSERT VALUES 的顺序)
|
||||
OLD_COLUMNS = [
|
||||
'id', 'yonghuid', 'avatar', 'phone', 'nicheng', 'leixing', 'zhifu',
|
||||
'skzhanghao', 'jine', 'zhuangtai', 'fangshi', 'shenheid', 'bhliyou',
|
||||
'create_time', 'update_time', 'shenhe_danhao', 'shenhe_jilu_id'
|
||||
]
|
||||
|
||||
# 新表字段顺序
|
||||
NEW_COLUMNS = [
|
||||
'id', 'yonghuid', 'avatar', 'phone', 'nicheng', 'leixing', 'zhifu',
|
||||
'skzhanghao', 'jine', 'zhuangtai', 'fangshi', 'shenheid', 'bhliyou',
|
||||
'shenhe_jilu_id', 'shenhe_danhao', 'create_time', 'update_time'
|
||||
]
|
||||
|
||||
def parse_sql_value(val_str):
|
||||
val_str = val_str.strip()
|
||||
if val_str.upper() == 'NULL': return None
|
||||
if val_str.startswith("'") and val_str.endswith("'"):
|
||||
return val_str[1:-1].replace("\\'", "'").replace("\\\\", "\\")
|
||||
try: return int(val_str)
|
||||
except ValueError:
|
||||
try: return float(val_str)
|
||||
except ValueError: return val_str
|
||||
|
||||
def split_sql_values(values_str):
|
||||
values, current, in_quote, escape = [], [], False, False
|
||||
for ch in values_str:
|
||||
if escape: current.append(ch); escape = False; continue
|
||||
if ch == '\\': current.append(ch); escape = True; continue
|
||||
if ch == "'": in_quote = not in_quote; current.append(ch); continue
|
||||
if ch == ',' and not in_quote: values.append(''.join(current).strip()); current = []; continue
|
||||
current.append(ch)
|
||||
if current: values.append(''.join(current).strip())
|
||||
return [parse_sql_value(v) for v in values]
|
||||
|
||||
pattern = re.compile(r"INSERT\s+INTO\s+`tixianjilu`\s+VALUES\s*\((.+?)\)\s*;", re.IGNORECASE | re.DOTALL)
|
||||
matches = list(pattern.finditer(sql_content))
|
||||
print(f"找到 {len(matches)} 条 tixianjilu 记录")
|
||||
|
||||
conn = MySQLdb.connect(
|
||||
host=DATABASE_HOST, port=int(DATABASE_PORT),
|
||||
user=DATABASE_USER, password=DATABASE_PASSWORD,
|
||||
database=DATABASE_NAME, charset='utf8mb4',
|
||||
connect_timeout=10, read_timeout=60, write_timeout=60
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SET FOREIGN_KEY_CHECKS = 0')
|
||||
|
||||
success = 0
|
||||
fail = 0
|
||||
start = time.time()
|
||||
|
||||
for i, m in enumerate(matches):
|
||||
vals = split_sql_values(m.group(1))
|
||||
if len(vals) != len(OLD_COLUMNS):
|
||||
fail += 1
|
||||
continue
|
||||
|
||||
# 旧字段 → 值映射
|
||||
old_dict = dict(zip(OLD_COLUMNS, vals))
|
||||
|
||||
# 按新字段顺序构建值列表
|
||||
new_vals = []
|
||||
for col in NEW_COLUMNS:
|
||||
new_vals.append(old_dict.get(col))
|
||||
|
||||
# 构建 INSERT 语句(指定列名)
|
||||
col_names = ', '.join(f'`{c}`' for c in NEW_COLUMNS)
|
||||
val_parts = []
|
||||
for v in new_vals:
|
||||
if v is None:
|
||||
val_parts.append('NULL')
|
||||
elif isinstance(v, str):
|
||||
escaped = conn.escape_string(v)
|
||||
if isinstance(escaped, bytes): escaped = escaped.decode()
|
||||
val_parts.append(f"'{escaped}'")
|
||||
elif isinstance(v, bool):
|
||||
val_parts.append('1' if v else '0')
|
||||
elif isinstance(v, (int, float)):
|
||||
val_parts.append(str(v))
|
||||
else:
|
||||
val_parts.append('NULL')
|
||||
|
||||
sql = f"INSERT INTO `tixianjilu` ({col_names}) VALUES ({', '.join(val_parts)})"
|
||||
try:
|
||||
cursor.execute(sql)
|
||||
success += 1
|
||||
except Exception as e:
|
||||
fail += 1
|
||||
if fail <= 3:
|
||||
print(f" ERR: {str(e)[:100]}")
|
||||
|
||||
if success % 100 == 0 and success > 0:
|
||||
conn.commit()
|
||||
|
||||
if (i + 1) % 200 == 0:
|
||||
elapsed = time.time() - start
|
||||
pct = (i + 1) / len(matches)
|
||||
sys.stdout.write(f'\r [{pct:5.1%}] {i+1}/{len(matches)} {elapsed:.0f}s OK:{success} FAIL:{fail}')
|
||||
sys.stdout.flush()
|
||||
|
||||
conn.commit()
|
||||
cursor.execute('SET FOREIGN_KEY_CHECKS = 1')
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
elapsed = time.time() - start
|
||||
print(f'\n完成: 成功 {success}, 失败 {fail}, 耗时 {elapsed:.0f}s')
|
||||
@@ -92,27 +92,34 @@ class RoleManager:
|
||||
return User.objects.filter(UserUUID__in=user_uuids)
|
||||
|
||||
@staticmethod
|
||||
def AssignPermission(RoleUUID, PermUUID):
|
||||
"""为角色分配权限"""
|
||||
def AssignPermission(RoleUUID, PermUUID, CompanyUUID):
|
||||
"""为角色分配权限(指定公司)"""
|
||||
rp = RolePermission(
|
||||
RolePermUUID=uuid.uuid4().bytes,
|
||||
RoleUUID=RoleUUID,
|
||||
PermUUID=PermUUID,
|
||||
CompanyUUID=CompanyUUID,
|
||||
CreateTime=datetime.datetime.utcnow(),
|
||||
)
|
||||
rp.save()
|
||||
return rp
|
||||
|
||||
@staticmethod
|
||||
def RemovePermission(RoleUUID, PermUUID):
|
||||
def RemovePermission(RoleUUID, PermUUID, CompanyUUID=None):
|
||||
"""移除角色的指定权限"""
|
||||
deleted, _ = RolePermission.objects.filter(RoleUUID=RoleUUID, PermUUID=PermUUID).delete()
|
||||
qs = RolePermission.objects.filter(RoleUUID=RoleUUID, PermUUID=PermUUID)
|
||||
if CompanyUUID is not None:
|
||||
qs = qs.filter(CompanyUUID=CompanyUUID)
|
||||
deleted, _ = qs.delete()
|
||||
return deleted > 0
|
||||
|
||||
@staticmethod
|
||||
def GetPermissionsForRole(RoleUUID):
|
||||
"""获取角色的所有权限"""
|
||||
perm_uuids = RolePermission.objects.filter(RoleUUID=RoleUUID).values_list('PermUUID', flat=True)
|
||||
def GetPermissionsForRole(RoleUUID, CompanyUUID=None):
|
||||
"""获取角色的所有权限(可按公司过滤)"""
|
||||
qs = RolePermission.objects.filter(RoleUUID=RoleUUID)
|
||||
if CompanyUUID is not None:
|
||||
qs = qs.filter(CompanyUUID=CompanyUUID)
|
||||
perm_uuids = qs.values_list('PermUUID', flat=True)
|
||||
return Permission.objects.filter(PermUUID__in=perm_uuids, PermStatus=1)
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ def PermissionVerifier(permission, attributes, user=None, request=None):
|
||||
"""权限验证器——混合 ABAC + RBAC 检查
|
||||
|
||||
RBAC 仅检查当前角色(CurrentRoleUUID Cookie 指定的角色)的权限,
|
||||
通过 RolePermission → Permission 链路查询。
|
||||
通过 RolePermission → Permission 链路查询,按当前公司过滤。
|
||||
超级管理员/员工直接放行。
|
||||
"""
|
||||
if not permission:
|
||||
@@ -63,6 +63,7 @@ def PermissionVerifier(permission, attributes, user=None, request=None):
|
||||
return True
|
||||
|
||||
current_role = getattr(request, 'current_role', None) if request else None
|
||||
current_company = getattr(request, 'current_company_uuid', None) if request else None
|
||||
|
||||
for attr in attributes:
|
||||
# ABAC 检查
|
||||
@@ -73,13 +74,16 @@ def PermissionVerifier(permission, attributes, user=None, request=None):
|
||||
if abac_match:
|
||||
continue
|
||||
|
||||
# RBAC 检查:仅检查当前角色
|
||||
# RBAC 检查:仅检查当前角色,按公司过滤权限
|
||||
if current_role and isinstance(current_role, Role):
|
||||
if current_role.RoleStatus != 1:
|
||||
return False
|
||||
perm_uuids = RolePermission.objects.filter(
|
||||
rp_qs = RolePermission.objects.filter(
|
||||
RoleUUID=current_role.RoleUUID
|
||||
).values_list('PermUUID', flat=True)
|
||||
)
|
||||
if current_company:
|
||||
rp_qs = rp_qs.filter(CompanyUUID=current_company)
|
||||
perm_uuids = rp_qs.values_list('PermUUID', flat=True)
|
||||
rbac_result = Permission.objects.filter(
|
||||
PermUUID__in=perm_uuids,
|
||||
PermCode=attr,
|
||||
@@ -94,9 +98,12 @@ def PermissionVerifier(permission, attributes, user=None, request=None):
|
||||
RoleUUID__in=user_role_uuids,
|
||||
RoleStatus=1,
|
||||
).values_list('RoleUUID', flat=True)
|
||||
perm_uuids = RolePermission.objects.filter(
|
||||
rp_qs = RolePermission.objects.filter(
|
||||
RoleUUID__in=active_role_uuids
|
||||
).values_list('PermUUID', flat=True)
|
||||
)
|
||||
if current_company:
|
||||
rp_qs = rp_qs.filter(CompanyUUID=current_company)
|
||||
perm_uuids = rp_qs.values_list('PermUUID', flat=True)
|
||||
rbac_result = Permission.objects.filter(
|
||||
PermUUID__in=perm_uuids,
|
||||
PermCode=attr,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Generated by Django 6.0.5 on 2026-06-13 11:43
|
||||
# Generated by Django 4.2.27 on 2026-06-17 17:07
|
||||
|
||||
import datetime
|
||||
import gvsdsdk.models
|
||||
from django.db import migrations, models
|
||||
import gvsdsdk.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@@ -16,9 +16,9 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='AccountActivation',
|
||||
fields=[
|
||||
('AccountActivationCode', gvsdsdk.models.FixedBinaryField(binary_length=6, db_column='AccountActivationCode', max_length=6, primary_key=True, serialize=False)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
|
||||
('AccountActivationCode', gvsdsdk.models.FixedBinaryField(binary_length=6, db_column='AccountActivationCode', max_length=6, primary_key=True, serialize=False, verbose_name='激活码')),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', verbose_name='用户UUID')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '账户激活',
|
||||
@@ -30,13 +30,13 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='EphemeralToken',
|
||||
fields=[
|
||||
('ELTUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='ELTUUID', primary_key=True, serialize=False)),
|
||||
('ELTUserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='ELTUserUUID', db_index=True)),
|
||||
('ELTCreateTime', models.DateTimeField(db_column='ELTCreateTime', default=datetime.datetime.utcnow)),
|
||||
('ELTEndTime', models.DateTimeField(db_column='ELTEndTime', default=gvsdsdk.models._elt_end_time_default)),
|
||||
('ELTType', models.SmallIntegerField(db_column='ELTType', default=0)),
|
||||
('ELTAllowIP', models.JSONField(db_column='ELTAllowIP', default=list)),
|
||||
('ELTStatus', models.SmallIntegerField(db_column='ELTStatus', db_index=True, default=1)),
|
||||
('ELTUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='ELTUUID', primary_key=True, serialize=False, verbose_name='令牌UUID')),
|
||||
('ELTUserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='ELTUserUUID', db_index=True, verbose_name='用户UUID')),
|
||||
('ELTCreateTime', models.DateTimeField(db_column='ELTCreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
('ELTEndTime', models.DateTimeField(db_column='ELTEndTime', default=gvsdsdk.models._EltEndTimeDefault, verbose_name='过期时间')),
|
||||
('ELTType', models.SmallIntegerField(db_column='ELTType', default=0, verbose_name='令牌类型')),
|
||||
('ELTAllowIP', models.JSONField(db_column='ELTAllowIP', default=list, verbose_name='允许IP')),
|
||||
('ELTStatus', models.SmallIntegerField(db_column='ELTStatus', db_index=True, default=1, verbose_name='状态')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '临时令牌',
|
||||
@@ -48,8 +48,8 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='Password',
|
||||
fields=[
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', primary_key=True, serialize=False)),
|
||||
('Password', models.CharField(db_column='Password', max_length=1024)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', primary_key=True, serialize=False, verbose_name='用户UUID')),
|
||||
('Password', models.CharField(db_column='Password', max_length=1024, verbose_name='密码哈希')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '密码',
|
||||
@@ -61,12 +61,14 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='Permission',
|
||||
fields=[
|
||||
('PermUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PermUUID', primary_key=True, serialize=False)),
|
||||
('PermName', models.CharField(db_column='PermName', max_length=128)),
|
||||
('PermCode', models.CharField(db_column='PermCode', max_length=128)),
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID')),
|
||||
('PermStatus', models.SmallIntegerField(db_column='PermStatus', default=1)),
|
||||
('PermDesc', models.CharField(db_column='PermDesc', default='', max_length=512)),
|
||||
('PermUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PermUUID', primary_key=True, serialize=False, verbose_name='权限UUID')),
|
||||
('TenantUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='TenantUUID', verbose_name='租户UUID')),
|
||||
('PermName', models.CharField(db_column='PermName', max_length=128, verbose_name='权限名称')),
|
||||
('PermCode', models.CharField(db_column='PermCode', max_length=128, verbose_name='权限键')),
|
||||
('PermCategory', models.CharField(db_column='PermCategory', default='', max_length=64, verbose_name='权限分类')),
|
||||
('PermStatus', models.SmallIntegerField(db_column='PermStatus', default=1, verbose_name='是否启用')),
|
||||
('PermDesc', models.CharField(db_column='PermDesc', default='', max_length=512, verbose_name='描述')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '权限',
|
||||
@@ -75,16 +77,72 @@ class Migration(migrations.Migration):
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Position',
|
||||
fields=[
|
||||
('PositionUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PositionUUID', primary_key=True, serialize=False, verbose_name='职务UUID')),
|
||||
('TenantUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='TenantUUID', verbose_name='租户UUID')),
|
||||
('PositionName', models.CharField(db_column='PositionName', max_length=128, verbose_name='职务名称')),
|
||||
('PositionCode', models.CharField(db_column='PositionCode', default='', max_length=64, verbose_name='职务编码')),
|
||||
('PositionLevel', models.SmallIntegerField(db_column='PositionLevel', default=0, verbose_name='职务级别')),
|
||||
('PositionStatus', models.SmallIntegerField(db_column='PositionStatus', default=1, verbose_name='状态')),
|
||||
('PositionDesc', models.CharField(db_column='PositionDesc', default='', max_length=512, verbose_name='描述')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
('UpdateTime', models.DateTimeField(db_column='UpdateTime', default=datetime.datetime.utcnow, verbose_name='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '人事职务标签',
|
||||
'verbose_name_plural': '人事职务标签',
|
||||
'db_table': 'Position',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PositionTemplate',
|
||||
fields=[
|
||||
('PositionTemplateUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PositionTemplateUUID', primary_key=True, serialize=False, verbose_name='岗位模板UUID')),
|
||||
('TenantUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='TenantUUID', verbose_name='租户UUID')),
|
||||
('TemplateName', models.CharField(db_column='TemplateName', max_length=128, verbose_name='模板名称')),
|
||||
('TemplateCode', models.CharField(db_column='TemplateCode', default='', max_length=64, verbose_name='模板编码')),
|
||||
('TemplateStatus', models.SmallIntegerField(db_column='TemplateStatus', default=1, verbose_name='模板状态')),
|
||||
('TemplateDesc', models.CharField(db_column='TemplateDesc', default='', max_length=512, verbose_name='模板描述')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
('UpdateTime', models.DateTimeField(db_column='UpdateTime', default=datetime.datetime.utcnow, verbose_name='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '岗位模板',
|
||||
'verbose_name_plural': '岗位模板',
|
||||
'db_table': 'PositionTemplate',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PositionTemplatePermission',
|
||||
fields=[
|
||||
('PTPermUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PTPermUUID', primary_key=True, serialize=False, verbose_name='关联UUID')),
|
||||
('PositionTemplateUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PositionTemplateUUID', verbose_name='岗位模板UUID')),
|
||||
('PermUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PermUUID', verbose_name='权限UUID')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '岗位模板权限关联',
|
||||
'verbose_name_plural': '岗位模板权限关联',
|
||||
'db_table': 'PositionTemplatePermission',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Role',
|
||||
fields=[
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID', primary_key=True, serialize=False)),
|
||||
('CompanyUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='CompanyUUID')),
|
||||
('DeptUUID', gvsdsdk.models.UUIDField(binary_length=16, blank=True, db_column='DeptUUID', null=True)),
|
||||
('RoleName', models.CharField(db_column='RoleName', max_length=128)),
|
||||
('RoleType', models.SmallIntegerField(db_column='RoleType', default=2)),
|
||||
('RoleStatus', models.SmallIntegerField(db_column='RoleStatus', default=1)),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID', primary_key=True, serialize=False, verbose_name='角色UUID')),
|
||||
('TenantUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='TenantUUID', verbose_name='租户UUID')),
|
||||
('RoleName', models.CharField(db_column='RoleName', max_length=128, verbose_name='角色名称')),
|
||||
('RoleType', models.SmallIntegerField(db_column='RoleType', default=2, verbose_name='角色类型')),
|
||||
('RoleStatus', models.SmallIntegerField(db_column='RoleStatus', default=1, verbose_name='角色状态')),
|
||||
('AssignScope', models.SmallIntegerField(db_column='AssignScope', default=0, verbose_name='分配可见范围')),
|
||||
('AssignScopeUUID', gvsdsdk.models.UUIDField(binary_length=16, blank=True, db_column='AssignScopeUUID', null=True, verbose_name='分配范围UUID')),
|
||||
('RoleDesc', models.CharField(db_column='RoleDesc', default='', max_length=512, verbose_name='角色描述')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '角色',
|
||||
@@ -94,55 +152,69 @@ class Migration(migrations.Migration):
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RoleDept',
|
||||
name='RolePermission',
|
||||
fields=[
|
||||
('RoleDeptUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleDeptUUID', primary_key=True, serialize=False)),
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID')),
|
||||
('DeptUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='DeptUUID')),
|
||||
('IsMainDept', models.SmallIntegerField(db_column='IsMainDept', default=1)),
|
||||
('RolePermUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RolePermUUID', primary_key=True, serialize=False, verbose_name='关联UUID')),
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID', verbose_name='角色UUID')),
|
||||
('PermUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PermUUID', verbose_name='权限UUID')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '角色部门关联',
|
||||
'verbose_name_plural': '角色部门关联',
|
||||
'db_table': 'RoleDept',
|
||||
'verbose_name': '角色权限关联',
|
||||
'verbose_name_plural': '角色权限关联',
|
||||
'db_table': 'RolePermission',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
name='RoleShop',
|
||||
fields=[
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', primary_key=True, serialize=False)),
|
||||
('UserName', models.CharField(db_column='UserName', max_length=256, unique=True)),
|
||||
('UserPassword', models.CharField(db_column='UserPassword', default='', max_length=60)),
|
||||
('UserPositionStatus', models.SmallIntegerField(db_column='UserPositionStatus', default=0)),
|
||||
('UserPersonalSignature', models.CharField(db_column='UserPersonalSignature', default='', max_length=1024)),
|
||||
('UserEmail', models.CharField(db_column='UserEmail', default='', max_length=256)),
|
||||
('UserEmailVerify', models.SmallIntegerField(db_column='UserEmailVerify', default=0)),
|
||||
('UserAccountLicense', models.SmallIntegerField(db_column='UserAccountLicense', default=1)),
|
||||
('UserGender', models.SmallIntegerField(db_column='UserGender', default=-1)),
|
||||
('UserTele', models.CharField(blank=True, db_column='UserTele', max_length=16, null=True)),
|
||||
('UserCreateTime', models.DateTimeField(db_column='UserCreateTime', default=datetime.datetime.utcnow)),
|
||||
('UserLastLoginDate', models.DateTimeField(db_column='UserLastLoginDate', default=datetime.datetime.utcnow)),
|
||||
('IsStaff', models.BooleanField(db_column='IsStaff', default=False)),
|
||||
('IsSuperuser', models.BooleanField(db_column='IsSuperuser', default=False)),
|
||||
('RoleShopUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleShopUUID', primary_key=True, serialize=False, verbose_name='关联UUID')),
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID', verbose_name='角色UUID')),
|
||||
('ShopUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='ShopUUID', verbose_name='商铺UUID')),
|
||||
('IsMainShop', models.SmallIntegerField(db_column='IsMainShop', default=0, verbose_name='主商铺')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户',
|
||||
'verbose_name_plural': '用户',
|
||||
'db_table': 'User',
|
||||
'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, verbose_name='商铺UUID')),
|
||||
('CompanyUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='CompanyUUID', verbose_name='公司UUID')),
|
||||
('ShopName', models.CharField(db_column='ShopName', max_length=128, verbose_name='商铺名称')),
|
||||
('ShopCode', models.CharField(db_column='ShopCode', default='', max_length=64, verbose_name='商铺编码')),
|
||||
('ShopType', models.SmallIntegerField(db_column='ShopType', default=0, verbose_name='商铺类型')),
|
||||
('ShopStatus', models.SmallIntegerField(db_column='ShopStatus', default=1, verbose_name='商铺状态')),
|
||||
('ShopAddress', models.CharField(db_column='ShopAddress', default='', max_length=512, verbose_name='商铺地址')),
|
||||
('ShopContact', models.CharField(db_column='ShopContact', default='', max_length=128, verbose_name='联系人')),
|
||||
('ShopPhone', models.CharField(db_column='ShopPhone', default='', max_length=32, verbose_name='联系电话')),
|
||||
('ShopDesc', models.CharField(db_column='ShopDesc', default='', max_length=512, verbose_name='描述')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
('UpdateTime', models.DateTimeField(db_column='UpdateTime', default=datetime.datetime.utcnow, verbose_name='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商铺',
|
||||
'verbose_name_plural': '商铺',
|
||||
'db_table': 'Shop',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='User2FA',
|
||||
fields=[
|
||||
('User2FAUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='User2FAUUID', primary_key=True, serialize=False)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', db_index=True)),
|
||||
('SecretKey', models.CharField(db_column='SecretKey', max_length=64)),
|
||||
('IsEnabled', models.SmallIntegerField(db_column='IsEnabled', default=0)),
|
||||
('Verified', models.SmallIntegerField(db_column='Verified', default=0)),
|
||||
('LastUsedAt', models.DateTimeField(blank=True, db_column='LastUsedAt', null=True)),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
|
||||
('User2FAUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='User2FAUUID', primary_key=True, serialize=False, verbose_name='2FA UUID')),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', db_index=True, verbose_name='用户UUID')),
|
||||
('SecretKey', models.CharField(db_column='SecretKey', max_length=64, verbose_name='密钥')),
|
||||
('IsEnabled', models.SmallIntegerField(db_column='IsEnabled', default=0, verbose_name='是否启用')),
|
||||
('Verified', models.SmallIntegerField(db_column='Verified', default=0, verbose_name='已验证')),
|
||||
('LastUsedAt', models.DateTimeField(blank=True, db_column='LastUsedAt', null=True, verbose_name='最后使用')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '双因素认证',
|
||||
@@ -154,9 +226,9 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='UserABAC',
|
||||
fields=[
|
||||
('UserABACUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserABACUUID', primary_key=True, serialize=False)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID')),
|
||||
('HierarchicalPermissionIdentifiers', models.CharField(db_column='HierarchicalPermissionIdentifiers', max_length=256)),
|
||||
('UserABACUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserABACUUID', primary_key=True, serialize=False, verbose_name='ABAC UUID')),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', verbose_name='用户UUID')),
|
||||
('HierarchicalPermissionIdentifiers', models.CharField(db_column='HierarchicalPermissionIdentifiers', max_length=256, verbose_name='层级权限标识')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户ABAC',
|
||||
@@ -168,10 +240,10 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='UserAvatar',
|
||||
fields=[
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', primary_key=True, serialize=False)),
|
||||
('UserAvatar', models.BinaryField(db_column='UserAvatar', editable=True)),
|
||||
('AvatarUploadTime', models.DateTimeField(db_column='AvatarUploadTime', default=datetime.datetime.utcnow)),
|
||||
('AvatarFileType', models.CharField(db_column='AvatarFileType', default='png', max_length=16)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', primary_key=True, serialize=False, verbose_name='用户UUID')),
|
||||
('UserAvatar', models.BinaryField(db_column='UserAvatar', editable=True, verbose_name='头像数据')),
|
||||
('AvatarUploadTime', models.DateTimeField(db_column='AvatarUploadTime', default=datetime.datetime.utcnow, verbose_name='上传时间')),
|
||||
('AvatarFileType', models.CharField(db_column='AvatarFileType', default='png', max_length=16, verbose_name='文件类型')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户头像',
|
||||
@@ -180,16 +252,33 @@ class Migration(migrations.Migration):
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserDept',
|
||||
fields=[
|
||||
('UserDeptUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserDeptUUID', primary_key=True, serialize=False, verbose_name='关联UUID')),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', verbose_name='用户UUID')),
|
||||
('DeptUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='DeptUUID', verbose_name='部门UUID')),
|
||||
('PositionUUID', gvsdsdk.models.UUIDField(binary_length=16, blank=True, db_column='PositionUUID', null=True, verbose_name='职务标签UUID')),
|
||||
('IsMainDept', models.SmallIntegerField(db_column='IsMainDept', default=1, verbose_name='是否主部门')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '员工部门关联',
|
||||
'verbose_name_plural': '员工部门关联',
|
||||
'db_table': 'UserDept',
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserLoginLog',
|
||||
fields=[
|
||||
('LogUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='LogUUID', primary_key=True, serialize=False)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', db_index=True)),
|
||||
('LoginIP', models.CharField(db_column='LoginIP', max_length=39)),
|
||||
('LoginPlatform', models.CharField(db_column='LoginPlatform', max_length=32)),
|
||||
('LoginStatus', models.SmallIntegerField(db_column='LoginStatus')),
|
||||
('LoginTime', models.DateTimeField(db_column='LoginTime', default=datetime.datetime.utcnow)),
|
||||
('UserAgent', models.CharField(db_column='UserAgent', default='', max_length=512)),
|
||||
('LogUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='LogUUID', primary_key=True, serialize=False, verbose_name='日志UUID')),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', db_index=True, verbose_name='用户UUID')),
|
||||
('LoginIP', models.CharField(db_column='LoginIP', max_length=39, verbose_name='登录IP')),
|
||||
('LoginPlatform', models.CharField(db_column='LoginPlatform', max_length=32, verbose_name='登录平台')),
|
||||
('LoginStatus', models.SmallIntegerField(db_column='LoginStatus', verbose_name='登录状态')),
|
||||
('LoginTime', models.DateTimeField(db_column='LoginTime', default=datetime.datetime.utcnow, verbose_name='登录时间')),
|
||||
('UserAgent', models.CharField(db_column='UserAgent', default='', max_length=512, verbose_name='用户代理')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '登录日志',
|
||||
@@ -201,10 +290,10 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='UserPending2FA',
|
||||
fields=[
|
||||
('PendingUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PendingUUID', primary_key=True, serialize=False)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', unique=True)),
|
||||
('SecretKey', models.CharField(db_column='SecretKey', max_length=64)),
|
||||
('ExpireAt', models.DateTimeField(db_column='ExpireAt')),
|
||||
('PendingUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='PendingUUID', primary_key=True, serialize=False, verbose_name='待确认UUID')),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', unique=True, verbose_name='用户UUID')),
|
||||
('SecretKey', models.CharField(db_column='SecretKey', max_length=64, verbose_name='密钥')),
|
||||
('ExpireAt', models.DateTimeField(db_column='ExpireAt', verbose_name='过期时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '2FA待确认',
|
||||
@@ -216,10 +305,11 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='UserRole',
|
||||
fields=[
|
||||
('UserRoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserRoleUUID', primary_key=True, serialize=False)),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID')),
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow)),
|
||||
('UserRoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserRoleUUID', primary_key=True, serialize=False, verbose_name='关联UUID')),
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', verbose_name='用户UUID')),
|
||||
('RoleUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='RoleUUID', verbose_name='角色UUID')),
|
||||
('CompanyUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='CompanyUUID', verbose_name='公司UUID')),
|
||||
('CreateTime', models.DateTimeField(db_column='CreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户角色关联',
|
||||
@@ -228,4 +318,37 @@ class Migration(migrations.Migration):
|
||||
'managed': True,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
fields=[
|
||||
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', primary_key=True, serialize=False, verbose_name='用户UUID')),
|
||||
('UserName', models.CharField(db_column='UserName', max_length=256, unique=True, verbose_name='用户名')),
|
||||
('UserPassword', models.CharField(db_column='UserPassword', default='', max_length=60, verbose_name='密码')),
|
||||
('UserPositionStatus', models.SmallIntegerField(db_column='UserPositionStatus', default=0, verbose_name='职位状态')),
|
||||
('UserPersonalSignature', models.CharField(db_column='UserPersonalSignature', default='', max_length=1024, verbose_name='个人签名')),
|
||||
('UserEmail', models.CharField(db_column='UserEmail', default='', max_length=256, verbose_name='邮箱')),
|
||||
('UserEmailVerify', models.SmallIntegerField(db_column='UserEmailVerify', default=0, verbose_name='邮箱验证')),
|
||||
('UserAccountLicense', models.SmallIntegerField(db_column='UserAccountLicense', default=1, verbose_name='账户许可')),
|
||||
('UserGender', models.SmallIntegerField(db_column='UserGender', default=-1, verbose_name='性别')),
|
||||
('UserTele', models.CharField(blank=True, db_column='UserTele', max_length=16, null=True, verbose_name='电话')),
|
||||
('UserCreateTime', models.DateTimeField(db_column='UserCreateTime', default=datetime.datetime.utcnow, verbose_name='创建时间')),
|
||||
('UserLastLoginDate', models.DateTimeField(db_column='UserLastLoginDate', default=datetime.datetime.utcnow, verbose_name='最后登录')),
|
||||
('UserUID', models.CharField(blank=True, db_column='UserUID', max_length=7, null=True, unique=True, verbose_name='用户业务ID')),
|
||||
('OpenID', models.CharField(blank=True, db_column='OpenID', max_length=64, null=True, unique=True, verbose_name='微信OpenID')),
|
||||
('UnionID', models.CharField(blank=True, db_column='UnionID', max_length=64, null=True, verbose_name='微信UnionID')),
|
||||
('Avatar', models.CharField(db_column='Avatar', default='a_long/morentouxiang.jpg', max_length=500, verbose_name='头像')),
|
||||
('Phone', models.CharField(blank=True, db_column='Phone', max_length=11, null=True, verbose_name='手机号')),
|
||||
('PhoneVerified', models.BooleanField(db_column='PhoneVerified', default=False, verbose_name='手机号是否已认证')),
|
||||
('IP', models.CharField(blank=True, db_column='IP', max_length=50, null=True, verbose_name='来访用户IP')),
|
||||
('IsStaff', models.BooleanField(db_column='IsStaff', default=False, verbose_name='是否员工')),
|
||||
('IsSuperuser', models.BooleanField(db_column='IsSuperuser', default=False, verbose_name='是否超级用户')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户',
|
||||
'verbose_name_plural': '用户',
|
||||
'db_table': 'User',
|
||||
'managed': True,
|
||||
'indexes': [models.Index(fields=['UserUID'], name='User_UserUID_a656ea_idx'), models.Index(fields=['OpenID'], name='User_OpenID_2a920d_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
),
|
||||
]
|
||||
+162
-19
@@ -186,17 +186,33 @@ class User(QModel):
|
||||
UserTele = models.CharField(max_length=16, null=True, blank=True, db_column='UserTele', verbose_name='电话')
|
||||
UserCreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='UserCreateTime', verbose_name='创建时间')
|
||||
UserLastLoginDate = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='UserLastLoginDate', verbose_name='最后登录')
|
||||
# === 本地业务字段(去远程化后新增) ===
|
||||
UserUID = models.CharField(max_length=7, unique=True, db_column='UserUID', verbose_name='用户业务ID', null=True, blank=True)
|
||||
OpenID = models.CharField(max_length=64, unique=True, db_column='OpenID', verbose_name='微信OpenID', null=True, blank=True)
|
||||
UnionID = models.CharField(max_length=64, db_column='UnionID', verbose_name='微信UnionID', null=True, blank=True)
|
||||
Avatar = models.CharField(max_length=500, default='a_long/morentouxiang.jpg', db_column='Avatar', verbose_name='头像')
|
||||
Phone = models.CharField(max_length=11, db_column='Phone', verbose_name='手机号', null=True, blank=True)
|
||||
PhoneVerified = models.BooleanField(default=False, db_column='PhoneVerified', verbose_name='手机号是否已认证')
|
||||
IP = models.CharField(max_length=50, db_column='IP', verbose_name='来访用户IP', null=True, blank=True)
|
||||
IsStaff = models.BooleanField(default=False, db_column='IsStaff', verbose_name='是否员工')
|
||||
IsSuperuser = models.BooleanField(default=False, db_column='IsSuperuser', verbose_name='是否超级用户')
|
||||
|
||||
objects = UserManager()
|
||||
|
||||
# Django auth 框架必需
|
||||
USERNAME_FIELD = 'UserName'
|
||||
REQUIRED_FIELDS = ['UserUID']
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True # 将由 QModelBase.__new__ 根据 GVSDSDK_MANAGE_TABLES 动态设置
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'User'
|
||||
verbose_name = '用户'
|
||||
verbose_name_plural = '用户'
|
||||
indexes = [
|
||||
models.Index(fields=['UserUID']),
|
||||
models.Index(fields=['OpenID']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.UserName
|
||||
@@ -304,6 +320,66 @@ class User(QModel):
|
||||
def is_authenticated(self):
|
||||
return self.IsAuthenticated
|
||||
|
||||
@property
|
||||
def yonghuid(self):
|
||||
"""兼容旧代码的 yonghuid 属性"""
|
||||
return self.UserUID
|
||||
|
||||
@property
|
||||
def openid(self):
|
||||
"""兼容旧代码的 openid 属性"""
|
||||
return self.OpenID
|
||||
|
||||
@property
|
||||
def user_type(self):
|
||||
"""兼容旧代码的 user_type 属性 — 通过 UserRole 推断(带实例缓存)"""
|
||||
# 实例缓存:同一请求内只查一次
|
||||
if hasattr(self, '_cached_user_type'):
|
||||
return self._cached_user_type
|
||||
try:
|
||||
# 单次查询获取所有角色名
|
||||
role_uuids = UserRole.objects.filter(
|
||||
UserUUID=self.UserUUID
|
||||
).values_list('RoleUUID', flat=True)
|
||||
role_names = set(
|
||||
Role.objects.filter(RoleUUID__in=role_uuids)
|
||||
.values_list('RoleName', flat=True)
|
||||
)
|
||||
# 优先级:管理员 > 客服 > 负责人 > 组长 > 审核官 > 商家 > 打手
|
||||
for rn in role_names:
|
||||
if '管理员' in rn or 'admin' in rn.lower():
|
||||
self._cached_user_type = 'admin'
|
||||
return 'admin'
|
||||
for rn in role_names:
|
||||
if '客服' in rn or 'kefu' in rn.lower():
|
||||
self._cached_user_type = 'kefu'
|
||||
return 'kefu'
|
||||
for rn in role_names:
|
||||
if '负责人' in rn or '管事' in rn or 'guanshi' in rn.lower():
|
||||
self._cached_user_type = 'guanshi'
|
||||
return 'guanshi'
|
||||
for rn in role_names:
|
||||
if '组长' in rn or 'zuzhang' in rn.lower():
|
||||
self._cached_user_type = 'zuzhang'
|
||||
return 'zuzhang'
|
||||
for rn in role_names:
|
||||
if '审核' in rn or 'shenheguan' in rn.lower():
|
||||
self._cached_user_type = 'shenheguan'
|
||||
return 'shenheguan'
|
||||
for rn in role_names:
|
||||
if '商家' in rn or 'shangjia' in rn.lower():
|
||||
self._cached_user_type = 'shop'
|
||||
return 'shop'
|
||||
for rn in role_names:
|
||||
if '打手' in rn or 'dashou' in rn.lower():
|
||||
self._cached_user_type = 'dashou'
|
||||
return 'dashou'
|
||||
self._cached_user_type = 'normal'
|
||||
return 'normal'
|
||||
except Exception:
|
||||
self._cached_user_type = 'normal'
|
||||
return 'normal'
|
||||
|
||||
@property
|
||||
def pk(self):
|
||||
return self.PK
|
||||
@@ -318,6 +394,73 @@ class User(QModel):
|
||||
def check_password(self, raw_password):
|
||||
return self.CheckPassword(raw_password)
|
||||
|
||||
@property
|
||||
def dashou_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import UserDashou
|
||||
return UserDashou.objects.filter(user=self).first()
|
||||
|
||||
@property
|
||||
def shop_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import UserShangjia
|
||||
return UserShangjia.objects.filter(user=self).first()
|
||||
|
||||
@property
|
||||
def guanshi_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import UserGuanshi
|
||||
return UserGuanshi.objects.filter(user=self).first()
|
||||
|
||||
@property
|
||||
def boss_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import UserBoss
|
||||
return UserBoss.objects.filter(user=self).first()
|
||||
|
||||
@property
|
||||
def admin_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import AdminProfile
|
||||
return AdminProfile.objects.filter(user=self).first()
|
||||
|
||||
@property
|
||||
def kefu_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import UserKefu
|
||||
return UserKefu.objects.filter(user=self).first()
|
||||
|
||||
@property
|
||||
def zuzhang_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import UserZuzhang
|
||||
return UserZuzhang.objects.filter(user=self).first()
|
||||
|
||||
@property
|
||||
def shenheguan_profile(self):
|
||||
"""兼容旧代码"""
|
||||
from users.models import UserShenheguan
|
||||
return UserShenheguan.objects.filter(user=self).first()
|
||||
|
||||
def has_role(self, role_code):
|
||||
"""检查用户是否拥有指定角色(支持角色名或旧 user_type 值)"""
|
||||
# 角色名映射:旧 user_type → 角色名
|
||||
ROLE_CODE_MAP = {
|
||||
'admin': '管理员', 'kefu': '客服', 'guanshi': '负责人',
|
||||
'zuzhang': '组长', 'shenheguan': '审核官', 'shop': '商家',
|
||||
'dashou': '打手', 'normal': '消费者',
|
||||
}
|
||||
target = ROLE_CODE_MAP.get(role_code, role_code)
|
||||
try:
|
||||
role_uuids = UserRole.objects.filter(
|
||||
UserUUID=self.UserUUID
|
||||
).values_list('RoleUUID', flat=True)
|
||||
return Role.objects.filter(
|
||||
RoleUUID__in=role_uuids, RoleName=target
|
||||
).exists()
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
# === 用户头像表 ===
|
||||
|
||||
@@ -330,7 +473,7 @@ class UserAvatar(QModel):
|
||||
AvatarFileType = models.CharField(max_length=16, default='png', db_column='AvatarFileType', verbose_name='文件类型')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'UserAvatar'
|
||||
verbose_name = '用户头像'
|
||||
@@ -351,7 +494,7 @@ class User2FA(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'User2FA'
|
||||
verbose_name = '双因素认证'
|
||||
@@ -369,7 +512,7 @@ class UserPending2FA(QModel):
|
||||
ExpireAt = models.DateTimeField(db_column='ExpireAt', verbose_name='过期时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'UserPending2FA'
|
||||
verbose_name = '2FA待确认'
|
||||
@@ -396,7 +539,7 @@ class EphemeralToken(QModel):
|
||||
ELTStatus = models.SmallIntegerField(default=1, db_index=True, db_column='ELTStatus', verbose_name='状态')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'EphemeralToken'
|
||||
verbose_name = '临时令牌'
|
||||
@@ -425,7 +568,7 @@ class UserLoginLog(QModel):
|
||||
UserAgent = models.CharField(max_length=512, default='', db_column='UserAgent', verbose_name='用户代理')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'UserLoginLog'
|
||||
verbose_name = '登录日志'
|
||||
@@ -442,7 +585,7 @@ class AccountActivation(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'AccountActivation'
|
||||
verbose_name = '账户激活'
|
||||
@@ -472,7 +615,7 @@ class Role(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'Role'
|
||||
verbose_name = '角色'
|
||||
@@ -516,7 +659,7 @@ class Permission(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'Permission'
|
||||
verbose_name = '权限'
|
||||
@@ -555,7 +698,7 @@ class UserRole(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'UserRole'
|
||||
verbose_name = '用户角色关联'
|
||||
@@ -577,7 +720,7 @@ class RolePermission(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'RolePermission'
|
||||
verbose_name = '角色权限关联'
|
||||
@@ -594,7 +737,7 @@ class UserABAC(QModel):
|
||||
HierarchicalPermissionIdentifiers = models.CharField(max_length=256, db_column='HierarchicalPermissionIdentifiers', verbose_name='层级权限标识')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'UserABAC'
|
||||
verbose_name = '用户ABAC'
|
||||
@@ -610,7 +753,7 @@ class Password(QModel):
|
||||
Password = models.CharField(max_length=1024, db_column='Password', verbose_name='密码哈希')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'Password'
|
||||
verbose_name = '密码'
|
||||
@@ -639,7 +782,7 @@ class Shop(QModel):
|
||||
UpdateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='UpdateTime', verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'Shop'
|
||||
verbose_name = '商铺'
|
||||
@@ -671,7 +814,7 @@ class RoleShop(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'RoleShop'
|
||||
verbose_name = '角色商铺关联'
|
||||
@@ -700,7 +843,7 @@ class PositionTemplate(QModel):
|
||||
UpdateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='UpdateTime', verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'PositionTemplate'
|
||||
verbose_name = '岗位模板'
|
||||
@@ -750,7 +893,7 @@ class PositionTemplatePermission(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'PositionTemplatePermission'
|
||||
verbose_name = '岗位模板权限关联'
|
||||
@@ -778,7 +921,7 @@ class Position(QModel):
|
||||
UpdateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='UpdateTime', verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'Position'
|
||||
verbose_name = '人事职务标签'
|
||||
@@ -806,7 +949,7 @@ class UserDept(QModel):
|
||||
CreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='CreateTime', verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
managed = True
|
||||
app_label = 'gvsdsdk'
|
||||
db_table = 'UserDept'
|
||||
verbose_name = '员工部门关联'
|
||||
|
||||
@@ -0,0 +1,532 @@
|
||||
"""MSYNC ORM 中转处理器
|
||||
|
||||
子服务器端注册 Socket.IO 事件处理器,接收主服务器发来的 ORM 查询请求,
|
||||
在本地数据库执行 SQL 并返回结果。
|
||||
|
||||
用法(子服务器端):
|
||||
from gvsdsdk.msync.orm_handler import ORMRelayHandler
|
||||
|
||||
handler = ORMRelayHandler()
|
||||
handler.Register(sio_client) # 注册到 MSyncSocketClient 实例
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ORMRelayHandler:
|
||||
"""ORM 中转处理器——在子服务器端执行本地 SQL 查询
|
||||
|
||||
通过 MSYNC Socket.IO 事件协议,主服务器将 ORM 请求转发给子服务器,
|
||||
子服务器在本地数据库执行查询后返回结果。
|
||||
"""
|
||||
|
||||
def Register(self, sio_client):
|
||||
"""将 ORM 事件处理器注册到 MSyncSocketClient 实例
|
||||
|
||||
Args:
|
||||
sio_client: MSyncSocketClient 实例,需要有 _sio 属性
|
||||
"""
|
||||
sio = sio_client._sio
|
||||
|
||||
@sio.on('msync:orm:tables', namespace='/msync')
|
||||
def on_orm_tables(data):
|
||||
return self.HandleTables(data)
|
||||
|
||||
@sio.on('msync:orm:columns', namespace='/msync')
|
||||
def on_orm_columns(data):
|
||||
return self.HandleColumns(data)
|
||||
|
||||
@sio.on('msync:orm:list', namespace='/msync')
|
||||
def on_orm_list(data):
|
||||
return self.HandleList(data)
|
||||
|
||||
@sio.on('msync:orm:add', namespace='/msync')
|
||||
def on_orm_add(data):
|
||||
return self.HandleAdd(data)
|
||||
|
||||
@sio.on('msync:orm:modify', namespace='/msync')
|
||||
def on_orm_modify(data):
|
||||
return self.HandleModify(data)
|
||||
|
||||
@sio.on('msync:orm:delete', namespace='/msync')
|
||||
def on_orm_delete(data):
|
||||
return self.HandleDelete(data)
|
||||
|
||||
logger.info('[ORM] ORM 中转处理器已注册')
|
||||
|
||||
def _GetConnection(self):
|
||||
"""获取本地数据库连接(Django default)"""
|
||||
from django.db import connections
|
||||
conn = connections['default']
|
||||
conn.ensure_connection()
|
||||
return conn
|
||||
|
||||
# ─── 事件处理 ──────────────────────────────────────────────
|
||||
|
||||
def HandleTables(self, data):
|
||||
"""列出本地数据库中所有用户表"""
|
||||
try:
|
||||
conn = self._GetConnection()
|
||||
except Exception as e:
|
||||
return {'code': 1, 'msg': f'数据库连接失败: {e}'}
|
||||
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
tables = self._ListTables(cursor)
|
||||
return {'code': 0, 'msg': 'success', 'data': tables}
|
||||
except Exception as e:
|
||||
logger.error(f'[ORM] HandleTables 异常: {e}')
|
||||
return {'code': 1, 'msg': f'查询失败: {e}'}
|
||||
|
||||
def HandleColumns(self, data):
|
||||
"""列出指定表的列信息"""
|
||||
table_name = (data or {}).get('Table', '')
|
||||
if not table_name:
|
||||
return {'code': 1, 'msg': '缺少 Table 参数'}
|
||||
|
||||
try:
|
||||
conn = self._GetConnection()
|
||||
except Exception as e:
|
||||
return {'code': 1, 'msg': f'数据库连接失败: {e}'}
|
||||
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
columns = self._ListColumns(cursor, table_name)
|
||||
return {'code': 0, 'msg': 'success', 'data': columns}
|
||||
except Exception as e:
|
||||
logger.error(f'[ORM] HandleColumns 异常: {e}')
|
||||
return {'code': 1, 'msg': f'查询失败: {e}'}
|
||||
|
||||
def HandleList(self, data):
|
||||
"""分页查询表数据"""
|
||||
table_name = (data or {}).get('Table', '')
|
||||
if not table_name:
|
||||
return {'code': 1, 'msg': '缺少 Table 参数'}
|
||||
|
||||
try:
|
||||
conn = self._GetConnection()
|
||||
except Exception as e:
|
||||
return {'code': 1, 'msg': f'数据库连接失败: {e}'}
|
||||
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
result = self._QueryTable(cursor, table_name, data or {})
|
||||
if result.get('error'):
|
||||
return {'code': 1, 'msg': result['error'], 'data': None}
|
||||
return {'code': 0, 'msg': 'success', 'data': result}
|
||||
except Exception as e:
|
||||
logger.error(f'[ORM] HandleList 异常: {e}')
|
||||
return {'code': 1, 'msg': f'查询失败: {e}'}
|
||||
|
||||
def HandleAdd(self, data):
|
||||
"""新增记录"""
|
||||
table_name = (data or {}).get('Table', '')
|
||||
record = (data or {}).get('Record', {})
|
||||
if not table_name:
|
||||
return {'code': 1, 'msg': '缺少 Table 参数'}
|
||||
|
||||
try:
|
||||
conn = self._GetConnection()
|
||||
except Exception as e:
|
||||
return {'code': 1, 'msg': f'数据库连接失败: {e}'}
|
||||
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
result = self._AddRecord(cursor, table_name, record)
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f'[ORM] HandleAdd 异常: {e}')
|
||||
return {'code': 1, 'msg': f'新增失败: {e}'}
|
||||
|
||||
def HandleModify(self, data):
|
||||
"""修改记录"""
|
||||
table_name = (data or {}).get('Table', '')
|
||||
record = (data or {}).get('Record', {})
|
||||
if not table_name:
|
||||
return {'code': 1, 'msg': '缺少 Table 参数'}
|
||||
|
||||
try:
|
||||
conn = self._GetConnection()
|
||||
except Exception as e:
|
||||
return {'code': 1, 'msg': f'数据库连接失败: {e}'}
|
||||
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
result = self._ModifyRecord(cursor, table_name, record)
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f'[ORM] HandleModify 异常: {e}')
|
||||
return {'code': 1, 'msg': f'修改失败: {e}'}
|
||||
|
||||
def HandleDelete(self, data):
|
||||
"""删除记录"""
|
||||
table_name = (data or {}).get('Table', '')
|
||||
record = (data or {}).get('Record', {})
|
||||
if not table_name:
|
||||
return {'code': 1, 'msg': '缺少 Table 参数'}
|
||||
|
||||
try:
|
||||
conn = self._GetConnection()
|
||||
except Exception as e:
|
||||
return {'code': 1, 'msg': f'数据库连接失败: {e}'}
|
||||
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
result = self._DeleteRecord(cursor, table_name, record)
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f'[ORM] HandleDelete 异常: {e}')
|
||||
return {'code': 1, 'msg': f'删除失败: {e}'}
|
||||
|
||||
# ─── SQL 执行 ──────────────────────────────────────────────
|
||||
|
||||
def _ListTables(self, cursor):
|
||||
"""列出所有用户表,含 i18n 标题"""
|
||||
cursor.execute(
|
||||
"SELECT TABLE_NAME, TABLE_ROWS, TABLE_COMMENT FROM information_schema.TABLES "
|
||||
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_TYPE = 'BASE TABLE' "
|
||||
"ORDER BY TABLE_NAME"
|
||||
)
|
||||
|
||||
from django.apps import apps
|
||||
# 构建表名→中文标题映射
|
||||
model_verbose = {}
|
||||
for model in apps.get_models():
|
||||
meta = model._meta
|
||||
# 优先使用 table_title(自定义 Meta 属性),其次 verbose_name
|
||||
table_title = getattr(meta, 'table_title', None)
|
||||
title = str(table_title) if table_title else (str(meta.verbose_name) if meta.verbose_name else '')
|
||||
if title:
|
||||
model_verbose[meta.object_name] = title
|
||||
model_verbose[meta.db_table] = title
|
||||
|
||||
result = []
|
||||
for row in cursor.fetchall():
|
||||
table_name, table_rows, table_comment = row
|
||||
# 优先级:TABLE_COMMENT > table_title/verbose_name > 表名
|
||||
title = table_comment or model_verbose.get(table_name) or table_name
|
||||
result.append({'name': table_name, 'title': title, 'count': table_rows or 0})
|
||||
return result
|
||||
|
||||
def _ListColumns(self, cursor, table_name):
|
||||
"""列出指定表的列信息"""
|
||||
cursor.execute(
|
||||
"SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA, COLUMN_TYPE, COLUMN_COMMENT "
|
||||
"FROM information_schema.COLUMNS "
|
||||
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s "
|
||||
"ORDER BY ORDINAL_POSITION",
|
||||
[table_name]
|
||||
)
|
||||
|
||||
model_verbose = self._FindModelVerboseNames(table_name)
|
||||
logger.info(f'[ORM] _ListColumns table={table_name} model_verbose={model_verbose}')
|
||||
|
||||
columns = []
|
||||
for row in cursor.fetchall():
|
||||
col_name, data_type, is_nullable, col_key, extra, col_type, col_comment = row
|
||||
is_pk = col_key == 'PRI'
|
||||
is_auto = 'auto_increment' in (extra or '').lower()
|
||||
|
||||
if data_type in ('int', 'bigint', 'tinyint', 'smallint', 'mediumint'):
|
||||
ftype = 'number'
|
||||
elif data_type in ('float', 'double', 'decimal'):
|
||||
ftype = 'number'
|
||||
elif data_type in ('datetime', 'timestamp'):
|
||||
ftype = 'datetime'
|
||||
elif data_type in ('date',):
|
||||
ftype = 'date'
|
||||
elif data_type in ('time',):
|
||||
ftype = 'time'
|
||||
elif data_type in ('json',):
|
||||
ftype = 'textarea'
|
||||
elif data_type in ('text', 'mediumtext', 'longtext', 'tinytext'):
|
||||
ftype = 'textarea'
|
||||
elif data_type in ('binary', 'varbinary', 'blob'):
|
||||
ftype = 'uuid'
|
||||
else:
|
||||
ftype = 'text'
|
||||
|
||||
title = col_comment or model_verbose.get(col_name) or col_name
|
||||
|
||||
columns.append({
|
||||
'field': col_name,
|
||||
'title': title,
|
||||
'type': ftype,
|
||||
'editable': not is_pk and not is_auto,
|
||||
'sortable': True,
|
||||
'filterable': True,
|
||||
'primaryKey': is_pk,
|
||||
'hideInForm': is_pk,
|
||||
'required': is_nullable == 'NO' and not is_auto,
|
||||
'dbType': col_type,
|
||||
})
|
||||
return columns
|
||||
|
||||
def _QueryTable(self, cursor, table_name, params):
|
||||
"""分页查询表数据"""
|
||||
cursor.execute(
|
||||
"SELECT COUNT(*) FROM information_schema.TABLES "
|
||||
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s",
|
||||
[table_name]
|
||||
)
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return {'records': [], 'total': 0, 'error': f'表不存在: {table_name}'}
|
||||
|
||||
col_info = self._GetTableColumns(cursor, table_name)
|
||||
pk_cols = {k: v for k, v in col_info.items() if v['is_pk']}
|
||||
|
||||
where_parts = []
|
||||
where_values = []
|
||||
for pk_name in pk_cols:
|
||||
pk_val = params.get(pk_name, '')
|
||||
if pk_val:
|
||||
where_parts.append(f'`{pk_name}` = %s')
|
||||
where_values.append(self._ConvertValueForDB(pk_val, pk_cols[pk_name]))
|
||||
|
||||
keyword = params.get('keyword', '')
|
||||
if not where_parts and keyword:
|
||||
cursor.execute(
|
||||
"SELECT COLUMN_NAME FROM information_schema.COLUMNS "
|
||||
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s "
|
||||
"AND DATA_TYPE IN ('varchar', 'char', 'text', 'mediumtext', 'longtext')",
|
||||
[table_name]
|
||||
)
|
||||
text_cols = [row[0] for row in cursor.fetchall()]
|
||||
if text_cols:
|
||||
conditions = [f'`{c}` LIKE %s' for c in text_cols]
|
||||
or_clause = ' OR '.join(conditions)
|
||||
where_parts.append(f'({or_clause})')
|
||||
where_values.extend([f'%{keyword}%'] * len(text_cols))
|
||||
|
||||
where_clause = (' WHERE ' + ' AND '.join(where_parts)) if where_parts else ''
|
||||
|
||||
if where_clause:
|
||||
cursor.execute(f'SELECT COUNT(*) FROM `{table_name}`{where_clause}', where_values)
|
||||
total = cursor.fetchone()[0]
|
||||
else:
|
||||
cursor.execute(f'SELECT COUNT(*) FROM `{table_name}`')
|
||||
total = cursor.fetchone()[0]
|
||||
|
||||
try:
|
||||
page = max(int(params.get('PageIndex', 1)), 1)
|
||||
except (ValueError, TypeError):
|
||||
page = 1
|
||||
try:
|
||||
page_size = min(max(int(params.get('PageSize', 20)), 1), 200)
|
||||
except (ValueError, TypeError):
|
||||
page_size = 20
|
||||
|
||||
offset = (page - 1) * page_size
|
||||
cursor.execute(
|
||||
f'SELECT * FROM `{table_name}`{where_clause} ORDER BY 1 LIMIT %s OFFSET %s',
|
||||
where_values + [page_size, offset]
|
||||
)
|
||||
desc = [d[0] for d in cursor.description]
|
||||
records = []
|
||||
for row in cursor.fetchall():
|
||||
record = {}
|
||||
for i, val in enumerate(row):
|
||||
val = self._SerializeValue(val)
|
||||
record[desc[i]] = val
|
||||
records.append(record)
|
||||
|
||||
return {'records': records, 'total': total, 'page': page, 'PageSize': page_size}
|
||||
|
||||
def _AddRecord(self, cursor, table_name, record):
|
||||
"""新增记录"""
|
||||
if not self._ValidateTableName(cursor, table_name):
|
||||
return {'code': 1, 'msg': f'表 {table_name} 不存在'}
|
||||
|
||||
col_info = self._GetTableColumns(cursor, table_name)
|
||||
|
||||
fields = []
|
||||
values = []
|
||||
for key, val in record.items():
|
||||
if key not in col_info:
|
||||
continue
|
||||
if col_info[key]['is_auto']:
|
||||
continue
|
||||
fields.append(f'`{key}`')
|
||||
values.append(self._ConvertValueForDB(val, col_info[key]))
|
||||
|
||||
if not fields:
|
||||
return {'code': 1, 'msg': '没有可插入的字段'}
|
||||
|
||||
placeholders = ', '.join(['%s'] * len(fields))
|
||||
sql = f'INSERT INTO `{table_name}` ({", ".join(fields)}) VALUES ({placeholders})'
|
||||
cursor.execute(sql, values)
|
||||
return {'code': 0, 'msg': '新增成功'}
|
||||
|
||||
def _ModifyRecord(self, cursor, table_name, record):
|
||||
"""修改记录"""
|
||||
if not self._ValidateTableName(cursor, table_name):
|
||||
return {'code': 1, 'msg': f'表 {table_name} 不存在'}
|
||||
|
||||
col_info = self._GetTableColumns(cursor, table_name)
|
||||
pk_cols = {k: v for k, v in col_info.items() if v['is_pk']}
|
||||
|
||||
if not pk_cols:
|
||||
return {'code': 1, 'msg': '表没有主键,无法定位记录'}
|
||||
|
||||
set_parts = []
|
||||
set_values = []
|
||||
for key, val in record.items():
|
||||
if key not in col_info or key in pk_cols:
|
||||
continue
|
||||
set_parts.append(f'`{key}` = %s')
|
||||
set_values.append(self._ConvertValueForDB(val, col_info[key]))
|
||||
|
||||
if not set_parts:
|
||||
return {'code': 0, 'msg': '没有需要更新的字段'}
|
||||
|
||||
where_parts = []
|
||||
where_values = []
|
||||
for pk_name in pk_cols:
|
||||
if pk_name not in record:
|
||||
return {'code': 1, 'msg': f'缺少主键字段: {pk_name}'}
|
||||
where_parts.append(f'`{pk_name}` = %s')
|
||||
where_values.append(self._ConvertValueForDB(record[pk_name], pk_cols[pk_name]))
|
||||
|
||||
sql = f'UPDATE `{table_name}` SET {", ".join(set_parts)} WHERE {" AND ".join(where_parts)}'
|
||||
cursor.execute(sql, set_values + where_values)
|
||||
|
||||
if cursor.rowcount == 0:
|
||||
return {'code': 1, 'msg': '记录不存在或未变更'}
|
||||
return {'code': 0, 'msg': '修改成功'}
|
||||
|
||||
def _DeleteRecord(self, cursor, table_name, record):
|
||||
"""删除记录"""
|
||||
if not self._ValidateTableName(cursor, table_name):
|
||||
return {'code': 1, 'msg': f'表 {table_name} 不存在'}
|
||||
|
||||
col_info = self._GetTableColumns(cursor, table_name)
|
||||
pk_cols = {k: v for k, v in col_info.items() if v['is_pk']}
|
||||
|
||||
if not pk_cols:
|
||||
return {'code': 1, 'msg': '表没有主键,无法定位记录'}
|
||||
|
||||
where_parts = []
|
||||
where_values = []
|
||||
for pk_name in pk_cols:
|
||||
if pk_name not in record:
|
||||
return {'code': 1, 'msg': f'缺少主键字段: {pk_name}'}
|
||||
where_parts.append(f'`{pk_name}` = %s')
|
||||
where_values.append(self._ConvertValueForDB(record[pk_name], pk_cols[pk_name]))
|
||||
|
||||
sql = f'DELETE FROM `{table_name}` WHERE {" AND ".join(where_parts)}'
|
||||
cursor.execute(sql, where_values)
|
||||
|
||||
if cursor.rowcount == 0:
|
||||
return {'code': 1, 'msg': '记录不存在'}
|
||||
return {'code': 0, 'msg': '删除成功'}
|
||||
|
||||
# ─── 工具方法 ──────────────────────────────────────────────
|
||||
|
||||
def _ValidateTableName(self, cursor, table_name):
|
||||
"""验证表名存在"""
|
||||
cursor.execute(
|
||||
"SELECT COUNT(*) FROM information_schema.TABLES "
|
||||
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s",
|
||||
[table_name]
|
||||
)
|
||||
return cursor.fetchone()[0] > 0
|
||||
|
||||
def _GetTableColumns(self, cursor, table_name):
|
||||
"""获取表的列信息"""
|
||||
cursor.execute(
|
||||
"SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE, COLUMN_KEY, EXTRA, IS_NULLABLE "
|
||||
"FROM information_schema.COLUMNS "
|
||||
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s "
|
||||
"ORDER BY ORDINAL_POSITION",
|
||||
[table_name]
|
||||
)
|
||||
cols = {}
|
||||
for row in cursor.fetchall():
|
||||
col_name, data_type, column_type, col_key, extra, is_nullable = row
|
||||
cols[col_name] = {
|
||||
'type': data_type,
|
||||
'column_type': column_type or '',
|
||||
'is_pk': col_key == 'PRI',
|
||||
'is_auto': 'auto_increment' in (extra or '').lower(),
|
||||
'is_nullable': is_nullable == 'YES',
|
||||
}
|
||||
return cols
|
||||
|
||||
def _ConvertValueForDB(self, value, col_info):
|
||||
"""将前端传来的值转换为数据库可接受的类型"""
|
||||
if value is None or value == '':
|
||||
if col_info['is_nullable']:
|
||||
return None
|
||||
return ''
|
||||
|
||||
data_type = col_info['type']
|
||||
|
||||
if data_type in ('int', 'bigint', 'tinyint', 'smallint', 'mediumint'):
|
||||
return int(value)
|
||||
elif data_type in ('float', 'double', 'decimal'):
|
||||
return float(value)
|
||||
elif data_type in ('binary', 'varbinary'):
|
||||
import re
|
||||
hex_str = re.sub(r'[^0-9a-fA-F]', '', str(value))
|
||||
if len(hex_str) == 32:
|
||||
return uuid.UUID(hex_str).bytes
|
||||
return value
|
||||
|
||||
return value
|
||||
|
||||
def _SerializeValue(self, val):
|
||||
"""将数据库值序列化为 JSON 安全格式"""
|
||||
if isinstance(val, bytes):
|
||||
if len(val) == 16:
|
||||
try:
|
||||
return str(uuid.UUID(bytes=val))
|
||||
except ValueError:
|
||||
return val.hex()
|
||||
return val.hex()
|
||||
elif isinstance(val, datetime.datetime):
|
||||
return val.strftime('%Y-%m-%d %H:%M:%S')
|
||||
elif isinstance(val, datetime.date):
|
||||
return val.isoformat()
|
||||
elif isinstance(val, datetime.time):
|
||||
return val.strftime('%H:%M:%S')
|
||||
elif isinstance(val, (bytearray, memoryview)):
|
||||
return bytes(val).hex()
|
||||
return val
|
||||
|
||||
def _FindModelVerboseNames(self, table_name):
|
||||
"""从 Django 模型中获取字段的 verbose_name"""
|
||||
from django.apps import apps
|
||||
verbose_map = {}
|
||||
try:
|
||||
for model in apps.get_models():
|
||||
if model._meta.db_table == table_name:
|
||||
logger.info(f'[ORM] _FindModelVerboseNames matched model={model.__name__} db_table={model._meta.db_table}')
|
||||
for f in model._meta.get_fields():
|
||||
# 获取数据库列名
|
||||
col_name = None
|
||||
if hasattr(f, 'column') and f.column:
|
||||
col_name = f.column
|
||||
elif hasattr(f, 'db_column') and f.db_column:
|
||||
col_name = f.db_column
|
||||
elif hasattr(f, 'attname'):
|
||||
col_name = f.attname
|
||||
|
||||
if not col_name:
|
||||
continue
|
||||
|
||||
vn = getattr(f, 'verbose_name', None)
|
||||
if vn and str(vn) != col_name:
|
||||
verbose_map[col_name] = str(vn)
|
||||
logger.debug(f'[ORM] {col_name} -> {str(vn)}')
|
||||
break
|
||||
else:
|
||||
# 没有匹配的模型
|
||||
available = [m._meta.db_table for m in apps.get_models()]
|
||||
logger.warning(f'[ORM] _FindModelVerboseNames: 未找到 db_table={table_name} 的模型, 可用表: {available[:20]}...')
|
||||
except Exception as e:
|
||||
logger.error(f'[ORM] _FindModelVerboseNames 异常: {e}')
|
||||
return verbose_map
|
||||
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3
|
||||
"""只导入用户迁移所需的表到临时数据库 xaio_old"""
|
||||
import MySQLdb
|
||||
import re
|
||||
from app_secrets import DATABASE_HOST, DATABASE_PORT, DATABASE_USER, DATABASE_PASSWORD
|
||||
|
||||
# 需要导入的表(用户相关)
|
||||
NEEDED_TABLES = {
|
||||
'user_main', 'user_dashou', 'user_guanshi', 'user_kefu',
|
||||
'user_shangjia', 'user_boss', 'admin_profile', 'user_zuzhang',
|
||||
'user_shenheguan', 'user_role', 'role', 'permission',
|
||||
'role_permission', 'account_permission',
|
||||
}
|
||||
|
||||
def get_conn(db=None):
|
||||
kwargs = dict(
|
||||
host=DATABASE_HOST, port=int(DATABASE_PORT),
|
||||
user=DATABASE_USER, password=DATABASE_PASSWORD,
|
||||
charset='utf8mb4', connect_timeout=60,
|
||||
read_timeout=300, write_timeout=300,
|
||||
)
|
||||
if db:
|
||||
kwargs['database'] = db
|
||||
return MySQLdb.connect(**kwargs)
|
||||
|
||||
# Drop and recreate
|
||||
conn = get_conn()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('DROP DATABASE IF EXISTS xaio_old')
|
||||
cursor.execute('CREATE DATABASE xaio_old CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci')
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print('临时数据库 xaio_old 已重建')
|
||||
|
||||
# Read the SQL file
|
||||
with open('xaio_cheng_xu_backup.sql', 'r', encoding='utf-8') as f:
|
||||
sql_content = f.read()
|
||||
|
||||
# Parse and filter statements
|
||||
# We need CREATE TABLE and INSERT statements for NEEDED_TABLES only
|
||||
# Also need DROP TABLE IF EXISTS for those tables
|
||||
statements = []
|
||||
current = []
|
||||
current_table = None
|
||||
in_create = False
|
||||
|
||||
for line in sql_content.split('\n'):
|
||||
stripped = line.strip()
|
||||
if not stripped or stripped.startswith('--') or stripped.startswith('/*'):
|
||||
continue
|
||||
|
||||
# Detect table name from CREATE TABLE or DROP TABLE or INSERT INTO
|
||||
create_match = re.match(r'CREATE\s+TABLE\s+`(\w+)`', stripped, re.IGNORECASE)
|
||||
drop_match = re.match(r'DROP\s+TABLE\s+IF\s+EXISTS\s+`(\w+)`', stripped, re.IGNORECASE)
|
||||
insert_match = re.match(r'INSERT\s+INTO\s+`(\w+)`', stripped, re.IGNORECASE)
|
||||
|
||||
if create_match:
|
||||
current_table = create_match.group(1)
|
||||
in_create = True
|
||||
elif drop_match:
|
||||
current_table = drop_match.group(1)
|
||||
elif insert_match:
|
||||
current_table = insert_match.group(1)
|
||||
in_create = False
|
||||
|
||||
# Only include statements for needed tables
|
||||
if current_table and current_table in NEEDED_TABLES:
|
||||
current.append(line)
|
||||
|
||||
if stripped.endswith(';'):
|
||||
stmt = '\n'.join(current).strip()
|
||||
current = []
|
||||
current_table = None
|
||||
in_create = False
|
||||
upper = stmt.upper()
|
||||
if not upper.startswith('SET ') and not upper.startswith('USE '):
|
||||
statements.append(stmt)
|
||||
elif stripped.endswith(';'):
|
||||
# Not a needed table, skip
|
||||
current = []
|
||||
current_table = None
|
||||
in_create = False
|
||||
elif current_table and current_table in NEEDED_TABLES:
|
||||
current.append(line)
|
||||
else:
|
||||
# Not needed, skip but track state
|
||||
if stripped.endswith(';'):
|
||||
current = []
|
||||
current_table = None
|
||||
|
||||
print(f'筛选出 {len(statements)} 条用户相关SQL语句')
|
||||
|
||||
# Execute
|
||||
conn = get_conn(db='xaio_old')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SET FOREIGN_KEY_CHECKS = 0')
|
||||
executed = 0
|
||||
errors = 0
|
||||
|
||||
for stmt in statements:
|
||||
try:
|
||||
cursor.execute(stmt)
|
||||
executed += 1
|
||||
if executed % 20 == 0:
|
||||
conn.commit()
|
||||
except MySQLdb.OperationalError as e:
|
||||
if e.args[0] in (2006, 2013):
|
||||
try:
|
||||
conn.close()
|
||||
except:
|
||||
pass
|
||||
conn = get_conn(db='xaio_old')
|
||||
cursor = conn.cursor()
|
||||
try:
|
||||
cursor.execute(stmt)
|
||||
executed += 1
|
||||
except Exception as e2:
|
||||
errors += 1
|
||||
if errors <= 5:
|
||||
print(f' ERR(retry): {str(e2)[:100]}')
|
||||
else:
|
||||
errors += 1
|
||||
if errors <= 5:
|
||||
print(f' ERR: {str(e)[:100]}')
|
||||
except Exception as e:
|
||||
errors += 1
|
||||
if errors <= 5:
|
||||
print(f' ERR: {str(e)[:100]}')
|
||||
|
||||
conn.commit()
|
||||
cursor.execute('SET FOREIGN_KEY_CHECKS = 1')
|
||||
conn.commit()
|
||||
print(f'\n导入完成: 成功 {executed}, 错误 {errors}')
|
||||
|
||||
# Check row counts
|
||||
print('\n关键表行数:')
|
||||
for table in sorted(NEEDED_TABLES):
|
||||
try:
|
||||
cursor.execute('SELECT COUNT(*) FROM `%s`' % table)
|
||||
count = cursor.fetchone()[0]
|
||||
print(f' {table}: {count} rows')
|
||||
except Exception:
|
||||
print(f' {table}: NOT FOUND')
|
||||
|
||||
conn.close()
|
||||
+463
@@ -0,0 +1,463 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
migrate_data.py — 从 SQL 备份文件直接迁移数据到新的 gvsdsdk User + RBAC 体系
|
||||
v3: 正确的字段映射 + 基于扩展表存在性分配角色 + bulk_create + 实时进度
|
||||
"""
|
||||
import os, sys, re, uuid, time, datetime, MySQLdb
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'a_long_dianjing.settings')
|
||||
import django; django.setup()
|
||||
|
||||
from app_secrets import DATABASE_HOST, DATABASE_PORT, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME
|
||||
|
||||
TENANT_UUID = uuid.UUID('a0000000-0000-0000-0000-000000000001').bytes
|
||||
COMPANY_UUID = uuid.UUID('b0000000-0000-0000-0000-000000000001').bytes
|
||||
BATCH_SIZE = 500
|
||||
|
||||
ROLE_MAP = {
|
||||
'normal': '消费者', 'dashou': '打手', 'shop': '商家',
|
||||
'guanshi': '负责人', 'admin': '管理员', 'kefu': '客服',
|
||||
'zuzhang': '组长', 'shenheguan': '审核官',
|
||||
}
|
||||
|
||||
# 角色优先级(高→低): 管理员 > 客服 > 负责人 > 组长 > 审核官 > 商家 > 打手 > 消费者
|
||||
ROLE_PRIORITY = ['admin', 'kefu', 'guanshi', 'zuzhang', 'shenheguan', 'shop', 'dashou', 'normal']
|
||||
|
||||
# 扩展表 → 角色类型 映射
|
||||
EXT_ROLE_MAP = {
|
||||
'admin_profile': 'admin',
|
||||
'user_kefu': 'kefu',
|
||||
'user_guanshi': 'guanshi',
|
||||
'user_zuzhang': 'zuzhang',
|
||||
'user_shenheguan': 'shenheguan',
|
||||
'user_shangjia': 'shop',
|
||||
'user_dashou': 'dashou',
|
||||
}
|
||||
|
||||
SQL_FILE = os.path.join(os.path.dirname(__file__), 'xaio_cheng_xu_backup.sql')
|
||||
|
||||
|
||||
class Progress:
|
||||
def __init__(self, total, width=35):
|
||||
self.total = total; self.width = width; self.start = time.time(); self.done = 0
|
||||
def update(self, n=1):
|
||||
self.done += n; pct = self.done / self.total if self.total else 0
|
||||
filled = int(self.width * pct); bar = '█' * filled + '░' * (self.width - filled)
|
||||
elapsed = time.time() - self.start
|
||||
eta = (elapsed / self.done * (self.total - self.done)) if self.done else 0
|
||||
sys.stdout.write(f'\r [{bar}] {pct:5.1%} {self.done}/{self.total} {elapsed:.0f}s ETA{eta:.0f}s')
|
||||
sys.stdout.flush()
|
||||
def finish(self):
|
||||
elapsed = time.time() - self.start
|
||||
sys.stdout.write(f'\r [{"█"*self.width}] 100% {self.done}/{self.total} {elapsed:.0f}s\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def parse_insert_values(table_name, sql_content):
|
||||
pattern = re.compile(r"INSERT\s+INTO\s+`" + re.escape(table_name) + r"`\s+VALUES\s*\((.+?)\)\s*;", re.IGNORECASE | re.DOTALL)
|
||||
return [m.group(1) for m in pattern.finditer(sql_content)]
|
||||
|
||||
|
||||
def parse_sql_value(val_str):
|
||||
val_str = val_str.strip()
|
||||
if val_str.upper() == 'NULL': return None
|
||||
if val_str.startswith("'") and val_str.endswith("'"):
|
||||
return val_str[1:-1].replace("\\'", "'").replace("\\\\", "\\")
|
||||
try: return int(val_str)
|
||||
except ValueError:
|
||||
try: return float(val_str)
|
||||
except ValueError: return val_str
|
||||
|
||||
|
||||
def split_sql_values(values_str):
|
||||
values, current, in_quote, escape = [], [], False, False
|
||||
for ch in values_str:
|
||||
if escape: current.append(ch); escape = False; continue
|
||||
if ch == '\\': current.append(ch); escape = True; continue
|
||||
if ch == "'": in_quote = not in_quote; current.append(ch); continue
|
||||
if ch == ',' and not in_quote: values.append(''.join(current).strip()); current = []; continue
|
||||
current.append(ch)
|
||||
if current: values.append(''.join(current).strip())
|
||||
return [parse_sql_value(v) for v in values]
|
||||
|
||||
|
||||
def parse_dt(v):
|
||||
if isinstance(v, str) and v:
|
||||
try: return datetime.datetime.fromisoformat(v.replace(' ', 'T'))
|
||||
except: pass
|
||||
return datetime.datetime.utcnow()
|
||||
|
||||
|
||||
def get_raw_conn(db=None):
|
||||
kwargs = dict(host=DATABASE_HOST, port=int(DATABASE_PORT), user=DATABASE_USER,
|
||||
password=DATABASE_PASSWORD, charset='utf8mb4', connect_timeout=10,
|
||||
read_timeout=60, write_timeout=60)
|
||||
if db: kwargs['database'] = db
|
||||
return MySQLdb.connect(**kwargs)
|
||||
|
||||
|
||||
def run_migration():
|
||||
from gvsdsdk.models import User, Role, UserRole
|
||||
from users.models import (
|
||||
UserBoss, UserDashou, UserShangjia, UserGuanshi,
|
||||
UserZuzhang, UserShenheguan, AdminProfile, UserKefu,
|
||||
UserSensitiveData
|
||||
)
|
||||
|
||||
print("=" * 60)
|
||||
print("开始从 SQL 备份迁移数据到 gvsdsdk.User + RBAC")
|
||||
print("=" * 60)
|
||||
|
||||
# [0] 读取 SQL
|
||||
print("\n[0/7] 读取 SQL 备份文件...", end=' ')
|
||||
with open(SQL_FILE, 'r', encoding='utf-8') as f:
|
||||
sql_content = f.read()
|
||||
print(f"{len(sql_content)/1024/1024:.1f} MB")
|
||||
|
||||
# [1] 解析所有扩展表的 user_id → 建立角色映射
|
||||
print("\n[1/7] 解析扩展表建立角色映射...")
|
||||
|
||||
# 正确的 user_id 索引位置
|
||||
ext_user_id_idx = {
|
||||
'user_dashou': 22,
|
||||
'user_guanshi': 11,
|
||||
'user_kefu': 9,
|
||||
'user_shangjia': 14,
|
||||
'user_boss': 6,
|
||||
'admin_profile': 4,
|
||||
'user_zuzhang': 17,
|
||||
'user_shenheguan': 9,
|
||||
}
|
||||
|
||||
# user_main.id → 角色集合
|
||||
user_roles = {} # old_user_id -> set of role_types
|
||||
|
||||
for table_name, role_type in EXT_ROLE_MAP.items():
|
||||
inserts = parse_insert_values(table_name, sql_content)
|
||||
uid_idx = ext_user_id_idx[table_name]
|
||||
count = 0
|
||||
for values_str in inserts:
|
||||
vals = split_sql_values(values_str)
|
||||
if uid_idx < len(vals) and vals[uid_idx] is not None:
|
||||
old_uid = vals[uid_idx]
|
||||
if old_uid not in user_roles:
|
||||
user_roles[old_uid] = set()
|
||||
user_roles[old_uid].add(role_type)
|
||||
count += 1
|
||||
print(f" {table_name}: {count} 条有 user_id")
|
||||
|
||||
# [2] 解析 user_main
|
||||
print("\n[2/7] 解析 user_main...")
|
||||
user_main_inserts = parse_insert_values('user_main', sql_content)
|
||||
total = len(user_main_inserts)
|
||||
print(f" 共 {total} 条记录")
|
||||
|
||||
uid_map = {} # yonghuid -> UserUUID (bytes)
|
||||
user_id_map = {} # old id -> yonghuid
|
||||
phone_to_yonghuid = {}
|
||||
|
||||
# 先解析所有 user_main 记录
|
||||
user_data = [] # (old_id, yonghuid, fields_dict, role_type)
|
||||
prog = Progress(total)
|
||||
|
||||
for i, values_str in enumerate(user_main_inserts):
|
||||
vals = split_sql_values(values_str)
|
||||
if len(vals) < 16:
|
||||
prog.update(); continue
|
||||
|
||||
old_id = vals[1]
|
||||
yonghuid = str(vals[2]) if vals[2] else None
|
||||
if not yonghuid:
|
||||
prog.update(); continue
|
||||
|
||||
# 确定角色:基于扩展表存在性 + user_type
|
||||
roles = user_roles.get(old_id, set())
|
||||
user_type = str(vals[11]) if vals[11] else 'normal'
|
||||
|
||||
# user_type 也可能指定角色
|
||||
if user_type == 'admin':
|
||||
roles.add('admin')
|
||||
elif user_type == 'kefu':
|
||||
roles.add('kefu')
|
||||
|
||||
# 如果没有任何角色,默认为 normal
|
||||
if not roles:
|
||||
roles.add('normal')
|
||||
|
||||
# 选择优先级最高的角色
|
||||
primary_role = 'normal'
|
||||
for r in ROLE_PRIORITY:
|
||||
if r in roles:
|
||||
primary_role = r
|
||||
break
|
||||
|
||||
user_data.append((old_id, yonghuid, vals, primary_role, roles))
|
||||
user_id_map[old_id] = yonghuid
|
||||
phone = str(vals[5]) if vals[5] else ''
|
||||
if phone: phone_to_yonghuid[phone] = yonghuid
|
||||
prog.update()
|
||||
|
||||
prog.finish()
|
||||
print(f" 解析完成: {len(user_data)} 条有效记录")
|
||||
|
||||
# [3] 创建角色
|
||||
print("\n[3/7] 创建角色...")
|
||||
created_roles = {}
|
||||
for user_type, role_name in ROLE_MAP.items():
|
||||
role, created = Role.objects.get_or_create(
|
||||
RoleName=role_name, TenantUUID=TENANT_UUID,
|
||||
defaults={'RoleUUID': uuid.uuid4().bytes, 'RoleDesc': f'{role_name}角色', 'RoleStatus': 1, 'AssignScope': 0})
|
||||
created_roles[user_type] = role
|
||||
print(f" {role_name}: {'NEW' if created else 'EXISTS'}")
|
||||
|
||||
# [4] 批量创建 User + UserRole + UserSensitiveData
|
||||
print("\n[4/7] 批量创建 User + UserRole + UserSensitiveData...")
|
||||
|
||||
user_batch, ur_batch, usd_batch = [], [], []
|
||||
errors = 0
|
||||
prog = Progress(len(user_data))
|
||||
|
||||
for old_id, yonghuid, vals, primary_role, all_roles in user_data:
|
||||
openid = str(vals[3]) if vals[3] else ''
|
||||
avatar = str(vals[4]) if vals[4] else 'a_long/morentouxiang.jpg'
|
||||
phone = str(vals[5]) if vals[5] else ''
|
||||
password = str(vals[6]) if vals[6] else ''
|
||||
zhifu = str(vals[7]) if vals[7] else ''
|
||||
skzhanghao = str(vals[8]) if vals[8] else ''
|
||||
ip = str(vals[9]) if vals[9] else ''
|
||||
last_login_time = vals[10]
|
||||
create_time = vals[12]
|
||||
unionid = str(vals[14]) if vals[14] else ''
|
||||
shoujihao_renzheng = bool(vals[15]) if vals[15] is not None else False
|
||||
|
||||
user_uuid = uuid.uuid4().bytes
|
||||
ct, lt = parse_dt(create_time), parse_dt(last_login_time)
|
||||
|
||||
user_batch.append(User(
|
||||
UserUUID=user_uuid, UserName=yonghuid, UserUID=yonghuid,
|
||||
OpenID=openid, UnionID=unionid, Avatar=avatar, Phone=phone,
|
||||
PhoneVerified=shoujihao_renzheng, IP=ip, UserAccountLicense=1,
|
||||
UserPositionStatus=0, UserCreateTime=ct, UserLastLoginDate=lt,
|
||||
IsStaff=('admin' in all_roles), IsSuperuser=('admin' in all_roles)))
|
||||
|
||||
# 为每个角色创建 UserRole(多对多)
|
||||
for role_type in all_roles:
|
||||
role = created_roles.get(role_type)
|
||||
if role:
|
||||
ur_batch.append(UserRole(
|
||||
UserRoleUUID=uuid.uuid4().bytes, UserUUID=user_uuid,
|
||||
RoleUUID=role.RoleUUID, CompanyUUID=COMPANY_UUID))
|
||||
|
||||
usd_batch.append(UserSensitiveData(
|
||||
user_uuid_id=user_uuid, password=password, zhifu=zhifu,
|
||||
skzhanghao=skzhanghao, shoujihao_renzheng=shoujihao_renzheng))
|
||||
|
||||
uid_map[yonghuid] = user_uuid
|
||||
|
||||
if len(user_batch) >= BATCH_SIZE:
|
||||
try:
|
||||
User.objects.bulk_create(user_batch, ignore_conflicts=True)
|
||||
UserRole.objects.bulk_create(ur_batch, ignore_conflicts=True)
|
||||
UserSensitiveData.objects.bulk_create(usd_batch, ignore_conflicts=True)
|
||||
except Exception: errors += len(user_batch)
|
||||
user_batch, ur_batch, usd_batch = [], [], []
|
||||
prog.update()
|
||||
|
||||
if user_batch:
|
||||
try:
|
||||
User.objects.bulk_create(user_batch, ignore_conflicts=True)
|
||||
UserRole.objects.bulk_create(ur_batch, ignore_conflicts=True)
|
||||
UserSensitiveData.objects.bulk_create(usd_batch, ignore_conflicts=True)
|
||||
except Exception: errors += len(user_batch)
|
||||
|
||||
prog.finish()
|
||||
print(f" 成功: {len(uid_map)}, 错误: {errors}")
|
||||
|
||||
# [5] 迁移扩展表 — 用 ORM bulk_create(正确字段映射)
|
||||
print("\n[5/7] 迁移扩展表...")
|
||||
|
||||
# 正确的字段映射: (sql_index, model_field_name)
|
||||
# None = 跳过, '_user_id' = FK 到新 User
|
||||
ext_configs = [
|
||||
('user_dashou', UserDashou, [
|
||||
(0, None), (1, 'nicheng'), (2, 'chenghao'), (3, 'zhuangtai'), (4, 'zaixianzhuangtai'),
|
||||
(5, 'zhanghaozhuangtai'), (6, 'jieshao'), (7, 'jiedanzongliang'), (8, 'chengjiaozongliang'),
|
||||
(9, 'tuikuanliang'), (10, 'yue'), (11, 'zonge'), (12, 'dianhua'), (13, 'wechat'),
|
||||
(14, 'yaoqingren'), (15, 'jinrijiedan'), (16, 'jinrishouyi'), (17, 'jinyuejiedan'),
|
||||
(18, 'jinyueshouyi'), (19, 'jifen'), (20, 'yajin'), (21, None), # create_time
|
||||
(22, '_user_id'), # user_id FK
|
||||
(23, 'ewai_xiane'), (24, 'jinritixian_jine'), (25, 'kaioi_ewai_xiane'),
|
||||
(26, 'last_tixian_date'),
|
||||
]),
|
||||
('user_guanshi', UserGuanshi, [
|
||||
(0, None), (1, 'yaoqingma'), (2, 'dianhua'), (3, 'wechat'),
|
||||
(4, 'yaogingshuliang'), (5, 'zhuangtai'), (6, 'jinrichongzhi'),
|
||||
(7, 'jinyuechongzhi'), (8, 'chongzhifenrun'), (9, 'yue'), (10, None), # create_time
|
||||
(11, '_user_id'),
|
||||
(12, 'fenghong_erci'), (13, 'fenghong_erci_enabled'), (14, 'fenhong_yici'),
|
||||
(15, 'ewai_xiane'), (16, 'jinritixian_jine'), (17, 'kaioi_ewai_xiane'),
|
||||
(18, 'last_tixian_date'), (19, 'yaoqingren'), (20, 'invite_qrcode_url'),
|
||||
]),
|
||||
('user_kefu', UserKefu, [
|
||||
(0, None), (1, 'nicheng'), (2, 'erjimima'), (3, 'zhuangtai'),
|
||||
(4, 'jinrichuli'), (5, 'jinyuechuli'), (6, 'zongchuli'),
|
||||
(7, None), (8, None), (9, '_user_id'),
|
||||
]),
|
||||
('user_shangjia', UserShangjia, [
|
||||
(0, None), (1, 'nicheng'), (2, 'zhuangtai'), (3, 'dianhua'), (4, 'wechat'),
|
||||
(5, 'fabu'), (6, 'tuikuan'), (7, 'yue'), (8, 'chengjiao'),
|
||||
(9, 'jinridingdan'), (10, 'jinriliushui'), (11, 'jinyuedingdan'),
|
||||
(12, 'jinyueliushui'), (13, None), (14, '_user_id'),
|
||||
]),
|
||||
('user_boss', UserBoss, [
|
||||
(0, None), (1, 'nickname'), (2, 'zonge'), (3, 'alldingdan'),
|
||||
(4, 'alltui'), (5, None), (6, '_user_id'),
|
||||
]),
|
||||
('admin_profile', AdminProfile, [
|
||||
(0, None), (1, 'password'), (2, 'wechat'), (3, None),
|
||||
(4, '_user_id'), (5, 'yaoqingma'),
|
||||
]),
|
||||
('user_zuzhang', UserZuzhang, [
|
||||
(0, None), (1, 'yaoqingma'), (2, 'fenyong_zonge'), (3, 'ketixian_jine'),
|
||||
(4, 'yaoqing_zongshu'), (5, 'jinri_fenyong'), (6, 'jinyue_fenyong'),
|
||||
(7, 'zhuangtai'), (8, 'haibao_url'), (9, 'jinri_tixian'), (10, 'last_tixian_time'),
|
||||
(11, 'ewai_tixian_xiane'), (12, 'kaioi_ewai_tixian'), (13, 'kaioi_ewai_fenhong'),
|
||||
(14, 'ewai_fenhong_jine'), (15, None), (16, None), (17, '_user_id'),
|
||||
]),
|
||||
('user_shenheguan', UserShenheguan, [
|
||||
(0, None), (1, 'zhuangtai'), (2, 'shenhe_zhuangtai'),
|
||||
(3, 'shenhe_zongshu'), (4, 'tongguo_zongshu'), (5, 'yue'), (6, 'zonge'),
|
||||
(7, None), (8, None), (9, '_user_id'), (10, 'is_renzheng'),
|
||||
]),
|
||||
]
|
||||
|
||||
for table_name, model, field_map in ext_configs:
|
||||
inserts = parse_insert_values(table_name, sql_content)
|
||||
if not inserts:
|
||||
print(f" {table_name}: 0 条"); continue
|
||||
|
||||
user_id_sql_idx = next((idx for idx, fn in field_map if fn == '_user_id'), None)
|
||||
if user_id_sql_idx is None:
|
||||
print(f" {table_name}: 无法定位 user_id"); continue
|
||||
|
||||
batch = []
|
||||
success = 0
|
||||
fail = 0
|
||||
prog = Progress(len(inserts))
|
||||
|
||||
for values_str in inserts:
|
||||
vals = split_sql_values(values_str)
|
||||
if not vals or user_id_sql_idx >= len(vals) or vals[user_id_sql_idx] is None:
|
||||
fail += 1; prog.update(); continue
|
||||
|
||||
old_user_id = vals[user_id_sql_idx]
|
||||
yonghuid = user_id_map.get(old_user_id)
|
||||
if not yonghuid:
|
||||
fail += 1; prog.update(); continue
|
||||
|
||||
new_uuid = uid_map.get(yonghuid)
|
||||
if not new_uuid:
|
||||
fail += 1; prog.update(); continue
|
||||
|
||||
try:
|
||||
obj = model(user_id=new_uuid)
|
||||
for sql_idx, field_name in field_map:
|
||||
if field_name is None or field_name == '_user_id':
|
||||
continue
|
||||
if sql_idx < len(vals) and vals[sql_idx] is not None:
|
||||
try: setattr(obj, field_name, vals[sql_idx])
|
||||
except: pass
|
||||
batch.append(obj)
|
||||
success += 1
|
||||
except Exception:
|
||||
fail += 1
|
||||
|
||||
if len(batch) >= BATCH_SIZE:
|
||||
try: model.objects.bulk_create(batch, ignore_conflicts=True)
|
||||
except: pass
|
||||
batch = []
|
||||
prog.update()
|
||||
|
||||
if batch:
|
||||
try: model.objects.bulk_create(batch, ignore_conflicts=True)
|
||||
except: pass
|
||||
|
||||
prog.finish()
|
||||
print(f" 成功: {success}, 失败(无user_id): {fail}")
|
||||
|
||||
# [6] 迁移其他引用表
|
||||
print("\n[6/7] 迁移其他引用 yonghuid 的表...")
|
||||
other_tables = [
|
||||
'tixianjilu', 'tixian_shenhe_jilu', 'tixian_auto_record',
|
||||
'xiugaijilu', 'ranking_record',
|
||||
]
|
||||
|
||||
conn = get_raw_conn(db=DATABASE_NAME)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SET FOREIGN_KEY_CHECKS = 0')
|
||||
|
||||
for table_name in other_tables:
|
||||
inserts = parse_insert_values(table_name, sql_content)
|
||||
if not inserts:
|
||||
print(f" {table_name}: 0 条"); continue
|
||||
|
||||
success = 0
|
||||
prog = Progress(len(inserts))
|
||||
|
||||
for values_str in inserts:
|
||||
sql = f"INSERT INTO `{table_name}` VALUES ({values_str})"
|
||||
try:
|
||||
cursor.execute(sql)
|
||||
success += 1
|
||||
except Exception:
|
||||
pass
|
||||
if success % 100 == 0 and success > 0:
|
||||
try: conn.commit()
|
||||
except: pass
|
||||
prog.update()
|
||||
|
||||
try: conn.commit()
|
||||
except MySQLdb.OperationalError:
|
||||
conn = get_raw_conn(db=DATABASE_NAME)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SET FOREIGN_KEY_CHECKS = 0')
|
||||
|
||||
prog.finish()
|
||||
print(f" 成功: {success}")
|
||||
|
||||
try:
|
||||
cursor.execute('SET FOREIGN_KEY_CHECKS = 1')
|
||||
conn.commit(); conn.close()
|
||||
except: pass
|
||||
|
||||
# [7] 验证
|
||||
print("\n[7/7] 验证迁移结果...")
|
||||
new_user_count = User.objects.count()
|
||||
new_ur_count = UserRole.objects.count()
|
||||
usd_count = UserSensitiveData.objects.count()
|
||||
|
||||
print(f" gvsdsdk.User: {new_user_count}")
|
||||
print(f" UserRole: {new_ur_count}")
|
||||
print(f" UserSensitiveData: {usd_count}")
|
||||
|
||||
print("\n 角色分布:")
|
||||
for user_type, role in created_roles.items():
|
||||
ur_count = UserRole.objects.filter(RoleUUID=role.RoleUUID).count()
|
||||
print(f" {ROLE_MAP[user_type]}: {ur_count} 人")
|
||||
|
||||
print("\n 扩展表:")
|
||||
for name, model in [('user_dashou', UserDashou), ('user_guanshi', UserGuanshi),
|
||||
('user_kefu', UserKefu), ('user_shangjia', UserShangjia),
|
||||
('user_boss', UserBoss), ('admin_profile', AdminProfile),
|
||||
('user_zuzhang', UserZuzhang), ('user_shenheguan', UserShenheguan)]:
|
||||
print(f" {name}: {model.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("=" * 60)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_migration()
|
||||
@@ -0,0 +1,259 @@
|
||||
#!/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 User, Role, Permission, UserRole, RolePermission
|
||||
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()
|
||||
+454
-205
@@ -1,205 +1,454 @@
|
||||
# Generated by Django 5.2.10 on 2026-01-14 19:59
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Lilubiao',
|
||||
fields=[
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'lilubiao',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Ptliushui',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('zonge', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='收取总金额')),
|
||||
('zhichuzonge', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='支出总金额')),
|
||||
('zongshouyi', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='总收益')),
|
||||
('rizonge', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='日收取')),
|
||||
('rizhichu', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='日支出')),
|
||||
('rishouyi', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='日收益')),
|
||||
('zongshoucishu', models.IntegerField(default=0, verbose_name='总收取次数')),
|
||||
('rishoucishu', models.IntegerField(default=0, verbose_name='日收取次数')),
|
||||
('zongzhichucishu', models.IntegerField(default=0, verbose_name='总支出次数')),
|
||||
('rizhichucishu', models.IntegerField(default=0, verbose_name='日支出次数')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'ptliushui',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Chufajilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dashouid', models.CharField(db_index=True, max_length=7, null=True, verbose_name='被罚打手ID')),
|
||||
('qingqiuid', models.CharField(db_index=True, max_length=7, null=True, verbose_name='请求处罚ID')),
|
||||
('chuliid', models.CharField(db_index=True, max_length=7, null=True, verbose_name='处理处罚ID')),
|
||||
('cfliyou', models.TextField(blank=True, null=True, verbose_name='处罚理由')),
|
||||
('sqzhuangtai', models.IntegerField(blank=True, default=0, null=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'chufajilu',
|
||||
'indexes': [models.Index(fields=['dashouid'], name='chufajilu_dashoui_07aac0_idx'), models.Index(fields=['qingqiuid'], name='chufajilu_qingqiu_ac160e_idx'), models.Index(fields=['chuliid'], name='chufajilu_chuliid_cd63ac_idx'), models.Index(fields=['dingdan_id'], name='chufajilu_dingdan_b8f0c2_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Dashoutupian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'dashoutupian',
|
||||
'indexes': [models.Index(fields=['dashou'], name='dashoutupia_dashou_7de8bd_idx'), models.Index(fields=['dingdan_id'], name='dashoutupia_dingdan_97c685_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Dingdan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('zhuangtai', models.IntegerField(blank=True, db_index=True, default=1, null=True, verbose_name='订单状态')),
|
||||
('fadan_pingtai', models.IntegerField(blank=True, null=True, verbose_name='发单平台')),
|
||||
('jine', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='订单金额')),
|
||||
('dashou_fencheng', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='打手分成')),
|
||||
('jiedan_dashou_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='接单打手ID')),
|
||||
('dashou_liuyan', models.TextField(blank=True, null=True, verbose_name='打手留言')),
|
||||
('zhiding_id', models.CharField(blank=True, max_length=32, null=True, verbose_name='指定ID')),
|
||||
('shangpin_id', models.IntegerField(blank=True, null=True, verbose_name='商品ID')),
|
||||
('leixing_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='商品类型ID')),
|
||||
('tupian', models.CharField(blank=True, max_length=500, null=True, verbose_name='商品图片URL')),
|
||||
('yaoqiuleixing', models.PositiveIntegerField(blank=True, null=True, verbose_name='抢单要求类型')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('yongjin', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='佣金要求')),
|
||||
('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='游戏昵称')),
|
||||
('user1_id', models.CharField(db_index=True, max_length=30, null=True, verbose_name='用户1标识')),
|
||||
('user2_id', models.CharField(db_index=True, max_length=30, null=True, verbose_name='用户2打手标识')),
|
||||
('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': 'dingdan',
|
||||
'indexes': [models.Index(fields=['zhuangtai'], name='dingdan_zhuangt_2febe8_idx'), models.Index(fields=['dingdan_id'], name='dingdan_dingdan_83dcb6_idx'), models.Index(fields=['jiedan_dashou_id'], name='dingdan_jiedan__921bfa_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Liaotian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||
('user1_id', models.CharField(db_index=True, max_length=30, verbose_name='用户1标识')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'liaotian',
|
||||
'indexes': [models.Index(fields=['user1_id'], name='liaotian_user1_i_6be6cd_idx'), models.Index(fields=['user2_id'], name='liaotian_user2_i_9f61a4_idx'), models.Index(fields=['zhuangtai'], name='liaotian_zhuangt_5e8be5_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Pingfen',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '评分表',
|
||||
'db_table': 'pingfenbiao',
|
||||
'indexes': [models.Index(fields=['dashou'], name='pingfenbiao_dashou_f62f10_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Tuikuanjilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('dashouid', models.CharField(max_length=7, null=True, verbose_name='接单打手ID')),
|
||||
('qingqiuid', models.CharField(max_length=7, null=True, verbose_name='请求用户ID')),
|
||||
('chuliid', models.CharField(db_index=True, max_length=7, null=True, verbose_name='处理人ID')),
|
||||
('liyou', models.TextField(blank=True, null=True, verbose_name='理由')),
|
||||
('sqzhuangtai', models.IntegerField(blank=True, db_index=True, default=0, null=True, verbose_name='申请状态:0待处理,1成功,2驳回')),
|
||||
('bhliyou', models.TextField(blank=True, null=True, verbose_name='驳回理由')),
|
||||
('jine', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='订单金额')),
|
||||
('dashou_fencheng', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='打手分成')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'tuikuanjilu',
|
||||
'indexes': [models.Index(fields=['chuliid'], name='tuikuanjilu_chuliid_0b0f16_idx'), models.Index(fields=['sqzhuangtai'], name='tuikuanjilu_sqzhuan_d89dc9_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DingdanPingtai',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('laoban_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='老板ID')),
|
||||
('laoban_pingjia', models.TextField(blank=True, null=True, verbose_name='老板评价')),
|
||||
('dingdan', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='pingtai_kuozhan', to='orders.dingdan', verbose_name='订单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '平台订单扩展',
|
||||
'verbose_name_plural': '平台订单扩展',
|
||||
'db_table': 'dingdan_pingtai',
|
||||
'indexes': [models.Index(fields=['laoban_id'], name='dingdan_pin_laoban__d55e6f_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DingdanShangjia',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('shangjia_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='商家ID')),
|
||||
('shangjia_pingjia', models.TextField(blank=True, null=True, verbose_name='商家评价')),
|
||||
('cfliyou', models.TextField(blank=True, null=True, verbose_name='商家处罚理由')),
|
||||
('sqzhuangtai', models.IntegerField(blank=True, default=0, null=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')),
|
||||
('bhliyou', models.TextField(blank=True, null=True, verbose_name='驳回商家处罚理由')),
|
||||
('sjnicheng', models.CharField(max_length=50, null=True, verbose_name='商家昵称')),
|
||||
('dingdan', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='shangjia_kuozhan', to='orders.dingdan', verbose_name='订单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家订单扩展',
|
||||
'verbose_name_plural': '商家订单扩展',
|
||||
'db_table': 'dingdan_shangjia',
|
||||
'indexes': [models.Index(fields=['shangjia_id'], name='dingdan_sha_shangji_64d28b_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
# Generated by Django 4.2.27 on 2026-06-17 16:31
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Chufajilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dashouid', models.CharField(db_index=True, max_length=7, null=True, verbose_name='被罚打手ID')),
|
||||
('qingqiuid', models.CharField(db_index=True, max_length=11, null=True, verbose_name='请求处罚ID')),
|
||||
('chuliid', models.CharField(db_index=True, max_length=11, null=True, verbose_name='处理处罚ID')),
|
||||
('cfliyou', models.TextField(blank=True, null=True, verbose_name='处罚理由')),
|
||||
('ssliyou', models.TextField(blank=True, null=True, verbose_name='打手申诉理由')),
|
||||
('sqzhuangtai', models.IntegerField(blank=True, default=0, null=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'chufajilu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Chufatupian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'chufatupian',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Dashoutupian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'dashoutupian',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Dingdan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('zhuangtai', models.IntegerField(blank=True, db_index=True, default=1, null=True, verbose_name='订单状态')),
|
||||
('fadan_pingtai', models.IntegerField(blank=True, null=True, verbose_name='发单平台')),
|
||||
('jine', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='订单金额')),
|
||||
('dashou_fencheng', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='打手分成')),
|
||||
('guanshi_fencheng', models.DecimalField(blank=True, decimal_places=2, default=0, max_digits=10, null=True, verbose_name='管事分成')),
|
||||
('jiedan_dashou_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='接单打手ID')),
|
||||
('dashou_liuyan', models.TextField(blank=True, null=True, verbose_name='打手留言')),
|
||||
('zhiding_id', models.CharField(blank=True, max_length=32, null=True, verbose_name='指定ID')),
|
||||
('shangpin_id', models.IntegerField(blank=True, null=True, verbose_name='商品ID')),
|
||||
('leixing_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='商品类型ID')),
|
||||
('tupian', models.CharField(blank=True, max_length=500, null=True, verbose_name='商品图片URL')),
|
||||
('yaoqiuleixing', models.PositiveIntegerField(blank=True, null=True, verbose_name='抢单要求类型')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('yongjin', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='佣金要求')),
|
||||
('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='游戏昵称')),
|
||||
('user1_id', models.CharField(db_index=True, max_length=30, null=True, verbose_name='用户1标识')),
|
||||
('user2_id', models.CharField(db_index=True, max_length=30, null=True, verbose_name='用户2打手标识')),
|
||||
('auto_task_id', models.CharField(blank=True, default='', max_length=255, verbose_name='延时任务ID')),
|
||||
('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='更新时间')),
|
||||
('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='微信支付订单号')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '订单',
|
||||
'verbose_name_plural': '订单',
|
||||
'db_table': 'dingdan',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DingdanPeihu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('zhudashou_id', models.CharField(db_index=True, max_length=32, verbose_name='主打手ID')),
|
||||
('peihu1_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='陪护1打手ID')),
|
||||
('peihu2_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='陪护2打手ID')),
|
||||
('zhuangtai', models.IntegerField(default=1, verbose_name='陪护订单状态')),
|
||||
('peihu_xuqiu_shuliang', models.IntegerField(default=1, verbose_name='陪护需求数量')),
|
||||
('yongjin_yaoqiu', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='抢单佣金要求')),
|
||||
('peihu1_dengji_xuqiu', models.PositiveIntegerField(blank=True, null=True, verbose_name='陪护1等级需求(称号ID)')),
|
||||
('peihu2_dengji_xuqiu', models.PositiveIntegerField(blank=True, null=True, verbose_name='陪护2等级需求(称号ID)')),
|
||||
('peihu1_zhadan_danze', models.CharField(blank=True, max_length=10, null=True, verbose_name='陪护1炸单担责比例')),
|
||||
('peihu2_zhadan_danze', models.CharField(blank=True, max_length=10, null=True, verbose_name='陪护2炸单担责比例')),
|
||||
('peihu1_fenhong', models.CharField(blank=True, max_length=10, null=True, verbose_name='陪护1分红比例')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '陪护订单',
|
||||
'verbose_name_plural': '陪护订单',
|
||||
'db_table': 'dingdan_peihu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DingdanPingtai',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('laoban_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='老板ID')),
|
||||
('laoban_pingjia', models.TextField(blank=True, null=True, verbose_name='老板评价')),
|
||||
('jjjs_biaoshi', models.IntegerField(default=0, verbose_name='拒绝结算标记(1表示拒绝结算)')),
|
||||
('pingtai_shouyi', models.DecimalField(blank=True, decimal_places=2, default=0.0, max_digits=10, null=True, verbose_name='平台收益')),
|
||||
('dianpu_shouyi', models.DecimalField(blank=True, decimal_places=2, default=0.0, max_digits=10, null=True, verbose_name='店铺收益')),
|
||||
('dianpu_id', models.PositiveIntegerField(blank=True, db_index=True, null=True, verbose_name='所属店铺ID')),
|
||||
('shangji_dianpu_id', models.PositiveIntegerField(blank=True, db_index=True, null=True, verbose_name='该订单的上级店铺ID')),
|
||||
('shangji_fenhong', models.DecimalField(blank=True, decimal_places=2, default=0.0, max_digits=10, null=True, verbose_name='上级分红金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '平台订单扩展',
|
||||
'verbose_name_plural': '平台订单扩展',
|
||||
'db_table': 'dingdan_pingtai',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DingdanShangjia',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('shangjia_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='商家ID')),
|
||||
('shangjia_pingjia', models.TextField(blank=True, null=True, verbose_name='商家评价')),
|
||||
('cfliyou', models.TextField(blank=True, null=True, verbose_name='商家处罚理由')),
|
||||
('sqzhuangtai', models.IntegerField(blank=True, default=0, null=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')),
|
||||
('bhliyou', models.TextField(blank=True, null=True, verbose_name='驳回商家处罚理由')),
|
||||
('sjnicheng', models.CharField(max_length=50, null=True, verbose_name='商家昵称')),
|
||||
('shangyige_dingdan_id', models.CharField(blank=True, max_length=32, null=True, verbose_name='上一个订单ID')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商家订单扩展',
|
||||
'verbose_name_plural': '商家订单扩展',
|
||||
'db_table': 'dingdan_shangjia',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Fadan',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='自增主键')),
|
||||
('beichufa_id', models.CharField(db_index=True, max_length=20, verbose_name='被处罚用户ID')),
|
||||
('shenqing_chufa', models.CharField(blank=True, max_length=20, null=True, verbose_name='申请处罚者ID')),
|
||||
('shenfen', models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '商家'), (4, '组长')], default=1, verbose_name='被处罚者身份')),
|
||||
('chufaliyou', models.TextField(blank=True, null=True, verbose_name='处罚理由')),
|
||||
('fakuanjine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='罚款金额')),
|
||||
('guanliandingdan_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='关联订单ID')),
|
||||
('zhuangtai', models.IntegerField(choices=[(1, '待缴纳'), (2, '已缴纳'), (3, '申诉中'), (4, '已驳回')], db_index=True, default=1, verbose_name='罚单状态')),
|
||||
('yingxiang_qiangdan', models.IntegerField(choices=[(1, '影响抢单'), (0, '不影响抢单')], db_index=True, default=1, verbose_name='是否影响抢单')),
|
||||
('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='更新时间')),
|
||||
('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='处理者')),
|
||||
('shenqingren_fenhong_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='申请人分红金额')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚单',
|
||||
'verbose_name_plural': '罚单',
|
||||
'db_table': 'fadan',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FadanFenhongLilv',
|
||||
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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚款分红费率配置',
|
||||
'verbose_name_plural': '罚款分红费率配置',
|
||||
'db_table': 'fadan_fenhong_lilv',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Lilubiao',
|
||||
fields=[
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'lilubiao',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Ptliushui',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('zonge', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='收取总金额')),
|
||||
('zhichuzonge', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='支出总金额')),
|
||||
('zongshouyi', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='总收益')),
|
||||
('rizonge', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='日收取')),
|
||||
('rizhichu', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='日支出')),
|
||||
('rishouyi', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='日收益')),
|
||||
('zongshoucishu', models.IntegerField(default=0, verbose_name='总收取次数')),
|
||||
('rishoucishu', models.IntegerField(default=0, verbose_name='日收取次数')),
|
||||
('zongzhichucishu', models.IntegerField(default=0, verbose_name='总支出次数')),
|
||||
('rizhichucishu', models.IntegerField(default=0, verbose_name='日支出次数')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'ptliushui',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Tuikuanjilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('dashouid', models.CharField(max_length=7, null=True, verbose_name='接单打手ID')),
|
||||
('qingqiuid', models.CharField(max_length=7, null=True, verbose_name='请求用户ID')),
|
||||
('chuliid', models.CharField(db_index=True, max_length=11, null=True, verbose_name='处理人ID')),
|
||||
('liyou', models.TextField(blank=True, null=True, verbose_name='理由')),
|
||||
('sqzhuangtai', models.IntegerField(blank=True, db_index=True, default=0, null=True, verbose_name='申请状态:0待处理,1成功,2驳回')),
|
||||
('bhliyou', models.TextField(blank=True, null=True, verbose_name='驳回理由')),
|
||||
('jine', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='订单金额')),
|
||||
('dashou_fencheng', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='打手分成')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'tuikuanjilu',
|
||||
'indexes': [models.Index(fields=['chuliid'], name='tuikuanjilu_chuliid_0b0f16_idx'), models.Index(fields=['sqzhuangtai'], name='tuikuanjilu_sqzhuan_d89dc9_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Pingfen',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '评分表',
|
||||
'db_table': 'pingfenbiao',
|
||||
'indexes': [models.Index(fields=['dashou'], name='pingfenbiao_dashou_f62f10_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OrderDashouHistory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, verbose_name='订单ID')),
|
||||
('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='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '订单打手变更历史',
|
||||
'verbose_name_plural': '订单打手变更历史',
|
||||
'db_table': 'order_dashou_history',
|
||||
'indexes': [models.Index(fields=['dingdan_id'], name='order_dasho_dingdan_1e79ab_idx'), models.Index(fields=['dashou_id'], name='order_dasho_dashou__0a637c_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Liaotian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(primary_key=True, serialize=False, verbose_name='主键ID')),
|
||||
('user1_id', models.CharField(db_index=True, max_length=30, verbose_name='用户1标识')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'liaotian',
|
||||
'indexes': [models.Index(fields=['user1_id'], name='liaotian_user1_i_6be6cd_idx'), models.Index(fields=['user2_id'], name='liaotian_user2_i_9f61a4_idx'), models.Index(fields=['zhuangtai'], name='liaotian_zhuangt_5e8be5_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FadanShensuTupian',
|
||||
fields=[
|
||||
('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='创建时间')),
|
||||
('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='关联罚单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚款申诉图片',
|
||||
'verbose_name_plural': '罚款申诉图片',
|
||||
'db_table': 'fadan_shensu_tupian',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FadanFenhong',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='自增主键')),
|
||||
('fenhongzhe_id', models.CharField(db_index=True, max_length=20, verbose_name='分红者ID')),
|
||||
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='分红总额')),
|
||||
('ketixian_fenhong', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现分红')),
|
||||
('shenfen', models.IntegerField(choices=[(1, '商家'), (2, '客服'), (3, '平台管理者'), (4, '店铺'), (5, '售后')], default=1, verbose_name='分红者身份')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚款分红',
|
||||
'verbose_name_plural': '罚款分红',
|
||||
'db_table': 'fadan_fenhong',
|
||||
'indexes': [models.Index(fields=['fenhongzhe_id'], name='fadan_fenhong_zhe_idx'), models.Index(fields=['shenfen'], name='fadan_fenhong_sf_idx')],
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='fadan',
|
||||
index=models.Index(fields=['beichufa_id', 'yingxiang_qiangdan', 'zhuangtai'], name='fadan_qiangdan_check'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='fadan',
|
||||
index=models.Index(fields=['guanliandingdan_id'], name='fadan_dingdan_idx'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdanshangjia',
|
||||
name='dingdan',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='shangjia_kuozhan', to='orders.dingdan', verbose_name='订单'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='dingdan',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='pingtai_kuozhan', to='orders.dingdan', verbose_name='订单'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanpeihu',
|
||||
index=models.Index(fields=['zhudashou_id'], name='dingdan_pei_zhudash_583f4e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanpeihu',
|
||||
index=models.Index(fields=['peihu1_id'], name='dingdan_pei_peihu1__728279_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanpeihu',
|
||||
index=models.Index(fields=['peihu2_id'], name='dingdan_pei_peihu2__77e45e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanpeihu',
|
||||
index=models.Index(fields=['zhuangtai'], name='dingdan_pei_zhuangt_22eaf6_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdan',
|
||||
index=models.Index(fields=['zhuangtai'], name='dingdan_zhuangt_2febe8_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdan',
|
||||
index=models.Index(fields=['dingdan_id'], name='dingdan_dingdan_83dcb6_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdan',
|
||||
index=models.Index(fields=['jiedan_dashou_id'], name='dingdan_jiedan__921bfa_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdan',
|
||||
index=models.Index(fields=['wechat_transaction_id'], name='dingdan_wechat__278b79_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dashoutupian',
|
||||
index=models.Index(fields=['dashou'], name='dashoutupia_dashou_7de8bd_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dashoutupian',
|
||||
index=models.Index(fields=['dingdan_id'], name='dashoutupia_dingdan_97c685_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chufatupian',
|
||||
index=models.Index(fields=['yonghuid'], name='chufatupian_yonghui_71e585_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chufatupian',
|
||||
index=models.Index(fields=['dingdan_id'], name='chufatupian_dingdan_ce0dd4_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chufajilu',
|
||||
index=models.Index(fields=['dashouid'], name='chufajilu_dashoui_07aac0_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chufajilu',
|
||||
index=models.Index(fields=['qingqiuid'], name='chufajilu_qingqiu_ac160e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chufajilu',
|
||||
index=models.Index(fields=['chuliid'], name='chufajilu_chuliid_cd63ac_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chufajilu',
|
||||
index=models.Index(fields=['dingdan_id'], name='chufajilu_dingdan_b8f0c2_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='fadanshensutupian',
|
||||
index=models.Index(fields=['fadan_id'], name='fadan_shens_fadan_i_78fab9_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='fadanshensutupian',
|
||||
index=models.Index(fields=['beichufa_id'], name='fadan_shens_beichuf_59748e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanshangjia',
|
||||
index=models.Index(fields=['shangjia_id'], name='dingdan_sha_shangji_64d28b_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanpingtai',
|
||||
index=models.Index(fields=['laoban_id'], name='dingdan_pin_laoban__d55e6f_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanpingtai',
|
||||
index=models.Index(fields=['dianpu_id'], name='dingdan_pin_dianpu__9fbe27_idx'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-17 15:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='auto_expire_at',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='计划过期时间'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='auto_task_id',
|
||||
field=models.CharField(blank=True, default='', max_length=255, verbose_name='延时任务ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-17 16:26
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0002_dingdan_auto_expire_at_dingdan_auto_task_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='pending_dispatch',
|
||||
field=models.BooleanField(db_index=True, default=False, verbose_name='待调度标记'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='status_8_time',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='状态变为8的时间'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-17 23:57
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0003_dingdan_pending_dispatch_dingdan_status_8_time'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='tuikuanjilu',
|
||||
name='chuliid',
|
||||
field=models.CharField(db_index=True, max_length=11, null=True, verbose_name='处理人ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-20 19:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0004_alter_tuikuanjilu_chuliid'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='chufajilu',
|
||||
name='chuliid',
|
||||
field=models.CharField(db_index=True, max_length=11, null=True, verbose_name='处理处罚ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,28 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-07 19:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0005_alter_chufajilu_chuliid'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Chufatupian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'chufatupian',
|
||||
'indexes': [models.Index(fields=['yonghuid'], name='chufatupian_yonghui_71e585_idx'), models.Index(fields=['dingdan_id'], name='chufatupian_dingdan_ce0dd4_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-08 00:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0006_chufatupian'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='chufajilu',
|
||||
name='ssliyou',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='打手申诉理由'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-14 18:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0007_chufajilu_ssliyou'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='is_cross',
|
||||
field=models.IntegerField(default=0, verbose_name='是否跨平台订单(0否,1是)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='partner_order_id',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='对方平台订单ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-21 14:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0008_dingdan_is_cross_dingdan_partner_order_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='clkf',
|
||||
field=models.CharField(db_index=True, max_length=20, null=True, verbose_name='处理客服'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='jjjs_biaoshi',
|
||||
field=models.IntegerField(default=0, verbose_name='拒绝结算标记(1表示拒绝结算)'),
|
||||
),
|
||||
]
|
||||
@@ -1,22 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-21 16:33
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0009_dingdanpingtai_clkf_dingdanpingtai_jjjs_biaoshi'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='dingdanpingtai',
|
||||
name='clkf',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='clkf',
|
||||
field=models.CharField(db_index=True, max_length=20, null=True, verbose_name='处理客服'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-21 17:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0010_remove_dingdanpingtai_clkf_dingdan_clkf'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='tkly',
|
||||
field=models.CharField(blank=True, max_length=500, null=True, verbose_name='退款/拒绝理由'),
|
||||
),
|
||||
]
|
||||
@@ -1,22 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-22 12:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0011_dingdan_tkly'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='wechat_transaction_id',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=64, null=True, verbose_name='微信支付订单号'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdan',
|
||||
index=models.Index(fields=['wechat_transaction_id'], name='dingdan_wechat__278b79_idx'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-22 19:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0012_dingdan_wechat_transaction_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='chufajilu',
|
||||
name='qingqiuid',
|
||||
field=models.CharField(db_index=True, max_length=11, null=True, verbose_name='请求处罚ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-24 17:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0013_alter_chufajilu_qingqiuid'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='dispatch_type',
|
||||
field=models.IntegerField(choices=[(1, '我方派单'), (2, '对方派单')], default=0, verbose_name='派发情况'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='partner_club_id',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=6, null=True, verbose_name='对方俱乐部ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,73 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-01 09:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0014_dingdan_dispatch_type_dingdan_partner_club_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PreSettlement',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='我方订单ID')),
|
||||
('partner_order_id', models.CharField(db_index=True, max_length=32, verbose_name='对方订单ID')),
|
||||
('partner_club_id', models.CharField(db_index=True, max_length=6, verbose_name='对方俱乐部ID')),
|
||||
('dashou_id', models.CharField(db_index=True, max_length=7, verbose_name='接单打手ID')),
|
||||
('amount', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='打手应分金额')),
|
||||
('order_amount', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='订单原金额')),
|
||||
('status', models.SmallIntegerField(choices=[(0, '待结算'), (1, '已结算'), (2, '已拒绝')], default=0, verbose_name='结算状态')),
|
||||
('process_time', models.DateTimeField(blank=True, null=True, verbose_name='处理时间')),
|
||||
('operator', models.CharField(blank=True, default='', max_length=32, 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': 'pre_settlement',
|
||||
'indexes': [models.Index(fields=['dingdan_id'], name='pre_settlem_dingdan_4f3541_idx'), models.Index(fields=['partner_order_id'], name='pre_settlem_partner_45b29e_idx'), models.Index(fields=['partner_club_id'], name='pre_settlem_partner_d2c44c_idx'), models.Index(fields=['dashou_id'], name='pre_settlem_dashou__d5fe7c_idx'), models.Index(fields=['status'], name='pre_settlem_status_0aa711_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OrderDashouHistory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, verbose_name='订单ID')),
|
||||
('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='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '订单打手变更历史',
|
||||
'verbose_name_plural': '订单打手变更历史',
|
||||
'db_table': 'order_dashou_history',
|
||||
'indexes': [models.Index(fields=['dingdan_id'], name='order_dasho_dingdan_1e79ab_idx'), models.Index(fields=['dashou_id'], name='order_dasho_dashou__0a637c_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CrossPlatformOrderData',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='我方订单ID')),
|
||||
('partner_order_id', models.CharField(db_index=True, max_length=32, verbose_name='对方平台订单ID')),
|
||||
('partner_club_id', models.CharField(db_index=True, max_length=6, verbose_name='对方俱乐部ID')),
|
||||
('partner_order_status', models.IntegerField(default=0, verbose_name='对方平台订单状态')),
|
||||
('partner_dashou_id', models.CharField(blank=True, default='', max_length=32, verbose_name='对方平台接单打手ID')),
|
||||
('partner_amount', 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '跨平台订单扩展',
|
||||
'verbose_name_plural': '跨平台订单扩展',
|
||||
'db_table': 'cross_platform_order_data',
|
||||
'indexes': [models.Index(fields=['dingdan_id'], name='cross_platf_dingdan_498d08_idx'), models.Index(fields=['partner_order_id'], name='cross_platf_partner_5d5615_idx'), models.Index(fields=['partner_club_id'], name='cross_platf_partner_1054e1_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,22 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-04 15:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0015_presettlement_orderdashouhistory_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='presettlement',
|
||||
name='dingdan_id',
|
||||
field=models.CharField(db_index=True, max_length=32, verbose_name='我方订单ID'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='presettlement',
|
||||
unique_together={('dingdan_id', 'dashou_id')},
|
||||
),
|
||||
]
|
||||
@@ -1,32 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-23 14:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0016_alter_presettlement_dingdan_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='dianpu_id',
|
||||
field=models.PositiveIntegerField(blank=True, db_index=True, null=True, verbose_name='所属店铺ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='dianpu_shouyi',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, default=0.0, max_digits=10, null=True, verbose_name='店铺收益'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='pingtai_shouyi',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, default=0.0, max_digits=10, null=True, verbose_name='平台收益'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanpingtai',
|
||||
index=models.Index(fields=['dianpu_id'], name='dingdan_pin_dianpu__9fbe27_idx'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-30 02:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0017_dingdanpingtai_dianpu_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdanshangjia',
|
||||
name='partner_yonghu_id',
|
||||
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='对方平台用户ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-05 10:33
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0018_dingdanshangjia_partner_yonghu_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='shangji_dianpu_id',
|
||||
field=models.PositiveIntegerField(blank=True, db_index=True, null=True, verbose_name='该订单的上级店铺ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dingdanpingtai',
|
||||
name='shangji_fenhong',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, default=0.0, max_digits=10, null=True, verbose_name='上级分红金额'),
|
||||
),
|
||||
]
|
||||
@@ -1,58 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-06 11:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0019_dingdanpingtai_shangji_dianpu_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FadanFenhong',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='自增主键')),
|
||||
('fenhongzhe_id', models.CharField(db_index=True, max_length=20, verbose_name='分红者ID')),
|
||||
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='分红总额')),
|
||||
('ketixian_fenhong', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现分红')),
|
||||
('shenfen', models.IntegerField(choices=[(1, '商家'), (2, '客服'), (3, '平台管理者')], default=1, verbose_name='分红者身份')),
|
||||
('fenhong_cishu', models.IntegerField(default=0, 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚款分红',
|
||||
'verbose_name_plural': '罚款分红',
|
||||
'db_table': 'fadan_fenhong',
|
||||
'indexes': [models.Index(fields=['fenhongzhe_id'], name='fadan_fenhong_zhe_idx'), models.Index(fields=['shenfen'], name='fadan_fenhong_sf_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Fadan',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='自增主键')),
|
||||
('beichufa_id', models.CharField(db_index=True, max_length=20, verbose_name='被处罚用户ID')),
|
||||
('shenqing_chufa', models.CharField(blank=True, max_length=20, null=True, verbose_name='申请处罚者ID')),
|
||||
('shenfen', models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '商家'), (4, '组长')], default=1, verbose_name='被处罚者身份')),
|
||||
('chufaliyou', models.TextField(blank=True, null=True, verbose_name='处罚理由')),
|
||||
('fakuanjine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='罚款金额')),
|
||||
('guanliandingdan_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='关联订单ID')),
|
||||
('zhuangtai', models.IntegerField(choices=[(1, '待缴纳'), (2, '已缴纳'), (3, '申诉中'), (4, '已驳回')], db_index=True, default=1, verbose_name='罚单状态')),
|
||||
('yingxiang_qiangdan', models.IntegerField(choices=[(1, '影响抢单'), (0, '不影响抢单')], db_index=True, default=1, verbose_name='是否影响抢单')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚单',
|
||||
'verbose_name_plural': '罚单',
|
||||
'db_table': 'fadan',
|
||||
'indexes': [models.Index(fields=['beichufa_id', 'yingxiang_qiangdan', 'zhuangtai'], name='fadan_qiangdan_check'), models.Index(fields=['guanliandingdan_id'], name='fadan_dingdan_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,30 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-07 11:15
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0020_fadanfenhong_fadan'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FadanShensuTupian',
|
||||
fields=[
|
||||
('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='创建时间')),
|
||||
('fadan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shensu_tupians', to='orders.fadan', verbose_name='关联罚单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚款申诉图片',
|
||||
'verbose_name_plural': '罚款申诉图片',
|
||||
'db_table': 'fadan_shensu_tupian',
|
||||
'indexes': [models.Index(fields=['fadan_id'], name='fadan_shens_fadan_i_78fab9_idx'), models.Index(fields=['beichufa_id'], name='fadan_shens_beichuf_59748e_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-07 16:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0021_fadanshensutupian'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='fadan',
|
||||
name='partner_club_id',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=6, null=True, verbose_name='对方俱乐部ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='fadan',
|
||||
name='shenqingren_shenfen',
|
||||
field=models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员')], default=1, verbose_name='申请处罚人身份'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-07 17:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0022_fadan_partner_club_id_fadan_shenqingren_shenfen'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='fadanshensutupian',
|
||||
name='yongtu',
|
||||
field=models.IntegerField(choices=[(1, '处罚证据图片'), (2, '申诉图片')], default=2, verbose_name='图片用途'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-07 19:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0023_fadanshensutupian_yongtu'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='fadan',
|
||||
name='chulizhe',
|
||||
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='处理者'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='fadan',
|
||||
name='chulizhe_shenfen',
|
||||
field=models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员')], default=2, verbose_name='处理者身份'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-10 00:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0024_fadan_chulizhe_fadan_chulizhe_shenfen'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='fadan',
|
||||
name='shenqingren_shenfen',
|
||||
field=models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺')], default=1, verbose_name='申请处罚人身份'),
|
||||
),
|
||||
]
|
||||
@@ -1,37 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-10 17:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0025_alter_fadan_shenqingren_shenfen'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FadanFenhongLilv',
|
||||
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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '罚款分红费率配置',
|
||||
'verbose_name_plural': '罚款分红费率配置',
|
||||
'db_table': 'fadan_fenhong_lilv',
|
||||
},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='fadan',
|
||||
name='shenqingren_shenfen',
|
||||
field=models.IntegerField(choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')], default=1, verbose_name='申请处罚人身份'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='fadanfenhong',
|
||||
name='shenfen',
|
||||
field=models.IntegerField(choices=[(1, '商家'), (2, '客服'), (3, '平台管理者'), (4, '店铺'), (5, '售后')], default=1, verbose_name='分红者身份'),
|
||||
),
|
||||
]
|
||||
@@ -1,42 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-22 15:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0026_fadanfenhonglilv_alter_fadan_shenqingren_shenfen_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DingdanPeihu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('zhudashou_id', models.CharField(db_index=True, max_length=32, verbose_name='主打手ID')),
|
||||
('peihu1_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='陪护1打手ID')),
|
||||
('peihu2_id', models.CharField(blank=True, db_index=True, max_length=32, null=True, verbose_name='陪护2打手ID')),
|
||||
('zhuangtai', models.IntegerField(default=1, verbose_name='陪护订单状态')),
|
||||
('peihu_xuqiu_shuliang', models.IntegerField(default=1, verbose_name='陪护需求数量')),
|
||||
('yongjin_yaoqiu', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='抢单佣金要求')),
|
||||
('peihu1_dengji_xuqiu', models.PositiveIntegerField(blank=True, null=True, verbose_name='陪护1等级需求(称号ID)')),
|
||||
('peihu2_dengji_xuqiu', models.PositiveIntegerField(blank=True, null=True, verbose_name='陪护2等级需求(称号ID)')),
|
||||
('peihu1_zhadan_danze', models.CharField(blank=True, max_length=10, null=True, verbose_name='陪护1炸单担责比例')),
|
||||
('peihu2_zhadan_danze', models.CharField(blank=True, max_length=10, null=True, verbose_name='陪护2炸单担责比例')),
|
||||
('peihu1_fenhong', models.CharField(blank=True, max_length=10, null=True, verbose_name='陪护1分红比例')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '陪护订单',
|
||||
'verbose_name_plural': '陪护订单',
|
||||
'db_table': 'dingdan_peihu',
|
||||
'indexes': [models.Index(fields=['zhudashou_id'], name='dingdan_pei_zhudash_583f4e_idx'), models.Index(fields=['peihu1_id'], name='dingdan_pei_peihu1__728279_idx'), models.Index(fields=['peihu2_id'], name='dingdan_pei_peihu2__77e45e_idx'), models.Index(fields=['zhuangtai'], name='dingdan_pei_zhuangt_22eaf6_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-29 17:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0027_dingdanpeihu'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdanshangjia',
|
||||
name='shangyige_dingdan_id',
|
||||
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='上一个订单ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-31 22:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0028_dingdanshangjia_shangyige_dingdan_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='fadanfenhong',
|
||||
name='is_individual_rate',
|
||||
field=models.BooleanField(default=False, verbose_name='是否单独开启分红利率'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-01 00:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0029_fadanfenhong_is_individual_rate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='fadan',
|
||||
name='shenqingren_fenhong_jine',
|
||||
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='申请人分红金额'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-12 01:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0030_fadan_shenqingren_fenhong_jine'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dingdan',
|
||||
name='guanshi_fencheng',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, default=0, max_digits=10, null=True, verbose_name='管事分成'),
|
||||
),
|
||||
]
|
||||
@@ -1,43 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-15 01:42
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0031_dingdan_guanshi_fencheng'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='CrossPlatformOrderData',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='PreSettlement',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dingdan',
|
||||
name='dispatch_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dingdan',
|
||||
name='is_cross',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dingdan',
|
||||
name='partner_club_id',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dingdan',
|
||||
name='partner_order_id',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dingdanshangjia',
|
||||
name='partner_yonghu_id',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='fadan',
|
||||
name='partner_club_id',
|
||||
),
|
||||
]
|
||||
+4
-3
@@ -15,7 +15,8 @@ import logging
|
||||
|
||||
# 导入模型 - 确保路径正确
|
||||
from orders.models import Dingdan
|
||||
from users.models import UserMain, UserDashou, UserShangjia
|
||||
from users.models import UserDashou, UserShangjia
|
||||
from gvsdsdk.models import User
|
||||
from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure
|
||||
from gvsdsdk.fluent import db, func, FQ
|
||||
|
||||
@@ -64,7 +65,7 @@ def process_expired_order(self, dingdan_id):
|
||||
if dashou_id:
|
||||
try:
|
||||
# 查询打手用户主表
|
||||
dashou_user = UserMain.query.filter(yonghuid=dashou_id).first()
|
||||
dashou_user = User.query.filter(yonghuid=dashou_id).first()
|
||||
if dashou_user:
|
||||
# 获取打手扩展表
|
||||
dashou_profile = getattr(dashou_user, 'dashou_profile', None)
|
||||
@@ -93,7 +94,7 @@ def process_expired_order(self, dingdan_id):
|
||||
shangjia_id = shangjia_kuozhan.shangjia_id
|
||||
if shangjia_id:
|
||||
# 查询商家用户
|
||||
shangjia_user = UserMain.query.filter(yonghuid=shangjia_id).first()
|
||||
shangjia_user = User.query.filter(yonghuid=shangjia_id).first()
|
||||
if shangjia_user:
|
||||
shangjia_profile = getattr(shangjia_user, 'shop_profile', None)
|
||||
if shangjia_profile:
|
||||
|
||||
+47
-46
@@ -62,7 +62,8 @@ from orders.models import (
|
||||
Lilubiao, Pingfen, Tuikuanjilu
|
||||
)
|
||||
from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai
|
||||
from users.models import UserMain, UserDashou, UserShangjia, UserBoss
|
||||
from users.models import UserDashou, UserShangjia, UserBoss
|
||||
from gvsdsdk.models import User
|
||||
from rank.models import DashouBiaoxian, Chenghao, DingdanBiaoqian, YonghuChenghao
|
||||
from config.models import (
|
||||
Szjilu, ShangjiaLianjie
|
||||
@@ -240,7 +241,7 @@ class WechatPayNotifyView(APIView):
|
||||
if hasattr(dingdan, 'pingtai_kuozhan'):
|
||||
laoban_id = dingdan.pingtai_kuozhan.laoban_id
|
||||
if laoban_id:
|
||||
user_main = UserMain.query.filter(yonghuid=laoban_id).first()
|
||||
user_main = User.query.filter(yonghuid=laoban_id).first()
|
||||
if user_main and hasattr(user_main, 'boss_profile'):
|
||||
boss = user_main.boss_profile
|
||||
boss.zonge = (boss.zonge or 0) + (dingdan.jine or 0)
|
||||
@@ -524,7 +525,7 @@ class PaymentVerifyView(APIView):
|
||||
# 更新老板扩展表
|
||||
laoban_id = dingdan.pingtai_kuozhan.laoban_id if hasattr(dingdan, 'pingtai_kuozhan') else None
|
||||
if laoban_id:
|
||||
user_main = UserMain.query.filter(yonghuid=laoban_id).first()
|
||||
user_main = User.query.filter(yonghuid=laoban_id).first()
|
||||
if user_main and hasattr(user_main, 'boss_profile'):
|
||||
boss = user_main.boss_profile
|
||||
boss.zonge = (boss.zonge or 0) + (dingdan.jine or 0)
|
||||
@@ -710,7 +711,7 @@ class CreateOrderView(APIView):
|
||||
zhiding_id_value = None
|
||||
if zhiding:
|
||||
# 查询主表中是否存在该打手
|
||||
zhiding_user = UserMain.query.filter(
|
||||
zhiding_user = User.query.filter(
|
||||
yonghuid=zhiding,
|
||||
#user_type='dashou'
|
||||
).first()
|
||||
@@ -1348,7 +1349,7 @@ class JiedanView(APIView):
|
||||
# 7. 更新打手扩展表(如果有打手ID和分成)
|
||||
if jiedan_dashou_id and dashou_fencheng > 0:
|
||||
# 查询打手用户
|
||||
dashou_user = UserMain.query.filter(yonghuid=jiedan_dashou_id).first()
|
||||
dashou_user = User.query.filter(yonghuid=jiedan_dashou_id).first()
|
||||
|
||||
if dashou_user:
|
||||
# 查询打手扩展表
|
||||
@@ -1511,7 +1512,7 @@ class DingdanXiangqingView2(APIView):
|
||||
jiedan_time = ''
|
||||
tijiao_time = ''
|
||||
if jiedan_dashou_id:
|
||||
dashou_user = UserMain.query.filter(yonghuid=jiedan_dashou_id).first()
|
||||
dashou_user = User.query.filter(yonghuid=jiedan_dashou_id).first()
|
||||
if dashou_user:
|
||||
dashou_touxiang = dashou_user.avatar or ''
|
||||
try:
|
||||
@@ -1660,7 +1661,7 @@ class JiedanView2(APIView):
|
||||
|
||||
# 9. 更新打手收益与状态
|
||||
if jiedan_dashou_id and dashou_fencheng > 0:
|
||||
dashou_user = UserMain.query.filter(yonghuid=jiedan_dashou_id).first()
|
||||
dashou_user = User.query.filter(yonghuid=jiedan_dashou_id).first()
|
||||
if dashou_user:
|
||||
try:
|
||||
dashou_ext = dashou_user.dashou_profile
|
||||
@@ -1915,11 +1916,11 @@ class ShangjiaPaifaView(APIView):
|
||||
zhiding_dashou = None
|
||||
if zhiding_uid:
|
||||
try:
|
||||
zhiding_user = UserMain.query.get(yonghuid=zhiding_uid)
|
||||
zhiding_user = User.query.get(yonghuid=zhiding_uid)
|
||||
zhiding_dashou = zhiding_user.dashou_profile
|
||||
if zhiding_dashou.zhanghaozhuangtai != 1:
|
||||
return Response({'code': 400, 'msg': '指定打手状态异常'})
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({'code': 400, 'msg': '指定用户不存在'})
|
||||
except UserDashou.DoesNotExist:
|
||||
return Response({'code': 400, 'msg': '指定用户不是打手'})
|
||||
@@ -2221,7 +2222,7 @@ class ShangjiaDingdanXiangqingView(APIView):
|
||||
dashou_nicheng = ''
|
||||
dashou_avatar = ''
|
||||
if dashou_yonghuid:
|
||||
dashou_user = UserMain.query.filter(
|
||||
dashou_user = User.query.filter(
|
||||
yonghuid=dashou_yonghuid
|
||||
).select_related('dashou_profile').first()
|
||||
if dashou_user:
|
||||
@@ -2425,9 +2426,9 @@ class ShangjiaJiesuanView(APIView):
|
||||
# ========== 本地订单正常结算给打手 ==========
|
||||
# 查询打手信息
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou = dashou_user.dashou_profile
|
||||
except (UserMain.DoesNotExist, UserDashou.DoesNotExist):
|
||||
except (User.DoesNotExist, UserDashou.DoesNotExist):
|
||||
return Response({
|
||||
'code': 8,
|
||||
'msg': '接单打手不存在或信息不完整',
|
||||
@@ -2767,7 +2768,7 @@ class ShangjiaTuikuanShenqingView(APIView):
|
||||
# ====== 原有功能:更新打手状态 ======
|
||||
if dingdan.jiedan_dashou_id:
|
||||
try:
|
||||
dashou_main = UserMain.query.filter(
|
||||
dashou_main = User.query.filter(
|
||||
yonghuid=dingdan.jiedan_dashou_id
|
||||
).first()
|
||||
if dashou_main and hasattr(dashou_main, 'dashou_profile'):
|
||||
@@ -2850,9 +2851,9 @@ class ShangjiaChufaShenqingView(APIView):
|
||||
with transaction.atomic():
|
||||
# 验证打手身份
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=dashou_id)
|
||||
dashou = dashou_user.dashou_profile
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response({
|
||||
'code': 5,
|
||||
'msg': '打手用户不存在',
|
||||
@@ -3028,7 +3029,7 @@ class DashouDingdanHuoquView(APIView):
|
||||
zhiding_ids = {item['zhiding_id'] for item in dingdan_list if item.get('zhiding_id')}
|
||||
zhiding_info = {}
|
||||
if zhiding_ids:
|
||||
dashou_query = UserMain.query.filter(
|
||||
dashou_query = User.query.filter(
|
||||
yonghuid__in=zhiding_ids
|
||||
).select_related('dashou_profile').annotate(
|
||||
nicheng=F('dashou_profile__nicheng')
|
||||
@@ -3078,10 +3079,10 @@ class DashouDingdanHuoquView(APIView):
|
||||
if sj['shangjia_id']:
|
||||
yonghuid_set.add(sj['shangjia_id'])
|
||||
|
||||
# 将 yonghuid 字符串转换为 UserMain 的主键 id
|
||||
# 将 yonghuid 字符串转换为 User 的主键 id
|
||||
user_id_map = {}
|
||||
if yonghuid_set:
|
||||
users = UserMain.query.filter(yonghuid__in=yonghuid_set).values('id', 'yonghuid')
|
||||
users = User.query.filter(yonghuid__in=yonghuid_set).values('id', 'yonghuid')
|
||||
for u in users:
|
||||
user_id_map[u['yonghuid']] = u['id']
|
||||
|
||||
@@ -3346,8 +3347,8 @@ def send_group_message(
|
||||
def check_user_permission(identity_type, uid, order):
|
||||
"""验证用户身份、账号状态、以及是否属于该订单"""
|
||||
try:
|
||||
user = UserMain.query.get(yonghuid=uid)
|
||||
except UserMain.DoesNotExist:
|
||||
user = User.query.get(yonghuid=uid)
|
||||
except User.DoesNotExist:
|
||||
return False, '用户不存在'
|
||||
|
||||
if identity_type == 'dashou':
|
||||
@@ -4672,11 +4673,11 @@ class AdGengHuanDaShou(APIView):
|
||||
|
||||
# 8. 验证新打手ID是否存在,并且是打手身份
|
||||
try:
|
||||
new_dashou_user = UserMain.query.get(
|
||||
new_dashou_user = User.query.get(
|
||||
yonghuid=new_dashou_id,
|
||||
#user_type='dashou'
|
||||
)
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
return Response(
|
||||
{'code': 404, 'message': '打手不存在或不是打手身份', 'data': None},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
@@ -4767,7 +4768,7 @@ class AdGengHuanDaShou(APIView):
|
||||
if old_dashou_id:
|
||||
try:
|
||||
# 查询原打手主表
|
||||
old_dashou_user = UserMain.query.get(
|
||||
old_dashou_user = User.query.get(
|
||||
yonghuid=old_dashou_id,
|
||||
#user_type='dashou'
|
||||
)
|
||||
@@ -4781,7 +4782,7 @@ class AdGengHuanDaShou(APIView):
|
||||
old_dashou_profile.save()
|
||||
|
||||
logger.info(f"成功更新原打手{old_dashou_id}状态")
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
# 原打手不存在,继续执行不影响更换
|
||||
logger.warning(f"原打手{old_dashou_id}不存在,跳过更新")
|
||||
except AttributeError:
|
||||
@@ -4911,7 +4912,7 @@ class AdQiangZhiJieDan(APIView):
|
||||
if jiedan_dashou_id:
|
||||
try:
|
||||
# 查询打手用户主表
|
||||
dashou_user = UserMain.query.get(
|
||||
dashou_user = User.query.get(
|
||||
yonghuid=jiedan_dashou_id,
|
||||
#user_type='dashou'
|
||||
)
|
||||
@@ -4938,7 +4939,7 @@ class AdQiangZhiJieDan(APIView):
|
||||
dashou_profile.save()
|
||||
logger.info(f"强制结单成功,打手{jiedan_dashou_id}结算分成:{dashou_fencheng}")
|
||||
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
# 打手用户不存在,记录日志但不影响强制结单
|
||||
logger.warning(f"强制结单:打手{jiedan_dashou_id}不存在,跳过打手结算")
|
||||
except AttributeError:
|
||||
@@ -4954,7 +4955,7 @@ class AdQiangZhiJieDan(APIView):
|
||||
|
||||
if shangjia_id:
|
||||
# 查询商家用户主表
|
||||
shangjia_user = UserMain.query.get(
|
||||
shangjia_user = User.query.get(
|
||||
yonghuid=shangjia_id,
|
||||
#user_type='shop'
|
||||
)
|
||||
@@ -4971,7 +4972,7 @@ class AdQiangZhiJieDan(APIView):
|
||||
except DingdanShangjia.DoesNotExist:
|
||||
# 商家订单扩展表不存在,跳过商家更新
|
||||
logger.warning(f"强制结单:订单{dingdan_id}商家扩展表不存在,跳过商家更新")
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
# 商家用户不存在,跳过商家更新
|
||||
logger.warning(f"强制结单:商家{shangjia_id}不存在,跳过商家更新")
|
||||
except AttributeError:
|
||||
@@ -5087,7 +5088,7 @@ class AdJuJueTuiKuan(APIView):
|
||||
if jiedan_dashou_id:
|
||||
try:
|
||||
# 查询打手用户主表
|
||||
dashou_user = UserMain.query.get(
|
||||
dashou_user = User.query.get(
|
||||
yonghuid=jiedan_dashou_id,
|
||||
#user_type='dashou'
|
||||
)
|
||||
@@ -5114,7 +5115,7 @@ class AdJuJueTuiKuan(APIView):
|
||||
dashou_profile.save()
|
||||
logger.info(f"拒绝退款成功,打手{jiedan_dashou_id}结算分成:{dashou_fencheng}")
|
||||
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
# 打手用户不存在,记录日志但不影响操作
|
||||
logger.warning(f"拒绝退款:打手{jiedan_dashou_id}不存在,跳过打手结算")
|
||||
except AttributeError:
|
||||
@@ -5130,7 +5131,7 @@ class AdJuJueTuiKuan(APIView):
|
||||
|
||||
if shangjia_id:
|
||||
# 查询商家用户主表
|
||||
shangjia_user = UserMain.query.get(
|
||||
shangjia_user = User.query.get(
|
||||
yonghuid=shangjia_id,
|
||||
#user_type='shop'
|
||||
)
|
||||
@@ -5147,7 +5148,7 @@ class AdJuJueTuiKuan(APIView):
|
||||
except DingdanShangjia.DoesNotExist:
|
||||
# 商家订单扩展表不存在,跳过商家更新
|
||||
logger.warning(f"拒绝退款:订单{dingdan_id}商家扩展表不存在,跳过商家更新")
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
# 商家用户不存在,跳过商家更新
|
||||
logger.warning(f"拒绝退款:商家{shangjia_id}不存在,跳过商家更新")
|
||||
except AttributeError:
|
||||
@@ -5318,7 +5319,7 @@ class AdTongYiTuiKuanShangJia(APIView):
|
||||
if jiedan_dashou_id:
|
||||
try:
|
||||
# 查询打手用户主表
|
||||
dashou_user = UserMain.query.get(
|
||||
dashou_user = User.query.get(
|
||||
yonghuid=jiedan_dashou_id,
|
||||
#user_type='dashou'
|
||||
)
|
||||
@@ -5332,7 +5333,7 @@ class AdTongYiTuiKuanShangJia(APIView):
|
||||
dashou_profile.save()
|
||||
logger.info(f"同意退款成功,打手{jiedan_dashou_id}退款订单+1")
|
||||
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
# 打手用户不存在,记录日志但不影响操作
|
||||
logger.warning(f"同意退款:打手{jiedan_dashou_id}不存在,跳过打手更新")
|
||||
except AttributeError:
|
||||
@@ -5343,7 +5344,7 @@ class AdTongYiTuiKuanShangJia(APIView):
|
||||
if shangjia_id:
|
||||
try:
|
||||
# 查询商家用户主表
|
||||
shangjia_user = UserMain.query.get(
|
||||
shangjia_user = User.query.get(
|
||||
yonghuid=shangjia_id,
|
||||
#user_type='shop'
|
||||
)
|
||||
@@ -5360,7 +5361,7 @@ class AdTongYiTuiKuanShangJia(APIView):
|
||||
shangjia_profile.save()
|
||||
logger.info(f"同意退款成功,商家{shangjia_id}退款订单+1,余额增加:{jine}")
|
||||
|
||||
except UserMain.DoesNotExist:
|
||||
except User.DoesNotExist:
|
||||
# 商家用户不存在,记录日志但不影响操作
|
||||
logger.warning(f"同意退款:商家{shangjia_id}不存在,跳过商家更新")
|
||||
except AttributeError:
|
||||
@@ -5528,25 +5529,25 @@ class AdTongYiTuiKuanPingTai(APIView):
|
||||
# 14. 更新打手扩展表
|
||||
if jiedan_dashou_id:
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou_profile = dashou_user.dashou_profile
|
||||
dashou_profile.zhuangtai = 1 # 打手状态设为空闲
|
||||
dashou_profile.tuikuanliang += 1
|
||||
dashou_profile.save()
|
||||
except (UserMain.DoesNotExist, AttributeError):
|
||||
except (User.DoesNotExist, AttributeError):
|
||||
logger.warning(f"平台退款:打手{jiedan_dashou_id}不存在或扩展信息缺失,跳过")
|
||||
|
||||
# 15. 更新老板扩展表
|
||||
if laoban_id:
|
||||
try:
|
||||
laoban_user = UserMain.query.get(yonghuid=laoban_id)
|
||||
laoban_user = User.query.get(yonghuid=laoban_id)
|
||||
laoban_profile = laoban_user.boss_profile
|
||||
laoban_profile.alltui += 1
|
||||
laoban_profile.zonge -= jine
|
||||
if laoban_profile.zonge < 0:
|
||||
laoban_profile.zonge = 0
|
||||
laoban_profile.save()
|
||||
except (UserMain.DoesNotExist, AttributeError):
|
||||
except (User.DoesNotExist, AttributeError):
|
||||
logger.warning(f"平台退款:老板{laoban_id}不存在或扩展信息缺失,跳过")
|
||||
|
||||
# 16. 更新收支记录表(id=1)
|
||||
@@ -5864,12 +5865,12 @@ class AdJuJueJieSuan(APIView):
|
||||
|
||||
# 8. 更新打手扩展表
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou_profile = dashou_user.dashou_profile
|
||||
dashou_profile.zhuangtai = 1 # 打手状态设为正常
|
||||
dashou_profile.tuikuanliang += 1 # 退款订单总量+1
|
||||
dashou_profile.save()
|
||||
except (UserMain.DoesNotExist, AttributeError) as e:
|
||||
except (User.DoesNotExist, AttributeError) as e:
|
||||
logger.warning(f"拒绝结算:打手{jiedan_dashou_id}信息更新失败 - {str(e)}")
|
||||
|
||||
return Response({'code': 0, 'message': '拒绝结算成功', 'data': None})
|
||||
@@ -5946,12 +5947,12 @@ class AdZhuanYiDaTing(APIView):
|
||||
# 如果有接单打手,更新其扩展表
|
||||
if jiedan_dashou_id:
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=jiedan_dashou_id)
|
||||
dashou_profile = dashou_user.dashou_profile
|
||||
dashou_profile.zhuangtai = 1
|
||||
dashou_profile.tuikuanliang += 1
|
||||
dashou_profile.save()
|
||||
except (UserMain.DoesNotExist, AttributeError) as e:
|
||||
except (User.DoesNotExist, AttributeError) as e:
|
||||
logger.warning(f"转移大厅:打手{jiedan_dashou_id}信息更新失败 - {str(e)}")
|
||||
|
||||
return Response({'code': 0, 'message': '转移大厅成功', 'data': None})
|
||||
@@ -6224,12 +6225,12 @@ class ZxsjghdsView(APIView):
|
||||
# 6.2 释放打手
|
||||
if dashou_id:
|
||||
try:
|
||||
dashou_user = UserMain.query.get(yonghuid=dashou_id)
|
||||
dashou_user = User.query.get(yonghuid=dashou_id)
|
||||
dashou_profile = dashou_user.dashou_profile
|
||||
dashou_profile.tuikuanliang = (dashou_profile.tuikuanliang or 0) + 1
|
||||
dashou_profile.zhuangtai = 1 # 空闲
|
||||
dashou_profile.save(update_fields=['tuikuanliang', 'zhuangtai'])
|
||||
except (UserMain.DoesNotExist, ObjectDoesNotExist):
|
||||
except (User.DoesNotExist, ObjectDoesNotExist):
|
||||
logger.warning(f"打手 {dashou_id} 不存在或扩展表缺失,跳过更新")
|
||||
|
||||
# 6.3 更新退款记录
|
||||
|
||||
+208
-149
@@ -1,149 +1,208 @@
|
||||
# Generated by Django 5.2.10 on 2026-01-14 19:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Huiyuan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('huiyuan_id', models.CharField(max_length=6, unique=True, verbose_name='会员ID')),
|
||||
('jieshao', models.CharField(max_length=30, verbose_name='会员介绍')),
|
||||
('jtjieshao', models.TextField(blank=True, null=True, verbose_name='会员规则介绍')),
|
||||
('jiage', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='会员价格')),
|
||||
('guanshifc', 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '会员',
|
||||
'verbose_name_plural': '会员',
|
||||
'db_table': 'huiyuan',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Huiyuangoumai',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='购买记录ID')),
|
||||
('huiyuan_id', models.CharField(db_index=True, max_length=6, verbose_name='会员ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=32, 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户购买会员',
|
||||
'verbose_name_plural': '用户购买会员',
|
||||
'db_table': 'huiyuangoumai',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Shangpin',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='商品ID')),
|
||||
('biaoqian', models.CharField(blank=True, max_length=45, null=True, verbose_name='商品标题')),
|
||||
('jiage', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='商品价格')),
|
||||
('kucun', models.PositiveIntegerField(default=0, verbose_name='商品库存')),
|
||||
('leixing_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='商品类型ID')),
|
||||
('zhuanqu_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='商品专区ID')),
|
||||
('zhenshi_xiaoliang', models.PositiveIntegerField(default=0, verbose_name='商品真实销量')),
|
||||
('duiwai_xiaoliang', models.PositiveIntegerField(default=0, verbose_name='商品对外销量')),
|
||||
('jieshao', models.TextField(blank=True, null=True, verbose_name='商品介绍')),
|
||||
('xiadan_xuzhi', models.TextField(blank=True, null=True, verbose_name='下单须知')),
|
||||
('guize_tupian', models.CharField(blank=True, max_length=500, null=True, verbose_name='规则图片URL')),
|
||||
('yaoqiuleixing', models.PositiveIntegerField(blank=True, null=True, verbose_name='抢单要求类型')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('yongjin', 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='更改时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品',
|
||||
'verbose_name_plural': '商品',
|
||||
'db_table': 'shangpin',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangpinLeixing',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='类型ID')),
|
||||
('yaoqiuleixing', models.PositiveIntegerField(blank=True, null=True, verbose_name='抢单要求类型')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('yongjin', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='佣金要求')),
|
||||
('jieshao', models.CharField(blank=True, max_length=45, null=True, verbose_name='类型介绍')),
|
||||
('tupian_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='类型图片URL')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品类型',
|
||||
'verbose_name_plural': '商品类型',
|
||||
'db_table': 'shangpin_leixing',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangpinZhuanqu',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='专区ID')),
|
||||
('mingzi', models.CharField(blank=True, max_length=45, null=True, verbose_name='专区名称')),
|
||||
('leixing_id', models.PositiveIntegerField(verbose_name='类型ID')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品专区',
|
||||
'verbose_name_plural': '商品专区',
|
||||
'db_table': 'shangpin_zhuanqu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Czjilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('zhuangtai', models.IntegerField(blank=True, null=True, verbose_name='订单状态')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '充值记录订单',
|
||||
'verbose_name_plural': '充值记录订单',
|
||||
'db_table': 'czjilu',
|
||||
'indexes': [models.Index(fields=['dingdan_id'], name='czjilu_dingdan_39bbd0_idx'), models.Index(fields=['yonghuid'], name='czjilu_yonghui_a0555f_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Gsfenhong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('guanshi', models.CharField(db_index=True, max_length=7, verbose_name='管事ID')),
|
||||
('dashouid', models.CharField(db_index=True, max_length=7, unique=True, verbose_name='打手ID')),
|
||||
('shuoming', models.CharField(blank=True, max_length=100, null=True, verbose_name='订单说明')),
|
||||
('fenhong', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='订单分红金额')),
|
||||
('avatar', models.CharField(blank=True, max_length=500, null=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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '管事分红记录',
|
||||
'verbose_name_plural': '管事分红记录',
|
||||
'db_table': 'gsfenhong',
|
||||
'indexes': [models.Index(fields=['guanshi'], name='gsfenhong_guanshi_dc440f_idx'), models.Index(fields=['dashouid'], name='gsfenhong_dashoui_5473ca_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
# Generated by Django 4.2.27 on 2026-06-17 16:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Czjilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('zhuangtai', models.IntegerField(blank=True, null=True, verbose_name='订单状态')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '充值记录订单',
|
||||
'verbose_name_plural': '充值记录订单',
|
||||
'db_table': 'czjilu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DuociFenhong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('huiyuan', models.CharField(max_length=10, verbose_name='会员ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, verbose_name='管事ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '多次分红配置',
|
||||
'verbose_name_plural': '多次分红配置',
|
||||
'db_table': 'duoci_fenhong',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Gsfenhong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('guanshi', models.CharField(db_index=True, max_length=7, verbose_name='管事ID')),
|
||||
('dashouid', models.CharField(db_index=True, max_length=7, verbose_name='打手ID')),
|
||||
('shuoming', models.CharField(blank=True, max_length=100, null=True, verbose_name='订单说明')),
|
||||
('fenhong', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='订单分红金额')),
|
||||
('avatar', models.CharField(blank=True, max_length=500, null=True, verbose_name='打手头像')),
|
||||
('nicheng', models.CharField(max_length=50, null=True, verbose_name='打手昵称')),
|
||||
('zuzhang_id', models.CharField(blank=True, db_index=True, max_length=7, null=True, verbose_name='组长ID')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '管事分红记录',
|
||||
'verbose_name_plural': '管事分红记录',
|
||||
'db_table': 'gsfenhong',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Huiyuan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('huiyuan_id', models.CharField(max_length=6, unique=True, verbose_name='会员ID')),
|
||||
('jieshao', models.CharField(max_length=30, verbose_name='会员介绍')),
|
||||
('jtjieshao', models.TextField(blank=True, null=True, verbose_name='会员规则介绍')),
|
||||
('jiage', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='会员价格')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '会员',
|
||||
'verbose_name_plural': '会员',
|
||||
'db_table': 'huiyuan',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Huiyuangoumai',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='购买记录ID')),
|
||||
('huiyuan_id', models.CharField(db_index=True, max_length=6, verbose_name='会员ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=32, 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户购买会员',
|
||||
'verbose_name_plural': '用户购买会员',
|
||||
'db_table': 'huiyuangoumai',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Shangpin',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='商品ID')),
|
||||
('biaoqian', models.CharField(blank=True, max_length=45, null=True, verbose_name='商品标题')),
|
||||
('jiage', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='商品价格')),
|
||||
('kucun', models.PositiveIntegerField(default=0, verbose_name='商品库存')),
|
||||
('leixing_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='商品类型ID')),
|
||||
('zhuanqu_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='商品专区ID')),
|
||||
('zhenshi_xiaoliang', models.PositiveIntegerField(default=0, verbose_name='商品真实销量')),
|
||||
('duiwai_xiaoliang', models.PositiveIntegerField(default=0, verbose_name='商品对外销量')),
|
||||
('jieshao', models.TextField(blank=True, null=True, verbose_name='商品介绍')),
|
||||
('xiadan_xuzhi', models.TextField(blank=True, null=True, verbose_name='下单须知')),
|
||||
('guize_tupian', models.CharField(blank=True, max_length=500, null=True, verbose_name='规则图片URL')),
|
||||
('yaoqiuleixing', models.PositiveIntegerField(blank=True, null=True, verbose_name='抢单要求类型')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('yongjin', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='佣金要求')),
|
||||
('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='更改时间')),
|
||||
('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='是否上架')),
|
||||
('fengjin_zhuangtai', models.BooleanField(default=True, verbose_name='是否封禁')),
|
||||
('shenhe_zhuangtai', models.BooleanField(default=False, help_text='True=审核通过,False=未审核', verbose_name='平台审核状态')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品',
|
||||
'verbose_name_plural': '商品',
|
||||
'db_table': 'shangpin',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangpinLeixing',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='类型ID')),
|
||||
('yaoqiuleixing', models.PositiveIntegerField(blank=True, null=True, verbose_name='抢单要求类型')),
|
||||
('huiyuan_id', models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID')),
|
||||
('yongjin', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='佣金要求')),
|
||||
('jieshao', models.CharField(blank=True, max_length=45, null=True, verbose_name='类型介绍')),
|
||||
('tupian_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='类型图片URL')),
|
||||
('paixu', models.IntegerField(default=0, verbose_name='排序权重')),
|
||||
('shenhezhuangtai', models.IntegerField(default=1, help_text='1=正常, 2=审核专用', verbose_name='审核状态')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品类型',
|
||||
'verbose_name_plural': '商品类型',
|
||||
'db_table': 'shangpin_leixing',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangpinMeiriTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, 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(decimal_places=2, default=0.0, max_digits=12, verbose_name='点单总额')),
|
||||
('chengjiao_zongliang', models.PositiveIntegerField(default=0, verbose_name='成交总量')),
|
||||
('chengjiao_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='成交总额')),
|
||||
('tuikuan_zongliang', models.PositiveIntegerField(default=0, verbose_name='退款总量')),
|
||||
('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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品每日统计',
|
||||
'verbose_name_plural': '商品每日统计',
|
||||
'db_table': 'shangpin_meiri_tongji',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShangpinZhuanqu',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, verbose_name='专区ID')),
|
||||
('mingzi', models.CharField(blank=True, max_length=45, null=True, verbose_name='专区名称')),
|
||||
('leixing_id', models.PositiveIntegerField(verbose_name='类型ID')),
|
||||
('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='是否上架')),
|
||||
('fengjin_zhuangtai', models.BooleanField(default=True, verbose_name='是否封禁')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品专区',
|
||||
'verbose_name_plural': '商品专区',
|
||||
'db_table': 'shangpin_zhuanqu',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,29 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-18 14:24
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='huiyuangoumai',
|
||||
unique_together={('yonghu_id', 'huiyuan_id')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='huiyuangoumai',
|
||||
index=models.Index(fields=['yonghu_id'], name='huiyuangoum_yonghu__ba2138_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='huiyuangoumai',
|
||||
index=models.Index(fields=['huiyuan_id'], name='huiyuangoum_huiyuan_35fe1d_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='huiyuangoumai',
|
||||
index=models.Index(fields=['yonghu_id', 'huiyuan_id'], name='huiyuangoum_yonghu__21e6e1_idx'),
|
||||
),
|
||||
]
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-17 01:32
|
||||
# Generated by Django 4.2.27 on 2026-06-17 16:31
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
@@ -9,8 +9,8 @@ class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('rank', '0001_initial'),
|
||||
('products', '0001_initial'),
|
||||
('rank', '0001_initial'),
|
||||
('shop', '0001_initial'),
|
||||
]
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-07 19:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0002_alter_huiyuangoumai_unique_together_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='paixu',
|
||||
field=models.IntegerField(default=0, verbose_name='排序权重'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinleixing',
|
||||
name='paixu',
|
||||
field=models.IntegerField(default=0, verbose_name='排序权重'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinleixing',
|
||||
name='shenhezhuangtai',
|
||||
field=models.IntegerField(default=1, help_text='1=正常, 2=审核专用', verbose_name='审核状态'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinzhuanqu',
|
||||
name='paixu',
|
||||
field=models.IntegerField(default=0, verbose_name='排序权重'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-09 15:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0003_shangpin_paixu_shangpinleixing_paixu_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='shenhezhuangtai',
|
||||
field=models.IntegerField(default=1, help_text='1=正常, 2=审核专用', verbose_name='审核状态'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinzhuanqu',
|
||||
name='shenhezhuangtai',
|
||||
field=models.IntegerField(default=1, help_text='1=正常, 2=审核专用', verbose_name='审核状态'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-27 15:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0004_shangpin_shenhezhuangtai_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='gsfenhong',
|
||||
name='dashouid',
|
||||
field=models.CharField(db_index=True, max_length=7, verbose_name='打手ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,45 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-18 12:09
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0005_alter_gsfenhong_dashouid'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='gsfenhong',
|
||||
name='huiyuan_id',
|
||||
field=models.CharField(blank=True, max_length=6, null=True, verbose_name='会员ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='huiyuan',
|
||||
name='zuzhangfc',
|
||||
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='组长分成'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DuociFenhong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('guanshi', models.CharField(db_index=True, max_length=7, verbose_name='管事ID')),
|
||||
('zuzhang', models.CharField(blank=True, db_index=True, max_length=7, null=True, verbose_name='组长ID')),
|
||||
('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='更新时间')),
|
||||
('huiyuan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.huiyuan', verbose_name='会员')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '多次分红配置',
|
||||
'verbose_name_plural': '多次分红配置',
|
||||
'db_table': 'duoci_fenhong',
|
||||
'indexes': [models.Index(fields=['guanshi'], name='duoci_fenho_guanshi_b3de53_idx'), models.Index(fields=['zuzhang'], name='duoci_fenho_zuzhang_69997d_idx')],
|
||||
'unique_together': {('huiyuan', 'guanshi', 'cishu')},
|
||||
},
|
||||
),
|
||||
]
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-19 13:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0006_gsfenhong_huiyuan_id_huiyuan_zuzhangfc_duocifenhong'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveIndex(
|
||||
model_name='duocifenhong',
|
||||
name='duoci_fenho_guanshi_b3de53_idx',
|
||||
),
|
||||
migrations.RemoveIndex(
|
||||
model_name='duocifenhong',
|
||||
name='duoci_fenho_zuzhang_69997d_idx',
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='duocifenhong',
|
||||
old_name='guanshi',
|
||||
new_name='yonghuid',
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='duocifenhong',
|
||||
unique_together=set(),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='duocifenhong',
|
||||
name='huiyuan',
|
||||
field=models.CharField(max_length=10, verbose_name='会员ID'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='duocifenhong',
|
||||
unique_together={('huiyuan', 'yonghuid', 'cishu')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='duocifenhong',
|
||||
index=models.Index(fields=['yonghuid'], name='duoci_fenho_yonghui_db6a2f_idx'),
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='duocifenhong',
|
||||
name='zuzhang',
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-19 13:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0007_remove_duocifenhong_duoci_fenho_guanshi_b3de53_idx_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='gsfenhong',
|
||||
name='zuzhang_fenhong',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='组长分红金额'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='gsfenhong',
|
||||
name='zuzhang_id',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=7, null=True, verbose_name='组长ID'),
|
||||
),
|
||||
]
|
||||
@@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-22 15:35
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0008_gsfenhong_zuzhang_fenhong_gsfenhong_zuzhang_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='ewai_dashou_fencheng',
|
||||
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='打手额外分成金额'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='kaioi_ewai_dashou_fencheng',
|
||||
field=models.BooleanField(default=False, verbose_name='是否开启打手额外分成'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-24 17:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0009_shangpin_ewai_dashou_fencheng_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangpinleixing',
|
||||
name='is_cross_enabled',
|
||||
field=models.BooleanField(default=False, verbose_name='是否开启平台互通'),
|
||||
),
|
||||
]
|
||||
@@ -1,60 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-21 12:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('shop', '0001_initial'),
|
||||
('products', '0010_shangpinleixing_is_cross_enabled'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='dianpu',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shop.dianpu', verbose_name='所属店铺'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='dianpu_leixing',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.shangpinleixingdianpu', verbose_name='店铺商品类型'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='fengjin_zhuangtai',
|
||||
field=models.BooleanField(default=True, verbose_name='是否封禁'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='shangjia_zhuangtai',
|
||||
field=models.BooleanField(default=True, verbose_name='是否上架'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='shenhe_zhuangtai',
|
||||
field=models.BooleanField(default=False, help_text='True=审核通过,False=未审核', verbose_name='平台审核状态'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinzhuanqu',
|
||||
name='dianpu',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shop.dianpu', verbose_name='所属店铺'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinzhuanqu',
|
||||
name='dianpu_leixing',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.shangpinleixingdianpu', verbose_name='店铺商品类型'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinzhuanqu',
|
||||
name='fengjin_zhuangtai',
|
||||
field=models.BooleanField(default=True, verbose_name='是否封禁'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinzhuanqu',
|
||||
name='shangjia_zhuangtai',
|
||||
field=models.BooleanField(default=True, verbose_name='是否上架'),
|
||||
),
|
||||
]
|
||||
@@ -1,42 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-23 14:56
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0011_shangpin_dianpu_shangpin_dianpu_leixing_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ShangpinMeiriTongji',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, 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(decimal_places=2, default=0.0, max_digits=12, verbose_name='点单总额')),
|
||||
('chengjiao_zongliang', models.PositiveIntegerField(default=0, verbose_name='成交总量')),
|
||||
('chengjiao_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='成交总额')),
|
||||
('tuikuan_zongliang', models.PositiveIntegerField(default=0, verbose_name='退款总量')),
|
||||
('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='更新时间')),
|
||||
('shangpin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.shangpin', verbose_name='商品ID')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '商品每日统计',
|
||||
'verbose_name_plural': '商品每日统计',
|
||||
'db_table': 'shangpin_meiri_tongji',
|
||||
'indexes': [models.Index(fields=['shangpin', 'riqi'], name='shangpin_me_shangpi_d27e5c_idx'), models.Index(fields=['nian', 'yue', 'ri'], name='shangpin_me_nian_e3b409_idx')],
|
||||
'unique_together': {('shangpin', 'riqi')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-14 04:25
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0003_alter_dashoubiaoxian_bankuai'),
|
||||
('products', '0012_shangpinmeiritongji'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangpinleixing',
|
||||
name='bankuai',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='rank.bankuai', verbose_name='所属板块'),
|
||||
),
|
||||
]
|
||||
@@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-16 16:51
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0010_kaohejilufeiyong'),
|
||||
('products', '0013_shangpinleixing_bankuai'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='huiyuan',
|
||||
name='bankuai',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='rank.bankuai', verbose_name='所属板块'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-12 01:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0014_huiyuan_bankuai'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='gsfenhong',
|
||||
name='fenhong_leixing',
|
||||
field=models.PositiveSmallIntegerField(choices=[(1, '会员分红'), (2, '押金分红'), (3, '商家订单分红')], default=1, verbose_name='分红类型'),
|
||||
),
|
||||
]
|
||||
@@ -1,17 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-15 01:42
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('products', '0015_gsfenhong_fenhong_leixing'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='shangpinleixing',
|
||||
name='is_cross_enabled',
|
||||
),
|
||||
]
|
||||
+4
-3
@@ -46,8 +46,9 @@ from .models import (
|
||||
Czjilu, Gsfenhong, Huiyuangoumai, DuociFenhong
|
||||
)
|
||||
from users.models import (
|
||||
UserMain, AdminProfile, UserDashou, UserGuanshi, UserZuzhang, UserShangjia
|
||||
AdminProfile, UserDashou, UserGuanshi, UserZuzhang, UserShangjia
|
||||
)
|
||||
from gvsdsdk.models import User
|
||||
|
||||
from orders.models import Lilubiao
|
||||
from config.models import Szjilu, Gonggao, Lunbo
|
||||
@@ -5945,7 +5946,7 @@ class ZuzhangFenhongView(APIView):
|
||||
return {}
|
||||
|
||||
# 查询用户主表,并预加载 boss_profile
|
||||
users = UserMain.query.filter(yonghuid__in=guanshi_ids).select_related(
|
||||
users = User.query.filter(yonghuid__in=guanshi_ids).select_related(
|
||||
'boss_profile'
|
||||
).only(
|
||||
'yonghuid', 'avatar',
|
||||
@@ -6008,7 +6009,7 @@ class CzhqdyView(APIView):
|
||||
{
|
||||
'id': 1,
|
||||
'name': '打手佣金抵扣',
|
||||
'profile_attr': 'dashou_profile', # UserMain 的反向 related_name
|
||||
'profile_attr': 'dashou_profile', # User 的反向 related_name
|
||||
'balance_field': 'yue',
|
||||
'rate_key': '5',
|
||||
'model': UserDashou,
|
||||
|
||||
+277
-111
@@ -1,111 +1,277 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-12 02:17
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('orders', '0026_fadanfenhonglilv_alter_fadan_shenqingren_shenfen_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Bankuai',
|
||||
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='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '板块',
|
||||
'verbose_name_plural': '板块',
|
||||
'db_table': 'bankuai',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Chenghao',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('mingcheng', models.CharField(max_length=50, unique=True, verbose_name='称号名称')),
|
||||
('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='创建时间')),
|
||||
('bankuai', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块(空=全板块通用)')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '称号',
|
||||
'verbose_name_plural': '称号',
|
||||
'db_table': 'chenghao',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='YonghuChenghao',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('huode_time', models.DateTimeField(auto_now_add=True, verbose_name='获得时间')),
|
||||
('chenghao', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.chenghao', verbose_name='称号')),
|
||||
('yonghu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chenghao_list', to=settings.AUTH_USER_MODEL, verbose_name='用户')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户称号关联',
|
||||
'verbose_name_plural': '用户称号关联',
|
||||
'db_table': 'yonghu_chenghao',
|
||||
'indexes': [models.Index(fields=['yonghu', 'chenghao'], name='yonghu_chen_yonghu__cac0a1_idx')],
|
||||
'unique_together': {('yonghu', 'chenghao')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='JingyanJilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('yonghu_leixing', models.CharField(choices=[('dashou', '打手'), ('boss', '老板'), ('shangjia', '商家'), ('guanshi', '管事'), ('zuzhang', '组长')], max_length=10, verbose_name='用户类型')),
|
||||
('sudu_jingyan', models.DecimalField(decimal_places=2, default=0, max_digits=8, verbose_name='上线速度经验')),
|
||||
('shili_jingyan', models.DecimalField(decimal_places=2, default=0, max_digits=8, verbose_name='打手实力经验')),
|
||||
('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='更新时间')),
|
||||
('bankuai', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '经验变动记录',
|
||||
'verbose_name_plural': '经验变动记录',
|
||||
'db_table': 'jingyan_jilu',
|
||||
'indexes': [models.Index(fields=['yonghu_id', 'bankuai', 'create_time'], name='jingyan_jil_yonghu__786992_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DashouBiaoxian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dashou_id', models.CharField(db_index=True, max_length=32, verbose_name='打手ID')),
|
||||
('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='创建时间')),
|
||||
('jiedan_time', models.DateTimeField(blank=True, null=True, verbose_name='接单时间')),
|
||||
('tijiao_time', models.DateTimeField(blank=True, null=True, verbose_name='提交时间')),
|
||||
('bankuai', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块')),
|
||||
('dingdan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='biaoxian', to='orders.dingdan', verbose_name='关联订单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '打手订单表现',
|
||||
'verbose_name_plural': '打手订单表现',
|
||||
'db_table': 'dashou_biaoxian',
|
||||
'indexes': [models.Index(fields=['dashou_id', 'bankuai', 'create_time'], name='dashou_biao_dashou__36e1c3_idx')],
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chenghao',
|
||||
index=models.Index(fields=['leixing', 'bankuai'], name='chenghao_leixing_8f4371_idx'),
|
||||
),
|
||||
]
|
||||
# Generated by Django 4.2.27 on 2026-06-17 16:31
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('orders', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Bankuai',
|
||||
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='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '板块',
|
||||
'verbose_name_plural': '板块',
|
||||
'db_table': 'bankuai',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Chenghao',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('mingcheng', models.CharField(max_length=50, unique=True, verbose_name='称号名称')),
|
||||
('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='创建时间')),
|
||||
('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='所属板块(空=全板块通用)')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '称号',
|
||||
'verbose_name_plural': '称号',
|
||||
'db_table': 'chenghao',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KaohePayTemp',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='订单ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, 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(blank=True, max_length=32, null=True, verbose_name='原记录ID(再次申请时)')),
|
||||
('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='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核支付临时表',
|
||||
'verbose_name_plural': '考核支付临时表',
|
||||
'db_table': 'kaohe_pay_temp',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShenheJilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='审核状态')),
|
||||
('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='更新时间')),
|
||||
('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')),
|
||||
('dashou_youxi_id', models.CharField(blank=True, max_length=50, null=True, verbose_name='打手游戏ID')),
|
||||
('dashou_beizhu', models.TextField(blank=True, null=True, verbose_name='打手备注')),
|
||||
('bankuai', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='审核板块')),
|
||||
('chenghao', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.chenghao', verbose_name='审核标签')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '审核记录',
|
||||
'verbose_name_plural': '审核记录',
|
||||
'db_table': 'shenhe_jilu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KaoheJujueJilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='创建时间')),
|
||||
('jilu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.shenhejilu', to_field='jilu_id', verbose_name='审核记录')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '拒绝原因记录',
|
||||
'verbose_name_plural': '拒绝原因记录',
|
||||
'db_table': 'kaohe_jujue_jilu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KaoheJiluFeiyong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cishu', models.IntegerField(verbose_name='第几次考核')),
|
||||
('jine', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='缴纳金额')),
|
||||
('jilu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.shenhejilu', to_field='jilu_id', verbose_name='考核记录')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核记录费用',
|
||||
'verbose_name_plural': '考核记录费用',
|
||||
'db_table': 'kaohe_jilu_feiyong',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KaoheguanBankuai',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('kaoheguan_id', models.CharField(db_index=True, max_length=7, verbose_name='考核官用户ID')),
|
||||
('bankuai', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.bankuai', verbose_name='所属板块')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核官板块关联',
|
||||
'verbose_name_plural': '考核官板块关联',
|
||||
'db_table': 'kaoheguan_bankuai',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KaoheCishuFeiyong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cishu', models.IntegerField(verbose_name='第几次考核')),
|
||||
('feiyong', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='需缴纳金额')),
|
||||
('chenghao', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.chenghao', verbose_name='标签')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核次数费用',
|
||||
'verbose_name_plural': '考核次数费用',
|
||||
'db_table': 'kaohe_cishu_feiyong',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='JingyanJilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('yonghu_id', models.CharField(db_index=True, max_length=7, verbose_name='用户ID')),
|
||||
('yonghu_leixing', models.CharField(choices=[('dashou', '打手'), ('boss', '老板'), ('shangjia', '商家'), ('guanshi', '管事'), ('zuzhang', '组长')], max_length=10, verbose_name='用户类型')),
|
||||
('sudu_jingyan', models.DecimalField(decimal_places=2, default=0, max_digits=8, verbose_name='上线速度经验')),
|
||||
('shili_jingyan', models.DecimalField(decimal_places=2, default=0, max_digits=8, verbose_name='打手实力经验')),
|
||||
('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='更新时间')),
|
||||
('bankuai', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '经验变动记录',
|
||||
'verbose_name_plural': '经验变动记录',
|
||||
'db_table': 'jingyan_jilu',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
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='创建时间')),
|
||||
('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='订单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '订单需求标签',
|
||||
'verbose_name_plural': '订单需求标签',
|
||||
'db_table': 'dingdan_biaoqian',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DashouBiaoxian',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dashou_id', models.CharField(db_index=True, max_length=32, verbose_name='打手ID')),
|
||||
('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='创建时间')),
|
||||
('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='所属板块')),
|
||||
('dingdan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='biaoxian', to='orders.dingdan', to_field='dingdan_id', verbose_name='关联订单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '打手订单表现',
|
||||
'verbose_name_plural': '打手订单表现',
|
||||
'db_table': 'dashou_biaoxian',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='YonghuChenghao',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('huode_time', models.DateTimeField(auto_now_add=True, verbose_name='获得时间')),
|
||||
('chenghao', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.chenghao', verbose_name='称号')),
|
||||
('yonghu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chenghao_list', to=settings.AUTH_USER_MODEL, verbose_name='用户')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '用户称号关联',
|
||||
'verbose_name_plural': '用户称号关联',
|
||||
'db_table': 'yonghu_chenghao',
|
||||
'indexes': [models.Index(fields=['yonghu', 'chenghao'], name='yonghu_chen_yonghu__cac0a1_idx')],
|
||||
'unique_together': {('yonghu', 'chenghao')},
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='shenhejilu',
|
||||
index=models.Index(fields=['shenqingren_id', 'zhuangtai'], name='shenhe_jilu_shenqin_502e9b_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='shenhejilu',
|
||||
index=models.Index(fields=['shenheguan_id'], name='shenhe_jilu_shenheg_5c9959_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='kaohejujuejilu',
|
||||
index=models.Index(fields=['jilu_id', 'cishu'], name='kaohe_jujue_jilu_id_1f2b29_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='kaohejilufeiyong',
|
||||
unique_together={('jilu', 'cishu')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='kaoheguanbankuai',
|
||||
index=models.Index(fields=['kaoheguan_id'], name='kaoheguan_b_kaohegu_00f7c5_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='kaoheguanbankuai',
|
||||
unique_together={('kaoheguan_id', 'bankuai')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='kaohecishufeiyong',
|
||||
index=models.Index(fields=['chenghao', 'cishu'], name='kaohe_cishu_chengha_edc272_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='kaohecishufeiyong',
|
||||
unique_together={('chenghao', 'cishu')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='jingyanjilu',
|
||||
index=models.Index(fields=['yonghu_id', 'bankuai', 'create_time'], name='jingyan_jil_yonghu__786992_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dingdanbiaoqian',
|
||||
index=models.Index(fields=['dingdan'], name='dingdan_bia_dingdan_4d046b_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='dingdanbiaoqian',
|
||||
unique_together={('dingdan', 'chenghao')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='dashoubiaoxian',
|
||||
index=models.Index(fields=['dashou_id', 'bankuai', 'create_time'], name='dashou_biao_dashou__36e1c3_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='chenghao',
|
||||
index=models.Index(fields=['leixing', 'bankuai'], name='chenghao_leixing_8f4371_idx'),
|
||||
),
|
||||
]
|
||||
@@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-12 02:25
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0026_fadanfenhonglilv_alter_fadan_shenqingren_shenfen_and_more'),
|
||||
('rank', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='dashoubiaoxian',
|
||||
name='dingdan',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='biaoxian', to='orders.dingdan', to_field='dingdan_id', verbose_name='关联订单'),
|
||||
),
|
||||
]
|
||||
@@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-12 02:32
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0002_alter_dashoubiaoxian_dingdan'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='dashoubiaoxian',
|
||||
name='bankuai',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='所属板块'),
|
||||
),
|
||||
]
|
||||
@@ -1,26 +0,0 @@
|
||||
# dengji/migrations/0004_dingdanbiaoqian.py
|
||||
from django.db import migrations
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0026_fadanfenhonglilv_alter_fadan_shenqingren_shenfen_and_more'), # 保持你之前的依赖
|
||||
('rank', '0003_alter_dashoubiaoxian_bankuai'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunSQL(
|
||||
sql="""
|
||||
CREATE TABLE IF NOT EXISTS dingdan_biaoqian (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
create_time DATETIME(6) NOT NULL,
|
||||
chenghao_id BIGINT NOT NULL,
|
||||
dingdan_id VARCHAR(32) NOT NULL,
|
||||
CONSTRAINT fk_dingdanbiaoqian_chenghao FOREIGN KEY (chenghao_id) REFERENCES chenghao (id),
|
||||
CONSTRAINT fk_dingdanbiaoqian_dingdan FOREIGN KEY (dingdan_id) REFERENCES dingdan (dingdan_id),
|
||||
UNIQUE KEY uniq_dingdan_chenghao (dingdan_id, chenghao_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
""",
|
||||
reverse_sql="DROP TABLE IF EXISTS dingdan_biaoqian;"
|
||||
),
|
||||
]
|
||||
@@ -1,36 +0,0 @@
|
||||
# dengji/migrations/0005_fix_state.py
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0026_fadanfenhonglilv_alter_fadan_shenqingren_shenfen_and_more'), # 保持你之前的依赖
|
||||
('rank', '0004_dingdanbiaoqian'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.SeparateDatabaseAndState(
|
||||
database_operations=[], # 表已存在,不做任何数据库操作
|
||||
state_operations=[
|
||||
migrations.CreateModel(
|
||||
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='创建时间')),
|
||||
('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='订单')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '订单需求标签',
|
||||
'verbose_name_plural': '订单需求标签',
|
||||
'db_table': 'dingdan_biaoqian',
|
||||
'unique_together': {('dingdan', 'chenghao')},
|
||||
'indexes': [
|
||||
models.Index(fields=['dingdan'], name='dingdan_bia_dingdan_4d046b_idx'),
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,35 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-14 18:42
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0005_fix_state'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ShenheJilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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, '未通过')], 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='更新时间')),
|
||||
('bankuai', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.bankuai', verbose_name='审核板块')),
|
||||
('chenghao', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='rank.chenghao', verbose_name='审核标签')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '审核记录',
|
||||
'verbose_name_plural': '审核记录',
|
||||
'db_table': 'shenhe_jilu',
|
||||
'indexes': [models.Index(fields=['shenqingren_id', 'zhuangtai'], name='shenhe_jilu_shenqin_502e9b_idx'), models.Index(fields=['shenheguan_id'], name='shenhe_jilu_shenheg_5c9959_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,29 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-15 00:31
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0006_shenhejilu'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='KaoheguanBankuai',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('kaoheguan_id', models.CharField(db_index=True, max_length=7, verbose_name='考核官用户ID')),
|
||||
('bankuai', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.bankuai', verbose_name='所属板块')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核官板块关联',
|
||||
'verbose_name_plural': '考核官板块关联',
|
||||
'db_table': 'kaoheguan_bankuai',
|
||||
'indexes': [models.Index(fields=['kaoheguan_id'], name='kaoheguan_b_kaohegu_00f7c5_idx')],
|
||||
'unique_together': {('kaoheguan_id', 'bankuai')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,48 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-15 04:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0007_kaoheguanbankuai'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='chenghao',
|
||||
name='kaohe_guize',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='考核规则'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shenhejilu',
|
||||
name='dashou_beizhu',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='打手备注'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shenhejilu',
|
||||
name='dashou_youxi_id',
|
||||
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='打手游戏ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shenhejilu',
|
||||
name='guize_neirong',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='规则内容'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shenhejilu',
|
||||
name='jilu_id',
|
||||
field=models.CharField(db_index=True, max_length=32, null=True, verbose_name='记录ID'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shenhejilu',
|
||||
name='shenheguan_youxi_id',
|
||||
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='审核官游戏ID'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='shenhejilu',
|
||||
name='zhuangtai',
|
||||
field=models.IntegerField(choices=[(0, '审核中'), (1, '通过'), (2, '未通过'), (3, '待审核')], default=0, verbose_name='审核状态'),
|
||||
),
|
||||
]
|
||||
@@ -1,58 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-15 13:20
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0008_chenghao_kaohe_guize_shenhejilu_dashou_beizhu_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='chenghao',
|
||||
name='kaioi_jinpai',
|
||||
field=models.BooleanField(default=False, verbose_name='是否同时开启金牌'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='shenhejilu',
|
||||
name='jilu_id',
|
||||
field=models.CharField(db_index=True, default='Sh111', max_length=32, unique=True, verbose_name='记录ID'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KaoheJujueJilu',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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='创建时间')),
|
||||
('jilu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.shenhejilu', to_field='jilu_id', verbose_name='审核记录')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '拒绝原因记录',
|
||||
'verbose_name_plural': '拒绝原因记录',
|
||||
'db_table': 'kaohe_jujue_jilu',
|
||||
'indexes': [models.Index(fields=['jilu_id', 'cishu'], name='kaohe_jujue_jilu_id_1f2b29_idx')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KaoheCishuFeiyong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cishu', models.IntegerField(verbose_name='第几次考核')),
|
||||
('feiyong', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='需缴纳金额')),
|
||||
('chenghao', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.chenghao', verbose_name='标签')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核次数费用',
|
||||
'verbose_name_plural': '考核次数费用',
|
||||
'db_table': 'kaohe_cishu_feiyong',
|
||||
'indexes': [models.Index(fields=['chenghao', 'cishu'], name='kaohe_cishu_chengha_edc272_idx')],
|
||||
'unique_together': {('chenghao', 'cishu')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,29 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-15 16:10
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0009_chenghao_kaioi_jinpai_alter_shenhejilu_jilu_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='KaoheJiluFeiyong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cishu', models.IntegerField(verbose_name='第几次考核')),
|
||||
('jine', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='缴纳金额')),
|
||||
('jilu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rank.shenhejilu', to_field='jilu_id', verbose_name='考核记录')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核记录费用',
|
||||
'verbose_name_plural': '考核记录费用',
|
||||
'db_table': 'kaohe_jilu_feiyong',
|
||||
'unique_together': {('jilu', 'cishu')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,35 +0,0 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-19 13:35
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rank', '0010_kaohejilufeiyong'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='KaohePayTemp',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('dingdan_id', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='订单ID')),
|
||||
('yonghuid', models.CharField(db_index=True, max_length=7, 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(blank=True, max_length=32, null=True, verbose_name='原记录ID(再次申请时)')),
|
||||
('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='创建时间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '考核支付临时表',
|
||||
'verbose_name_plural': '考核支付临时表',
|
||||
'db_table': 'kaohe_pay_temp',
|
||||
},
|
||||
),
|
||||
]
|
||||
Loaded 100 of 132 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user