diff --git a/fir_client/src/assets/sign/help/sign_help_0.png b/fir_client/src/assets/sign/help/sign_help_0.png new file mode 100644 index 0000000..1e2aada Binary files /dev/null and b/fir_client/src/assets/sign/help/sign_help_0.png differ diff --git a/fir_client/src/assets/sign/help/sign_help_1.png b/fir_client/src/assets/sign/help/sign_help_1.png new file mode 100644 index 0000000..e27cec9 Binary files /dev/null and b/fir_client/src/assets/sign/help/sign_help_1.png differ diff --git a/fir_client/src/assets/sign/help/sign_help_2.png b/fir_client/src/assets/sign/help/sign_help_2.png new file mode 100644 index 0000000..2eab88d Binary files /dev/null and b/fir_client/src/assets/sign/help/sign_help_2.png differ diff --git a/fir_client/src/assets/sign/help/sign_help_3.png b/fir_client/src/assets/sign/help/sign_help_3.png new file mode 100644 index 0000000..e154532 Binary files /dev/null and b/fir_client/src/assets/sign/help/sign_help_3.png differ diff --git a/fir_client/src/assets/sign/help/sign_help_4.png b/fir_client/src/assets/sign/help/sign_help_4.png new file mode 100644 index 0000000..b55912e Binary files /dev/null and b/fir_client/src/assets/sign/help/sign_help_4.png differ diff --git a/fir_client/src/assets/sign/help/sign_help_5.png b/fir_client/src/assets/sign/help/sign_help_5.png new file mode 100644 index 0000000..4600dbf Binary files /dev/null and b/fir_client/src/assets/sign/help/sign_help_5.png differ diff --git a/fir_client/src/components/apps/FirApps.vue b/fir_client/src/components/apps/FirApps.vue index 2d2fc43..091497a 100644 --- a/fir_client/src/components/apps/FirApps.vue +++ b/fir_client/src/components/apps/FirApps.vue @@ -594,12 +594,19 @@ delete this.analyseappinfo.icon; this.$message.success(file.name + '上传成功'); this.analyseappinfo.short = this.short; + const loading = this.$loading({ + lock: true, + text: '应用入库中,请耐心等待', + spinner: 'el-icon-loading', + // background: 'rgba(0, 0, 0, 0.7)' + }); analyseApps(data => { if (data.code === 1000) { let app_uuid = this.analyseappinfo.app_uuid; this.closeUpload(); this.$router.push({name: 'FirAppInfostimeline', params: {id: app_uuid}}); } + loading.close() }, {'methods': 'PUT', 'data': this.analyseappinfo}); } }, diff --git a/fir_client/src/components/index/FirIndexBody.vue b/fir_client/src/components/index/FirIndexBody.vue index 5228447..f2326c9 100644 --- a/fir_client/src/components/index/FirIndexBody.vue +++ b/fir_client/src/components/index/FirIndexBody.vue @@ -8,8 +8,6 @@
{{ item.title }}
{{ item.content }}
- -
@@ -29,7 +27,7 @@
- logo + logo

{{item.title}}

您身边的应用托管分发专家
7x24小时提供出色的不间断服务
- 联系我们
diff --git a/fir_client/src/components/user/FirSuperSignBase.vue b/fir_client/src/components/user/FirSuperSignBase.vue index d85991d..3a93882 100644 --- a/fir_client/src/components/user/FirSuperSignBase.vue +++ b/fir_client/src/components/user/FirSuperSignBase.vue @@ -23,8 +23,8 @@
- - + + @@ -219,8 +219,8 @@
- - + + @@ -232,6 +232,21 @@
+ +

获取密钥:

+

前往 AppStore Connect 。按照 + + 此步骤 + + 获取 API 密钥,将获取到的密钥添加到这里。 +

+ +

注意事项:

+

1.添加后,请勿撤销 API 密钥,否则会导致用户安装的软件闪退或无法安装!

+

2.每个开发者账号最多可创建两本证书,请确保至少还可以创建一本证书!

+

3.添加后,系统会自动创建证书、设备和描述文件,请勿删除这些文件,否则会导致用户安装的软件闪退或无法安装!

+ +
= 100) { + p = 100 + } + this.percentage = p; } } diff --git a/fir_client/src/components/user/FirSuperSignHelp.vue b/fir_client/src/components/user/FirSuperSignHelp.vue new file mode 100644 index 0000000..927c28a --- /dev/null +++ b/fir_client/src/components/user/FirSuperSignHelp.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/fir_client/src/router/index.js b/fir_client/src/router/index.js index 33caab3..84afe79 100644 --- a/fir_client/src/router/index.js +++ b/fir_client/src/router/index.js @@ -152,7 +152,12 @@ const router = new VueRouter({ meta: {label: '订单详情'}, component: () => import("@/components/user/FirUserOrders"), }, - + { + path: 'supersign-help', + name: 'FirSuperSignHelp', + meta: {label: '密钥获取帮助'}, + component: () => import("@/components/user/FirSuperSignHelp"), + } ] }, { diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index ccb55d3..7388009 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -261,6 +261,13 @@ class AppIOSDeveloperInfo(models.Model): verbose_name_plural = "苹果开发者账户" unique_together = (('user_id', 'issuer_id'),) + def save(self, *args, **kwargs): + if self.usable_number > 100: + self.usable_number = 100 + elif self.usable_number < 0: + self.usable_number = 0 + return super(AppIOSDeveloperInfo, self).save(*args, **kwargs) + def __str__(self): return "%s-%s" % (self.user_id, self.issuer_id) diff --git a/fir_ser/api/utils/app/iossignapi.py b/fir_ser/api/utils/app/iossignapi.py index 8174dab..32dcd82 100644 --- a/fir_ser/api/utils/app/iossignapi.py +++ b/fir_ser/api/utils/app/iossignapi.py @@ -105,7 +105,7 @@ class AppDeveloperApiV2(object): req.get_subject().L = 'BJ' req.get_subject().ST = 'BJ' req.get_subject().C = 'CN' - req.get_subject().emailAddress = 'fly@fly.com' + req.get_subject().emailAddress = 'flyapps@126.com' req.set_pubkey(key) req.sign(key, 'sha256') csr_content = dump_certificate_request(FILETYPE_PEM, req) diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index a4b27be..e2664f1 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -7,7 +7,7 @@ import uuid, xmltodict, os, re, logging, time from api.utils.response import BaseResponse -from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, SERVER_DOMAIN, MOBILECONFIG_SIGN_SSL +from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, SERVER_DOMAIN, MOBILECONFIG_SIGN_SSL, MSGTEMPLATE from api.utils.app.iossignapi import ResignApp, AppDeveloperApiV2 from api.models import APPSuperSignUsedInfo, AppUDID, AppIOSDeveloperInfo, AppReleaseInfo, Apps, APPToDeveloper, \ UDIDsyncDeveloper, DeveloperAppID, DeveloperDevicesID @@ -37,6 +37,7 @@ def check_org_file(user_obj, org_file): def resign_by_app_id(app_obj, need_download_profile=True): user_obj = app_obj.user_id + info_list = [] if app_obj.issupersign and user_obj.supersign_active: for dappid_obj in DeveloperAppID.objects.filter(app_id=app_obj).all(): developer_obj = dappid_obj.developerid @@ -49,7 +50,10 @@ def resign_by_app_id(app_obj, need_download_profile=True): else: download_flag = True with cache.lock("%s_%s_%s" % ('run_sign', app_obj.app_id, developer_obj.issuer_id), timeout=60 * 10): - IosUtils.run_sign(user_obj, app_obj, developer_obj, download_flag, None, d_time, {}, True) + status, result = IosUtils.run_sign(user_obj, app_obj, developer_obj, download_flag, None, d_time, {}, + True) + info_list.append({'developer_id': developer_obj.issuer_id, 'result': (status, result)}) + return info_list def check_app_sign_limit(app_obj): @@ -243,9 +247,9 @@ class IosUtils(object): if self.user_obj.email: if send_msg_over_limit("get", self.user_obj.email): send_msg_over_limit("set", self.user_obj.email) - send_ios_developer_active_status(self.user_obj, - 'user %s app %s sign failed. has not exists enabled developer' % ( - self.user_obj, self.app_obj)) + send_ios_developer_active_status(self.user_obj, MSGTEMPLATE.get('NOT_EXIST_DEVELOPER', '') + % ( + self.user_obj.first_name, self.app_obj.name)) else: logger.error("user %s send msg failed. over limit" % self.user_obj) @@ -341,8 +345,9 @@ class IosUtils(object): developer_obj.is_actived = False developer_obj.save() send_ios_developer_active_status(developer_obj.user_id, - 'app %s developer %s sign failed %s. disable this developer' % ( - app_obj, developer_obj, result)) + MSGTEMPLATE.get('ERROR_DEVELOPER') % ( + developer_obj.user_id.first_name, app_obj.name, + developer_obj.issuer_id)) return False, result if not developer_app_id and result.get("aid", None): diff --git a/fir_ser/api/utils/crontab/ctasks.py b/fir_ser/api/utils/crontab/ctasks.py index 6fe77cc..cb4f028 100644 --- a/fir_ser/api/utils/crontab/ctasks.py +++ b/fir_ser/api/utils/crontab/ctasks.py @@ -9,7 +9,7 @@ from api.utils.storage.storage import Storage from api.utils.app.supersignutils import IosUtils from api.utils.utils import send_ios_developer_active_status from django.core.cache import cache -from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE, SUPER_SIGN_ROOT +from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE, SUPER_SIGN_ROOT, MSGTEMPLATE import time, os import logging @@ -67,11 +67,12 @@ def auto_check_ios_developer_active(): if userinfo.supersign_active: status, result = IosUtils.active_developer(ios_developer) msg = "auto_check_ios_developer_active user:%s ios.developer:%s status:%s result:%s" % ( - ios_developer.user_id, ios_developer, status, result) + userinfo, ios_developer, status, result) if status: logger.info(msg) else: ios_developer.is_actived = False ios_developer.save() logger.error(msg) - send_ios_developer_active_status(ios_developer.user_id, msg) + send_ios_developer_active_status(userinfo, MSGTEMPLATE.get('AUTO_CHECK_DEVELOPER') % ( + userinfo.first_name, ios_developer.name)) diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index 4766a05..bee0d2d 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -15,7 +15,7 @@ token_obj = DownloadToken() def get_download_url_from_context(self, obj, key, url, force_new=False): - icon_url = "" + download_url = "" if self.context.get("key", None) and self.context.get("key") != "undefined": key = self.context.get("key", '') if self.context.get("storage", None) and self.context.get("storage") != "undefined": @@ -25,11 +25,15 @@ def get_download_url_from_context(self, obj, key, url, force_new=False): storage = Storage(obj.user_id) elif isinstance(obj, models.AppReleaseInfo): storage = Storage(obj.app_id.user_id) + elif isinstance(obj, models.UserInfo): + storage = Storage(obj) else: storage = None if storage: - icon_url = storage.get_download_url(os.path.basename(url), 600, key, force_new) - return icon_url + download_url = storage.get_download_url(os.path.basename(url), 600, key, force_new) + logger.info( + 'get %s download_url %s force_new:%s key:%s' % (os.path.basename(url), download_url, force_new, key)) + return download_url def get_app_master_obj_from_context(self, obj): @@ -59,8 +63,7 @@ class UserInfoSerializer(serializers.ModelSerializer): head_img = serializers.SerializerMethodField() def get_head_img(self, obj): - storage = Storage(obj) - return storage.get_download_url(obj.head_img) + return get_download_url_from_context(self, obj, '', obj.head_img) free_download_times = serializers.SerializerMethodField() @@ -315,7 +318,7 @@ class AppReleaseSerializer(serializers.ModelSerializer): return token_obj.make_token(obj.release_id, 600) def get_icon_url(self, obj): - return get_download_url_from_context(self, obj, '', os.path.basename(obj.icon_url), force_new=False) + return get_download_url_from_context(self, obj, '', os.path.basename(obj.icon_url)) def get_master_color(self, obj): if obj.is_master: diff --git a/fir_ser/api/utils/storage/aliyunApi.py b/fir_ser/api/utils/storage/aliyunApi.py index 6458c8e..cdb0213 100644 --- a/fir_ser/api/utils/storage/aliyunApi.py +++ b/fir_ser/api/utils/storage/aliyunApi.py @@ -113,8 +113,8 @@ class AliYunOss(object): self.domain_name = domain_name self.bucket_get = None self.bucket = None - self.make_auth_bucket('init_get', 900, True) - self.make_auth_bucket('init_auth', 900) + self.make_auth_bucket('init_get', 1800, True) + self.make_auth_bucket('init_auth', 1800) def fetch_sts_token(self, name, expires, only_put=False, only_get=False): """子用户角色扮演获取临时用户的密钥 diff --git a/fir_ser/api/views/apps.py b/fir_ser/api/views/apps.py index 4b1ddd2..ea39533 100644 --- a/fir_ser/api/views/apps.py +++ b/fir_ser/api/views/apps.py @@ -226,7 +226,8 @@ class AppInfoView(APIView): if do_sign_flag == 2: c_task = run_resign_task.apply_async((apps_obj.app_id, False)) if c_task: - c_task.get(propagate=False) + msg = c_task.get(propagate=False) + logger.info("app %s run_resign_task msg:%s" % (apps_obj, msg)) if c_task.successful(): c_task.forget() del_cache_response_by_short(apps_obj.app_id) diff --git a/fir_ser/api/views/uploads.py b/fir_ser/api/views/uploads.py index fcf7f56..4b13d95 100644 --- a/fir_ser/api/views/uploads.py +++ b/fir_ser/api/views/uploads.py @@ -120,7 +120,9 @@ class AppAnalyseView(APIView): app_info = Apps.objects.filter(bundle_id=data.get("bundleid")).first() if app_info: if app_info.issupersign and app_info.user_id.supersign_active: - c_task = run_resign_task.apply_async((app_info.app_id, False)).get(propagate=False) + c_task = run_resign_task.apply_async((app_info.app_id, False)) + msg = c_task.get(propagate=False) + logger.info("app %s run_resign_task msg:%s" % (app_info, msg)) if c_task.successful(): c_task.forget() else: diff --git a/fir_ser/fir_ser/settings.py b/fir_ser/fir_ser/settings.py index cbff79e..541e1b5 100644 --- a/fir_ser/fir_ser/settings.py +++ b/fir_ser/fir_ser/settings.py @@ -582,3 +582,9 @@ CELERY_BEAT_SCHEDULE = { 'one_off': True }, } + +MSGTEMPLATE = { + 'NOT_EXIST_DEVELOPER': '用户 %s 你好,应用 %s 签名失败了,苹果开发者总设备量已经超限,请添加新的苹果开发者或者修改开发者设备数量。感谢有你!', + 'ERROR_DEVELOPER': '用户 %s 你好,应用 %s 签名失败了,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!', + 'AUTO_CHECK_DEVELOPER': '用户 %s 你好,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!', +}