优化代码,修改已知问题

publicsignpoll
youngS 3 years ago
parent 4c29d32d67
commit 002c90d5e3
  1. 7
      fir_client/src/components/apps/FirApps.vue
  2. 174
      fir_client/src/components/user/FirSuperSignBase.vue
  3. 6
      fir_client/src/utils/index.js
  4. 19
      fir_ser/api/migrations/0022_iosdeveloperpublicpoolbill_app_id.py
  5. 16
      fir_ser/api/migrations/0023_remove_appudid_binary_file.py
  6. 6
      fir_ser/api/models.py
  7. 4
      fir_ser/api/tasks.py
  8. 9
      fir_ser/api/utils/app/apputils.py
  9. 73
      fir_ser/api/utils/app/supersignutils.py
  10. 52
      fir_ser/api/utils/modelutils.py
  11. 10
      fir_ser/api/utils/serializer.py
  12. 19
      fir_ser/api/utils/storage/caches.py
  13. 12
      fir_ser/api/views/apps.py
  14. 34
      fir_ser/api/views/supersign.py
  15. 17
      fir_ser/api/views/uploads.py

@ -175,6 +175,9 @@
}} UDID
</el-link>
</el-col>
<el-col :span="6" v-if="analyseappinfo.sign && analyseappinfo.type === 'iOS'">
<el-checkbox v-model="enable_sign">开启超级签</el-checkbox>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 18px;">
<el-col :span="18">
@ -597,6 +600,7 @@
pay_choices: [],
analyseappinfo: {icon: ''},
short: '',
enable_sign: '',
keysearch: '',
searchfromtype: '',
applists: [],
@ -672,6 +676,7 @@
analyseApps(data => {
if (data.code === 1000) {
this.short = data.data.short;
this.enable_sign = data.data.enable_sign;
for (let name of Object.keys(data.data)) {
analyseappinfo[name] = data.data[name]
}
@ -773,6 +778,7 @@
this.$message.success(file.raw.name + '上传成功');
if (!multiFlag) {
analyseappinfo.short = this.short;
analyseappinfo.enable_sign = this.enable_sign;
}
const loading = this.$loading({
lock: true,
@ -817,6 +823,7 @@
const pnumber = 20;
this.uploadprocess[process_key].process = process;
this.uploadprocess[process_key].short = analyseappinfo.short;
this.uploadprocess[process_key].enable_sign = analyseappinfo.enable_sign;
this.uploadprocess[process_key].appname = analyseappinfo.appname;
if (process > 0) {
let percent = this.uploadprocess[process_key].percent;

@ -94,6 +94,81 @@
</el-form>
</el-dialog>
<el-dialog title="设备消耗详细信息" :destroy-on-close="true" :visible.sync="dialogShowDeviceBillInfo"
:close-on-click-modal="false" center width="750px">
<el-table
:data="app_bill_info_lists"
v-loading="loading"
border
stripe
style="width: 100%">
<el-table-column
prop="app_name"
align="center"
label="应用名称"
>
</el-table-column>
<el-table-column
prop="remote_addr"
align="center"
label="客户端IP">
</el-table-column>
<el-table-column
prop="action"
label="账单类型"
align="center"
width="100">
</el-table-column>
<el-table-column
:formatter="deviceformatter"
align="center"
prop="created_time"
label="日期"
width="160">
</el-table-column>
<el-table-column
label="应用状态"
align="center"
width="110">
<template slot-scope="scope">
<el-tag v-if="scope.row.app_status===false" type="info">应用删除</el-tag>
<el-tag v-else>
应用存在
</el-tag>
</template>
</el-table-column>
<el-table-column
label="设备状态"
align="center"
width="110">
<template slot-scope="scope">
<el-tag v-if="scope.row.is_used===false" type="info">已经释放</el-tag>
<el-tag v-else>
使用中
</el-tag>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 20px">
<el-pagination
@size-change="billhandleSizeChange"
@current-change="billhandleCurrentChange"
:current-page.sync="billpagination.currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="billpagination.pagesize"
layout="total,sizes, prev, pager, next"
:total="billpagination.total">
</el-pagination>
</div>
<span slot="footer">
<el-button @click="closeDeviceBillInfo">关闭</el-button>
</span>
</el-dialog>
<el-tabs v-model="activeName" type="border-card" @tab-click="handleClick" tab-position="top">
<el-tab-pane label="开发者账户" name="iosdeveloper">
<el-input
@ -298,7 +373,7 @@
<h1>注意事项</h1>
<p>1.添加后请勿撤销 API 密钥否则会导致用户安装的软件闪退或无法安装</p>
<p>2.每个开发者账号最多可创建两本证书请确保至少还可以创建一本证书</p>
<p>3.添加后系统自动创建证书设备和描述文件请勿删除这些文件否则会导致用户安装的软件闪退或无法安装</p>
<p>3.添加后激活开发者账户然后您就可以上传p12证书或者通过系统自动创建证书设备和描述文件请勿删除这些文件否则会导致用户安装的软件闪退或无法安装</p>
</el-card>
</el-tab-pane>
@ -499,47 +574,34 @@
align="center"
label="设备ID"
>
<template slot-scope="scope">
<el-tooltip effect="dark" content="点击查看设备安装详细信息" placement="top">
<el-link :underline="false" @click="showDeviceBill(scope.row.udid)">
{{ scope.row.udid }}
</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column
prop="version"
prop="product"
label="设备名称"
width="200"
align="center">
<template slot-scope="scope">
{{scope.row.product}} {{scope.row.version}}
</template>
</el-table-column>
<el-table-column
width="100"
prop="app_name"
prop="version"
align="center"
label="消费者"
label="设备版本"
>
</el-table-column>
<el-table-column
prop="remote_addr"
align="center"
label="客户端IP"
width="100">
</el-table-column>
<el-table-column
prop="action"
label="账单类型"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="description"
label="备注"
prop="counts"
align="center"
width="200">
</el-table-column>
<el-table-column
:formatter="deviceformatter"
align="center"
prop="created_time"
label="生成日期"
width="160">
label="设备安装次数"
width="110">
</el-table-column>
<el-table-column
@ -547,7 +609,7 @@
align="center"
width="110">
<template slot-scope="scope">
<el-tag v-if="scope.row.is_used===false" type="info">已经释放</el-tag>
<el-tag v-if="!scope.row.udid_sync_info_id" type="info">已经释放</el-tag>
<el-tag v-else>
使用中
</el-tag>
@ -582,10 +644,13 @@
name: "FirSuperSignBase",
data() {
return {
dialogShowDeviceBillInfo: false,
currentudid: '',
fileList: [],
app_developer_lists: [],
app_devices_lists: [],
app_bill_lists: [],
app_bill_info_lists: [],
app_udid_lists: [],
activeName: "iosdeveloper",
udidsearch: "",
@ -598,6 +663,7 @@
isedit: false,
placeholder: "",
pagination: {"currentPage": 1, "total": 0, "pagesize": 10},
billpagination: {"currentPage": 1, "total": 0, "pagesize": 10},
developer_used_info: {"all_usable_number": 0, "other_used_sum": 0, "all_use_number": 0},
percentage: 0,
apple_auth_list: [],
@ -614,6 +680,38 @@
}
},
methods: {
closeDeviceBillInfo() {
this.dialogShowDeviceBillInfo = false;
this.currentudid = '';
this.app_bill_info_lists = [];
},
showDeviceBill(udid) {
this.currentudid = udid;
this.iosdevicebillFun({"methods": "GET", "data": {'udid': udid, 'act': 'info'}});
this.dialogShowDeviceBillInfo = true;
},
billhandleSizeChange(val) {
this.billpagination.pagesize = val;
this.iosdevicebillFun({
"methods": "GET", "data": {
"size": this.billpagination.pagesize,
"page": 1,
"act": "info",
'udid': this.currentudid
}
})
},
billhandleCurrentChange(val) {
this.billpagination.currentPage = val;
this.iosdevicebillFun({
"methods": "GET", "data": {
"size": this.billpagination.pagesize,
"page": this.billpagination.currentPage,
"act": "info",
'udid': this.currentudid
}
})
},
beforeAvatarUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2;
if (file.type === 'application/x-pkcs12') {
@ -889,18 +987,22 @@
}
}, params)
},
iosdevicebillFun(data) {
iosdevicebillFun(params) {
this.loading = true;
DeviceBillInfo(data => {
if (data.code === 1000) {
this.app_bill_lists = data.data;
this.pagination.total = data.count;
if (params.data.act && params.data.act === 'info') {
this.app_bill_info_lists = data.data;
this.billpagination.total = data.count;
} else {
this.app_bill_lists = data.data;
this.pagination.total = data.count;
}
} else {
this.$message.error("操作失败了 " + data.msg);
}
this.loading = false
}, data)
}, params)
},
iosdevicesudidFun(action, data, scope) {
if (action !== 'GET') {

@ -140,7 +140,7 @@ function get_file_type(upload_key) {
function get_filename(app_info, upload_key) {
if (app_info) {
let app_type = app_info.type;
if (app_type === 'iOS' || app_info === 'Android') {
if (app_type === 'iOS' || app_type === 'Android') {
return app_info.appname + '-' + app_info.version + '-' + app_info.short + '.' + get_file_type(upload_key)
}
}
@ -196,6 +196,10 @@ export function uploadaliyunoss(file, certinfo, app, successcallback, processcal
'Content-Disposition': 'attachment; filename="' + encodeURIComponent(filename) + '"',
'Cache-Control': ''
}
} else {
options['headers'] = {
'Cache-Control': ''
}
}
if (currentCheckpoint) {

@ -0,0 +1,19 @@
# Generated by Django 3.2.3 on 2021-11-06 13:04
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0021_appreportinfo'),
]
operations = [
migrations.AddField(
model_name='iosdeveloperpublicpoolbill',
name='app_id',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='api.apps',
verbose_name='属于哪个APP'),
),
]

@ -0,0 +1,16 @@
# Generated by Django 3.2.3 on 2021-11-06 16:14
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0022_iosdeveloperpublicpoolbill_app_id'),
]
operations = [
migrations.RemoveField(
model_name='appudid',
name='binary_file',
),
]

@ -236,7 +236,6 @@ class AppStorage(models.Model):
class AppUDID(models.Model):
app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP")
# udid = models.CharField(max_length=64, verbose_name="udid唯一标识", db_index=True)
udid = models.ForeignKey(to="UDIDsyncDeveloper", verbose_name="udid唯一标识", on_delete=models.CASCADE)
product = models.CharField(max_length=64, verbose_name="产品", blank=True, null=True, )
serial = models.CharField(max_length=64, verbose_name="序列号", blank=True, null=True, )
@ -247,7 +246,6 @@ class AppUDID(models.Model):
updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
is_signed = models.BooleanField(verbose_name="是否完成签名打包", default=False)
is_download = models.BooleanField(verbose_name="描述文件是否已经下载", default=False)
binary_file = models.CharField(max_length=128, blank=True, verbose_name="签名包名称", null=True)
class Meta:
verbose_name = '设备详情'
@ -541,9 +539,7 @@ class IosDeveloperPublicPoolBill(models.Model):
developer_info = models.JSONField(max_length=256, verbose_name="开发者信息", null=True, blank=True)
udid_sync_info = models.ForeignKey(to="UDIDsyncDeveloper", on_delete=models.SET_NULL, verbose_name="关联同步设备信息",
null=True, blank=True)
# 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)
app_id = models.ForeignKey(to="Apps", on_delete=models.SET_NULL, verbose_name="属于哪个APP", null=True, blank=True)
description = models.CharField(verbose_name="操作描述", max_length=128, default='', blank=True)
remote_addr = models.GenericIPAddressField(verbose_name="远程IP地址")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="添加时间")

@ -49,10 +49,10 @@ def run_sign_task(format_udid_info, short, client_ip):
@shared_task
def run_resign_task(app_id, need_download_profile=True):
def run_resign_task(app_id, need_download_profile=True, force=True):
app_obj = Apps.objects.filter(app_id=app_id).first()
with cache.lock("%s_%s" % ('task_resign', app_id), timeout=60 * 60):
return resign_by_app_id(app_obj, need_download_profile)
return resign_by_app_id(app_obj, need_download_profile, force)
@app.task

@ -114,7 +114,7 @@ def get_random_short(number=4):
return short_url
def save_app_infos(app_file_name, user_obj, app_info, bundle_id, app_img, short, size):
def save_app_infos(app_file_name, user_obj, app_info, bundle_id, app_img, short, size, issupersign):
app_uuid = make_app_uuid(user_obj, bundle_id + app_file_name.split(".")[1])
##判断是否存在该app
app_obj = Apps.objects.filter(app_id=app_uuid, user_id=user_obj).first()
@ -129,6 +129,7 @@ def save_app_infos(app_file_name, user_obj, app_info, bundle_id, app_img, short,
"name": app_info["labelname"],
"new_bundle_name": app_info["labelname"],
"short": short,
"issupersign": issupersign,
"bundle_id": bundle_id,
"count_hits": 0,
"wxeasytype": False if get_user_domain_name(user_obj) else True
@ -145,14 +146,16 @@ def save_app_infos(app_file_name, user_obj, app_info, bundle_id, app_img, short,
is_new_app = False
app_obj.short = short
app_obj.name = app_info["labelname"]
app_obj.issupersign = issupersign
# appmobj.wxeasytype = False if user_obj.domain_name or appmobj.domain_name else True
app_obj.bundle_id = bundle_id
app_obj.save(update_fields=["short", "name", "bundle_id"])
app_obj.save(update_fields=["short", "name", "bundle_id", "issupersign"])
except Exception as e:
logger.error(f"save app info failed,app_obj:{app_obj} Exception:{e}")
app_obj.bundle_id = bundle_id
app_obj.issupersign = issupersign
app_obj.name = app_info["labelname"]
app_obj.save(update_fields=["name", "bundle_id"])
app_obj.save(update_fields=["name", "bundle_id", "issupersign"])
del_cache_response_by_short(app_obj.app_id)
AppReleaseInfo.objects.filter(app_id=app_obj).update(is_master=False)

@ -12,13 +12,13 @@ import zipfile
import xmltodict
from django.core.cache import cache
from django.db.models import Sum
from api.models import APPSuperSignUsedInfo, AppUDID, AppIOSDeveloperInfo, AppReleaseInfo, Apps, APPToDeveloper, \
UDIDsyncDeveloper, DeveloperAppID, DeveloperDevicesID, IosDeveloperPublicPoolBill
from api.utils.app.iossignapi import ResignApp, AppDeveloperApiV2
from api.utils.baseutils import file_format_path, delete_app_profile_file, get_profile_full_path, format_apple_date, \
get_format_time, make_app_uuid, make_from_user_uuid
from api.utils.modelutils import get_ios_developer_public_num, check_ipa_is_latest_sign
from api.utils.response import BaseResponse
from api.utils.serializer import BillAppInfoSerializer, BillDeveloperInfoSerializer
from api.utils.storage.caches import del_cache_response_by_short, send_msg_over_limit, check_app_permission, \
@ -42,12 +42,14 @@ def check_org_file(user_obj, org_file):
return download_files_form_oss(storage_obj, org_file)
def resign_by_app_id(app_obj, need_download_profile=True):
def resign_by_app_id(app_obj, need_download_profile=True, force=True):
user_obj = app_obj.user_id
info_list = []
if app_obj.issupersign and user_obj.supersign_active:
for developer_app_id_obj in DeveloperAppID.objects.filter(app_id=app_obj).all():
developer_obj = developer_app_id_obj.developerid
if check_ipa_is_latest_sign(app_obj, developer_obj) and not force:
continue
developer_app_id = developer_app_id_obj.aid
d_time = time.time()
if need_download_profile:
@ -57,8 +59,7 @@ 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):
status, result = 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, '', d_time, {})
info_list.append({'developer_id': developer_obj.issuer_id, 'result': (status, result)})
return info_list
@ -199,21 +200,6 @@ def err_callback(func, *args, **kwargs):
return wrapper
def get_ios_developer_public_num(user_obj):
add_number = IosDeveloperPublicPoolBill.objects.filter(to_user_id=user_obj, action__in=[1, 2]).aggregate(
number=Sum('number'))
used_number = IosDeveloperPublicPoolBill.objects.filter(user_id=user_obj, action=0,
udid_sync_info__isnull=False).aggregate(
number=Sum('number'))
add_number = add_number.get("number", 0)
if not add_number:
add_number = -99
used_number = used_number.get("number", 0)
if not used_number:
used_number = 0
return add_number - used_number
def get_developer_user_by_app_udid(user_obj, udid):
use_device_obj = APPSuperSignUsedInfo.objects.filter(udid__udid__udid=udid,
user_id=user_obj, developerid__is_actived=True,
@ -458,7 +444,8 @@ class IosUtils(object):
self.developer_obj).data,
action=0, number=1, udid_sync_info=udid_sync_info,
remote_addr=client_ip, product=udid_sync_info.product,
udid=self.udid, version=udid_sync_info.version
udid=self.udid, version=udid_sync_info.version,
app_id=self.app_obj
)
@staticmethod
@ -466,18 +453,14 @@ class IosUtils(object):
# 更新新签名的ipa包
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
}
# 更新已经完成签名状态,设备消耗记录,和开发者已消耗数量
udid_obj = UDIDsyncDeveloper.objects.filter(developerid=developer_obj, udid=udid).first()
AppUDID.objects.filter(app_id=app_obj, udid=udid_obj).update(**newdata)
if udid:
udid_obj = UDIDsyncDeveloper.objects.filter(developerid=developer_obj, udid=udid).first()
AppUDID.objects.filter(app_id=app_obj, udid=udid_obj).update(**{"is_signed": True})
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, udid, d_time, result, resign=False):
def run_sign(user_obj, app_obj, developer_obj, download_flag, udid, d_time, result):
d_result = {'code': 0, 'msg': 'success'}
start_time = time.time()
if download_flag:
@ -489,18 +472,11 @@ class IosUtils(object):
if status:
s_time1 = time.time()
logger.info(f"app_id {app_obj} exec sign ipa success. time:{s_time1 - start_time}")
if resign:
if not IosUtils.update_sign_file_name(user_obj, app_obj, developer_obj, release_obj,
random_file_name):
d_result['code'] = 1004
d_result['msg'] = '数据更新失败,请稍后重试'
return status, d_result
else:
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
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
else:
d_result['code'] = 1004
d_result['msg'] = '签名失败,请检查包是否正常'
@ -553,13 +529,16 @@ class IosUtils(object):
udid__developerid=self.developer_obj).first()
if app_udid_obj and app_udid_obj.is_download:
if app_udid_obj.is_signed:
release_obj = AppReleaseInfo.objects.filter(app_id=self.app_obj, is_master=True).first()
for apptodev_obj in APPToDeveloper.objects.filter(app_id=self.app_obj).all():
if release_obj.release_id == apptodev_obj.release_file:
msg = "udid %s exists app_id %s" % (self.udid, self.app_obj)
d_result['msg'] = msg
logger.info(d_result)
return True, d_result
# release_obj = AppReleaseInfo.objects.filter(app_id=self.app_obj, is_master=True).first()
if check_ipa_is_latest_sign(self.app_obj, self.developer_obj):
#
# for apptodev_obj in APPToDeveloper.objects.filter(app_id=self.app_obj).all():
# if release_obj.release_id == apptodev_obj.release_file:
msg = "udid %s exists app_id %s" % (self.udid, self.app_obj)
d_result['msg'] = msg
logger.info(d_result)
return True, d_result
else:
with cache.lock("%s_%s_%s" % ('run_sign', self.app_obj.app_id, self.developer_obj.issuer_id),
timeout=60 * 10):

