172 lines
6.9 KiB
Python
172 lines
6.9 KiB
Python
"""业务用户模型——继承 SDK 抽象基类,添加本服务业务字段和方法
|
||
|
||
本文件位于 users app(业务层),不属于 gvsdsdk SDK 包。
|
||
User 类继承自 gvsdsdk.models.User(抽象基类),添加业务字段和方法。
|
||
|
||
业务字段:
|
||
- UserUID:用户业务ID(7位)
|
||
- OpenID / UnionID:微信认证字段
|
||
- Avatar:头像路径
|
||
- Phone / PhoneVerified:手机号及认证状态
|
||
- IP:来访用户IP
|
||
- IsStaff / IsSuperuser:Django 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
|