修正了 SDK,修复了 aggregate 不能传入 args 的问题

This commit is contained in:
2026-06-19 18:57:50 +08:00
parent fcd2a5e8a9
commit ee42d80d93
27 changed files with 622 additions and 469 deletions

View File

@@ -175,7 +175,7 @@ AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend', 'django.contrib.auth.backends.ModelBackend',
] ]
AUTH_USER_MODEL = 'gvsdsdk.User' AUTH_USER_MODEL = 'users.User'
# ==================== DRF 配置 ==================== # ==================== DRF 配置 ====================
REST_FRAMEWORK = { REST_FRAMEWORK = {

View File

@@ -61,7 +61,7 @@ from users.models import (
UserGuanshi, UserBoss, UserZuzhang, UserGuanshi, UserBoss, UserZuzhang,
UserKefu, UserDashou, Xiugaijilu, UserShangjia, UserShenheguan UserKefu, UserDashou, Xiugaijilu, UserShangjia, UserShenheguan
) )
from gvsdsdk.models import User from users.business_models import User
## orders ## orders
from orders.models import ( from orders.models import (

View File

@@ -40,7 +40,7 @@ from users.models import (
AdminProfile, UserDashou, UserBoss, AdminProfile, UserDashou, UserBoss,
UserShangjia, UserGuanshi, UserZuzhang UserShangjia, UserGuanshi, UserZuzhang
) )
from gvsdsdk.models import User from users.business_models import User
from orders.models import CommissionRate, Order, MerchantOrderExt from orders.models import CommissionRate, Order, MerchantOrderExt
from orders.notice_tasks import dingdan_guangbo from orders.notice_tasks import dingdan_guangbo
@@ -2715,13 +2715,13 @@ class GuanZhuAListView(APIView):
images = list(qs.values_list('ImageURL', flat=True)) images = list(qs.values_list('ImageURL', flat=True))
# 获取最新更新时间取所有记录的update_time最大值 # 获取最新更新时间取所有记录的update_time最大值
last_update = qs.aggregate(Max('update_time'))['update_time__max'] last_update = qs.aggregate(update_time__max=Max('update_time'))['update_time__max']
last_update_str = last_update.strftime('%Y-%m-%d %H:%M:%S') if last_update else None last_update_str = last_update.strftime('%Y-%m-%d %H:%M:%S') if last_update else None
# 原子性增加访问次数 # 原子性增加访问次数
# 先更新所有记录,再获取更新后的最大次数 # 先更新所有记录,再获取更新后的最大次数
qs.update(AccessCount=F('AccessCount') + 1) qs.update(AccessCount=F('AccessCount') + 1)
visit_count = qs.aggregate(Max('AccessCount'))['AccessCount__max'] or 0 visit_count = qs.aggregate(access_count__max=Max('AccessCount'))['access_count__max'] or 0
return Response({ return Response({
'code': 0, 'code': 0,

View File

@@ -13,7 +13,8 @@ class ELTAuthentication:
except (ValueError, AttributeError): except (ValueError, AttributeError):
return None return None
from gvsdsdk.models import User, EphemeralToken from gvsdsdk.models import EphemeralToken
from gvsds.apps.core.models import User
import datetime import datetime
try: try:

View File

@@ -87,7 +87,7 @@ class RoleManager:
@staticmethod @staticmethod
def GetUsersForRole(RoleUUID): def GetUsersForRole(RoleUUID):
"""获取拥有指定角色的所有用户""" """获取拥有指定角色的所有用户"""
from gvsdsdk.models import User from gvsds.apps.core.models import User
user_uuids = UserRole.objects.filter(RoleUUID=RoleUUID).values_list('UserUUID', flat=True) user_uuids = UserRole.objects.filter(RoleUUID=RoleUUID).values_list('UserUUID', flat=True)
return User.objects.filter(UserUUID__in=user_uuids) return User.objects.filter(UserUUID__in=user_uuids)

View File

@@ -1,4 +1,5 @@
from gvsdsdk.models import User, UserRole, Role, RolePermission, Permission, UserABAC from gvsds.apps.core.models import User
from gvsdsdk.models import UserRole, Role, RolePermission, Permission, UserABAC
from rest_framework.permissions import BasePermission from rest_framework.permissions import BasePermission

View File

@@ -1,6 +1,8 @@
"""将 User 表中明文密码迁移为 bcrypt 哈希""" """将 User 表中明文密码迁移为 bcrypt 哈希"""
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from gvsdsdk.models import User from django.contrib.auth import get_user_model
User = get_user_model()
class Command(BaseCommand): class Command(BaseCommand):

View File

@@ -1,4 +1,4 @@
# Generated by Django 4.2.27 on 2026-06-17 17:07 # Generated by Django 4.2.27 on 2026-06-19 18:42
import datetime import datetime
from django.db import migrations, models from django.db import migrations, models
@@ -318,37 +318,4 @@ class Migration(migrations.Migration):
'managed': True, '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')],
},
),
] ]

View File

@@ -0,0 +1,90 @@
# 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,
},
),
]

View File