@ -9,9 +9,10 @@ import logging
import random
from urllib.parse import urljoin
from django.db.models import Count
from django.db.models import Count, Sum
from api.models import AppReleaseInfo, UserDomainInfo, DomainCnameInfo, UserAdDisplayInfo, RemoteClientInfo
from api.models import AppReleaseInfo, UserDomainInfo, DomainCnameInfo, UserAdDisplayInfo, RemoteClientInfo, \
AppIOSDeveloperInfo, IosDeveloperPublicPoolBill, APPToDeveloper
from api.utils.baseutils import get_server_domain_from_request, get_user_default_domain_name, get_real_ip_address, \
get_origin_domain_name
@ -116,10 +117,51 @@ def check_app_domain_name_access(app_obj, access_domain_name, user_obj, extra_do
if extra_domain:
domain_list.append(extra_domain)
app_domain_name = get_app_domain_name(app_obj)
if app_domain_name: domain_list.append(app_domain_name)
if app_domain_name:
domain_list.append(app_domain_name)
user_domain_name = get_user_domain_name(user_obj)
if user_domain_name: domain_list.append(user_domain_name)
if user_domain_name:
domain_list.append(user_domain_name)
user_qr_domain_name = get_user_domain_name(user_obj, 0)
if user_qr_domain_name: domain_list.append(user_qr_domain_name)
if user_qr_domain_name:
domain_list.append(user_qr_domain_name)
if access_domain_name in domain_list:
return True
def get_ios_developer_public_num(user_obj):
add_number = IosDeveloperPublicPoolBill.objects.filter(to_user_id=user_obj, action__in=[1, 2]).aggregate(
number=Sum('number'))
used_number = IosDeveloperPublicPoolBill.objects.filter(user_id=user_obj, action=0,
udid_sync_info__isnull=False).aggregate(
number=Sum('number'))
add_number = add_number.get("number", 0)
if not add_number:
add_number = -99
used_number = used_number.get("number", 0)
if not used_number:
used_number = 0
return add_number - used_number
def check_super_sign_permission(user_obj):
developer_count = AppIOSDeveloperInfo.objects.filter(user_id=user_obj).count()
if not user_obj.supersign_active:
return False
if developer_count == 0 and get_ios_developer_public_num(user_obj) < 0:
return False
return True
def check_ipa_is_latest_sign(app_obj, developer_obj=None):
release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, is_master=True).first()
all_app_to_dev = APPToDeveloper.objects.filter(app_id=app_obj)
if developer_obj:
all_app_to_dev = all_app_to_dev.filter(developerid=developer_obj)
all_app_to_dev = all_app_to_dev.all()
t_count = 0
for apptodev_obj in all_app_to_dev:
if release_obj.release_id == apptodev_obj.release_file:
t_count += 1
if t_count == all_app_to_dev.count():
return True

