models.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. # coding=utf-8
  2. import time
  3. import os
  4. from django.conf import settings
  5. from django.db import models
  6. from django.utils import timezone
  7. from apps.WechatTp.models import WechatTp
  8. from utils.wx.wechat import WeChat
  9. from utils.exceptions import CustomError
  10. from utils.file_operation import CertPath
  11. from apps.tenant.models import Tenant
  12. class WechatApplet(models.Model):
  13. AUDIT_SUCCESS = 0
  14. AUDIT_REJECT = 1
  15. AUDITING = 2
  16. RECALL = 3
  17. AUDIT_DELAY = 4
  18. AUDIT_STATUS_CHOICE = (
  19. (AUDIT_SUCCESS, u'审核通过'),
  20. (AUDIT_REJECT, u'审核拒绝'),
  21. (AUDITING, u'审核中'),
  22. (RECALL, u'已撤回'),
  23. (AUDIT_DELAY, u'审核延后'),
  24. )
  25. tenant = models.ForeignKey(Tenant, verbose_name=u'企业', on_delete=models.PROTECT, editable=False)
  26. wechat_tp = models.ForeignKey(WechatTp, verbose_name=u'第三方平台', on_delete=models.PROTECT, editable=False)
  27. authorizer_appid = models.CharField(max_length=512, verbose_name=u'授权方appid')
  28. secret = models.CharField(max_length=512, verbose_name=u'小程序秘钥', null=True)
  29. authorizer_refresh_token = models.CharField(max_length=512, verbose_name=u'刷新令牌')
  30. authorizer_access_token = models.CharField(max_length=512, verbose_name=u'令牌')
  31. access_token_gtime = models.DateTimeField(verbose_name=u"获取令牌时间")
  32. expires_in = models.IntegerField(verbose_name=u'令牌有效期')
  33. is_authorize = models.BooleanField(verbose_name=u'是否授权', default=False)
  34. message_template_id = models.CharField(max_length=255, verbose_name=u'消息模版ID', null=True)
  35. nick_name = models.CharField(max_length=255, verbose_name=u'昵称', default="")
  36. head_img = models.CharField(max_length=255, verbose_name=u'头像', default="")
  37. principal_name = models.CharField(max_length=255, verbose_name=u'主体名称', default="")
  38. qrcode_url = models.CharField(max_length=512, verbose_name=u'二维码', default="")
  39. user_version = models.CharField(max_length=512, verbose_name=u'当前程序版本', default="")
  40. template_id = models.CharField(max_length=512, verbose_name=u'当前模板', default="")
  41. tenant_num = models.CharField(max_length=512, verbose_name=u'商户号', default="")
  42. tenant_key = models.CharField(max_length=512, verbose_name=u'商户密钥', default="")
  43. apiclient_cert = models.CharField(max_length=255, verbose_name=u'API证书cert', default="")
  44. apiclient_key = models.CharField(max_length=255, verbose_name=u'API证书key', default="")
  45. auditid = models.CharField(max_length=512, verbose_name=u'待审核ID', default="")
  46. wait_audit_version = models.CharField(max_length=512, verbose_name=u'待审核版本', null=True)
  47. wait_audit_template = models.CharField(max_length=512, verbose_name=u'待审核模板', null=True)
  48. audit_status = models.IntegerField(choices=AUDIT_STATUS_CHOICE, verbose_name=u'审核状态', null=True)
  49. reject_reason = models.CharField(max_length=512, verbose_name=u'拒绝原因', default="")
  50. class Meta:
  51. db_table = "wechat_applet"
  52. ordering = ['-id']
  53. index_together = ()
  54. verbose_name = u"小程序"
  55. default_permissions = ()
  56. @staticmethod
  57. def getById(id):
  58. try:
  59. id = int(id)
  60. except:
  61. raise CustomError(u'无效的小程序ID!')
  62. instance = WechatApplet.objects.filter(pk=id).first()
  63. if not instance:
  64. raise CustomError(u'未找到相应的小程序!')
  65. return instance
  66. @staticmethod
  67. def getByAppid(appid):
  68. instance = WechatApplet.objects.filter(authorizer_appid=appid).first()
  69. if not instance:
  70. raise CustomError(u'未找到相应的小程序!')
  71. return instance
  72. @staticmethod
  73. def addAuthorizer(wechat_component, authorization_code, tenant):
  74. gtime = timezone.now()
  75. component_appid = wechat_component.getAppid()
  76. component_access_token = wechat_component.getAccessToken()
  77. res = WeChat.getAuthorizationInfo(component_appid, authorization_code, component_access_token)
  78. ares = WeChat.getAuthorizerInfo(component_appid, res['authorization_info']['authorizer_appid'], component_access_token)
  79. authorizer = WechatApplet.getByAppidAndComponentAppid(res['authorization_info']['authorizer_appid'], component_appid)
  80. if authorizer:
  81. if authorizer.is_authorize:
  82. raise CustomError(u'该小程序已授权!')
  83. authorizer.refresh(res['authorization_info'], ares['authorizer_info'], gtime, tenant)
  84. else:
  85. authorizer = WechatApplet.objects.create(
  86. tenant=tenant,
  87. wechat_tp=wechat_component,
  88. authorizer_appid=res['authorization_info']['authorizer_appid'],
  89. authorizer_refresh_token=res['authorization_info']['authorizer_refresh_token'],
  90. authorizer_access_token=res['authorization_info']['authorizer_access_token'],
  91. access_token_gtime=gtime,
  92. expires_in=res['authorization_info']['expires_in'],
  93. principal_name=ares['authorizer_info']['principal_name'],
  94. nick_name=ares['authorizer_info']['nick_name'],
  95. head_img=ares['authorizer_info']['head_img'],
  96. qrcode_url=ares['authorizer_info']['qrcode_url'],
  97. is_authorize=True
  98. )
  99. # 设置服务器域名
  100. authorizer.setDomain()
  101. return authorizer
  102. @staticmethod
  103. def getByAppidAndComponentAppid(appid, component_appid):
  104. authorizer = WechatApplet.objects.filter(authorizer_appid=appid, wechat_tp_id__component_appid=component_appid).first()
  105. return authorizer
  106. def getComponent(self):
  107. return self.wechat_tp
  108. def getAccessToken(self):
  109. if self.authorizer_access_token:
  110. last_time = time.mktime(self.access_token_gtime.timetuple()) + self.expires_in
  111. now = time.mktime(timezone.now().timetuple())
  112. if last_time > now:
  113. return self.authorizer_access_token
  114. if not self.authorizer_refresh_token:
  115. return ''
  116. gtime = timezone.now()
  117. component = self.getComponent()
  118. res = WeChat.getAuthorizerAccessToken(component.getAppid(), self.authorizer_appid, self.authorizer_refresh_token, component.getAccessToken())
  119. self.refreshAccessToken(gtime, res['authorizer_access_token'], res['expires_in'], res['authorizer_refresh_token'])
  120. return self.authorizer_access_token
  121. def revoke(self):
  122. tenant = self.tenant
  123. tenant.is_bind_app = False
  124. tenant.save()
  125. self.is_authorize = False
  126. self.save()
  127. def refreshAccessToken(self, gtime, access_token, expires_in, refresh_token):
  128. self.authorizer_access_token = access_token
  129. self.access_token_gtime = gtime
  130. self.expires_in = expires_in
  131. self.authorizer_refresh_token = refresh_token
  132. self.save()
  133. def refresh(self, authorization_info, authorizer_info, access_token_gtime, tenant):
  134. self.authorizer_refresh_token = authorization_info['authorizer_refresh_token']
  135. self.authorizer_access_token = authorization_info['authorizer_access_token']
  136. self.access_token_gtime = access_token_gtime
  137. self.expires_in = authorization_info['expires_in']
  138. self.principal_name = authorizer_info['principal_name']
  139. self.nick_name = authorizer_info['nick_name']
  140. self.head_img = authorizer_info['head_img']
  141. self.qrcode_url = authorizer_info['qrcode_url']
  142. self.is_authorize = True
  143. self.tenant = tenant
  144. self.save()
  145. def uploadCode(self, template_id, user_version, user_desc):
  146. WeChat.commitCode(self.getAccessToken(), template_id, user_version, user_desc)
  147. result = WeChat.submitAuditCode(self.getAccessToken())
  148. self.auditid = result['auditid']
  149. self.wait_audit_version = user_version
  150. self.wait_audit_template = template_id
  151. self.audit_status = WechatApplet.AUDITING
  152. self.reject_reason = ''
  153. self.save()
  154. def refreshAuditStatus(self):
  155. result = WeChat.getLastSubmitAuditCodeStatus(self.getAccessToken())
  156. if self.auditid == str(result['auditid']):
  157. if result['status'] == WechatApplet.AUDIT_SUCCESS:
  158. self.weapp_audit_success()
  159. elif result['status'] == WechatApplet.AUDIT_REJECT:
  160. self.weapp_audit_fail(result['reason'])
  161. elif result['status'] == WechatApplet.RECALL:
  162. self.weapp_audit_recall()
  163. elif result['status'] == WechatApplet.AUDIT_DELAY:
  164. self.weapp_audit_delay(result['reason'])
  165. def weapp_audit_recall(self):
  166. self.auditid = ''
  167. self.wait_audit_template = None
  168. self.wait_audit_version = None
  169. self.audit_status = None
  170. self.reject_reason = ''
  171. self.save()
  172. def weapp_audit_success(self):
  173. self.user_version = self.wait_audit_version
  174. self.template_id = self.wait_audit_template
  175. self.auditid = ''
  176. self.wait_audit_template = None
  177. self.wait_audit_version = None
  178. self.audit_status = None
  179. self.reject_reason = ''
  180. self.save()
  181. def weapp_audit_fail(self, reason):
  182. self.audit_status = WechatApplet.AUDIT_REJECT
  183. self.reject_reason = reason
  184. self.save()
  185. def weapp_audit_delay(self, reason):
  186. self.audit_status = WechatApplet.AUDIT_DELAY
  187. self.reject_reason = reason
  188. self.save()
  189. def setDomain(self):
  190. requestdomain = uploaddomain = downloaddomain = ['https://baoxiu360.top', ]
  191. wsrequestdomain = []
  192. WeChat.modify_domain(self.getAccessToken(), 'set', requestdomain, wsrequestdomain, uploaddomain, downloaddomain)
  193. def addPlugin(self):
  194. result = WeChat.addPlugin(self.getAccessToken())
  195. return result
  196. def releaseApplet(self):
  197. result = WeChat.releaseCode(self.getAccessToken())
  198. return result
  199. def getMsgTemplateId(self):
  200. if self.message_template_id:
  201. return self.message_template_id
  202. templates = WeChat.getTemplateList(self.getAccessToken())
  203. for template in templates:
  204. if template['title'] == u'维修完成通知':
  205. self.message_template_id = template['priTmplId']
  206. self.save()
  207. return template['priTmplId']
  208. return ''
  209. def sendMsg(self, openid, name, address, fault_des, no):
  210. template_id = self.getMsgTemplateId()
  211. if not template_id:
  212. return
  213. time = timezone.now().strftime('%Y-%m-%d %H:%M:%S')
  214. data = {
  215. 'time5': {'value': time},
  216. 'name4':{'value':name},
  217. 'thing3':{'value':address},
  218. 'thing2':{'value': fault_des},
  219. 'character_string7':{'value': no},
  220. }
  221. page = 'pages/repairList/repairList?sort=baoxiu&name=我的报修'
  222. WeChat.sendSubscribeMessage(self.getAccessToken(), openid, template_id, page, data)
  223. def upload_cert_file(self, file):
  224. path = 'zzly_xcx_cert/%d/' % self.id
  225. upload_path = CertPath(path)
  226. filename = '%s%s' % (upload_path.path, file.name)
  227. full_filename = "%s/%s" % (settings.MEDIA_ROOT, filename)
  228. with open(full_filename, 'wb+') as destination:
  229. for chunk in file.chunks():
  230. destination.write(chunk)
  231. if file.name == 'apiclient_cert.pem':
  232. self.apiclient_cert = full_filename
  233. elif file.name == 'apiclient_key.pem':
  234. self.apiclient_key = full_filename
  235. self.save()