@@ -13,10 +13,10 @@
4. 鉴权规则层:操作权限校验(角色汇总)+ 数据权限校验(组织属性) 4. 鉴权规则层:操作权限校验(角色汇总)+ 数据权限校验(组织属性)
使用方式(子服务器): 使用方式(子服务器):
from gvsdsdk.models import User, Permission, Role, UserRole, RolePermission from gvsdsdk.models import Permission, Role, UserRole, RolePermission
# 查询所有启用的用户 # 查询所有启用的用户(需在业务子类中定义具体 User 模型)
users = User.objects.using('saas').filter(UserAccountLicense=1) users = User.objects.filter(UserAccountLicense=1)
# 或配置 DatabaseRouter 后直接使用 # 或配置 DatabaseRouter 后直接使用
users = User.objects.filter(UserAccountLicense=1) users = User.objects.filter(UserAccountLicense=1)
@@ -27,6 +27,10 @@
3. PascalCase字段名、方法名遵循帕斯卡命名法 3. PascalCase字段名、方法名遵循帕斯卡命名法
4. 兼容db_table、db_column 与 SAAS 主库完全一致 4. 兼容db_table、db_column 与 SAAS 主库完全一致
5. 租户隔离:所有权限相关数据依附于独立租户空间,不同租户互相不可见 5. 租户隔离:所有权限相关数据依附于独立租户空间,不同租户互相不可见
注意User 为抽象基类,仅包含 SAAS 主库标准字段。
业务子类应继承 User 并在单独文件中添加业务字段和方法。
参见 gvsdsdk/business_models.py。
""" """
import uuid as _uuid import uuid as _uuid
@@ -172,7 +176,12 @@ class UserManager(BaseUserManager):
# === 用户表 === # === 用户表 ===
class User(QModel): class User(QModel):
"""用户表——系统核心身份模型(映射 SAAS 主库 User 表""" """用户表——系统核心身份模型(抽象基类,映射 SAAS 主库 User 表标准字段)
本类为抽象基类,仅包含 SAAS 主库 User 表的标准字段和方法。
业务子类应继承本类,在单独文件中添加业务字段和方法。
参见 gvsdsdk/business_models.py。
"""
UserUUID = UUIDField(primary_key=True, db_column='UserUUID', verbose_name='用户UUID', default=_uuid.uuid4) UserUUID = UUIDField(primary_key=True, db_column='UserUUID', verbose_name='用户UUID', default=_uuid.uuid4)
UserName = models.CharField(max_length=256, unique=True, db_column='UserName', verbose_name='用户名') UserName = models.CharField(max_length=256, unique=True, db_column='UserName', verbose_name='用户名')
@@ -186,34 +195,13 @@ class User(QModel):
UserTele = models.CharField(max_length=16, null=True, blank=True, db_column='UserTele', verbose_name='电话') 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='创建时间') UserCreateTime = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='UserCreateTime', verbose_name='创建时间')
UserLastLoginDate = models.DateTimeField(default=_datetime.datetime.utcnow, db_column='UserLastLoginDate', 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='是否员工') # Django auth 框架必需(由具体子类覆盖)
IsSuperuser = models.BooleanField(default=False, db_column='IsSuperuser', verbose_name='是否超级用户')
objects = UserManager()
# Django auth 框架必需
USERNAME_FIELD = 'UserName' USERNAME_FIELD = 'UserName'
REQUIRED_FIELDS = ['UserUID'] REQUIRED_FIELDS = []
class Meta: class Meta:
managed = True # 将由 QModelBase.__new__ 根据 GVSDSDK_MANAGE_TABLES 动态设置 abstract = True
app_label = 'gvsdsdk'
db_table = 'User'
verbose_name = '用户'
verbose_name_plural = '用户'
indexes = [
models.Index(fields=['UserUID']),
models.Index(fields=['OpenID']),
]
def __str__(self): def __str__(self):
return self.UserName return self.UserName
@@ -341,115 +329,6 @@ class User(QModel):
def check_password(self, raw_password): def check_password(self, raw_password):
return self.CheckPassword(raw_password) return self.CheckPassword(raw_password)
# ── 用户类型推断(通过 UserRole → Role 推断,带实例缓存)──
@property
def UserType(self):
"""用户类型 — 通过 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'
# ── 收款信息(存于 UserSensitiveData──
@property
def PaymentQRCode(self):
"""收款码图片(存于 UserSensitiveData.zhifu"""
try:
return self.sensitive_data.zhifu
except Exception:
return ''
@PaymentQRCode.setter
def PaymentQRCode(self, value):
try:
sd = self.sensitive_data
sd.zhifu = value
sd.save(update_fields=['zhifu'])
except Exception:
pass
@property
def PaymentAccount(self):
"""收款账号(存于 UserSensitiveData.skzhanghao"""
try:
return self.sensitive_data.skzhanghao
except Exception:
return ''
@PaymentAccount.setter
def PaymentAccount(self, value):
try:
sd = self.sensitive_data
sd.skzhanghao = value
sd.save(update_fields=['skzhanghao'])
except Exception:
pass
# ── 关联扩展表快捷访问 ──
# DashouProfile / ShopProfile / GuanshiProfile / BossProfile /
# AdminProfile / KefuProfile / ZuzhangProfile / ShenheguanProfile
# 均由 OneToOneField related_name 直接提供反向关联访问
def HasRole(self, role_code):
"""检查用户是否拥有指定角色(支持角色名或 UserType 值)"""
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
# === 用户头像表 === # === 用户头像表 ===
@@ -622,10 +501,12 @@ class Role(QModel):
def GetUsers(self): def GetUsers(self):
"""获取拥有该角色的用户列表""" """获取拥有该角色的用户列表"""
from django.apps import apps
UserModel = apps.get_model('gvsdsdk', 'User')
user_uuids = UserRole.objects.filter( user_uuids = UserRole.objects.filter(
RoleUUID=self.RoleUUID RoleUUID=self.RoleUUID
).values_list('UserUUID', flat=True) ).values_list('UserUUID', flat=True)
return User.objects.filter(UserUUID__in=user_uuids) return UserModel.objects.filter(UserUUID__in=user_uuids)
# === 权限表 === # === 权限表 ===

View File

@@ -46,7 +46,8 @@ PERMISSION_MAP = {
def run_migration(): def run_migration():
from gvsdsdk.models import User, Role, Permission, UserRole, RolePermission from gvsdsdk.models import Role, Permission, UserRole, RolePermission
from users.business_models import User
from users.models import ( from users.models import (
UserMain, UserBoss, UserDashou, UserShangjia, UserGuanshi, UserMain, UserBoss, UserDashou, UserShangjia, UserGuanshi,
UserZuzhang, UserShenheguan, AdminProfile, UserKefu, UserZuzhang, UserShenheguan, AdminProfile, UserKefu,

View File

@@ -16,7 +16,7 @@ import logging
# 导入模型 - 确保路径正确 # 导入模型 - 确保路径正确
from orders.models import Order from orders.models import Order
from users.models import UserDashou, UserShangjia from users.models import UserDashou, UserShangjia
from gvsdsdk.models import User from users.business_models import User
from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure
from gvsdsdk.fluent import db, func, FQ from gvsdsdk.fluent import db, func, FQ

View File

@@ -63,7 +63,7 @@ from orders.models import (
) )
from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai
from users.models import UserDashou, UserShangjia, UserBoss from users.models import UserDashou, UserShangjia, UserBoss
from gvsdsdk.models import User from users.business_models import User
from rank.models import DashouBiaoxian, Chenghao, DingdanBiaoqian, YonghuChenghao from rank.models import DashouBiaoxian, Chenghao, DingdanBiaoqian, YonghuChenghao
from config.models import ( from config.models import (
Szjilu, ShangjiaLianjie Szjilu, ShangjiaLianjie

View File

@@ -48,7 +48,7 @@ from .models import (
from users.models import ( from users.models import (
AdminProfile, UserDashou, UserGuanshi, UserZuzhang, UserShangjia AdminProfile, UserDashou, UserGuanshi, UserZuzhang, UserShangjia
) )
from gvsdsdk.models import User from users.business_models import User
from orders.models import CommissionRate from orders.models import CommissionRate
from config.models import Szjilu, Gonggao, Lunbo from config.models import Szjilu, Gonggao, Lunbo

View File

@@ -13,7 +13,7 @@ from .models import (
) )
## users应用 ## users应用
from users.models import UserShenheguan, UserDashou from users.models import UserShenheguan, UserDashou
from gvsdsdk.models import User from users.business_models import User
## orders应用 ## orders应用
from .models import YonghuChenghao from .models import YonghuChenghao
# 日志对象 # 日志对象

View File

@@ -12,7 +12,7 @@ from .models import (
KaoheguanBankuai, Bankuai, ShenheJilu, KaoheJiluFeiyong KaoheguanBankuai, Bankuai, ShenheJilu, KaoheJiluFeiyong
) )
from users.models import UserShenheguan, UserDashou from users.models import UserShenheguan, UserDashou
from gvsdsdk.models import User from users.business_models import User
from products.models import ShangpinLeixing from products.models import ShangpinLeixing

View File

@@ -148,7 +148,7 @@ class DianpuShouzhiMeiriTongji(QModel):
class YonghuDianpuBangding(QModel): class YonghuDianpuBangding(QModel):
id = models.AutoField(primary_key=True, verbose_name='绑定自增ID') id = models.AutoField(primary_key=True, verbose_name='绑定自增ID')
yonghu = models.ForeignKey( yonghu = models.ForeignKey(
'gvsdsdk.User', 'users.User',
on_delete=models.CASCADE, on_delete=models.CASCADE,
db_column='UserUUID', db_column='UserUUID',
db_index=True, db_index=True,

View File

@@ -43,7 +43,7 @@ from backend.utils import update_dashou_daily_by_action
from .models import YonghuPingzheng, Dianpu, DianpuShouzhiMeiriTongji from .models import YonghuPingzheng, Dianpu, DianpuShouzhiMeiriTongji
from users.models import UserDashou, UserShangjia, UserGuanshi, UserZuzhang from users.models import UserDashou, UserShangjia, UserGuanshi, UserZuzhang
from gvsdsdk.models import User from users.business_models import User
from shop.models import YonghuDianpuBangding, ShangpinLeixingDianpu, DianpuShangpinShenheShezhi from shop.models import YonghuDianpuBangding, ShangpinLeixingDianpu, DianpuShangpinShenheShezhi

171
users/business_models.py Normal file
View File

@@ -0,0 +1,171 @@
"""业务用户模型——继承 SDK 抽象基类,添加本服务业务字段和方法
本文件位于 users app业务层不属于 gvsdsdk SDK 包。
User 类继承自 gvsdsdk.models.User抽象基类添加业务字段和方法。
业务字段:
- UserUID用户业务ID7位
- OpenID / UnionID微信认证字段
- Avatar头像路径
- Phone / PhoneVerified手机号及认证状态
- IP来访用户IP
- IsStaff / IsSuperuserDjango auth 框架必需
业务方法:
- UserType通过 UserRole 推断用户类型admin/kefu/guanshi/...
- PaymentQRCode / PaymentAccount收款信息存于 UserSensitiveData
- HasRole检查用户是否拥有指定角色
"""
import datetime as _datetime
from django.db import models
from gvsdsdk.models import User as _UserBase, UserManager
from gvsdsdk.models import UserRole, Role
class User(_UserBase):
"""业务用户表——继承 SDK 抽象 User添加本服务业务字段和方法
映射与 SDK 相同的 User 表db_table='User'),但额外包含:
- 微信认证字段OpenID, UnionID
- 业务标识字段UserUID, Avatar, Phone, IP
- Django auth 扩展字段IsStaff, IsSuperuser
- 业务方法UserType, PaymentQRCode, PaymentAccount, HasRole
"""
# === 本地业务字段 ===
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 = True
app_label = 'users'
db_table = 'User'
verbose_name = '用户'
verbose_name_plural = '用户'
indexes = [
models.Index(fields=['UserUID']),
models.Index(fields=['OpenID']),
]
# ── 用户类型推断(通过 UserRole → Role 推断,带实例缓存)──
@property
def UserType(self):
"""用户类型 — 通过 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'
# ── 收款信息(存于 UserSensitiveData──
@property
def PaymentQRCode(self):
"""收款码图片(存于 UserSensitiveData.zhifu"""
try:
return self.sensitive_data.zhifu
except Exception:
return ''
@PaymentQRCode.setter
def PaymentQRCode(self, value):
try:
sd = self.sensitive_data
sd.zhifu = value
sd.save(update_fields=['zhifu'])
except Exception:
pass
@property
def PaymentAccount(self):
"""收款账号(存于 UserSensitiveData.skzhanghao"""
try:
return self.sensitive_data.skzhanghao
except Exception:
return ''
@PaymentAccount.setter
def PaymentAccount(self, value):
try:
sd = self.sensitive_data
sd.skzhanghao = value
sd.save(update_fields=['skzhanghao'])
except Exception:
pass
# ── 关联扩展表快捷访问 ──
# DashouProfile / ShopProfile / GuanshiProfile / BossProfile /
# AdminProfile / KefuProfile / ZuzhangProfile / ShenheguanProfile
# 均由 OneToOneField related_name 直接提供反向关联访问
def HasRole(self, role_code):
"""检查用户是否拥有指定角色(支持角色名或 UserType 值)"""
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

View File

@@ -1,8 +1,11 @@
# Generated by Django 4.2.27 on 2026-06-17 16:31 # Generated by Django 4.2.27 on 2026-06-19 18:42
import datetime
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import gvsdsdk.models
import uuid
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -10,7 +13,6 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ operations = [
@@ -41,6 +43,38 @@ class Migration(migrations.Migration):
'managed': False, 'managed': False,
}, },
), ),
migrations.CreateModel(
name='User',
fields=[
('UserUUID', gvsdsdk.models.UUIDField(binary_length=16, db_column='UserUUID', default=uuid.uuid4, 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,
},
),
migrations.CreateModel( migrations.CreateModel(
name='OfficialAccountUser', name='OfficialAccountUser',
fields=[ fields=[
@@ -87,6 +121,203 @@ class Migration(migrations.Migration):
'db_table': 'xiugaijilu', 'db_table': 'xiugaijilu',
}, },
), ),
migrations.CreateModel(
name='UserZuzhang',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('yaoqingma', models.CharField(db_index=True, max_length=20, null=True, verbose_name='组长邀请码')),
('fenyong_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='分佣总额(元)')),
('ketixian_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现金额(元)')),
('yaoqing_zongshu', models.IntegerField(default=0, verbose_name='邀请总数')),
('jinri_fenyong', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日分佣(元)')),
('jinyue_fenyong', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今月分佣(元)')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态')),
('haibao_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='推广海报相对URL')),
('jinri_tixian', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日提现金额(元)')),
('last_tixian_time', models.DateTimeField(blank=True, null=True, verbose_name='最后提现时间')),
('ewai_tixian_xiane', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外提现限额(元)')),
('kaioi_ewai_tixian', models.BooleanField(default=False, verbose_name='开启额外提现')),
('kaioi_ewai_fenhong', models.BooleanField(default=False, verbose_name='开启额外分红')),
('ewai_fenhong_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外分红金额(元)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ZuzhangProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '组长扩展表',
'verbose_name_plural': '组长扩展表',
'db_table': 'user_zuzhang',
},
),
migrations.CreateModel(
name='UserShenheguan',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态')),
('shenhe_zhuangtai', models.IntegerField(choices=[(0, '空闲'), (1, '审核中')], default=0, verbose_name='审核官状态')),
('is_renzheng', models.BooleanField(default=False, verbose_name='是否认证')),
('shenhe_zongshu', models.IntegerField(default=0, verbose_name='审核总数')),
('tongguo_zongshu', models.IntegerField(default=0, verbose_name='通过总数')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='赚取总额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ShenheguanProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '审核官扩展表',
'verbose_name_plural': '审核官扩展表',
'db_table': 'user_shenheguan',
},
),
migrations.CreateModel(
name='UserShangjia',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nicheng', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='商家昵称')),
('zhuangtai', models.IntegerField(choices=[(0, '待审核'), (1, '正常'), (2, '禁用')], default=1, verbose_name='商家状态')),
('dianhua', models.CharField(max_length=20, null=True, verbose_name='商家电话')),
('wechat', models.CharField(max_length=50, null=True, verbose_name='商家微信号')),
('fabu', models.IntegerField(default=0, verbose_name='发布订单总数量')),
('tuikuan', models.IntegerField(default=0, verbose_name='退款订单总量')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家余额')),
('chengjiao', models.IntegerField(default=0, verbose_name='商家成交订单总量')),
('jinridingdan', models.IntegerField(default=0, verbose_name='商家今日订单总量')),
('jinriliushui', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家今日流水')),
('jinyuedingdan', models.IntegerField(default=0, verbose_name='商家今月订单总量')),
('jinyueliushui', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家今月流水')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ShopProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '商家扩展表',
'verbose_name_plural': '商家扩展表',
'db_table': 'user_shangjia',
},
),
migrations.CreateModel(
name='UserSensitiveData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(blank=True, max_length=200, null=True, verbose_name='密码')),
('zhifu', models.CharField(blank=True, max_length=500, null=True, verbose_name='收款码图片')),
('skzhanghao', models.CharField(blank=True, max_length=11, null=True, verbose_name='收款账号')),
('shoujihao_renzheng', models.BooleanField(default=False, verbose_name='手机号是否已认证')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user_uuid', models.OneToOneField(db_column='user_uuid_id', on_delete=django.db.models.deletion.CASCADE, related_name='sensitive_data', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '用户敏感数据',
'verbose_name_plural': '用户敏感数据',
'db_table': 'user_sensitive_data',
},
),
migrations.CreateModel(
name='UserKefu',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nicheng', models.CharField(max_length=50, verbose_name='客服昵称')),
('erjimima', models.CharField(max_length=128, verbose_name='二级密码')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='客服状态')),
('jinrichuli', models.IntegerField(default=0, verbose_name='今日处理订单数')),
('jinyuechuli', models.IntegerField(default=0, verbose_name='本月处理订单数')),
('zongchuli', models.IntegerField(default=0, verbose_name='累计处理订单数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='KefuProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '客服扩展表',
'verbose_name_plural': '客服扩展表',
'db_table': 'user_kefu',
},
),
migrations.CreateModel(
name='UserGuanshi',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('yaoqingren', models.CharField(db_index=True, max_length=7, null=True, verbose_name='邀请人ID')),
('yaoqingma', models.CharField(db_index=True, max_length=20, null=True, verbose_name='邀请码')),
('invite_qrcode_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='邀请码二维码图片URL')),
('dianhua', models.CharField(max_length=20, null=True, verbose_name='管事电话')),
('wechat', models.CharField(max_length=50, null=True, verbose_name='管事微信号')),
('yaogingshuliang', models.IntegerField(default=0, verbose_name='邀请打手总数')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='管事状态')),
('jinrichongzhi', models.IntegerField(default=0, verbose_name='今日充值打手数量')),
('jinyuechongzhi', models.IntegerField(default=0, verbose_name='今月充值打手数量')),
('chongzhifenrun', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='充值分佣总额')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('fenhong_yici', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='首次分红金额')),
('fenghong_erci_enabled', models.BooleanField(default=False, verbose_name='开启二次分红')),
('fenghong_erci', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='二次分红金额')),
('last_tixian_date', models.DateField(blank=True, null=True, verbose_name='最近提现日期')),
('jinritixian_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日已提现金额')),
('kaioi_ewai_xiane', models.BooleanField(default=False, verbose_name='是否开启额外提现限额')),
('ewai_xiane', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外提现限额(元)')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='GuanshiProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '管事扩展表',
'verbose_name_plural': '管事扩展表',
'db_table': 'user_guanshi',
},
),
migrations.CreateModel(
name='UserDashou',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nicheng', models.CharField(max_length=50, null=True, verbose_name='打手昵称')),
('chenghao', models.CharField(max_length=50, null=True, verbose_name='打手称号')),
('zhuangtai', models.IntegerField(default=1, verbose_name='打手状态')),
('zaixianzhuangtai', models.IntegerField(default=1, verbose_name='打手在线状态')),
('zhanghaozhuangtai', models.IntegerField(default=1, verbose_name='打手账号状态')),
('jieshao', models.TextField(null=True, verbose_name='打手介绍')),
('jiedanzongliang', models.IntegerField(default=0, verbose_name='接单总量')),
('chengjiaozongliang', models.IntegerField(default=0, verbose_name='成交单总量')),
('tuikuanliang', models.IntegerField(default=0, verbose_name='退款订单总量')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='打单赚取总额')),
('dianhua', models.CharField(max_length=20, null=True, verbose_name='打手电话')),
('wechat', models.CharField(max_length=50, null=True, verbose_name='打手微信号')),
('yaoqingren', models.CharField(db_index=True, max_length=7, null=True, verbose_name='邀请人ID')),
('jinrijiedan', models.IntegerField(default=0, verbose_name='今日接单数量')),
('jinrishouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日收益金额')),
('jinyuejiedan', models.IntegerField(default=0, verbose_name='今月接单数量')),
('jinyueshouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今月收益金额')),
('jifen', models.IntegerField(default=0, verbose_name='打手积分')),
('yajin', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='打手押金')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('last_tixian_date', models.DateField(blank=True, null=True, verbose_name='最近提现日期')),
('jinritixian_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日已提现金额')),
('kaioi_ewai_xiane', models.BooleanField(default=False, verbose_name='是否开启额外提现限额')),
('ewai_xiane', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外提现限额(元)')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='DashouProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '打手扩展表',
'verbose_name_plural': '打手扩展表',
'db_table': 'user_dashou',
},
),
migrations.CreateModel(
name='UserBoss',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nickname', models.CharField(max_length=50, verbose_name='老板昵称')),
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='消费总额')),
('alldingdan', models.IntegerField(default=0, verbose_name='订单总数')),
('alltui', models.IntegerField(default=0, verbose_name='退款总数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='BossProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '老板扩展表',
'verbose_name_plural': '老板扩展表',
'db_table': 'user_boss',
},
),
migrations.CreateModel( migrations.CreateModel(
name='TixianShenheJilu', name='TixianShenheJilu',
fields=[ fields=[
@@ -192,211 +423,6 @@ class Migration(migrations.Migration):
'unique_together': {('zhouqi', 'tongji_date', 'shenfen', 'paiming')}, 'unique_together': {('zhouqi', 'tongji_date', 'shenfen', 'paiming')},
}, },
), ),
migrations.CreateModel(
name='UserZuzhang',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('yaoqingma', models.CharField(db_index=True, max_length=20, null=True, verbose_name='组长邀请码')),
('fenyong_zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='分佣总额(元)')),
('ketixian_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现金额(元)')),
('yaoqing_zongshu', models.IntegerField(default=0, verbose_name='邀请总数')),
('jinri_fenyong', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日分佣(元)')),
('jinyue_fenyong', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今月分佣(元)')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态')),
('haibao_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='推广海报相对URL')),
('jinri_tixian', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日提现金额(元)')),
('last_tixian_time', models.DateTimeField(blank=True, null=True, verbose_name='最后提现时间')),
('ewai_tixian_xiane', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外提现限额(元)')),
('kaioi_ewai_tixian', models.BooleanField(default=False, verbose_name='开启额外提现')),
('kaioi_ewai_fenhong', models.BooleanField(default=False, verbose_name='开启额外分红')),
('ewai_fenhong_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外分红金额(元)')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='zuzhang_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '组长扩展表',
'verbose_name_plural': '组长扩展表',
'db_table': 'user_zuzhang',
'indexes': [models.Index(fields=['user'], name='user_zuzhan_UserUUI_125e05_idx'), models.Index(fields=['yaoqingma'], name='user_zuzhan_yaoqing_cba91d_idx')],
},
),
migrations.CreateModel(
name='UserShenheguan',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态')),
('shenhe_zhuangtai', models.IntegerField(choices=[(0, '空闲'), (1, '审核中')], default=0, verbose_name='审核官状态')),
('is_renzheng', models.BooleanField(default=False, verbose_name='是否认证')),
('shenhe_zongshu', models.IntegerField(default=0, verbose_name='审核总数')),
('tongguo_zongshu', models.IntegerField(default=0, verbose_name='通过总数')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='赚取总额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='shenheguan_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '审核官扩展表',
'verbose_name_plural': '审核官扩展表',
'db_table': 'user_shenheguan',
'indexes': [models.Index(fields=['user'], name='user_shenhe_UserUUI_bdc981_idx')],
},
),
migrations.CreateModel(
name='UserShangjia',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nicheng', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='商家昵称')),
('zhuangtai', models.IntegerField(choices=[(0, '待审核'), (1, '正常'), (2, '禁用')], default=1, verbose_name='商家状态')),
('dianhua', models.CharField(max_length=20, null=True, verbose_name='商家电话')),
('wechat', models.CharField(max_length=50, null=True, verbose_name='商家微信号')),
('fabu', models.IntegerField(default=0, verbose_name='发布订单总数量')),
('tuikuan', models.IntegerField(default=0, verbose_name='退款订单总量')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家余额')),
('chengjiao', models.IntegerField(default=0, verbose_name='商家成交订单总量')),
('jinridingdan', models.IntegerField(default=0, verbose_name='商家今日订单总量')),
('jinriliushui', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家今日流水')),
('jinyuedingdan', models.IntegerField(default=0, verbose_name='商家今月订单总量')),
('jinyueliushui', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='商家今月流水')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='shop_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '商家扩展表',
'verbose_name_plural': '商家扩展表',
'db_table': 'user_shangjia',
'indexes': [models.Index(fields=['user'], name='user_shangj_UserUUI_9d7fad_idx'), models.Index(fields=['nicheng'], name='user_shangj_nicheng_6967bc_idx')],
},
),
migrations.CreateModel(
name='UserSensitiveData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(blank=True, max_length=200, null=True, verbose_name='密码')),
('zhifu', models.CharField(blank=True, max_length=500, null=True, verbose_name='收款码图片')),
('skzhanghao', models.CharField(blank=True, max_length=11, null=True, verbose_name='收款账号')),
('shoujihao_renzheng', models.BooleanField(default=False, verbose_name='手机号是否已认证')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user_uuid', models.OneToOneField(db_column='user_uuid_id', on_delete=django.db.models.deletion.CASCADE, related_name='sensitive_data', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '用户敏感数据',
'verbose_name_plural': '用户敏感数据',
'db_table': 'user_sensitive_data',
'indexes': [models.Index(fields=['user_uuid'], name='user_sensit_user_uu_1d562f_idx')],
},
),
migrations.CreateModel(
name='UserKefu',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nicheng', models.CharField(max_length=50, verbose_name='客服昵称')),
('erjimima', models.CharField(max_length=128, verbose_name='二级密码')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='客服状态')),
('jinrichuli', models.IntegerField(default=0, verbose_name='今日处理订单数')),
('jinyuechuli', models.IntegerField(default=0, verbose_name='本月处理订单数')),
('zongchuli', models.IntegerField(default=0, verbose_name='累计处理订单数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='kefu_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '客服扩展表',
'verbose_name_plural': '客服扩展表',
'db_table': 'user_kefu',
'indexes': [models.Index(fields=['user'], name='user_kefu_UserUUI_ccf71c_idx'), models.Index(fields=['zhuangtai'], name='user_kefu_zhuangt_317491_idx')],
},
),
migrations.CreateModel(
name='UserGuanshi',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('yaoqingren', models.CharField(db_index=True, max_length=7, null=True, verbose_name='邀请人ID')),
('yaoqingma', models.CharField(db_index=True, max_length=20, null=True, verbose_name='邀请码')),
('invite_qrcode_url', models.CharField(blank=True, max_length=500, null=True, verbose_name='邀请码二维码图片URL')),
('dianhua', models.CharField(max_length=20, null=True, verbose_name='管事电话')),
('wechat', models.CharField(max_length=50, null=True, verbose_name='管事微信号')),
('yaogingshuliang', models.IntegerField(default=0, verbose_name='邀请打手总数')),
('zhuangtai', models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='管事状态')),
('jinrichongzhi', models.IntegerField(default=0, verbose_name='今日充值打手数量')),
('jinyuechongzhi', models.IntegerField(default=0, verbose_name='今月充值打手数量')),
('chongzhifenrun', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='充值分佣总额')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('fenhong_yici', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='首次分红金额')),
('fenghong_erci_enabled', models.BooleanField(default=False, verbose_name='开启二次分红')),
('fenghong_erci', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='二次分红金额')),
('last_tixian_date', models.DateField(blank=True, null=True, verbose_name='最近提现日期')),
('jinritixian_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日已提现金额')),
('kaioi_ewai_xiane', models.BooleanField(default=False, verbose_name='是否开启额外提现限额')),
('ewai_xiane', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外提现限额(元)')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='guanshi_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '管事扩展表',
'verbose_name_plural': '管事扩展表',
'db_table': 'user_guanshi',
'indexes': [models.Index(fields=['user'], name='user_guansh_UserUUI_1d9453_idx'), models.Index(fields=['yaoqingma'], name='user_guansh_yaoqing_21d1d4_idx')],
},
),
migrations.CreateModel(
name='UserDashou',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nicheng', models.CharField(max_length=50, null=True, verbose_name='打手昵称')),
('chenghao', models.CharField(max_length=50, null=True, verbose_name='打手称号')),
('zhuangtai', models.IntegerField(default=1, verbose_name='打手状态')),
('zaixianzhuangtai', models.IntegerField(default=1, verbose_name='打手在线状态')),
('zhanghaozhuangtai', models.IntegerField(default=1, verbose_name='打手账号状态')),
('jieshao', models.TextField(null=True, verbose_name='打手介绍')),
('jiedanzongliang', models.IntegerField(default=0, verbose_name='接单总量')),
('chengjiaozongliang', models.IntegerField(default=0, verbose_name='成交单总量')),
('tuikuanliang', models.IntegerField(default=0, verbose_name='退款订单总量')),
('yue', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='可提现余额')),
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='打单赚取总额')),
('dianhua', models.CharField(max_length=20, null=True, verbose_name='打手电话')),
('wechat', models.CharField(max_length=50, null=True, verbose_name='打手微信号')),
('yaoqingren', models.CharField(db_index=True, max_length=7, null=True, verbose_name='邀请人ID')),
('jinrijiedan', models.IntegerField(default=0, verbose_name='今日接单数量')),
('jinrishouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日收益金额')),
('jinyuejiedan', models.IntegerField(default=0, verbose_name='今月接单数量')),
('jinyueshouyi', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今月收益金额')),
('jifen', models.IntegerField(default=0, verbose_name='打手积分')),
('yajin', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='打手押金')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('last_tixian_date', models.DateField(blank=True, null=True, verbose_name='最近提现日期')),
('jinritixian_jine', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='今日已提现金额')),
('kaioi_ewai_xiane', models.BooleanField(default=False, verbose_name='是否开启额外提现限额')),
('ewai_xiane', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='额外提现限额(元)')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='dashou_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '打手扩展表',
'verbose_name_plural': '打手扩展表',
'db_table': 'user_dashou',
'indexes': [models.Index(fields=['user'], name='user_dashou_UserUUI_92ac5a_idx'), models.Index(fields=['yaoqingren'], name='user_dashou_yaoqing_894658_idx')],
},
),
migrations.CreateModel(
name='UserBoss',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nickname', models.CharField(max_length=50, verbose_name='老板昵称')),
('zonge', models.DecimalField(decimal_places=2, default=0.0, max_digits=12, verbose_name='消费总额')),
('alldingdan', models.IntegerField(default=0, verbose_name='订单总数')),
('alltui', models.IntegerField(default=0, verbose_name='退款总数')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='boss_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
],
options={
'verbose_name': '老板扩展表',
'verbose_name_plural': '老板扩展表',
'db_table': 'user_boss',
'indexes': [models.Index(fields=['user'], name='user_boss_UserUUI_4579c2_idx')],
},
),
migrations.CreateModel( migrations.CreateModel(
name='AdminProfile', name='AdminProfile',
fields=[ fields=[
@@ -405,13 +431,76 @@ class Migration(migrations.Migration):
('wechat', models.CharField(blank=True, max_length=50, verbose_name='管理员微信')), ('wechat', models.CharField(blank=True, max_length=50, verbose_name='管理员微信')),
('yaoqingma', models.CharField(db_index=True, max_length=20, null=True, verbose_name='管理员邀请码')), ('yaoqingma', models.CharField(db_index=True, max_length=20, null=True, verbose_name='管理员邀请码')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='admin_profile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')), ('user', models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='AdminProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户')),
], ],
options={ options={
'verbose_name': '管理员扩展表', 'verbose_name': '管理员扩展表',
'verbose_name_plural': '管理员扩展表', 'verbose_name_plural': '管理员扩展表',
'db_table': 'admin_profile', 'db_table': 'admin_profile',
'indexes': [models.Index(fields=['user'], name='admin_profi_UserUUI_0699ce_idx')],
}, },
), ),
migrations.AddIndex(
model_name='user',
index=models.Index(fields=['UserUID'], name='User_UserUID_a656ea_idx'),
),
migrations.AddIndex(
model_name='user',
index=models.Index(fields=['OpenID'], name='User_OpenID_2a920d_idx'),
),
migrations.AddIndex(
model_name='userzuzhang',
index=models.Index(fields=['user'], name='user_zuzhan_UserUUI_125e05_idx'),
),
migrations.AddIndex(
model_name='userzuzhang',
index=models.Index(fields=['yaoqingma'], name='user_zuzhan_yaoqing_cba91d_idx'),
),
migrations.AddIndex(
model_name='usershenheguan',
index=models.Index(fields=['user'], name='user_shenhe_UserUUI_bdc981_idx'),
),
migrations.AddIndex(
model_name='usershangjia',
index=models.Index(fields=['user'], name='user_shangj_UserUUI_9d7fad_idx'),
),
migrations.AddIndex(
model_name='usershangjia',
index=models.Index(fields=['nicheng'], name='user_shangj_nicheng_6967bc_idx'),
),
migrations.AddIndex(
model_name='usersensitivedata',
index=models.Index(fields=['user_uuid'], name='user_sensit_user_uu_1d562f_idx'),
),
migrations.AddIndex(
model_name='userkefu',
index=models.Index(fields=['user'], name='user_kefu_UserUUI_ccf71c_idx'),
),
migrations.AddIndex(
model_name='userkefu',
index=models.Index(fields=['zhuangtai'], name='user_kefu_zhuangt_317491_idx'),
),
migrations.AddIndex(
model_name='userguanshi',
index=models.Index(fields=['user'], name='user_guansh_UserUUI_1d9453_idx'),
),
migrations.AddIndex(
model_name='userguanshi',
index=models.Index(fields=['yaoqingma'], name='user_guansh_yaoqing_21d1d4_idx'),
),
migrations.AddIndex(
model_name='userdashou',
index=models.Index(fields=['user'], name='user_dashou_UserUUI_92ac5a_idx'),
),
migrations.AddIndex(
model_name='userdashou',
index=models.Index(fields=['yaoqingren'], name='user_dashou_yaoqing_894658_idx'),
),
migrations.AddIndex(
model_name='userboss',
index=models.Index(fields=['user'], name='user_boss_UserUUI_4579c2_idx'),
),
migrations.AddIndex(
model_name='adminprofile',
index=models.Index(fields=['user'], name='admin_profi_UserUUI_0699ce_idx'),
),
] ]

