123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- # coding=utf-8
- from django.db import models
- from django.db.models import Q
- from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager, Group, AbstractUser
- from django.utils import timezone
- from rest_framework.utils import model_meta
- from utils.exceptions import CustomError
- from django.conf import settings
- from utils.wx.WXBizDataCrypt import WXBizDataCrypt
- from utils.wx.wechat import WeChat
- from apps.WechatApplet.models import WechatApplet
- class UserManager(BaseUserManager):
- def create_superuser(self, username, password, **extra_fields):
- u = self.create_user(User.EMPLOYEE, username, password, **extra_fields)
- u.is_active = True
- u.is_superuser = True
- u.save(using=self._db)
- return u
- def create_user(self, type, username, password=None, **extra_fields):
- if not username:
- raise CustomError(u'请输入账号!')
- count = User.objects.filter(username=username).count()
- if count > 0:
- raise CustomError(u'该账号已存在!')
- user = self.model(
- type=type,
- username=username,
- is_superuser=False,
- last_login=timezone.now(),
- **extra_fields
- )
- user.set_password(password)
- user.save(using=self._db)
- return user
- class User(AbstractBaseUser, PermissionsMixin):
- EMPLOYEE = 1
- SELLER = 2
- CUSTOMER = 3
- TYPE_CHOICES = (
- (EMPLOYEE, u'管理者'), # 内部员工
- (SELLER, u'业务员'), # 客户
- (CUSTOMER, u'客户'), # 客户
- )
- username = models.CharField(verbose_name=u'用户名', max_length=30, db_index=True,unique=True,
- help_text=u'不多于20个字符。只能用字母、数字和字符。')
- # password = models.CharField(u'密码', max_length=128, blank=True,)
- is_active = models.BooleanField(verbose_name=u'是否可用', default=True, editable=False)
- date_joined = models.DateTimeField(verbose_name=u'注册时间', auto_now_add=True, editable=False)
- type = models.PositiveSmallIntegerField(verbose_name=u"类型", choices=TYPE_CHOICES, default=CUSTOMER)
- name = models.CharField(max_length=20, verbose_name=u"姓名")
- gender = models.PositiveSmallIntegerField(choices=settings.GENDER_CHOICES, verbose_name=u"性别",
- default=settings.MALE)
- face = models.CharField(max_length=200, verbose_name=u'头像', null=True)
- tel = models.CharField(max_length=15, verbose_name=u"手机", null=True, )
- ID_card = models.CharField(max_length=18, verbose_name=u"身份证号", null=True, blank=True)
- address = models.CharField(max_length=100, verbose_name=u"家庭住址", null=True, blank=True)
- position = models.CharField(max_length=15, verbose_name=u"岗位", null=True)
- create_user = models.ForeignKey('self', verbose_name='创建者', null=True, on_delete=models.PROTECT)
- manager_users = models.CharField(max_length=200, verbose_name=u'管理人员', null=True, blank=True, )
- objects = UserManager()
- USERNAME_FIELD = 'username'
- REQUIRED_FIELDS = []
- class Meta:
- db_table = "auth_user"
- verbose_name = u"人员管理"
- unique_together = [
- ('username')
- ]
- ordering = ['-id']
- default_permissions = ()
- permissions = [
- ]
- def __unicode__(self):
- return self.username
- def change_password(self, new_password, confirm_password, old_password):
- if new_password != confirm_password:
- raise CustomError(u'两次输入的密码不一致,请检查')
- if not self.check_password(old_password):
- raise CustomError(u'原密码输入错误,请检查')
- self.set_password(new_password)
- self.save()
- def update_item(self, validated_data):
- def update():
- info = model_meta.get_field_info(self)
- for attr, value in validated_data.items():
- if attr in info.relations and info.relations[attr].to_many:
- field = getattr(self, attr)
- field.set(value)
- else:
- setattr(self, attr, value)
- if not 'username' in validated_data:
- raise CustomError(u'账号不能为空!')
- count = User.objects.filter(username=validated_data['username']).exclude(id=self.id).count()
- if count > 0:
- raise CustomError(u'该账号已存在!')
- if not 'password' in validated_data or not validated_data['password']:
- validated_data['password'] = self.password
- update()
- else:
- update()
- self.set_password(validated_data['password'])
- self.save()
- return self
- def is_login(self):
- if self.is_authenticated and self:
- return True
- return False
- def get_manager_users(self):
- if self.is_superuser:
- users = User.objects.filter(is_active=True)
- elif self.manager_users:
- users = User.objects.filter(id__in=self.manager_users.split(','), is_active=True)
- else:
- return [self.id]
- return users.values_list('id', flat=True)
- class CustomerWechat(models.Model):
- wechat_app = models.ForeignKey(WechatApplet, verbose_name=u'小程序', on_delete=models.PROTECT, editable=False)
- customer = models.ForeignKey(User, verbose_name=u'用户', on_delete=models.PROTECT, editable=False, null=True)
- openid = models.CharField(max_length=512, verbose_name=u"openid")
- session_key = models.CharField(max_length=512, verbose_name=u'session_key', null=True)
- # 保存客户+小程序的关联信息。如果一个客户登录多个小程序,这里会有多条数据
- class Meta:
- db_table = 'customer_wechat'
- verbose_name = u'微信客户'
- unique_together = [
- ('openid', 'wechat_app')
- ]
- default_permissions = ()
- @staticmethod
- def login(code, appid):
- wechat_applet = WechatApplet.getByAppid(appid)
- res = WeChat.code2Session(appid, wechat_applet.secret, code)
- instance = CustomerWechat.objects.filter(openid=res['openid'], wechat_app__authorizer_appid=appid).first()
- if not instance:
- instance = CustomerWechat.objects.create(
- wechat_app=wechat_applet,
- openid=res['openid'],
- session_key=res['session_key']
- )
- else:
- instance.session_key = res['session_key']
- instance.save()
- return instance
- @staticmethod
- def bindWechat(appid, openid, phoneEncryptedData, phoneIv):
- customer_wechat = CustomerWechat.objects.filter(openid=openid, wechat_app__authorizer_appid=appid).first()
- if not customer_wechat:
- raise CustomError(u'未找到相应的微信客户!')
- pc = WXBizDataCrypt(appid, customer_wechat.session_key)
- phon_data = pc.decrypt(phoneEncryptedData, phoneIv)
- tel = phon_data['purePhoneNumber']
- if customer_wechat.customer and customer_wechat.customer.username == tel:
- # 已绑定用户,且用户账号和手机号一致
- return customer_wechat.customer
- # 用户用手机号、密码登录后,在绑定微信,两个号码可能会不符
- # 张三是绑定用户。 张三的账号,在李四小程序上登录,绑定信息时,手机号可能不符。
- # 这种情况,应该返回tel对应的账号,或者创建tel账号
- user = User.objects.filter(username=tel).first()
- if not user:
- # 密码默认手机号
- user = User.objects.create_user(User.CUSTOMER, tel, password=tel,
- **{
- 'tel': tel,
- 'name': tel,
- }
- )
- customer_wechat.customer = user
- customer_wechat.save()
- return user
- Group.add_to_class('create_user',
- models.ForeignKey(User, verbose_name=u"创建人", on_delete=models.PROTECT, editable=False))
|