@ -553,7 +553,7 @@ class DeviceUDIDSerializer(serializers.ModelSerializer):
class Meta:
model = models.AppUDID
# depth = 1
exclude = ["binary_file", "updated_time", "is_signed"]
exclude = ["updated_time", "is_signed"]
bundle_id = serializers.SerializerMethodField()
bundle_name = serializers.SerializerMethodField()
@ -742,12 +742,18 @@ class BillDeveloperInfoSerializer(serializers.ModelSerializer):
class BillInfoSerializer(serializers.ModelSerializer):
class Meta:
model = models.IosDeveloperPublicPoolBill
exclude = ["user_id", "to_user_id", "developer_info", "app_info", "udid_sync_info"]
exclude = ["user_id", "to_user_id", "developer_info", "app_info", "udid_sync_info", "app_id"]
app_name = serializers.SerializerMethodField()
action = serializers.SerializerMethodField()
description = serializers.SerializerMethodField()
is_used = serializers.SerializerMethodField()
app_status = serializers.SerializerMethodField()
def get_app_status(self, obj):
if obj.app_id:
return True
return False
def get_is_used(self, obj):
if obj.udid_sync_info or obj.to_user_id:

@ -502,25 +502,24 @@ def get_wx_ticket_login_info_cache(ticket):
class CacheBaseState(object):
prefix = ''
def __init__(self, prefix):
CacheBaseState.prefix = prefix
@classmethod
def get_state(cls, key):
return cache.get(f"{cls.prefix}_{key}")
return cache.get(f"{cls.__name__}_{key}")
@classmethod
def set_state(cls, key, value=time.time(), timeout=3600 * 24):
cls.del_state(f"{cls.prefix}_{key}")
cache.set(f"{cls.prefix}_{key}", value, timeout)
cls.del_state(f"{cls.__name__}_{key}")
cache.set(f"{cls.__name__}_{key}", value, timeout)
@classmethod
def del_state(cls, key):
cache.delete(f"{cls.prefix}_{key}")
cache.delete(f"{cls.__name__}_{key}")
class MigrateStorageState(CacheBaseState):
def __init__(self):
super().__init__('migrate_storage')
...
class CleanSignDataState(CacheBaseState):
...