View File

@@ -1,56 +0,0 @@
# Generated by Django 4.2.27 on 2026-06-19 01:08
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('users', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='adminprofile',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='AdminProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='userboss',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='BossProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='userdashou',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='DashouProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='userguanshi',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='GuanshiProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='userkefu',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='KefuProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='usershangjia',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ShopProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='usershenheguan',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ShenheguanProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='userzuzhang',
name='user',
field=models.OneToOneField(db_column='UserUUID', on_delete=django.db.models.deletion.CASCADE, related_name='ZuzhangProfile', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
]

View File

@@ -91,7 +91,7 @@ class OfficialAccountUser(QModel):
# ==================== 老板扩展表 ==================== # ==================== 老板扩展表 ====================
class UserBoss(QModel): class UserBoss(QModel):
user = models.OneToOneField('gvsdsdk.User', on_delete=models.CASCADE, related_name='BossProfile', user = models.OneToOneField('users.User', on_delete=models.CASCADE, related_name='BossProfile',
verbose_name='关联用户', db_column='UserUUID') verbose_name='关联用户', db_column='UserUUID')
nickname = models.CharField(max_length=50, verbose_name='老板昵称') nickname = models.CharField(max_length=50, verbose_name='老板昵称')
zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='消费总额') zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='消费总额')
@@ -108,7 +108,7 @@ class UserBoss(QModel):
# ==================== 打手扩展表 ==================== # ==================== 打手扩展表 ====================
class UserDashou(QModel): class UserDashou(QModel):
user = models.OneToOneField('gvsdsdk.User', on_delete=models.CASCADE, related_name='DashouProfile', user = models.OneToOneField('users.User', on_delete=models.CASCADE, related_name='DashouProfile',
verbose_name='关联用户', db_column='UserUUID') verbose_name='关联用户', db_column='UserUUID')
nicheng = models.CharField(max_length=50, null=True, verbose_name='打手昵称') nicheng = models.CharField(max_length=50, null=True, verbose_name='打手昵称')
chenghao = models.CharField(max_length=50, null=True,verbose_name='打手称号') chenghao = models.CharField(max_length=50, null=True,verbose_name='打手称号')
@@ -152,7 +152,7 @@ class UserDashou(QModel):
# ==================== 商家扩展表 ==================== # ==================== 商家扩展表 ====================
class UserShangjia(QModel): class UserShangjia(QModel):
user = models.OneToOneField('gvsdsdk.User', on_delete=models.CASCADE, related_name='ShopProfile', user = models.OneToOneField('users.User', on_delete=models.CASCADE, related_name='ShopProfile',
verbose_name='关联用户', db_column='UserUUID') verbose_name='关联用户', db_column='UserUUID')
nicheng = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='商家昵称') nicheng = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='商家昵称')
zhuangtai = models.IntegerField(choices=[(0, '待审核'), (1, '正常'), (2, '禁用')], default=1, zhuangtai = models.IntegerField(choices=[(0, '待审核'), (1, '正常'), (2, '禁用')], default=1,
@@ -181,7 +181,7 @@ class UserShangjia(QModel):
# ==================== 管事扩展表 ==================== # ==================== 管事扩展表 ====================
class UserGuanshi(QModel): class UserGuanshi(QModel):
user = models.OneToOneField('gvsdsdk.User', on_delete=models.CASCADE, related_name='GuanshiProfile', user = models.OneToOneField('users.User', on_delete=models.CASCADE, related_name='GuanshiProfile',
verbose_name='关联用户', db_column='UserUUID') verbose_name='关联用户', db_column='UserUUID')
yaoqingren = models.CharField(max_length=7,null=True, db_index=True, verbose_name='邀请人ID') yaoqingren = models.CharField(max_length=7,null=True, db_index=True, verbose_name='邀请人ID')
yaoqingma = models.CharField(max_length=20,null=True,db_index=True, verbose_name='邀请码') yaoqingma = models.CharField(max_length=20,null=True,db_index=True, verbose_name='邀请码')
@@ -224,7 +224,7 @@ class UserGuanshi(QModel):
class UserZuzhang(QModel): class UserZuzhang(QModel):
"""组长扩展表与UserMain一对一关联""" """组长扩展表与UserMain一对一关联"""
user = models.OneToOneField( user = models.OneToOneField(
'gvsdsdk.User', 'users.User',
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name='ZuzhangProfile', related_name='ZuzhangProfile',
verbose_name='关联用户', verbose_name='关联用户',
@@ -278,7 +278,7 @@ class UserZuzhang(QModel):
class UserShenheguan(QModel): class UserShenheguan(QModel):
"""审核官扩展表与UserMain一对一关联""" """审核官扩展表与UserMain一对一关联"""
user = models.OneToOneField('gvsdsdk.User', on_delete=models.CASCADE, related_name='ShenheguanProfile', verbose_name='关联用户', db_index=True, db_column='UserUUID') user = models.OneToOneField('users.User', on_delete=models.CASCADE, related_name='ShenheguanProfile', verbose_name='关联用户', db_index=True, db_column='UserUUID')
zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态') zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态')
shenhe_zhuangtai = models.IntegerField(choices=[(0, '空闲'), (1, '审核中')], default=0, verbose_name='审核官状态') shenhe_zhuangtai = models.IntegerField(choices=[(0, '空闲'), (1, '审核中')], default=0, verbose_name='审核官状态')
is_renzheng = models.BooleanField(default=False, verbose_name='是否认证') is_renzheng = models.BooleanField(default=False, verbose_name='是否认证')
@@ -298,7 +298,7 @@ class UserShenheguan(QModel):
# ==================== 管理员扩展表 ==================== # ==================== 管理员扩展表 ====================
class AdminProfile(QModel): class AdminProfile(QModel):
user = models.OneToOneField('gvsdsdk.User', on_delete=models.CASCADE, related_name='AdminProfile', user = models.OneToOneField('users.User', on_delete=models.CASCADE, related_name='AdminProfile',
verbose_name='关联用户', db_column='UserUUID') verbose_name='关联用户', db_column='UserUUID')
password = models.CharField(max_length=255, verbose_name='密码') password = models.CharField(max_length=255, verbose_name='密码')
wechat = models.CharField(max_length=50, blank=True, verbose_name='管理员微信') wechat = models.CharField(max_length=50, blank=True, verbose_name='管理员微信')
@@ -313,7 +313,7 @@ class AdminProfile(QModel):
class UserKefu(QModel): class UserKefu(QModel):
user = models.OneToOneField('gvsdsdk.User', on_delete=models.CASCADE, related_name='KefuProfile', verbose_name='关联用户', db_column='UserUUID') user = models.OneToOneField('users.User', on_delete=models.CASCADE, related_name='KefuProfile', verbose_name='关联用户', db_column='UserUUID')
nicheng = models.CharField(max_length=50, verbose_name='客服昵称') nicheng = models.CharField(max_length=50, verbose_name='客服昵称')
erjimima = models.CharField(max_length=128, verbose_name='二级密码') erjimima = models.CharField(max_length=128, verbose_name='二级密码')
zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='客服状态') zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='客服状态')
@@ -604,7 +604,7 @@ class RankingRecord(QModel):
class UserSensitiveData(QModel): class UserSensitiveData(QModel):
"""用户敏感数据表——独立存储敏感信息,不继承 gvsdsdk""" """用户敏感数据表——独立存储敏感信息,不继承 gvsdsdk"""
user_uuid = models.OneToOneField( user_uuid = models.OneToOneField(
'gvsdsdk.User', 'users.User',
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name='sensitive_data', related_name='sensitive_data',
verbose_name='关联用户', verbose_name='关联用户',
@@ -627,3 +627,9 @@ class UserSensitiveData(QModel):
return f'敏感数据-{self.user_uuid_id}' return f'敏感数据-{self.user_uuid_id}'
# === 业务用户模型注册 ===
# 导入业务子类,使 Django app registry 注册具体 User 模型users.User
# 放在文件末尾以避免循环导入:此时本模块所有类已定义完毕。
from users.business_models import User as _BusinessUser # noqa: E402,F401

View File

@@ -18,7 +18,7 @@ from backend.models import (
MerchantDailyStats, MerchantDailyStats,
) )
from users.models import UserDashou, UserShangjia, UserBoss, UserGuanshi from users.models import UserDashou, UserShangjia, UserBoss, UserGuanshi
from gvsdsdk.models import User from users.business_models import User
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -15,7 +15,7 @@ from users.models import (
UserDashou, UserShangjia, UserGuanshi, UserBoss, UserDashou, UserShangjia, UserGuanshi, UserBoss,
RankingRecord RankingRecord
) )
from gvsdsdk.models import User from users.business_models import User
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -45,7 +45,7 @@ from .models import (
UserShangjia, UserShangjia,
UserZuzhang, UserZuzhang,
) )
from gvsdsdk.models import User from users.business_models import User
from orders.utils import update_daily_payout from orders.utils import update_daily_payout

