From abbe709d272711bc1ee877c08bfa5da96b085314 Mon Sep 17 00:00:00 2001 From: youngS Date: Thu, 28 Oct 2021 18:37:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B1=E6=9C=89=E6=B1=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/user/FirSuperSignBase.vue | 20 ++- fir_client/src/utils/index.js | 3 + fir_ser/api/admin.py | 1 + fir_ser/api/models.py | 8 +- fir_ser/api/utils/app/supersignutils.py | 114 +++++++++--------- fir_ser/api/utils/serializer.py | 9 +- fir_ser/api/views/apps.py | 4 +- fir_ser/api/views/supersign.py | 61 +++++----- 8 files changed, 124 insertions(+), 96 deletions(-) diff --git a/fir_client/src/components/user/FirSuperSignBase.vue b/fir_client/src/components/user/FirSuperSignBase.vue index 4f1e1cd..0b1c4da 100644 --- a/fir_client/src/components/user/FirSuperSignBase.vue +++ b/fir_client/src/components/user/FirSuperSignBase.vue @@ -420,13 +420,18 @@ + align="center" + width="110"> @@ -543,8 +548,7 @@ } }, udidDeleteFun(scope) { - this.iosdevicesudidFun('DELETE', {id: scope.row.id, aid: scope.row.app_id}); - this.app_udid_lists = removeAaary(this.app_udid_lists, scope.row) + this.iosdevicesudidFun('DELETE', {id: scope.row.id, aid: scope.row.app_id},scope); }, handleSizeChange(val) { this.pagination.pagesize = val; @@ -661,7 +665,7 @@ if (tabname === "useddevices") { this.iosdevicesFun('GET', data) } else if (tabname === "devicesudid") { - this.iosdevicesudidFun('GET', data) + this.iosdevicesudidFun('GET', data, null) } else if (tabname === "adddeveloper") { this.iosdeveloperFun({"methods": "GET", "data": data}) // this.title='新增私有开发者账户'; @@ -755,7 +759,7 @@ } }, params) }, - iosdevicesudidFun(action, data) { + iosdevicesudidFun(action, data, scope) { if (action !== 'GET') { this.loadingfun = this.$loading({ lock: true, @@ -771,7 +775,13 @@ if (action !== "DELETE") { this.app_udid_lists = data.data; this.pagination.total = data.count; + }else { + if(scope){ + this.app_udid_lists = removeAaary(this.app_udid_lists, scope.row) + } } + }else { + this.$message.error("操作失败了 "+data.msg); } if (action !== 'GET') { this.loadingfun.close() diff --git a/fir_client/src/utils/index.js b/fir_client/src/utils/index.js index 23684e2..92fd286 100644 --- a/fir_client/src/utils/index.js +++ b/fir_client/src/utils/index.js @@ -45,6 +45,9 @@ export function getappinfo(file, successcallback, errcallback) { let analyseappinfo = {}; parser.parse().then(result => { analyseappinfo.icon = result.icon; + if (analyseappinfo.icon === '' || analyseappinfo.icon === null) { + analyseappinfo.icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAABNVBMVEXzpkDzpkHzp0Lzp0PzqETzqUjzqkjzqknzrE7zrU/0rVD0r1P0r1T0sFX0sFb0sFf0sVf0sVj0sVn0slr1tWD1tWH1tmL1tmP1t2T1umz1u231u2/2vG/2vHD2vXH2wHj2wXr2wXv2wnz2wn32wn72w373xYL3xYT3xoT3xoX3x4f3x4j3yIn3yIr3yYv3yYz3yo34zJL4zJP4zZT4zpb4z5n50p/506H506L51KL51KP516v52Kz52a762q/62rD62rH63rn63rr637v637z64L375Mb75cj75cn75sn75sr86tP869T869X87Nb87Nf879798N/98OD98eH98eL98uP98uT98+X98+b99On99er99ev99uz++PH++fL++fP++/f++/j+/Pn+/fz+/v3+/v7///+pZW9PAAAC/0lEQVR4AezBgQAAAACAoP2pF6kCAAAAAAAAAAAAAABm376aWjmiIAD3XnEvWQQTMGACyIGAAzkHkMDkIDAGJCGxov//T3ChObWlAVRlrVQ1e8r+3qb0dB521bPT85/R/tPcd4B+S0WyuAT1fmPJr1DOu2PJnQfdEhQJ6HZJcQnVRhgYgWYnDJxAsQGWGYBeKZZJQa1un2X8bmi1S8sulGp5oeWlBTqt8511qNT4TOPqisZzIzRapJiaoliEQg1PNB5isQcaTw3QZ45iHpinmIM6XppG9ivwNUsj7UGbSYrlt9UyxSS0uaCRb3pbNeVpXECZYYpNs96kGIYuxzT8DrPu8GkcQ5V+in2IfYp+aJKk6IXopUhCkS6fxiEChzT8LuixTTGIwCDFtqL8XqBxhjJnNAp60vwaxRjKjFGsQYlvORo3sNzQyH3Tlt+nYZlWluYbHmk8xmCJBT/oSPMzFAt4Z4FiBhqkKz4KwcOThgLjFCv4YIViHNF3TqPQjA+aCzTOEXlDFFv4xBbFEKLuiIbfiU90+jSOEHF9FAf41AFFH6KjLZlhHWVS7Y7myLLOcm4mSbLuUnAhw7rL/D9ILVKsuyRcaM+xzrJtcDNJqr6v36TM4dxsxfxeIc3PIpqsrWyIrbCG/F45zSvL75XTvLb8rijNH1XxSbQrSPPq8ruCNC8Oqjo26LfHdi/01u9PeyMZHfbjG/7V4FpTvtoX6rl1WBoZKxQT+Jcm7L/PiAhRCLAKBZFhx8DwEdO1EKUZq3QD98IffFjHKFFxHRTLQhXTrhERYyGrfuv2UaN7p0H5MmR58xSRMEixgyrtUHyPKDgMXVDutgoSrvW80kiF/zT22gP39moo8Q9Q7MG5uE/jpJZrGX4crm1Q/FDTRZkNuHZP47K2q0t/w7EvRRqJ2i6TFb/Asb9YcushFO+WJfdRuTA5ipBGWfI7XPNWi2RhHqH9kSeLqx7ci//yYytq0Jr4OY5/2oMDGQAAAIBB/tb3+KoLAAAAAAAAAAAAAAAg6P6/9f2bMMkAAAAASUVORK5CYII=" + } analyseappinfo.filename = file.name; analyseappinfo.filesize = file.size; if (result.CFBundleDisplayName) { diff --git a/fir_ser/api/admin.py b/fir_ser/api/admin.py index e9fffef..5bdf7f4 100644 --- a/fir_ser/api/admin.py +++ b/fir_ser/api/admin.py @@ -19,3 +19,4 @@ admin.site.register(Order) admin.site.register(DomainCnameInfo) admin.site.register(UserDomainInfo) admin.site.register(UserAdDisplayInfo) +admin.site.register(IosDeveloperPublicPoolBill) diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index 4665db8..68fd517 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -524,10 +524,10 @@ class UserAdDisplayInfo(models.Model): class IosDeveloperPublicPoolBill(models.Model): user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE) action_choices = ((0, 'used'), (1, 'add')) - action = models.SmallIntegerField(choices=action_choices, default=1, verbose_name="消费类型", + action = models.SmallIntegerField(choices=action_choices, default=0, verbose_name="消费类型", help_text="0 表示消耗 1表示充值") number = models.IntegerField(verbose_name="消耗次数", default=1) - app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP") - udid = models.ForeignKey(to="AppUDID", on_delete=models.CASCADE, verbose_name="所消耗的udid") - developerid = models.ForeignKey(to="AppIOSDeveloperInfo", on_delete=models.CASCADE, verbose_name="所使用苹果开发者账户") + app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP",null=True,blank=True) + udid = models.ForeignKey(to="AppUDID", on_delete=models.CASCADE, verbose_name="所消耗的udid",null=True,blank=True) + developerid = models.ForeignKey(to="AppIOSDeveloperInfo", on_delete=models.CASCADE, verbose_name="所使用苹果开发者账户",null=True,blank=True) created_time = models.DateTimeField(auto_now_add=True, verbose_name="添加时间") diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index a810129..414f7fc 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -223,10 +223,9 @@ def get_ios_developer_public_num(user_obj): used_number = ios_developer_base_obj.filter(action=0).aggregate(number=Sum('number')) if add_number: add_number = add_number.get("number", 0) + used_number = used_number.get("number", 0) if not used_number: used_number = 0 - else: - used_number = used_number.get("number", 0) if add_number - used_number > 0: return True return False @@ -252,6 +251,47 @@ def get_redirect_server_domain(request, user_obj=None, app_domain_name=None): return get_server_domain_from_request(request, server_domain) + +def get_developer_user_by_app_udid(user_obj,udid): + + use_device_obj = APPSuperSignUsedInfo.objects.filter(udid__udid=udid, + user_id=user_obj, developerid__is_actived=True, + developerid__certid__isnull=False).first() + # 只要账户下面存在udid,就可以使用该苹果开发者账户,避免多个开发者账户下面出现同一个udid + if use_device_obj: + developer_obj = use_device_obj.developerid + else: + developer_udid_obj = UDIDsyncDeveloper.objects.filter(udid=udid, + developerid__is_actived=True, + developerid__certid__isnull=False).first() + if developer_udid_obj and developer_udid_obj.developerid.user_id.pk == user_obj.pk: + developer_obj = developer_udid_obj.developerid + else: + for developer_obj in AppIOSDeveloperInfo.objects.filter(user_id=user_obj, is_actived=True, + certid__isnull=False).order_by("created_time"): + if get_developer_udided(developer_obj)[1] < developer_obj.usable_number: + return developer_obj + return None + return developer_obj + +def get_developer_obj_by_others(user_obj, udid): + result = get_developer_user_by_app_udid(user_obj, udid) + if result: + return result + if not get_ios_developer_public_num(user_obj): + return None + admin_user_obj_list = UserInfo.objects.filter(is_active=True, role=3, is_staff=True).all() + for admin_user_obj in admin_user_obj_list: + result = get_developer_user_by_app_udid(admin_user_obj,udid) + if result is None: + continue + else: + logger.warning(f"user admin {admin_user_obj} developer to sign") + return result + return None + + + class IosUtils(object): def __init__(self, udid_info, user_obj, app_obj=None): self.developer_obj = None @@ -276,48 +316,8 @@ class IosUtils(object): else: logger.error(f"user {self.user_obj} send msg failed. over limit") - def get_developer_user_by_app_udid(self, user_obj_list=None): - if user_obj_list is None: - user_obj_list = [] - use_device_obj = APPSuperSignUsedInfo.objects.filter(udid__udid=self.udid_info.get('udid'), - user_id=self.user_obj, developerid__is_actived=True, - developerid__certid__isnull=False).first() - # 只要账户下面存在udid,就可以使用该苹果开发者账户,避免多个开发者账户下面出现同一个udid - if use_device_obj: - developer_obj = use_device_obj.developerid - else: - developer_udid_obj = UDIDsyncDeveloper.objects.filter(udid=self.udid_info.get('udid'), - developerid__is_actived=True, - developerid__certid__isnull=False).first() - if developer_udid_obj: - developer_obj = developer_udid_obj.developerid - else: - for developer_obj in AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, is_actived=True, - certid__isnull=False).order_by("created_time"): - if get_developer_udided(developer_obj)[1] < developer_obj.usable_number: - return developer_obj - if get_ios_developer_public_num(self.user_obj): - if user_obj_list == 'end': - return None - if not user_obj_list and isinstance(user_obj_list, list): - user_obj_list = UserInfo.objects.filter(is_active=True, role=3, is_staff=True).all() - for admin_user_obj in user_obj_list: - if admin_user_obj: - self.user_obj = admin_user_obj - user_obj_list.remove(admin_user_obj) - if len(user_obj_list) == 0: - user_obj_list = 'end' - result = self.get_developer_user_by_app_udid(user_obj_list) - if user_obj_list and isinstance(user_obj_list, list) and result is None: - return self.get_developer_user_by_app_udid(user_obj_list) - else: - return result - else: - return None - return None - else: - return None - return developer_obj + def get_developer_user_by_app_udid(self): + return get_developer_obj_by_others(self.user_obj, self.udid_info.get('udid')) # def download_profile(self, developer_app_id, device_id_list): # return get_api_obj(self.auth).get_profile(self.app_obj, self.udid_info, @@ -476,29 +476,33 @@ class IosUtils(object): user_id=self.user_obj, developerid=self.developer_obj, udid=udid_obj) - - def update_sign_data(self, random_file_name, release_obj): + IosDeveloperPublicPoolBill.objects.update_or_create(app_id=self.app_obj, + user_id=self.user_obj, + developerid=self.developer_obj, + udid=udid_obj,action=0,number=1) + @staticmethod + def update_sign_data(user_obj, app_obj, developer_obj,random_file_name, release_obj,udid): # 更新新签名的ipa包 - if IosUtils.update_sign_file_name(self.user_obj, self.app_obj, self.developer_obj, release_obj, + if IosUtils.update_sign_file_name(user_obj, app_obj, developer_obj, release_obj, random_file_name): newdata = { "is_signed": True, "binary_file": random_file_name } # 更新已经完成签名状态,设备消耗记录,和开发者已消耗数量 - AppUDID.objects.filter(app_id=self.app_obj, udid=self.udid_info.get('udid')).update(**newdata) - del_cache_response_by_short(self.app_obj.app_id, udid=self.udid_info.get('udid')) + AppUDID.objects.filter(app_id=app_obj, udid=udid).update(**newdata) + del_cache_response_by_short(app_obj.app_id, udid=udid) return True @staticmethod - def run_sign(user_obj, app_obj, developer_obj, download_flag, obj, d_time, result, resign=False): + def run_sign(user_obj, app_obj, developer_obj, download_flag, udid, d_time, result, resign=False): d_result = {'code': 0, 'msg': 'success'} start_time = time.time() if download_flag: logger.info(f"app_id {app_obj} download profile success. time:{start_time - d_time}") - random_file_name = make_from_user_uuid(user_obj) + random_file_name = make_from_user_uuid(developer_obj.user_id) release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, is_master=True).first() - status, e_result = IosUtils.exec_sign(user_obj, app_obj, developer_obj, random_file_name, release_obj) + status, e_result = IosUtils.exec_sign(developer_obj.user_id, app_obj, developer_obj, random_file_name, release_obj) if status: s_time1 = time.time() logger.info(f"app_id {app_obj} exec sign ipa success. time:{s_time1 - start_time}") @@ -509,7 +513,7 @@ class IosUtils(object): d_result['msg'] = '数据更新失败,请稍后重试' return status, d_result else: - if not obj.update_sign_data(random_file_name, release_obj): + if not IosUtils.update_sign_data(user_obj, app_obj, developer_obj,random_file_name, release_obj,udid): d_result['code'] = 1004 d_result['msg'] = '数据更新失败,请稍后重试' return status, d_result @@ -567,7 +571,7 @@ class IosUtils(object): with cache.lock("%s_%s_%s" % ('run_sign', self.app_obj.app_id, self.developer_obj.issuer_id), timeout=60 * 10): logger.info("start run_sign ...") - return IosUtils.run_sign(self.user_obj, self.app_obj, self.developer_obj, 1, self, time.time(), + return IosUtils.run_sign(self.user_obj, self.app_obj, self.developer_obj, 1, self.udid_info.get('udid'), time.time(), None) logger.info("udid %s not exists app_id %s ,need sign" % (self.udid_info.get('udid'), self.app_obj)) @@ -634,7 +638,7 @@ class IosUtils(object): return False, d_result with cache.lock("%s_%s_%s" % ('run_sign', self.app_obj.app_id, self.developer_obj.issuer_id), timeout=60 * 10): logger.info("start run_sign ...") - return IosUtils.run_sign(self.user_obj, self.app_obj, self.developer_obj, download_flag, self, start_time, + return IosUtils.run_sign(self.user_obj, self.app_obj, self.developer_obj, download_flag, self.udid_info.get('udid'), start_time, result) @staticmethod diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index d2b47dc..d8425f5 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -482,7 +482,10 @@ class SuperSignUsedSerializer(serializers.ModelSerializer): return obj.udid.product def get_developer_id(self, obj): - return obj.developerid.issuer_id + if self.context.get('mine'): + return obj.developerid.issuer_id + else: + return '公共账号池' def get_bundle_id(self, obj): return obj.app_id.bundle_id @@ -526,6 +529,10 @@ class DeviceUDIDSerializer(serializers.ModelSerializer): bundle_id = serializers.SerializerMethodField() bundle_name = serializers.SerializerMethodField() + is_mine = serializers.SerializerMethodField() + + def get_is_mine(self, obj): + return self.context.get('mine') def get_bundle_id(self, obj): return obj.app_id.bundle_id diff --git a/fir_ser/api/views/apps.py b/fir_ser/api/views/apps.py index 9832a33..1191d8a 100644 --- a/fir_ser/api/views/apps.py +++ b/fir_ser/api/views/apps.py @@ -11,7 +11,7 @@ from api.utils.response import BaseResponse from api.utils.auth import ExpiringTokenAuthentication from rest_framework.response import Response from django.db.models import Sum -from api.utils.app.supersignutils import IosUtils +from api.utils.app.supersignutils import IosUtils, get_ios_developer_public_num from api.utils.storage.storage import Storage from api.utils.storage.caches import del_cache_response_by_short, get_app_today_download_times, del_cache_by_delete_app from api.models import Apps, AppReleaseInfo, APPToDeveloper, AppIOSDeveloperInfo, UserInfo, AppScreenShot @@ -223,7 +223,7 @@ class AppInfoView(APIView): # res.msg = "超级签余额不足,无法开启" # return Response(res.dict) developer_count = AppIOSDeveloperInfo.objects.filter(user_id=request.user).count() - if developer_count == 0: + if developer_count == 0 and not get_ios_developer_public_num(request.user): logger.error(f"app_id:{app_id} can't open super_sign,owner has no ios developer") res.code = 1008 res.msg = "超级签开发者不存在,无法开启" diff --git a/fir_ser/api/views/supersign.py b/fir_ser/api/views/supersign.py index a04a609..dfe8c72 100644 --- a/fir_ser/api/views/supersign.py +++ b/fir_ser/api/views/supersign.py @@ -186,31 +186,36 @@ class DeveloperView(APIView): return self.get(request) +def base_super_sign_used_info(request): + udid = request.query_params.get("udid", None) + bundle_id = request.query_params.get("bundleid", None) + developer_id = request.query_params.get("appid", None) + mine = False + super_sign_used_objs = APPSuperSignUsedInfo.objects.filter(user_id=request.user, ) + if not super_sign_used_objs: + super_sign_used_objs = APPSuperSignUsedInfo.objects.filter(developerid__user_id=request.user, ) + mine = True + if developer_id: + super_sign_used_objs = super_sign_used_objs.filter(developerid__issuer_id=developer_id) + if udid: + super_sign_used_objs = super_sign_used_objs.filter(udid__udid=udid) + if bundle_id: + super_sign_used_objs = super_sign_used_objs.filter(app_id__bundle_id=bundle_id) + return super_sign_used_objs, mine + + class SuperSignUsedView(APIView): authentication_classes = [ExpiringTokenAuthentication, ] permission_classes = [SuperSignPermission, ] def get(self, request): res = BaseResponse() - - udid = request.query_params.get("udid", None) - bundle_id = request.query_params.get("bundleid", None) - developer_id = request.query_params.get("appid", None) - - super_sign_used_objs = APPSuperSignUsedInfo.objects.filter(user_id=request.user, ) - - if developer_id: - super_sign_used_objs = super_sign_used_objs.filter(developerid__issuer_id=developer_id) - if udid: - super_sign_used_objs = super_sign_used_objs.filter(udid__udid=udid) - if bundle_id: - super_sign_used_objs = super_sign_used_objs.filter(app_id__bundle_id=bundle_id) - + super_sign_used_objs, mine = base_super_sign_used_info(request) page_obj = PageNumber() app_page_serializer = page_obj.paginate_queryset(queryset=super_sign_used_objs.order_by("-created_time"), request=request, view=self) - app_serializer = SuperSignUsedSerializer(app_page_serializer, many=True, ) + app_serializer = SuperSignUsedSerializer(app_page_serializer, many=True, context={'mine': mine}) res.data = app_serializer.data res.count = super_sign_used_objs.count() return Response(res.dict) @@ -222,20 +227,13 @@ class AppUDIDUsedView(APIView): def get(self, request): res = BaseResponse() - - udid = request.query_params.get("udid", None) - bundle_id = request.query_params.get("bundleid", None) - app_udid_objs = AppUDID.objects.filter(app_id__user_id_id=request.user) - if udid: - app_udid_objs = app_udid_objs.filter(udid=udid) - if bundle_id: - app_udid_objs = app_udid_objs.filter(app_id__bundle_id=bundle_id) - + super_sign_used_objs, mine = base_super_sign_used_info(request) + app_udid_objs = AppUDID.objects.filter(app_id__appsupersignusedinfo__in=super_sign_used_objs) page_obj = PageNumber() app_page_serializer = page_obj.paginate_queryset(queryset=app_udid_objs.order_by("-created_time"), request=request, view=self) - app_serializer = DeviceUDIDSerializer(app_page_serializer, many=True, ) + app_serializer = DeviceUDIDSerializer(app_page_serializer, many=True, context={'mine': mine} ) res.data = app_serializer.data res.count = app_udid_objs.count() return Response(res.dict) @@ -244,11 +242,16 @@ class AppUDIDUsedView(APIView): res = BaseResponse() pk = request.query_params.get("id", None) app_id = request.query_params.get("aid", None) - app_udid_obj = AppUDID.objects.filter(app_id__user_id_id=request.user, pk=pk) + app_udid_obj = AppUDID.objects.filter(pk=pk) if app_udid_obj: - logger.error(f"user {request.user} delete devices {app_udid_obj}") - IosUtils.disable_udid(app_udid_obj.first(), app_id) - app_udid_obj.delete() + super_sign_used_obj = APPSuperSignUsedInfo.objects.filter(udid=app_udid_obj.first()).first() + if super_sign_used_obj and super_sign_used_obj.developerid.user_id.pk == request.user.pk: + logger.error(f"user {request.user} delete devices {app_udid_obj}") + IosUtils.disable_udid(app_udid_obj.first(), app_id) + app_udid_obj.delete() + else: + res.code = 10002 + res.msg = '公共账号池不允许删除' return Response(res.dict)