models.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. # coding=utf-8
  2. from django.db import models
  3. from django.db.models import Q
  4. from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager, Group, AbstractUser
  5. from django.utils import timezone
  6. from rest_framework.utils import model_meta
  7. from utils.exceptions import CustomError
  8. from django.conf import settings
  9. from utils.wx.WXBizDataCrypt import WXBizDataCrypt
  10. from utils.wx.wechat import WeChat
  11. from apps.WechatApplet.models import WechatApplet
  12. class UserManager(BaseUserManager):
  13. def create_superuser(self, username, password, **extra_fields):
  14. u = self.create_user(User.EMPLOYEE, username, password, **extra_fields)
  15. u.is_active = True
  16. u.is_superuser = True
  17. u.save(using=self._db)
  18. return u
  19. def create_user(self, type, username, password=None, **extra_fields):
  20. if not username:
  21. raise CustomError(u'请输入账号!')
  22. count = User.objects.filter(username=username).count()
  23. if count > 0:
  24. raise CustomError(u'该账号已存在!')
  25. user = self.model(
  26. type=type,
  27. username=username,
  28. is_superuser=False,
  29. last_login=timezone.now(),
  30. **extra_fields
  31. )
  32. user.set_password(password)
  33. user.save(using=self._db)
  34. return user
  35. class User(AbstractBaseUser, PermissionsMixin):
  36. EMPLOYEE = 1
  37. SELLER = 2
  38. CUSTOMER = 3
  39. TYPE_CHOICES = (
  40. (EMPLOYEE, u'管理者'), # 内部员工
  41. (SELLER, u'业务员'), # 客户
  42. (CUSTOMER, u'客户'), # 客户
  43. )
  44. username = models.CharField(verbose_name=u'用户名', max_length=30, db_index=True,unique=True,
  45. help_text=u'不多于20个字符。只能用字母、数字和字符。')
  46. # password = models.CharField(u'密码', max_length=128, blank=True,)
  47. is_active = models.BooleanField(verbose_name=u'是否可用', default=True, editable=False)
  48. date_joined = models.DateTimeField(verbose_name=u'注册时间', auto_now_add=True, editable=False)
  49. type = models.PositiveSmallIntegerField(verbose_name=u"类型", choices=TYPE_CHOICES, default=CUSTOMER)
  50. name = models.CharField(max_length=20, verbose_name=u"姓名")
  51. gender = models.PositiveSmallIntegerField(choices=settings.GENDER_CHOICES, verbose_name=u"性别",
  52. default=settings.MALE)
  53. face = models.CharField(max_length=200, verbose_name=u'头像', null=True)
  54. tel = models.CharField(max_length=15, verbose_name=u"手机", null=True, )
  55. ID_card = models.CharField(max_length=18, verbose_name=u"身份证号", null=True, blank=True)
  56. address = models.CharField(max_length=100, verbose_name=u"家庭住址", null=True, blank=True)
  57. position = models.CharField(max_length=15, verbose_name=u"岗位", null=True)
  58. create_user = models.ForeignKey('self', verbose_name='创建者', null=True, on_delete=models.PROTECT)
  59. manager_users = models.CharField(max_length=200, verbose_name=u'管理人员', null=True, blank=True, )
  60. objects = UserManager()
  61. USERNAME_FIELD = 'username'
  62. REQUIRED_FIELDS = []
  63. class Meta:
  64. db_table = "auth_user"
  65. verbose_name = u"人员管理"
  66. unique_together = [
  67. ('username')
  68. ]
  69. ordering = ['-id']
  70. default_permissions = ()
  71. permissions = [
  72. ]
  73. def __unicode__(self):
  74. return self.username
  75. def change_password(self, new_password, confirm_password, old_password):
  76. if new_password != confirm_password:
  77. raise CustomError(u'两次输入的密码不一致,请检查')
  78. if not self.check_password(old_password):
  79. raise CustomError(u'原密码输入错误,请检查')
  80. self.set_password(new_password)
  81. self.save()
  82. def update_item(self, validated_data):
  83. def update():
  84. info = model_meta.get_field_info(self)
  85. for attr, value in validated_data.items():
  86. if attr in info.relations and info.relations[attr].to_many:
  87. field = getattr(self, attr)
  88. field.set(value)
  89. else:
  90. setattr(self, attr, value)
  91. if not 'username' in validated_data:
  92. raise CustomError(u'账号不能为空!')
  93. count = User.objects.filter(username=validated_data['username']).exclude(id=self.id).count()
  94. if count > 0:
  95. raise CustomError(u'该账号已存在!')
  96. if not 'password' in validated_data or not validated_data['password']:
  97. validated_data['password'] = self.password
  98. update()
  99. else:
  100. update()
  101. self.set_password(validated_data['password'])
  102. self.save()
  103. return self
  104. def is_login(self):
  105. if self.is_authenticated and self:
  106. return True
  107. return False
  108. def get_manager_users(self):
  109. if self.is_superuser:
  110. users = User.objects.filter(is_active=True)
  111. elif self.manager_users:
  112. users = User.objects.filter(id__in=self.manager_users.split(','), is_active=True)
  113. else:
  114. return [self.id]
  115. return users.values_list('id', flat=True)
  116. class CustomerWechat(models.Model):
  117. wechat_app = models.ForeignKey(WechatApplet, verbose_name=u'小程序', on_delete=models.PROTECT, editable=False)
  118. customer = models.ForeignKey(User, verbose_name=u'用户', on_delete=models.PROTECT, editable=False, null=True)
  119. openid = models.CharField(max_length=512, verbose_name=u"openid")
  120. session_key = models.CharField(max_length=512, verbose_name=u'session_key', null=True)
  121. # 保存客户+小程序的关联信息。如果一个客户登录多个小程序,这里会有多条数据
  122. class Meta:
  123. db_table = 'customer_wechat'
  124. verbose_name = u'微信客户'
  125. unique_together = [
  126. ('openid', 'wechat_app')
  127. ]
  128. default_permissions = ()
  129. @staticmethod
  130. def login(code, appid):
  131. wechat_applet = WechatApplet.getByAppid(appid)
  132. res = WeChat.code2Session(appid, wechat_applet.secret, code)
  133. instance = CustomerWechat.objects.filter(openid=res['openid'], wechat_app__authorizer_appid=appid).first()
  134. if not instance:
  135. instance = CustomerWechat.objects.create(
  136. wechat_app=wechat_applet,
  137. openid=res['openid'],
  138. session_key=res['session_key']
  139. )
  140. else:
  141. instance.session_key = res['session_key']
  142. instance.save()
  143. return instance
  144. @staticmethod
  145. def bindWechat(appid, openid, phoneEncryptedData, phoneIv):
  146. customer_wechat = CustomerWechat.objects.filter(openid=openid, wechat_app__authorizer_appid=appid).first()
  147. if not customer_wechat:
  148. raise CustomError(u'未找到相应的微信客户!')
  149. pc = WXBizDataCrypt(appid, customer_wechat.session_key)
  150. phon_data = pc.decrypt(phoneEncryptedData, phoneIv)
  151. tel = phon_data['purePhoneNumber']
  152. if customer_wechat.customer and customer_wechat.customer.username == tel:
  153. # 已绑定用户,且用户账号和手机号一致
  154. return customer_wechat.customer
  155. # 用户用手机号、密码登录后,在绑定微信,两个号码可能会不符
  156. # 张三是绑定用户。 张三的账号,在李四小程序上登录,绑定信息时,手机号可能不符。
  157. # 这种情况,应该返回tel对应的账号,或者创建tel账号
  158. user = User.objects.filter(username=tel).first()
  159. if not user:
  160. # 密码默认手机号
  161. user = User.objects.create_user(User.CUSTOMER, tel, password=tel,
  162. **{
  163. 'tel': tel,
  164. 'name': tel,
  165. }
  166. )
  167. customer_wechat.customer = user
  168. customer_wechat.save()
  169. return user
  170. Group.add_to_class('create_user',
  171. models.ForeignKey(User, verbose_name=u"创建人", on_delete=models.PROTECT, editable=False))