Files
Django/users/business_models.py

176 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""业务用户模型——继承 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='是否超级用户')
ClubID = models.CharField(
max_length=16, default='', db_column='ClubID', verbose_name='所属俱乐部',
null=True, blank=True,
)
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