@ -12,11 +12,11 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from api.base_views import app_delete
from api.models import Apps, AppReleaseInfo, APPToDeveloper, AppIOSDeveloperInfo, UserInfo, AppScreenShot
from api.models import Apps, AppReleaseInfo, APPToDeveloper, UserInfo, AppScreenShot
from api.tasks import run_resign_task
from api.utils.app.supersignutils import IosUtils, get_ios_developer_public_num
from api.utils.app.supersignutils import IosUtils
from api.utils.auth import ExpiringTokenAuthentication
from api.utils.modelutils import get_user_domain_name, get_app_domain_name
from api.utils.modelutils import get_user_domain_name, get_app_domain_name, check_super_sign_permission
from api.utils.response import BaseResponse
from api.utils.serializer import AppsSerializer, AppReleaseSerializer, AppsListSerializer
from api.utils.storage.caches import del_cache_response_by_short, get_app_today_download_times, del_cache_by_delete_app
@ -223,12 +223,12 @@ class AppInfoView(APIView):
# res.code = 1008
# res.msg = "超级签余额不足,无法开启"
# return Response(res.dict)
developer_count = AppIOSDeveloperInfo.objects.filter(user_id=request.user).count()
if developer_count == 0 and get_ios_developer_public_num(request.user) < 0:
if not check_super_sign_permission(request.user):
logger.error(f"app_id:{app_id} can't open super_sign,owner has no ios developer")
res.code = 1008
res.msg = "超级签余额不足,无法开启"
return Response(res.dict)
do_sign_flag = 3
app_obj.issupersign = data.get("issupersign", app_obj.issupersign)
update_fields.append("issupersign")
logger.info(f"app_id:{app_id} update new data:{app_obj.__dict__}")
@ -239,6 +239,8 @@ class AppInfoView(APIView):
c_task = run_resign_task.apply_async((app_obj.app_id, True))
if do_sign_flag == 2:
c_task = run_resign_task.apply_async((app_obj.app_id, False))
if do_sign_flag == 3:
c_task = run_resign_task.apply_async((app_obj.app_id, False, False))
if c_task:
msg = c_task.get(propagate=False)
logger.info(f"app {app_obj} run_resign_task msg:{msg}")

