优化代码,修复多个开发者,下载不是最新签名包问题,增加批量修改开发者状态

dependabot/npm_and_yarn/fir_admin/url-parse-1.5.10
MMXX 3 years ago
parent 4d4ee64a65
commit 03f66df7b9
  1. 1
      fir_client/src/components/base/AppleDeveloperBindApp.vue
  2. 133
      fir_client/src/components/user/FirSuperSignBase.vue
  3. 4
      fir_ser/api/utils/app/supersignutils.py
  4. 24
      fir_ser/api/utils/crontab/ctasks.py
  5. 21
      fir_ser/api/utils/serializer.py
  6. 17
      fir_ser/api/utils/storage/caches.py
  7. 6
      fir_ser/api/utils/utils.py
  8. 26
      fir_ser/api/views/supersign.py
  9. 7
      fir_ser/common/base/baseutils.py
  10. 1
      fir_ser/fir_ser/settings.py

@ -41,6 +41,7 @@
</p>
<p>该应用已经消耗 {{ option.app_used_number }} 个设备数</p>
<p>描述: {{ option.description }}</p>
<p>账户状态: {{ option.status_display }}</p>
<div slot="reference" class="name-wrapper">
<div>

@ -203,6 +203,31 @@
</span>
</el-dialog>
<el-dialog :close-on-click-modal="false" :destroy-on-close="true" :visible.sync="setdeveloperstatusVisible"
style="text-align:center" title="批量修改账户状态" width="700px">
<el-select v-model="change_developer_status" clearable
placeholder="账户状态" style="width: 49%;margin-right: 45px;margin-bottom: 10px">
<el-option
v-for="item in status_choices"
:key="item.id"
:disabled="item.disabled"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-button @click="setdeveloperstatus">确定</el-button>
<el-button @click="setdeveloperstatusVisible=false">取消</el-button>
<div style="text-align: left">
<p>受影响的开发者ID</p>
<el-row v-for="isid in multipleSelection" :key="isid.issuer_id">
<el-col :span="16">账户ID{{ isid.issuer_id }}</el-col>
<el-col :span="8">当前状态{{ format_status(isid.status) }}</el-col>
</el-row>
</div>
</el-dialog>
<el-tabs v-model="activeName" tab-position="top" type="border-card" @tab-click="handleClick">
<el-tab-pane label="开发者账户" name="iosdeveloper">
<el-input
@ -237,32 +262,41 @@
</div>
<el-row>
<el-col :span="24"><div>
<el-select v-model="developer_status_choice" clearable multiple
placeholder="账户状态" style="width: 49%;margin-right: 45px;margin-bottom: 10px">
<el-option
v-for="item in status_choices"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-button icon="el-icon-search" type="primary" @click="handleCurrentChange(1)">
搜索
</el-button>
</div>
<el-col :span="24">
<div>
<el-select v-model="developer_status_choice" clearable multiple
placeholder="账户状态" style="width: 49%;margin-right: 45px;margin-bottom: 10px">
<el-option
v-for="item in status_choices"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-button icon="el-icon-search" type="primary" @click="handleCurrentChange(1)">
搜索
</el-button>
<el-button type="plain" @click="activemanydeveloperFun">
账户状态检测
</el-button>
<el-button type="plain" @click="setdeveloperstatusFun">
批量设置账户状态
</el-button>
</div>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="app_developer_lists"
border
stripe
style="width: 100%">
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="39">
</el-table-column>
<el-table-column
align="center"
fixed
@ -321,14 +355,14 @@
<p v-if="!scope.row.certid && scope.row.status!==0">
开发证书不可用请在编辑中导入或手动创建发布证书</p>
<p v-if="!scope.row.certid && scope.row.status=== 0">请先激活开发者账户</p>
<p v-if="scope.row.certid && scope.row.status!==0">{{ format_status(scope.row) }}</p>
<p v-if="scope.row.certid && scope.row.status!==0">{{ format_status(scope.row.status) }}</p>
<div slot="reference" class="name-wrapper">
<div v-if="scope.row.certid">
<el-button v-if="scope.row.status === 1" size="small" type="success">
{{ format_status(scope.row) }}
{{ format_status(scope.row.status) }}
</el-button>
<el-button v-else size="small" type="warning" @click="activedeveloperFun(scope.row,'checkauth')">
{{ format_status(scope.row) }}
{{ format_status(scope.row.status) }}
</el-button>
</div>
@ -585,6 +619,7 @@
<el-popover placement="top" trigger="hover">
<p>开发者ID: {{ scope.row.developer_id }}</p>
<p>开发者备注: {{ scope.row.developer_description }}</p>
<p>开发者状态: {{ scope.row.developer_status }}</p>
<div slot="reference" class="name-wrapper">
<span>{{ scope.row.developer_id }}</span>
</div>
@ -664,6 +699,7 @@
<el-popover placement="top" trigger="hover">
<p>开发者ID: {{ scope.row.developer_id }}</p>
<p>开发者备注: {{ scope.row.developer_description }}</p>
<p>开发者状态: {{ scope.row.developer_status }}</p>
<div slot="reference" class="name-wrapper">
<span>{{ scope.row.developer_id }}</span>
</div>
@ -771,6 +807,7 @@
<el-popover placement="top" trigger="hover">
<p>开发者ID: {{ scope.row.issuer_id }}</p>
<p>开发者备注: {{ scope.row.developer_description }}</p>
<p>开发者状态: {{ scope.row.developer_status }}</p>
<div slot="reference" class="name-wrapper">
<span>{{ scope.row.issuer_id }}</span>
</div>
@ -1071,7 +1108,10 @@ export default {
appletoapp_title: '',
status_choices: [],
read_only_mode: 'off',
developer_status_choice: []
developer_status_choice: [],
multipleSelection: [],
setdeveloperstatusVisible: false,
change_developer_status: ''
}
}, watch: {
'dialogaddDeveloperVisible': function () {
@ -1081,14 +1121,34 @@ export default {
}
},
methods: {
setdeveloperstatusFun() {
if (this.multipleSelection && this.multipleSelection.length > 0) {
this.setdeveloperstatusVisible = true
} else {
this.$message.warning("开发者账户未选择")
}
},
setdeveloperstatus() {
if (this.change_developer_status === '') {
this.$message.warning("账户状态未选择")
} else {
this.iosdeveloperFun({
"methods": "PUT",
"data": {"issuer_ids": this.getIssuerIds(), "act": 'setstatus', "status": this.change_developer_status}
});
}
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
sort_method_usable_number(a, b) {
return this.formatter_usable_number(a) - this.formatter_usable_number(b)
},
formatter_usable_number(row) {
return row.usable_number - row.developer_used_number > 0 ? row.usable_number - row.developer_used_number : 0
},
format_status(row) {
return format_choices(row.status, this.status_choices)
format_status(status) {
return format_choices(status, this.status_choices)
},
downloadipa(info) {
this.loading = true;
@ -1303,6 +1363,21 @@ export default {
activedeveloperFun(developer, act) {
this.iosdeveloperFun({"methods": "PUT", "data": {"issuer_id": developer.issuer_id, "act": act}});
},
activemanydeveloperFun() {
let issuer_ids = this.getIssuerIds()
if (issuer_ids.length === 0) {
this.$message.warning("开发者账户未选择")
} else {
this.iosdeveloperFun({"methods": "PUT", "data": {"issuer_ids": issuer_ids, "act": 'checkauth'}});
}
},
getIssuerIds() {
let issuer_ids = []
for (let i = 0; i < this.multipleSelection.length; i++) {
issuer_ids.push(this.multipleSelection[i]['issuer_id'])
}
return issuer_ids
},
canceledit() {
this.dialogaddDeveloperVisible = false;
this.editdeveloperinfo = {auth_type: 0, usable_number: 100, app_limit_number: 100};
@ -1461,7 +1536,13 @@ export default {
}
}
}
if (params.methods === 'PUT') {
this.$message.success("操作成功");
}
if (params.data.act === 'setstatus') {
this.setdeveloperstatusVisible = false
this.change_developer_status = ''
}
if (this.dialogaddDeveloperVisible) {
this.canceledit();
this.$message.success("操作成功");
@ -1632,7 +1713,7 @@ export default {
<style scoped>
.el-main {
margin: 20px auto 100px;
width: 1166px;
width: 1188px;
position: relative;
padding-bottom: 1px;
color: #9b9b9b;

@ -31,7 +31,7 @@ from common.base.baseutils import file_format_path, delete_app_profile_file, get
get_format_time, make_app_uuid, make_from_user_uuid
from common.base.magic import run_function_by_locker, call_function_try_attempts
from common.cache.state import CleanErrorBundleIdSignDataState
from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, MOBILE_CONFIG_SIGN_SSL, MSGTEMPLATE
from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, MOBILE_CONFIG_SIGN_SSL, MSGTEMPLATE, DEVELOPER_USE_STATUS
logger = logging.getLogger(__name__)
@ -286,7 +286,7 @@ def get_developer_user_by_app_udid(user_objs, udid, app_obj, private_first=True,
"""
if read_only:
status_choice = [1, 2, 3, 4, 5]
status_choice = DEVELOPER_USE_STATUS
else:
status_choice = [1]
status_filter = {'developerid__certid__isnull': False, 'developerid__status__in': status_choice}

@ -71,21 +71,15 @@ def auto_check_ios_developer_active():
userinfo = ios_developer.user_id
err_issuer_id = error_issuer_id.get(userinfo.uid, [])
if userinfo.supersign_active:
count = 3
while count > 0:
status, result = IosUtils.active_developer(ios_developer)
msg = f"auto_check_ios_developer_active user:{userinfo} ios.developer:{ios_developer} status:{status} result:{result}"
if status:
IosUtils.get_device_from_developer(ios_developer)
logger.info(msg)
break
else:
count -= 1
time.sleep(5)
if count == 0:
err_issuer_id.append(ios_developer.issuer_id)
logger.error(msg)
error_issuer_id[userinfo.uid] = list(set(err_issuer_id))
status, result = IosUtils.active_developer(ios_developer)
msg = f"auto_check_ios_developer_active user:{userinfo} ios.developer:{ios_developer} status:{status} result:{result}"
if status:
IosUtils.get_device_from_developer(ios_developer)
logger.info(msg)
else:
err_issuer_id.append(ios_developer.issuer_id)
logger.error(msg)
error_issuer_id[userinfo.uid] = list(set(err_issuer_id))
for uid, val in error_issuer_id.items():
userinfo = UserInfo.objects.filter(uid=uid).first()
send_ios_developer_active_status(userinfo, MSGTEMPLATE.get('AUTO_CHECK_DEVELOPER') % (

@ -13,6 +13,7 @@ from api.utils.storage.storage import Storage
from api.utils.utils import get_developer_udided
from common.base.baseutils import get_choices_dict, get_choices_name_from_key
from common.cache.storage import AdPicShowCache
from fir_ser.settings import DEVELOPER_USE_STATUS
logger = logging.getLogger(__name__)
@ -500,6 +501,7 @@ class DeveloperSerializer(serializers.ModelSerializer):
app_usable_number = serializers.SerializerMethodField()
app_used_number = serializers.SerializerMethodField()
private_usable_number = serializers.SerializerMethodField()
status_display = serializers.CharField(source="get_status_display")
def get_app_usable_number(self, obj):
app_id = self.context.get('app_id')
@ -527,7 +529,7 @@ class DeveloperSerializer(serializers.ModelSerializer):
app_id = self.context.get('app_id', '')
if app_id:
developer_app_obj = models.DeveloperAppID.objects.filter(developerid=obj,
developerid__status__in=[1, 2, 3, 4, 5],
developerid__status__in=DEVELOPER_USE_STATUS,
developerid__certid__isnull=False)
if developer_app_obj.filter(app_id__app_id=app_id).distinct().count():
return False
@ -575,7 +577,7 @@ class SuperSignUsedSerializer(serializers.ModelSerializer):
class Meta:
model = models.APPSuperSignUsedInfo
fields = ["created_time", "device_udid", "device_name", "developer_id", "bundle_id", "bundle_name", "other_uid",
"developer_description"]
"developer_description", "developer_status"]
device_udid = serializers.CharField(source="udid.udid.udid")
device_name = serializers.CharField(source="udid.product")
@ -584,6 +586,13 @@ class SuperSignUsedSerializer(serializers.ModelSerializer):
other_uid = serializers.SerializerMethodField()
developer_id = serializers.SerializerMethodField()
developer_description = serializers.SerializerMethodField()
developer_status = serializers.SerializerMethodField()
def get_developer_status(self, obj):
if self.context.get('mine'):
return obj.developerid.get_status_display()
else:
return '公共账号池'
def get_developer_id(self, obj):
if self.context.get('mine'):
@ -629,6 +638,7 @@ class DeveloperDeviceSerializer(serializers.ModelSerializer):
developer_id = serializers.CharField(source="developerid.issuer_id")
developer_description = serializers.CharField(source="developerid.description")
developer_status = serializers.CharField(source="developerid.get_status_display")
class DeviceUDIDSerializer(serializers.ModelSerializer):
@ -641,6 +651,7 @@ class DeviceUDIDSerializer(serializers.ModelSerializer):
bundle_id = serializers.CharField(source="app_id.bundle_id")
issuer_id = serializers.SerializerMethodField()
developer_description = serializers.SerializerMethodField()
developer_status = serializers.SerializerMethodField()
udid = serializers.CharField(source="udid.udid")
is_mine = serializers.SerializerMethodField()
other_uid = serializers.SerializerMethodField()
@ -651,6 +662,12 @@ class DeviceUDIDSerializer(serializers.ModelSerializer):
else:
return '公共账号池'
def get_developer_status(self, obj):
if self.context.get('mine'):
return obj.udid.developerid.get_status_display()
else:
return '公共账号池'
def get_developer_description(self, obj):
if self.context.get('mine'):
return obj.udid.developerid.description

@ -24,7 +24,7 @@ from common.cache.storage import AppDownloadTodayTimesCache, AppDownloadTimesCac
UploadTmpFileNameCache, RedisCacheBase, UserCanDownloadCache, UserFreeDownloadTimesCache, WxTicketCache, \
SignUdidQueueCache, CloudStorageCache
from fir_ser.settings import CACHE_KEY_TEMPLATE, SERVER_DOMAIN, SYNC_CACHE_TO_DATABASE, DEFAULT_MOBILEPROVISION, \
USER_FREE_DOWNLOAD_TIMES, AUTH_USER_FREE_DOWNLOAD_TIMES
USER_FREE_DOWNLOAD_TIMES, AUTH_USER_FREE_DOWNLOAD_TIMES, DEVELOPER_USE_STATUS
logger = logging.getLogger(__name__)
@ -45,15 +45,16 @@ def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='',
if app_obj.get('issupersign', None):
download_url_type = 'mobileconifg'
else:
appudid_obj = AppUDID.objects.filter(app_id_id=app_obj.get("pk"), udid__udid=udid, is_signed=True).first()
appudid_obj = AppUDID.objects.filter(app_id_id=app_obj.get("pk"), udid__udid=udid, is_signed=True).last()
if appudid_obj:
super_sign_obj = APPSuperSignUsedInfo.objects.filter(udid__udid__udid=udid,
app_id_id=app_obj.get("pk")).first()
app_id_id=app_obj.get("pk"),
developerid__status__in=DEVELOPER_USE_STATUS).last()
if super_sign_obj and super_sign_obj.user_id.supersign_active:
app_to_developer_obj = APPToDeveloper.objects.filter(app_id_id=app_obj.get("pk"),
developerid=super_sign_obj.developerid).first()
developerid=super_sign_obj.developerid).last()
if app_to_developer_obj:
release_obj = AppReleaseInfo.objects.filter(app_id_id=app_obj.get("pk"), is_master=True).first()
release_obj = AppReleaseInfo.objects.filter(app_id_id=app_obj.get("pk"), is_master=True).last()
if release_obj.release_id == app_to_developer_obj.release_file:
binary_file = app_to_developer_obj.binary_file
else:
@ -546,11 +547,9 @@ def get_app_download_url(request, res, app_id, short, password, release_id, isdo
else:
app_type = '.ipa'
if isdownload:
download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600,
udid=udid)
download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, udid=udid)
else:
download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600,
isdownload,
download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, isdownload,
udid=udid)
res.data = {"download_url": download_url, "extra_url": extra_url}

@ -23,7 +23,7 @@ from api.utils.storage.localApi import LocalStorage
from api.utils.storage.storage import Storage
from common.base.baseutils import get_real_ip_address
from common.cache.storage import UserTokenCache, TempCache
from fir_ser.settings import SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT
from fir_ser.settings import SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT, DEVELOPER_USE_STATUS
logger = logging.getLogger(__name__)
@ -61,13 +61,13 @@ def get_developer_devices(developer_obj_lists):
other_used_sum = 0
flyapp_used_sum = 0
max_total = 0
for dev_obj in developer_obj_lists.filter(status__in=[1, 2, 3, 4, 5]):
for dev_obj in developer_obj_lists.filter(status__in=DEVELOPER_USE_STATUS):
other_used, flyapp_used, _ = get_developer_udided(dev_obj)
other_used_sum += other_used
flyapp_used_sum += flyapp_used
max_total += 100
use_number_obj_list = developer_obj_lists.filter(status__in=[1, 2, 3, 4, 5])
use_number_obj_list = developer_obj_lists.filter(status__in=DEVELOPER_USE_STATUS)
all_use_number = 0
all_usable_number = 0
for use_number_obj in use_number_obj_list:

@ -23,8 +23,9 @@ from api.utils.serializer import DeveloperSerializer, SuperSignUsedSerializer, D
DeveloperDeviceSerializer, AppleDeveloperToAppUseSerializer, AppleDeveloperToAppUseAppsSerializer
from api.utils.storage.caches import get_app_download_url
from api.utils.utils import get_developer_devices
from common.base.baseutils import get_choices_dict
from common.base.baseutils import get_choices_dict, get_choices_name_from_key
from common.cache.state import CleanSignDataState
from fir_ser.settings import DEVELOPER_USE_STATUS
logger = logging.getLogger(__name__)
@ -72,7 +73,7 @@ class DeveloperView(APIView):
res.data = developer_serializer.data
res.count = developer_obj.count()
res.status_choices = get_choices_dict(AppIOSDeveloperInfo.status_choices)
res.status_choices = get_choices_dict(AppIOSDeveloperInfo.status_choices, [2, 4, 5])
res.apple_auth_list = get_choices_dict(AppIOSDeveloperInfo.auth_type_choices)
return Response(res.dict)
@ -88,13 +89,30 @@ class DeveloperView(APIView):
res = BaseResponse()
result_list = []
for developer_s_obj in AppIOSDeveloperInfo.objects.filter(user_id=request.user,
status__in=[1, 2, 3, 4, 5]).all():
status__in=DEVELOPER_USE_STATUS).all():
status, result = IosUtils.get_device_from_developer(developer_s_obj)
if not status:
result_list.append(result.get("err_info"))
if len(result_list):
logger.warning(result_list)
return Response(res.dict)
elif act == "checkauth":
issuer_ids = data.get("issuer_ids", [])
if issuer_ids:
for developer_s_obj in AppIOSDeveloperInfo.objects.filter(user_id=request.user,
issuer_id__in=issuer_ids).all():
status, result = IosUtils.active_developer(developer_s_obj)
if status:
IosUtils.get_device_from_developer(developer_s_obj)
elif act == "setstatus":
issuer_ids = data.get("issuer_ids", [])
status = data.get("status", None)
if issuer_ids and status is not None:
status_text = get_choices_name_from_key(AppIOSDeveloperInfo.status_choices, status)
if status_text:
AppIOSDeveloperInfo.objects.filter(user_id=request.user, issuer_id__in=issuer_ids).update(
status=status)
return Response(res.dict)
if developer_obj:
@ -553,7 +571,7 @@ class AppleDeveloperBindAppsView(APIView):
for item in add_issuer_ids:
developer_obj = AppIOSDeveloperInfo.objects.filter(issuer_id=item, user_id=request.user,
status__in=[1, 2, 3, 4, 5],
status__in=DEVELOPER_USE_STATUS,
certid__isnull=False).first()
developer_aid_obj = DeveloperAppID.objects.filter(developerid=developer_obj)
is_exist = developer_aid_obj.filter(app_id=app_obj).count()

@ -306,11 +306,14 @@ def get_order_num(order_type=1):
random.randint(1000, 9999))
def get_choices_dict(choices):
def get_choices_dict(choices, disabled_choices=None):
result = []
choices_org_list = list(choices)
for choice in choices_org_list:
result.append({'id': choice[0], 'name': choice[1]})
val = {'id': choice[0], 'name': choice[1], 'disabled': False}
if disabled_choices and isinstance(disabled_choices, list) and choice[0] in disabled_choices:
val['disabled'] = True
result.append(val)
return result

@ -249,6 +249,7 @@ USER_FREE_DOWNLOAD_TIMES = 5
AUTH_USER_FREE_DOWNLOAD_TIMES = 10
NEW_USER_GIVE_DOWNLOAD_TIMES = 100
AUTH_USER_GIVE_DOWNLOAD_TIMES = 200
DEVELOPER_USE_STATUS = [1, 2, 3, 4, 5] # 开发者可用状态,详情查看 model.AppIOSDeveloperInfo
SYNC_CACHE_TO_DATABASE = {
'download_times': 10, # 下载次数同步时间

Loading…
Cancel
Save