View File

@@ -65,7 +65,7 @@ from .models import (
TixianAutoRecord, TixianShenheJilu, Tixianjilu, Xiugaijilu, TixianAutoRecord, TixianShenheJilu, Tixianjilu, Xiugaijilu,
RankingRecord RankingRecord
) )
from gvsdsdk.models import User from users.business_models import User
from .tixian_shenhe_services import ( from .tixian_shenhe_services import (
load_audit_meta_map, refund_balance, sync_audit_and_jilu_status, load_audit_meta_map, refund_balance, sync_audit_and_jilu_status,
mark_transfer_success, release_collect_quota_for_record, mark_transfer_success, release_collect_quota_for_record,
@@ -219,7 +219,7 @@ class WechatMiniProgramLoginView(APIView):
if created: if created:
UserBoss.query.create(user=user_main, nickname='板板大人') UserBoss.query.create(user=user_main, nickname='板板大人')
# 新用户默认分配消费者角色 # 新用户默认分配消费者角色
from gvsdsdk.models import UserRole, Role from users.business_models import UserRole, Role
normal_role = Role.objects.filter(RoleName='消费者').first() normal_role = Role.objects.filter(RoleName='消费者').first()
if normal_role: if normal_role:
UserRole.objects.create( UserRole.objects.create(

View File

@@ -5,7 +5,7 @@ import requests
from django.conf import settings from django.conf import settings
from orders.models import Order, PlatformOrderExt, MerchantOrderExt from orders.models import Order, PlatformOrderExt, MerchantOrderExt
from users.models import UserDashou, UserBoss, UserShangjia from users.models import UserDashou, UserBoss, UserShangjia
from gvsdsdk.models import User from users.business_models import User
logger = logging.getLogger('chat_utils') logger = logging.getLogger('chat_utils')