diff --git a/fir_client/src/components/user/FirUserProfileInfo.vue b/fir_client/src/components/user/FirUserProfileInfo.vue index 9f82a6e..55c3609 100644 --- a/fir_client/src/components/user/FirUserProfileInfo.vue +++ b/fir_client/src/components/user/FirUserProfileInfo.vue @@ -344,11 +344,49 @@ export default { unique_key: '' } }, methods: { + + loop_get_wx_web_info(wx_login_ticket, c_count = 1, unique_key = getRandomStr()) { + if (wx_login_ticket && wx_login_ticket.length < 3) { + this.$message.error("获取登陆码失败,请稍后再试"); + return + } + if (!this.show_web_visible) { + return; + } + wxLoginFun(data => { + c_count += 1; + if (c_count > 30) { + return; + } + if (data.code === 1000) { + if (this.userinfo.uid === data.data.uid) { + this.$message.success("更新成功"); + this.show_web_visible = false; + this.get_wx_user_list(); + } + } else if (data.code === 1006) { + return this.loop_get_wx_web_info(wx_login_ticket, c_count, unique_key) + } else { + this.$message({ + message: data.msg, + type: 'error', + duration: 30000 + }); + this.show_web_visible = false; + } + }, { + "methods": "POST", + data: {"ticket": wx_login_ticket, "unique_key": unique_key} + }) + }, + + wx_web_login_fun() { wxWebScanFun(data => { if (data.code === 1000) { this.show_web_visible = true; this.wx_web_login_url = data.data; + this.loop_get_wx_web_info(data.ticket) } else { this.$message.error("信息获取失败") } diff --git a/fir_client/src/restful/index.js b/fir_client/src/restful/index.js index 0b93a1c..c56142c 100644 --- a/fir_client/src/restful/index.js +++ b/fir_client/src/restful/index.js @@ -263,7 +263,7 @@ export function wxBindFun(callBack, params, load = true) { export function wxWebScanFun(callBack, params, load = true) { getData( params.methods, - USERSEVER + '/mp.web.login', + USERSEVER + '/mp.web.sync', params.data, data => { callBack(data); diff --git a/fir_ser/api/urls.py b/fir_ser/api/urls.py index 409a9ce..37ace0d 100644 --- a/fir_ser/api/urls.py +++ b/fir_ser/api/urls.py @@ -22,7 +22,8 @@ from api.views.download import ShortDownloadView, InstallView, DownloadView from api.views.getip import GetRemoteIp from api.views.login import LoginView, UserInfoView, RegistView, AuthorizationView, ChangeAuthorizationView, \ UserApiTokenView, CertificationView, ChangeInfoView -from api.views.login_wx import WeChatLoginView, WeChatLoginCheckView, WeChatBindView, WeChatWebLoginView +from api.views.login_wx import WeChatLoginView, WeChatLoginCheckView, WeChatBindView, WeChatWebLoginView, \ + WeChatWebSyncView from api.views.logout import LogoutView from api.views.notify import NotifyReceiverView, NotifyConfigView, NotifyInfoView from api.views.order import PriceView, OrderView, PaySuccess, OrderSyncView @@ -68,6 +69,7 @@ urlpatterns = [ re_path("^domain_info$", DomainInfoView.as_view()), re_path("^mp.weixin$", ValidWxChatToken.as_view()), re_path("^mp.web.login$", WeChatWebLoginView.as_view(), name="mp.web.login"), + re_path("^mp.web.sync$", WeChatWebSyncView.as_view(), name="mp.web.sync"), re_path("^third.wx.login$", WeChatLoginView.as_view()), re_path("^third.wx.bind$", WeChatBindView.as_view()), re_path("^third.wx.sync$", WeChatLoginCheckView.as_view()), diff --git a/fir_ser/api/views/login_wx.py b/fir_ser/api/views/login_wx.py index 1e9ab3a..dbb3beb 100644 --- a/fir_ser/api/views/login_wx.py +++ b/fir_ser/api/views/login_wx.py @@ -1,6 +1,6 @@ import logging -from django.http import HttpResponse +from django.shortcuts import redirect from rest_framework.response import Response from rest_framework.views import APIView @@ -17,7 +17,7 @@ from common.core.throttle import VisitRegister1Throttle, VisitRegister2Throttle from common.libs.mp.wechat import make_wx_login_qrcode, show_qrcode_url, WxWebLogin, WxTemplateMsg from common.utils.caches import set_wx_ticket_login_info_cache, get_wx_ticket_login_info_cache from common.utils.pending import get_pending_result -from common.utils.token import verify_token +from common.utils.token import verify_token, generate_alphanumeric_token_of_length logger = logging.getLogger(__name__) @@ -185,11 +185,11 @@ class WeChatWebLoginView(APIView): throttle_classes = [VisitRegister1Throttle, VisitRegister2Throttle] def get(self, request): - logger.error(request.query_params) wx_login_obj = WxWebLogin() ret = BaseResponse() code = request.query_params.get('code') if code: + state = request.query_params.get('state', 'FLYAPPS') wx_login_obj.get_wx_token(code) wx_user_info = wx_login_obj.get_user_info() logger.info(f'{wx_user_info}') @@ -197,13 +197,29 @@ class WeChatWebLoginView(APIView): 'openid': wx_user_info.get('openid'), 'nickname': wx_user_info.get('nickname'), 'sex': wx_user_info.get('sex'), - # 'subscribe_time': wx_user_info.get('subscribe_time', 0), 'head_img_url': wx_user_info.get('headimgurl', ''), 'address': f"{wx_user_info.get('country')}-{wx_user_info.get('province')}-{wx_user_info.get('city')}", - # 'subscribe': wx_user_info.get('subscribe', 0), } logger.info(f'{wx_user_info}') WeChatInfo.objects.filter(openid=wx_user_info.get('openid')).update(**wx_user_info) - return HttpResponse('

更新成功

') - ret.data = wx_login_obj.make_auth_uri() + info = WxLoginBindCache(state).get_storage_cache() + if info and isinstance(info, dict): + info.update({'w_type': 'web', 'to_user': wx_user_info.get('openid')}) + set_wx_ticket_login_info_cache(state, info) + return redirect(Config.WEB_DOMAIN) + return Response(ret.dict) + + +class WeChatWebSyncView(APIView): + authentication_classes = [ExpiringTokenAuthentication, ] + throttle_classes = [VisitRegister1Throttle, VisitRegister2Throttle] + + def get(self, request): + logger.error(request.query_params) + wx_login_obj = WxWebLogin() + ret = BaseResponse() + ticket = generate_alphanumeric_token_of_length(32) + WxLoginBindCache(ticket).set_storage_cache({'ip_addr': get_real_ip_address(request), 'pk': request.user.pk}) + ret.data = wx_login_obj.make_auth_uri(ticket) + ret.ticket = ticket return Response(ret.dict) diff --git a/fir_ser/common/libs/mp/wechat.py b/fir_ser/common/libs/mp/wechat.py index 2637d5b..ebc25f4 100644 --- a/fir_ser/common/libs/mp/wechat.py +++ b/fir_ser/common/libs/mp/wechat.py @@ -566,7 +566,7 @@ class WxWebLogin(object): self.app_id = auth_info.get('app_id') self.app_secret = auth_info.get('app_secret') - def make_auth_uri(self): + def make_auth_uri(self, state): """ 第一步: 用户通过微信客户端打开该URI :return: @@ -575,7 +575,7 @@ class WxWebLogin(object): local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN) url = f'{local_storage.get_base_url()}{reverse("mp.web.login")}' encode_url = urllib.parse.quote(url, safe='/', encoding=None, errors=None) - code_url = f'https://open.weixin.qq.com/connect/oauth2/authorize?appid={self.app_id}&redirect_uri={encode_url}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect' + code_url = f'https://open.weixin.qq.com/connect/oauth2/authorize?appid={self.app_id}&redirect_uri={encode_url}&response_type=code&scope=snsapi_userinfo&state={state}#wechat_redirect ' return code_url def get_wx_token(self, code): diff --git a/fir_ser/common/notify/ntasks.py b/fir_ser/common/notify/ntasks.py index 57db90a..de3c1f9 100644 --- a/fir_ser/common/notify/ntasks.py +++ b/fir_ser/common/notify/ntasks.py @@ -99,13 +99,16 @@ def check_user_download_times(user_obj, days=None): def check_apple_developer_devices(user_obj, days=None): if days is None: days = [0, 3, 7] - developer_used_info = get_developer_devices(AppIOSDeveloperInfo.objects.filter(user_id=user_obj)) + developer_queryset = AppIOSDeveloperInfo.objects.filter(user_id=user_obj) + if developer_queryset.count() == 0: + return + developer_used_info = get_developer_devices(developer_queryset) device_count = developer_used_info.get('can_sign_number', 0) - if user_obj.notify_available_signs == 0 or user_obj.notify_available_signs < device_count: + if user_obj.notify_available_signs == 0 or device_count > user_obj.notify_available_signs: return notify_rules = [ { - 'func': magic_wrapper(lambda obj: device_count < obj.notify_available_downloads, user_obj), + 'func': magic_wrapper(lambda obj: device_count < obj.notify_available_signs, user_obj), 'notify': days, 'cache': NotifyLoopCache(user_obj.uid, 'sign_device_times'), 'notify_func': [magic_wrapper(apple_developer_devices_not_enough, user_obj, device_count)] @@ -124,7 +127,7 @@ def check_apple_developer_cert(user_obj, expire_day=7): notify_rules = [ { - 'func': magic_wrapper(lambda obj: obj.download_times < obj.notify_available_downloads, user_obj), + 'func': magic_wrapper(lambda: True), 'notify': [0, 3, 7], 'cache': NotifyLoopCache(user_obj.uid, 'developer_cert'), 'notify_func': [magic_wrapper(apple_developer_cert_expired, user_obj, developer_queryset)]