models.py 8.2 KB

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