@ -5,7 +5,7 @@
# date: 2020/3/4
import logging
from django.db.models import Q
from django.db.models import Count
from django.http.response import FileResponse
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
@ -16,6 +16,7 @@ from api.utils.app.supersignutils import IosUtils
from api.utils.auth import ExpiringTokenAuthentication, SuperSignPermission
from api.utils.response import BaseResponse
from api.utils.serializer import DeveloperSerializer, SuperSignUsedSerializer, DeviceUDIDSerializer, BillInfoSerializer
from api.utils.storage.caches import CleanSignDataState
from api.utils.utils import get_developer_devices, get_choices_dict
logger = logging.getLogger(__name__)
@ -113,7 +114,13 @@ class DeveloperView(APIView):
return Response(res.dict)
elif act == "cleandevice":
if CleanSignDataState.get_state(request.user.uid):
res.code = 1008
res.msg = "数据清理中,请耐心等待"
return Response(res.dict)
CleanSignDataState.set_state(request.user.uid, timeout=60 * 10)
status, result = IosUtils.clean_developer(developer_obj, request.user, False)
CleanSignDataState.del_state(request.user.uid)
if not status:
res.code = 1008
res.msg = result.get("err_info")
@ -317,14 +324,29 @@ class DeviceUsedBillView(APIView):
def get(self, request):
res = BaseResponse()
udid = request.query_params.get("udid", None)
act = request.query_params.get("act", None)
user_used_list = IosDeveloperPublicPoolBill.objects.filter(user_id=request.user)
page_obj = PageNumber()
user_used_list = IosDeveloperPublicPoolBill.objects.filter(Q(to_user_id=request.user) | Q(user_id=request.user))
if udid:
user_used_list = user_used_list.filter(udid=udid)
app_page_serializer = page_obj.paginate_queryset(queryset=user_used_list.order_by("-created_time"),
else:
user_used_list = user_used_list.filter(udid__isnull=False)
if act and act == 'info':
app_page_serializer = page_obj.paginate_queryset(queryset=user_used_list.order_by("-created_time"),
request=request,
view=self)
app_serializer = BillInfoSerializer(app_page_serializer, many=True, context={'user_obj': request.user})
res.data = app_serializer.data
res.count = user_used_list.count()
else:
user_used_list3 = user_used_list.values('udid', 'product', 'version', 'udid_sync_info_id').annotate(
counts=Count('udid')).order_by("-created_time")
res.count = user_used_list3.count()
user_used_list3 = page_obj.paginate_queryset(queryset=user_used_list3.order_by("-created_time"),
request=request,
view=self)
app_serializer = BillInfoSerializer(app_page_serializer, many=True, context={'user_obj': request.user})
res.data = app_serializer.data
res.count = user_used_list.count()
for user_used in user_used_list3:
user_used['counts'] = user_used_list.filter(udid=user_used.get('udid')).count()
res.data = user_used_list3
return Response(res.dict)

@ -16,7 +16,7 @@ from api.utils.TokenManager import verify_token
from api.utils.app.apputils import get_random_short, save_app_infos
from api.utils.auth import ExpiringTokenAuthentication
from api.utils.baseutils import make_app_uuid, make_from_user_uuid
from api.utils.modelutils import get_app_domain_name, get_redirect_server_domain
from api.utils.modelutils import get_app_domain_name, get_redirect_server_domain, check_super_sign_permission
from api.utils.response import BaseResponse
from api.utils.storage.caches import upload_file_tmp_name, del_cache_response_by_short
from api.utils.storage.storage import Storage
@ -48,8 +48,10 @@ class AppAnalyseView(APIView):
png_id = make_from_user_uuid(request.user)
app_obj = Apps.objects.filter(app_id=app_uuid).first()
binary_url = ''
enable_sign = False
if app_obj:
is_new = False
enable_sign = app_obj.issupersign
short = app_obj.short
app_release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, is_master=True).first()
short_domain_name = get_redirect_server_domain(request, request.user, get_app_domain_name(app_obj))
@ -77,7 +79,11 @@ class AppAnalyseView(APIView):
"png_token": png_token,
"png_key": png_key,
"storage": storage_type,
"is_new": is_new, "binary_url": binary_url}
"is_new": is_new,
"binary_url": binary_url,
"sign": check_super_sign_permission(request.user),
"enable_sign": enable_sign
}
if storage_type not in [1, 2]:
res.data['domain_name'] = settings.SERVER_DOMAIN.get("FILE_UPLOAD_DOMAIN", None)
else:
@ -113,15 +119,16 @@ class AppAnalyseView(APIView):
png_new_filename = data.get("png_key").strip(settings.FILE_UPLOAD_TMP_KEY)
logger.info(f"user {request.user} create or update app {data.get('bundleid')} data:{data}")
if save_app_infos(app_new_filename, request.user, app_info,
data.get("bundleid"), png_new_filename, data.get("short"), data.get('filesize')):
data.get("bundleid"), png_new_filename, data.get("short"), data.get('filesize'),
data.get('enable_sign')):
# 需要将tmp 文件修改为正式文件
storage.rename_file(app_tmp_filename, app_new_filename)
storage.rename_file(png_tmp_filename, png_new_filename)
app_obj = Apps.objects.filter(bundle_id=data.get("bundleid")).first()
app_obj = Apps.objects.filter(bundle_id=data.get("bundleid"), user_id=request.user).first()
if app_obj:
if app_obj.issupersign and app_obj.user_id.supersign_active:
c_task = run_resign_task.apply_async((app_obj.app_id, False))
c_task = run_resign_task.apply_async((app_obj.app_id, False, False))
msg = c_task.get(propagate=False)
logger.info(f"app {app_obj} run_resign_task msg:{msg}")
if c_task.successful():

Loading…
Cancel
Save