diff --git a/fir_ser/api/utils/ctasks.py b/fir_ser/api/utils/ctasks.py index 0ebcd6b..553225f 100644 --- a/fir_ser/api/utils/ctasks.py +++ b/fir_ser/api/utils/ctasks.py @@ -54,12 +54,12 @@ def auto_clean_remote_client_log(clean_day=30): def notify_check_user_download_times(): - for user_obj in UserInfo.objects.filter(is_active=True).all(): + for user_obj in UserInfo.objects.filter(is_active=True, notify_available_downloads__gt=0).all(): check_user_download_times(user_obj, days=[0, 3, 7]) def notify_check_apple_developer_devices(): - for user_obj in UserInfo.objects.filter(is_active=True, supersign_active=True).all(): + for user_obj in UserInfo.objects.filter(is_active=True, supersign_active=True, notify_available_signs__gt=0).all(): check_apple_developer_devices(user_obj, days=[0, 3, 7]) diff --git a/fir_ser/api/views/thirdlogin.py b/fir_ser/api/views/thirdlogin.py index 39e1795..c2a4adb 100644 --- a/fir_ser/api/views/thirdlogin.py +++ b/fir_ser/api/views/thirdlogin.py @@ -6,6 +6,7 @@ import logging import random +from django.db.models import Q from django.http.response import HttpResponse from rest_framework.response import Response from rest_framework.views import APIView @@ -165,7 +166,8 @@ class ValidWxChatToken(APIView): logger.info(f"replay msg: {result}") return HttpResponse(result) elif rec_msg.Eventkey in ['query_bind', 'unbind']: - wx_user_obj = ThirdWeChatUserInfo.objects.filter(openid=to_user).first() + wx_user_obj = ThirdWeChatUserInfo.objects.filter(openid=to_user).filter( + Q(enable_login=True) | Q(enable_notify=True)).first() if rec_msg.Eventkey == 'query_bind': if wx_user_obj: user_obj = wx_user_obj.user_id @@ -180,10 +182,18 @@ class ValidWxChatToken(APIView): name = user_cert_obj.name else: name = user_obj.first_name + description = f'绑定了' + if wx_user_obj.enable_login: + description += " 微信登录 " + if wx_user_obj.enable_notify: + description += " 消息通知 " + description += "功能。" + WxTemplateMsg(to_user, wx_user_obj.nickname).bind_query_success_msg(user_obj.first_name, name, user_obj.mobile, - user_obj.email) + user_obj.email, + description) else: content = '暂无登录绑定信息' wx_user_info = update_or_create_wx_userinfo(to_user) diff --git a/fir_ser/common/core/sysconfig.py b/fir_ser/common/core/sysconfig.py index f8f27df..29642d4 100644 --- a/fir_ser/common/core/sysconfig.py +++ b/fir_ser/common/core/sysconfig.py @@ -269,6 +269,10 @@ class EmailMsgCache(ConfigCacheBase): def MSG_NOT_EXIST_DEVELOPER(self): return super().get_value('MSG_NOT_EXIST_DEVELOPER', MSGCONF.MSG_NOT_EXIST_DEVELOPER) + @property + def MSG_SING_APP_OVER_LIMIT(self): + return super().get_value('MSG_SING_APP_OVER_LIMIT', MSGCONF.MSG_SING_APP_OVER_LIMIT) + @property def MSG_ERROR_DEVELOPER(self): return super().get_value('MSG_ERROR_DEVELOPER', MSGCONF.MSG_ERROR_DEVELOPER) diff --git a/fir_ser/common/libs/mp/wechat.py b/fir_ser/common/libs/mp/wechat.py index 57ce1da..53294e4 100644 --- a/fir_ser/common/libs/mp/wechat.py +++ b/fir_ser/common/libs/mp/wechat.py @@ -329,7 +329,7 @@ class WxTemplateMsg(object): } return self.send_msg(msg_id, content_data) - def bind_query_success_msg(self, username, name, mobile, email): + def bind_query_success_msg(self, username, name, mobile, email, description): msg_id = 'yU15jLNSULagJTff01X67mDtDytBSs3iBpOBi8c7dvs' content_data = { "first": { @@ -353,7 +353,7 @@ class WxTemplateMsg(object): "color": "#173177" }, "remark": { - "value": "感谢您的关注", + "value": f"{description}感谢您的关注", "color": "#173177" }, } @@ -506,7 +506,7 @@ class WxTemplateMsg(object): msg_id = 'Hnrk5iXRjbaCTVpSIyC5KC8cwFNDgplNUzPsnyDXRLo' content_data = { "first": { - "value": f'你好,“{self.wx_nick_name}“,操作失败了', + "value": f'你好,“{self.wx_nick_name}“,签名失败了', "color": "#173177" }, "keyword1": { diff --git a/fir_ser/common/notify/notify.py b/fir_ser/common/notify/notify.py index 6bde445..3135eec 100644 --- a/fir_ser/common/notify/notify.py +++ b/fir_ser/common/notify/notify.py @@ -49,13 +49,13 @@ def sign_failed_notify(user_obj, developer_obj, app_obj): now_time = get_format_time().replace('_', ' ') msg = Config.MSG_ERROR_DEVELOPER % ( - developer_obj.user_id.first_name, app_obj.name, - now_time, developer_obj.issuer_id) + user_obj.first_name, app_obj.name, now_time, developer_obj.issuer_id, developer_obj.description) for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).operate_failed_msg( user_obj.first_name, f'应用 {app_obj.name} 签名失败了', - f'开发者{developer_obj.issuer_id} 状态 {developer_obj.get_status_dispaly()}', now_time, '请登录后台查看具体信息') + f'开发者{developer_obj.issuer_id} 状态 {developer_obj.get_status_dispaly()}', now_time, + f'开发者备注:{developer_obj.description},请登录后台查看具体信息') logger.info(f'user_obj {user_obj} weixin notify pay success result: {res}') notify_by_email(user_obj, message_type, msg) @@ -76,3 +76,23 @@ def sign_unavailable_developer(user_obj, app_obj): logger.info(f'user_obj {user_obj} weixin notify pay success result: {res}') notify_by_email(user_obj, message_type, msg) + + +def sign_app_over_limit(user_obj, app_obj, used_num, limit_number): + """ + 0, '签名余额不足' + :param limit_number: + :param used_num: + :param app_obj: + :param user_obj: + :return: + """ + message_type = 2 + now_time = get_format_time().replace('_', ' ') + msg = Config.MSG_SING_APP_OVER_LIMIT % (user_obj.first_name, app_obj.name, now_time, used_num, limit_number) + for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): + res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).operate_failed_msg( + user_obj.first_name, f'应用 {app_obj.name} 签名失败了', f'超过该应用的签名限额 {limit_number}', now_time, + f'该应用已经使用设备数 {used_num},已超过您设置该应用的签名限额 {limit_number},当前已经无法安装新设备,为了避免业务使用,您可以修改该应用签名限额') + logger.info(f'user_obj {user_obj} sign devices not enough result: {res}') + notify_by_email(user_obj, message_type, msg) diff --git a/fir_ser/common/notify/ntasks.py b/fir_ser/common/notify/ntasks.py index 30d82a3..6a98a2b 100644 --- a/fir_ser/common/notify/ntasks.py +++ b/fir_ser/common/notify/ntasks.py @@ -19,14 +19,14 @@ from xsign.utils.modelutils import get_developer_devices logger = logging.getLogger(__name__) -def download_times_not_enough(user_obj): +def download_times_not_enough(user_obj, msg): """ 1, '下载次数不足' + :param msg: :param user_obj: :return: """ message_type = 1 - msg = f"您当前账户下载次数仅剩 {user_obj.download_times},已超过您设置的阈值 {user_obj.notify_available_downloads},为了避免业务使用,望您尽快充值!" for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).download_times_not_enough_msg( user_obj.first_name, user_obj.download_times, msg) @@ -83,12 +83,13 @@ def check_user_download_times(user_obj, days=None): days = [0, 3, 7] if user_obj.notify_available_downloads == 0 or user_obj.notify_available_downloads < user_obj.download_times: return + msg = f"您当前账户下载次数仅剩 {user_obj.download_times},已超过您设置的阈值 {user_obj.notify_available_downloads},为了避免业务使用,望您尽快充值!" notify_rules = [ { 'func': magic_wrapper(lambda obj: obj.download_times < obj.notify_available_downloads, user_obj), 'notify': days, 'cache': NotifyLoopCache(user_obj.uid, 'download_times'), - 'notify_func': [magic_wrapper(download_times_not_enough, user_obj)] + 'notify_func': [magic_wrapper(download_times_not_enough, user_obj, msg)] } ] magic_notify(notify_rules) diff --git a/fir_ser/common/utils/caches.py b/fir_ser/common/utils/caches.py index b63a12d..2441988 100644 --- a/fir_ser/common/utils/caches.py +++ b/fir_ser/common/utils/caches.py @@ -21,6 +21,7 @@ from common.cache.storage import AppDownloadTodayTimesCache, AppDownloadTimesCac SignUdidQueueCache, CloudStorageCache from common.core.sysconfig import Config from common.notify.notify import pay_success_notify +from common.notify.ntasks import download_times_not_enough from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE logger = logging.getLogger(__name__) @@ -196,6 +197,8 @@ def consume_user_download_times(user_id, app_id, amount=1, auth_status=False): logger.error(f"{user_id} download_times less then 0. Exception:{e}") disable_user_download_times_flag(user_id) del_cache_response_by_short(app_id) + msg = f"您当前账户下载次数不足,应用已经无法下载安装。为了避免业务使用,望您尽快充值!" + download_times_not_enough(UserInfo.objects.filter(pk=user_id).first(), msg) return False return True diff --git a/fir_ser/config.py b/fir_ser/config.py index 3775d13..d1515ea 100644 --- a/fir_ser/config.py +++ b/fir_ser/config.py @@ -352,8 +352,9 @@ bIX1aWjPxirQX9mzaL3oEQI= class MSGCONF(object): MSG_NOT_EXIST_DEVELOPER = '用户 %s 你好,应用 %s 在 %s 签名失败了,苹果开发者总设备量已经超限,请添加新的苹果开发者或者修改开发者设备数量。感谢有你!' - MSG_ERROR_DEVELOPER = '用户 %s 你好,应用 %s 在 %s 签名失败了,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!' + MSG_ERROR_DEVELOPER = '用户 %s 你好,应用 %s 在 %s 签名失败了,苹果开发者【%s】开发者备注【%s】 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!' MSG_AUTO_CHECK_DEVELOPER = '用户 %s 你好,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!' + MSG_SING_APP_OVER_LIMIT = '用户 %s 你好,应用 %s 在 %s 签名失败了,该应用已经使用设备数 %s,超过您设置的签名限额 %s,当前已经无法安装新设备,为了避免业务使用,您可以修改该应用签名限额 ' class DOWNLOADTIMESCONF(object): diff --git a/fir_ser/xsign/utils/supersignutils.py b/fir_ser/xsign/utils/supersignutils.py index 5e1825d..3b292b1 100644 --- a/fir_ser/xsign/utils/supersignutils.py +++ b/fir_ser/xsign/utils/supersignutils.py @@ -22,7 +22,7 @@ from common.base.baseutils import file_format_path, delete_app_profile_file, get from common.base.magic import run_function_by_locker, call_function_try_attempts, magic_wrapper from common.cache.state import CleanErrorBundleIdSignDataState from common.core.sysconfig import Config -from common.notify.notify import sign_failed_notify, sign_unavailable_developer +from common.notify.notify import sign_failed_notify, sign_unavailable_developer, sign_app_over_limit from common.utils.caches import del_cache_response_by_short, send_msg_over_limit, check_app_permission, \ consume_user_download_times_by_app_obj, add_udid_cache_queue, get_and_clean_udid_cache_queue from common.utils.storage import Storage @@ -533,6 +533,7 @@ class IosUtils(object): d_result['msg'] = "app_id %s used over limit.now %s limit: %s" % ( self.app_obj, used_num, self.app_obj.supersign_limit_number) logger.error(d_result) + sign_app_over_limit(self.app_obj.user_id, self.app_obj, used_num, self.app_obj.supersign_limit_number) return False, d_result res = check_app_permission(self.app_obj, BaseResponse())