123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- # coding=utf-8
- import time
- import os
- from django.conf import settings
- from django.db import models
- from django.utils import timezone
- from apps.WechatTp.models import WechatTp
- from utils.wx.wechat import WeChat
- from utils.exceptions import CustomError
- from utils.file_operation import CertPath
- class WechatApplet(models.Model):
- AUDIT_SUCCESS = 0
- AUDIT_REJECT = 1
- AUDITING = 2
- RECALL = 3
- AUDIT_DELAY = 4
- AUDIT_STATUS_CHOICE = (
- (AUDIT_SUCCESS, u'审核通过'),
- (AUDIT_REJECT, u'审核拒绝'),
- (AUDITING, u'审核中'),
- (RECALL, u'已撤回'),
- (AUDIT_DELAY, u'审核延后'),
- )
- # agent = models.ForeignKey(Agent, verbose_name=u'代理商', on_delete=models.PROTECT, null=True, editable=False)
- wechat_tp = models.ForeignKey(WechatTp, verbose_name=u'第三方平台', on_delete=models.PROTECT, editable=False)
- authorizer_appid = models.CharField(max_length=512, verbose_name=u'授权方appid')
- secret = models.CharField(max_length=512, verbose_name=u'小程序秘钥', null=True)
- authorizer_refresh_token = models.CharField(max_length=512, verbose_name=u'刷新令牌')
- authorizer_access_token = models.CharField(max_length=512, verbose_name=u'令牌')
- access_token_gtime = models.DateTimeField(verbose_name=u"获取令牌时间")
- expires_in = models.IntegerField(verbose_name=u'令牌有效期')
- is_authorize = models.BooleanField(verbose_name=u'是否授权', default=False)
- message_template_id = models.CharField(max_length=255, verbose_name=u'消息模版ID', null=True)
- nick_name = models.CharField(max_length=255, verbose_name=u'昵称', default="")
- head_img = models.CharField(max_length=255, verbose_name=u'头像', default="")
- principal_name = models.CharField(max_length=255, verbose_name=u'主体名称', default="")
- qrcode_url = models.CharField(max_length=512, verbose_name=u'二维码', default="")
- user_version = models.CharField(max_length=512, verbose_name=u'当前程序版本', default="")
- template_id = models.CharField(max_length=512, verbose_name=u'当前模板', default="")
- agent_num = models.CharField(max_length=512, verbose_name=u'商户号', default="")
- agent_key = models.CharField(max_length=512, verbose_name=u'商户密钥', default="")
- apiclient_cert = models.CharField(max_length=255, verbose_name=u'API证书cert', default="")
- apiclient_key = models.CharField(max_length=255, verbose_name=u'API证书key', default="")
- auditid = models.CharField(max_length=512, verbose_name=u'待审核ID', default="")
- wait_audit_version = models.CharField(max_length=512, verbose_name=u'待审核版本', null=True)
- wait_audit_template = models.CharField(max_length=512, verbose_name=u'待审核模板', null=True)
- audit_status = models.IntegerField(choices=AUDIT_STATUS_CHOICE, verbose_name=u'审核状态', null=True)
- reject_reason = models.CharField(max_length=512, verbose_name=u'拒绝原因', default="")
- is_admin = models.BooleanField(verbose_name=u'是管理者小程序', default=False) # 河南全品书城管理系统的小程序属于管理者小程序,其他是代理商小程序
- class Meta:
- db_table = "wechat_applet"
- ordering = ['-id']
- index_together = ()
- verbose_name = u"代理商小程序"
- default_permissions = ()
- permissions = [
- ('manage_wechat_applet', u'管理'),
- ]
- @staticmethod
- def getById(id):
- try:
- id = int(id)
- except:
- raise CustomError(u'无效的小程序ID!')
- instance = WechatApplet.objects.filter(pk=id).first()
- if not instance:
- raise CustomError(u'未找到相应的小程序!')
- return instance
- @staticmethod
- def getByAppid(appid):
- instance = WechatApplet.objects.filter(authorizer_appid=appid, is_authorize=True).first()
- if not instance:
- raise CustomError(u'未找到相应的小程序!')
- return instance
- @staticmethod
- def addAuthorizer(wechat_component, authorization_code, agent):
- gtime = timezone.now()
- component_appid = wechat_component.getAppid()
- component_access_token = wechat_component.getAccessToken()
- res = WeChat.getAuthorizationInfo(component_appid, authorization_code, component_access_token)
- ares = WeChat.getAuthorizerInfo(component_appid, res['authorization_info']['authorizer_appid'], component_access_token)
- authorizer = WechatApplet.getByAppidAndComponentAppid(res['authorization_info']['authorizer_appid'], component_appid)
- if authorizer:
- if authorizer.is_authorize:
- raise CustomError(u'该小程序已授权!')
- authorizer.refresh(res['authorization_info'], ares['authorizer_info'], gtime, agent)
- else:
- authorizer = WechatApplet.objects.create(
- agent=agent,
- wechat_tp=wechat_component,
- authorizer_appid=res['authorization_info']['authorizer_appid'],
- authorizer_refresh_token=res['authorization_info']['authorizer_refresh_token'],
- authorizer_access_token=res['authorization_info']['authorizer_access_token'],
- access_token_gtime=gtime,
- expires_in=res['authorization_info']['expires_in'],
- principal_name=ares['authorizer_info']['principal_name'],
- nick_name=ares['authorizer_info']['nick_name'],
- head_img=ares['authorizer_info']['head_img'],
- qrcode_url=ares['authorizer_info']['qrcode_url'],
- is_authorize=True
- )
- # 设置服务器域名
- authorizer.setDomain()
- return authorizer
- @staticmethod
- def getByAppidAndComponentAppid(appid, component_appid):
- authorizer = WechatApplet.objects.filter(authorizer_appid=appid, wechat_tp__component_appid=component_appid).first()
- return authorizer
- def getComponent(self):
- return self.wechat_tp
- def getAccessToken(self):
- if self.authorizer_access_token:
- last_time = time.mktime(self.access_token_gtime.timetuple()) + self.expires_in
- now = time.mktime(timezone.now().timetuple())
- if last_time > now:
- return self.authorizer_access_token
- gtime = timezone.now()
- res = WeChat.getAccessToken(self.authorizer_appid, self.secret)
- self.refreshAccessToken(gtime, res['access_token'], res['expires_in'])
- return self.authorizer_access_token
- def getAccessToken2(self):
- # 绑定第三方平台小程序,获取token
- if self.authorizer_access_token:
- last_time = time.mktime(self.access_token_gtime.timetuple()) + self.expires_in
- now = time.mktime(timezone.now().timetuple())
- if last_time > now:
- return self.authorizer_access_token
- if not self.authorizer_refresh_token:
- return ''
- gtime = timezone.now()
- component = self.getComponent()
- res = WeChat.getAuthorizerAccessToken(component.getAppid(), self.authorizer_appid, self.authorizer_refresh_token, component.getAccessToken())
- self.refreshAccessToken(gtime, res['authorizer_access_token'], res['expires_in'], res['authorizer_refresh_token'])
- return self.authorizer_access_token
- def revoke(self):
- agent = self.agent
- agent.is_bind_app = False
- agent.save()
- self.is_authorize = False
- self.save()
- def refreshAccessToken(self, gtime, access_token, expires_in, refresh_token=''):
- self.authorizer_access_token = access_token
- self.access_token_gtime = gtime
- self.expires_in = expires_in
- self.authorizer_refresh_token = refresh_token
- self.save()
- def refresh(self, authorization_info, authorizer_info, access_token_gtime, agent):
- self.authorizer_refresh_token = authorization_info['authorizer_refresh_token']
- self.authorizer_access_token = authorization_info['authorizer_access_token']
- self.access_token_gtime = access_token_gtime
- self.expires_in = authorization_info['expires_in']
- self.principal_name = authorizer_info['principal_name']
- self.nick_name = authorizer_info['nick_name']
- self.head_img = authorizer_info['head_img']
- self.qrcode_url = authorizer_info['qrcode_url']
- self.is_authorize = True
- self.agent = agent
- self.save()
- def uploadCode(self, template_id, user_version, user_desc):
- WeChat.commitCode(self.getAccessToken2(), template_id, user_version, user_desc)
- result = WeChat.submitAuditCode(self.getAccessToken2())
- self.auditid = result['auditid']
- self.wait_audit_version = user_version
- self.wait_audit_template = template_id
- self.audit_status = WechatApplet.AUDITING
- self.reject_reason = ''
- self.save()
- def refreshAuditStatus(self):
- result = WeChat.getLastSubmitAuditCodeStatus(self.getAccessToken2())
- if self.auditid == str(result['auditid']):
- if result['status'] == WechatApplet.AUDIT_SUCCESS:
- self.weapp_audit_success()
- elif result['status'] == WechatApplet.AUDIT_REJECT:
- self.weapp_audit_fail(result['reason'])
- elif result['status'] == WechatApplet.RECALL:
- self.weapp_audit_recall()
- elif result['status'] == WechatApplet.AUDIT_DELAY:
- self.weapp_audit_delay(result['reason'])
- def weapp_audit_recall(self):
- self.auditid = ''
- self.wait_audit_template = None
- self.wait_audit_version = None
- self.audit_status = None
- self.reject_reason = ''
- self.save()
- def weapp_audit_success(self):
- self.user_version = self.wait_audit_version
- self.template_id = self.wait_audit_template
- self.auditid = ''
- self.wait_audit_template = None
- self.wait_audit_version = None
- self.audit_status = None
- self.reject_reason = ''
- self.save()
- def weapp_audit_fail(self, reason):
- self.audit_status = WechatApplet.AUDIT_REJECT
- self.reject_reason = reason
- self.save()
- def weapp_audit_delay(self, reason):
- self.audit_status = WechatApplet.AUDIT_DELAY
- self.reject_reason = reason
- self.save()
- def setDomain(self):
- requestdomain = uploaddomain = downloaddomain = ['https://lsr.zzly.vip', ]
- wsrequestdomain = []
- WeChat.modify_domain(self.getAccessToken2(), 'set', requestdomain, wsrequestdomain, uploaddomain, downloaddomain)
- def addPlugin(self):
- result = WeChat.addPlugin(self.getAccessToken2())
- return result
- def releaseApplet(self):
- result = WeChat.releaseCode(self.getAccessToken2())
- return result
- def getMsgTemplateId(self, title):
- templates = WeChat.getTemplateList(self.getAccessToken())
- for template in templates:
- if template['title'] == title:
- return template['priTmplId']
- return ''
- def sendCreateOrderMsg(self, openid, msg_data, value=0):
- template_id = self.getMsgTemplateId('订单状态通知')
- if not template_id:
- return
- data = {
- 'character_string1': {'value': msg_data['no']},
- 'date3':{'value':msg_data['create_time'].strftime('%Y-%m-%d %H:%M:%S')},
- 'phrase2':{'value':msg_data['status']},
- 'thing4':{'value': msg_data['commoditys']},
- 'thing8':{'value': msg_data['tips']},
- }
- page = 'pages/order/order?value={}'.format(value)
- WeChat.sendSubscribeMessage(self.getAccessToken(), openid, template_id, page, data)
- def sendConfirmOrderMsg(self, openid, msg_data):
- template_id = self.getMsgTemplateId('订单确认通知')
- if not template_id:
- return
- data = {
- 'character_string1': {'value': msg_data['no']},
- 'time2':{'value':msg_data['create_time'].strftime('%Y-%m-%d %H:%M:%S')},
- 'thing3':{'value':msg_data['commoditys']},
- 'thing4':{'value': msg_data['address']},
- 'thing5':{'value': msg_data['tips']},
- }
- page = 'pages/order/order?value=2'
- WeChat.sendSubscribeMessage(self.getAccessToken(), openid, template_id, page, data)
- def sendSubmitLogisicsMsg(self, openid, msg_data):
- template_id = self.getMsgTemplateId('订单发货通知')
- if not template_id:
- return
- data = {
- 'character_string8': {'value': msg_data['no']},
- 'time2':{'value':msg_data['dispatch_time']},
- 'character_string4':{'value':msg_data['logistics_no']},
- 'thing9':{'value': msg_data['logistics_company']},
- 'thing12':{'value': msg_data['address']},
- }
- page = 'pages/order/order?value=3'
- WeChat.sendSubscribeMessage(self.getAccessToken(), openid, template_id, page, data)
- def sendPayOrderMsg(self, openid, msg_data):
- template_id = self.getMsgTemplateId('订单支付成功通知')
- if not template_id:
- return
- data = {
- 'date3':{'value':msg_data['pay_time'].strftime('%Y-%m-%d %H:%M:%S')},
- 'phrase4': {'value': msg_data['payment']},
- 'character_string5': {'value': msg_data['no']},
- 'amount2':{'value': msg_data['pay_amount']},
- 'thing7':{'value': msg_data['tips']},
- }
- page = 'pages/order/order?value=1'
- WeChat.sendSubscribeMessage(self.getAccessToken(), openid, template_id, page, data)
- def upload_cert_file(self, file):
- path = 'zzly_xcx_cert/%d/' % self.id
- upload_path = CertPath(path)
- filename = '%s%s' % (upload_path.path, file.name)
- full_filename = "%s/%s" % (settings.MEDIA_ROOT, filename)
- with open(full_filename, 'wb+') as destination:
- for chunk in file.chunks():
- destination.write(chunk)
- if file.name == 'apiclient_cert.pem':
- self.apiclient_cert = full_filename
- elif file.name == 'apiclient_key.pem':
- self.apiclient_key = full_filename
- self.save()
- def getWXAppCode(self, param):
- page = 'pages/index/index'
- filename = WeChat.getWXAppCode(self.getAccessToken2(), page, param)
- return filename
- class MessageTemplate(models.Model):
- CREATE_ORDER = 1
- PAY_ORDER = 2
- CONFIRM_ORDER = 3
- DELIVER = 4
- TYPE_CHOICE = (
- (CREATE_ORDER, u'用户下单'),
- (PAY_ORDER, u'支付成功'),
- (CONFIRM_ORDER, u'确认订单'),
- (DELIVER, u'发货通知'),
- )
- wechat_app = models.ForeignKey(WechatApplet, verbose_name=u'小程序', on_delete=models.PROTECT)
- type = models.IntegerField(choices=TYPE_CHOICE, verbose_name=u'模板类别', null=True)
- template = models.CharField(max_length=60, verbose_name=u'模板ID', default="")
- class Meta:
- db_table = "wechat_message_temp"
- ordering = ['-id']
- index_together = ()
- verbose_name = u"小程序消息模板"
- default_permissions = ()
- @staticmethod
- def get_temp_list(wechat_app):
- rows = MessageTemplate.objects.filter(wechat_app=wechat_app).exclude(template='').values_list('template', flat=True)
- return rows
|