优化第三方下载显示

super_signature 3.0.1
nineven 5 years ago
parent 31c075a3f8
commit 68c8db9339
  1. 62
      fir_client/src/components/FirAppInfostimeline.vue
  2. 318
      fir_client/src/components/FirApps.vue
  3. 2
      fir_ser/api/models.py
  4. 9
      fir_ser/api/views/uploads.py

@ -10,7 +10,7 @@
<div class="directive-view-release">
<i class="el-icon-cloudy" v-if="! app.is_master"></i>
<i class="el-icon-cloudy" style="background-color: #409eff" v-else></i>
<i class="el-icon-cloudy" style="background-color: rgb(96, 200, 279)" v-else></i>
<b class="ng-binding">{{app.app_version}} (Build {{app.build_version}})</b>
<div class="release-metainfo ng-hide"
@ -28,18 +28,12 @@
</small> &nbsp;&nbsp;·&nbsp;&nbsp;
<small>{{app.release_type|getiOStype}}</small>
<!-- <i-->
<!-- v-if="app.changelog" class="ng-hide">&nbsp;&nbsp;·&nbsp;&nbsp;</i>-->
<!-- <small v-if="app.changelog"-->
<!-- ng-bind="activity.distribution_name"-->
<!-- class="ng-binding ng-hide"> {{app.changelog}}</small>-->
</div>
<p>{{app.changelog}}</p>
<textarea v-if="app.editing.changelog"
v-model="app.changelog"
placeholder="更新日志" >
placeholder="更新日志">
</textarea>
<div class="release-actions editing " v-if="app.editing.changelog">
@ -52,7 +46,7 @@
<el-input v-if="app.editing.binary_url"
v-model="app.binary_url"
placeholder="下载地址,默认本服务器,填写第三方可以 自动跳转到第三方平台" >
placeholder="下载地址,默认本服务器,填写第三方可以 自动跳转到第三方平台">
</el-input>
<div class="release-actions editing " v-if="app.editing.binary_url">
@ -81,7 +75,7 @@
<el-button class="tooltip-top" tooltip="下载原文件"
@click="downloadPackage(app)">
<i class="el-icon-download"></i>
<span >{{app.binary_size}}</span>
<span>{{app.binary_size}}</span>
</el-button>
</el-tooltip>
@ -90,7 +84,7 @@
<el-button class="tooltip-top" tooltip="修改下载地址"
@click="startEdit(app,'binary_url')"><i
class="el-icon-link"></i> <span >下载地址</span>
class="el-icon-link"></i> <span>下载地址</span>
</el-button>
</el-tooltip>
@ -130,30 +124,34 @@
release_apps: [],
currentapp: {},
activity: {
editing: {'changelog':false,'binary_url':false}
editing: {'changelog': false, 'binary_url': false}
},
updatas:{},
updatas: {},
}
},
methods: {
downloadPackage(app){
getdownloadurl(res=>{
if(res.code === 1000){
window.location.href=res.data.download_url;
downloadPackage(app) {
getdownloadurl(res => {
if (res.code === 1000) {
window.location.href = res.data.download_url;
}
}, {
'data': {
'token': app.download_token,
'short': this.currentapp.short,
'release_id': app.release_id,
"isdownload":true
"isdownload": true
},
'app_id': this.currentapp.app_id
})
},
previewRelase(app){
this.$router.push({name: 'FirDownload', params: { short: this.currentapp.short },query:{release_id:app.release_id}})
previewRelase(app) {
this.$router.push({
name: 'FirDownload',
params: {short: this.currentapp.short},
query: {release_id: app.release_id}
})
},
getapptimelineFun() {
@ -236,19 +234,19 @@
});
},
endEdit(app,type) {
if(type==='changelog'){
endEdit(app, type) {
if (type === 'changelog') {
app.editing.changelog = false;
}else if(type === 'binary_url'){
} else if (type === 'binary_url') {
app.editing.binary_url = false;
}
},
updateChangelog(app,type) {
if(type==='changelog'){
updateChangelog(app, type) {
if (type === 'changelog') {
this.activity.editing.changelog = false;
this.updatas = {"changelog": app.changelog}
}else if(type === 'binary_url') {
} else if (type === 'binary_url') {
this.activity.editing.binary_url = false;
this.updatas = {"binary_url": app.binary_url}
}
@ -257,9 +255,9 @@
"release_id": app.release_id,
"data": this.updatas
});
this.updatas={}
this.updatas = {}
},
startEdit(app,type) {
startEdit(app, type) {
if (type === 'changelog') {
app.editing.changelog = true;
@ -275,10 +273,10 @@
this.$store.dispatch('doappInfoIndex', [[5, 5], [5, 5]]);
this.getapptimelineFun();
}, filters: {
downcontent(content){
if(content){
downcontent(content) {
if (content) {
return content
}else{
} else {
return "修改下载地址"
}
},
@ -292,7 +290,7 @@
let ftype = '';
if (type === 1) {
ftype = '内测版'
} else if(type === 2) {
} else if (type === 2) {
ftype = '企业版'
}
return ftype

@ -1,6 +1,6 @@
<template>
<div>
<el-container >
<el-container>
<el-header style="height: 100px">
@ -22,7 +22,7 @@
:show-close="!uploading"
width="40%"
:close-on-click-modal="false"
@closed="closeUpload" >
@closed="closeUpload">
<div v-if="!uploading" style="">
<el-row :gutter="20">
@ -36,12 +36,13 @@
<el-col :span="18">
<div class="grid-content bg-purple">
<el-row :gutter="20" style="margin-top: 8px;">
<el-col :span="18" >
{{ analyseappinfo.version}} (Build {{ analyseappinfo.buildversion}}) {{ analyseappinfo.release_type_id|getiOStype}}
<el-col :span="18">
{{ analyseappinfo.version}} (Build {{ analyseappinfo.buildversion}}) {{
analyseappinfo.release_type_id|getiOStype}}
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 18px;">
<el-col :span="18" >
<el-col :span="18">
<el-input v-model="analyseappinfo.appname"></el-input>
</el-col>
@ -57,7 +58,7 @@
<div class="grid-content bg-purple">
<el-row :gutter="20" style="margin-top: 18px;">
<el-col :span="18" :offset="8">
<span >短连接</span>
<span>短连接</span>
</el-col>
</el-row>
</div>
@ -65,7 +66,7 @@
<el-col :span="18">
<div class="grid-content bg-purple">
<el-row :gutter="20" style="margin-top: 10px;">
<el-col :span="18" >
<el-col :span="18">
<el-input v-model="analyseappinfo.short">
<template slot="prepend">{{analyseappinfo.domain_name}}/</template>
</el-input>
@ -81,7 +82,7 @@
<div class="grid-content bg-purple">
<el-row :gutter="20" style="margin-top: 18px;">
<el-col :span="18" :offset="8">
<span >更新日志</span>
<span>更新日志</span>
</el-col>
</el-row>
</div>
@ -89,7 +90,7 @@
<el-col :span="18">
<div class="grid-content bg-purple">
<el-row :gutter="20" style="margin-top: 10px;">
<el-col :span="18" >
<el-col :span="18">
<el-input type="textarea"
v-model="analyseappinfo.changelog"
placeholder="请输入内容"
@ -156,17 +157,19 @@
<span slot="footer" class="dialog-footer">
<el-progress :text-inside="true" :stroke-width="26" :percentage="uploadprocess" v-if="uploadflag === true"></el-progress>
<el-button type="primary" plain @click="uploadcloud" v-else>开始上传</el-button>
<el-progress :text-inside="true" :stroke-width="26" :percentage="uploadprocess"
v-if="uploadflag === true"></el-progress>
<el-button type="primary" plain @click="uploadcloud" v-else>{{ analyseappinfo.is_new|get_upload_text}}</el-button>
</span>
</el-dialog>
<el-row>
<el-col :span="4">
<el-radio-group v-model="searchfromtype">
<el-radio-button label="android" icon="el-icon-mobile-phone"><i class="iconfont icon-android2"/>
<el-radio-button label="android" icon="el-icon-mobile-phone"><i
class="iconfont icon-android2"/>
</el-radio-button>
<el-radio-button label="ios" ><i class="iconfont icon-ios"/>
<el-radio-button label="ios"><i class="iconfont icon-ios"/>
</el-radio-button>
</el-radio-group>
@ -313,8 +316,6 @@
</p>
<table>
<tbody>
<tr>
<td class="ng-binding">应用大小</td>
<td><span
@ -334,15 +335,26 @@
<td><span class="ng-binding">{{ r.master_release.app_version }}Build {{ r.master_release.build_version }}</span>
</td>
</tr>
<tr v-if="r.type === 1">
<tr v-if="r.type === 1 && r.master_release.binary_url === ''">
<td class="ng-binding">打包类型</td>
<td><span class="ng-binding">
{{ r.master_release.release_type|getiOStype }}
</span></td>
</tr>
<tr v-if=" r.master_release.binary_url !== ''">
<td>第三方平台下载</td>
<td>
<span>
<el-tooltip :content="r.master_release.binary_url" placement="top">
<a target="_blank" :href="r.master_release.binary_url">{{ r.master_release.binary_url| autoformat}}</a>
</el-tooltip>
</span>
</td>
</tr>
</tbody>
</table>
<div class="action">
<el-button @click="appInfos(r)">
<i class="icon-pen el-icon-edit"></i> 管理
@ -372,38 +384,47 @@
</template>
<script>
import {getapps, deleteapp,analyseApps,getuploadurl} from "../restful";
import {getScrollHeight,getScrollTop,getWindowHeight,getappinfo,uploadqiniuoss,dataURLtoFile,uploadaliyunoss,uploadlocalstorage} from "../utils";
import {getapps, deleteapp, analyseApps, getuploadurl} from "../restful";
import {
getScrollHeight,
getScrollTop,
getWindowHeight,
getappinfo,
uploadqiniuoss,
dataURLtoFile,
uploadaliyunoss,
uploadlocalstorage
} from "../utils";
export default {
name: "FirApps",
data() {
return {
analyseappinfo:{'appname':'','short':'','changelog':''},
analyseappinfo: {'appname': '', 'short': '', 'changelog': ''},
keysearch: '',
searchfromtype: '',
applists: [],
orgapplists: [],
hdata: {},
willDeleteApp: false,
willuploadApp:false,
uploading:false,
willuploadApp: false,
uploading: false,
delapp: {},
has_next:false,
query:{'page':1,size:20},
searchflag:false,
uploadflag:false,
autoloadflag:true,
firstloadflag:true,
currentfile:null,
uploadprocess:0,
uploadsuccess:0,
loadingobj:null
has_next: false,
query: {'page': 1, size: 20},
searchflag: false,
uploadflag: false,
autoloadflag: true,
firstloadflag: true,
currentfile: null,
uploadprocess: 0,
uploadsuccess: 0,
loadingobj: null
}
}, methods: {
updateappinfo(file){
this.uploadsuccess +=1;
if(this.uploadsuccess === 2){
updateappinfo(file) {
this.uploadsuccess += 1;
if (this.uploadsuccess === 2) {
this.$message.success(file.name + '上传成功');
analyseApps(data => {
if (data.code === 1000) {
@ -411,118 +432,154 @@
this.closeUpload();
this.$router.push({name: 'FirAppInfostimeline', params: {id: app_uuid}});
}
},{'methods':'PUT','data':this.analyseappinfo});
}, {'methods': 'PUT', 'data': this.analyseappinfo});
}
},
uploadtostorage(file,certinfo){
uploadtostorage(file, certinfo) {
if(this.analyseappinfo.storage === 1){
if (this.analyseappinfo.storage === 1) {
// eslint-disable-next-line no-unused-vars,no-unreachable
uploadqiniuoss(file,certinfo,this,res=>{
uploadqiniuoss(file, certinfo, this, res => {
this.updateappinfo(file)
},process=>{
if(this.uploadsuccess === 1) {
}, process => {
if (this.uploadsuccess === 1) {
this.uploadprocess = process;
}
})
}else if(this.analyseappinfo.storage === 2){
} else if (this.analyseappinfo.storage === 2) {
// eslint-disable-next-line no-unused-vars
uploadaliyunoss(file,certinfo,this,res=>{
uploadaliyunoss(file, certinfo, this, res => {
this.updateappinfo(file)
},process=>{
if(this.uploadsuccess === 1) {
}, process => {
if (this.uploadsuccess === 1) {
this.uploadprocess = process;
}
});
}else {
} else {
//
certinfo.upload_url = getuploadurl();
certinfo.ftype = 'app';
certinfo.app_id = this.analyseappinfo.app_uuid;
// eslint-disable-next-line no-unused-vars,no-unreachable
uploadlocalstorage(file,certinfo,this,res=>{
uploadlocalstorage(file, certinfo, this, res => {
this.updateappinfo(file)
},process=>{
if(this.uploadsuccess === 1) {
}, process => {
if (this.uploadsuccess === 1) {
this.uploadprocess = process;
}
})
}
},
getuploadtoken(loading){
analyseApps(data =>{
if(data.code === 1000){
getuploadtoken(loading) {
analyseApps(data => {
if (data.code === 1000) {
this.analyseappinfo.short = data.data.short;
this.analyseappinfo.domain_name = data.data.domain_name;
this.analyseappinfo.app_uuid= data.data.app_uuid;
this.analyseappinfo.upload_token= data.data.upload_token;
this.analyseappinfo.upload_key= data.data.upload_key;
this.analyseappinfo.png_key= data.data.png_key;
this.analyseappinfo.png_token= data.data.png_token;
this.analyseappinfo.storage= data.data.storage;
this.willuploadApp=true;
}else {
this.analyseappinfo.app_uuid = data.data.app_uuid;
this.analyseappinfo.upload_token = data.data.upload_token;
this.analyseappinfo.upload_key = data.data.upload_key;
this.analyseappinfo.png_key = data.data.png_key;
this.analyseappinfo.png_token = data.data.png_token;
this.analyseappinfo.storage = data.data.storage;
this.analyseappinfo.is_new = data.data.is_new;
this.analyseappinfo.binary_url = data.data.binary_url;
this.willuploadApp = true;
} else {
this.$message.error("上传token获取失败,请刷新重试")
}
loading.close();
},{'methos':true,'data':{"bundleid":this.analyseappinfo.bundleid,"type":this.analyseappinfo.type}})
}, {
'methos': true,
'data': {"bundleid": this.analyseappinfo.bundleid, "type": this.analyseappinfo.type}
})
},
uploadcloud() {
if (this.analyseappinfo.binary_url !== '') {
this.$confirm(`该应用存在第三方下载链接 <a target="_blank" href="${this.analyseappinfo.binary_url}"> ${this.analyseappinfo.binary_url} </a>更新之后,将不会自动跳转第三方下载;若您还需要第三方跳转,请在第三方平台更新该应用。`, '确定更新应用?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
type: 'warning'
}).then(() => {
this.$message({
type: 'success',
message: '开始更新'
});
this.uploadstorage()
}).catch(() => {
this.$message({
type: 'info',
message: '已取消更新'
});
this.closeUpload();
});
} else {
this.uploadstorage()
}
},
uploadcloud(){
this.uploadflag=true;
uploadstorage() {
this.uploadflag = true;
this.uploading = true;
let file=dataURLtoFile(this.analyseappinfo.icon,this.analyseappinfo.png_key);
let file = dataURLtoFile(this.analyseappinfo.icon, this.analyseappinfo.png_key);
this.uploadtostorage(file,{'upload_key':this.analyseappinfo.png_key,'upload_token':this.analyseappinfo.png_token});
this.uploadtostorage(file, {
'upload_key': this.analyseappinfo.png_key,
'upload_token': this.analyseappinfo.png_token
});
file = this.currentfile;
this.uploadtostorage(file,{'upload_key':this.analyseappinfo.upload_key,'upload_token':this.analyseappinfo.upload_token});
this.uploadtostorage(file, {
'upload_key': this.analyseappinfo.upload_key,
'upload_token': this.analyseappinfo.upload_token
});
},
closeUpload(){
closeUpload() {
this.uploadsuccess = 0;
this.uploadprocess=0;
this.uploadflag=false;
this.uploadprocess = 0;
this.uploadflag = false;
this.uploading = false;
this.willuploadApp=false;
this.currentfile=null;
this.willuploadApp = false;
this.currentfile = null;
this.uploadflag = false;
this.analyseappinfo={};
this.analyseappinfo = {};
},
searchFun(){
searchFun() {
let keysearch = this.keysearch.replace(/^\s+|\s+$/g, "");
if(keysearch === ''){
this.searchflag=false;
this.applists=[];
this.orgapplists=[];
this.query.page=1;
if(this.searchfromtype){
if (keysearch === '') {
this.searchflag = false;
this.applists = [];
this.orgapplists = [];
this.query.page = 1;
if (this.searchfromtype) {
this.getappsFun({"type": this.searchfromtype});
}else {
} else {
this.getappsFun({});
}
}else {
this.searchflag=true
} else {
this.searchflag = true
}
if(this.searchflag){
this.applists=[];
this.orgapplists=[];
if(this.searchfromtype){
this.getappsFun({"type": this.searchfromtype,'page':1,size:999});
}else {
this.getappsFun({'page':1,size:999});
if (this.searchflag) {
this.applists = [];
this.orgapplists = [];
if (this.searchfromtype) {
this.getappsFun({"type": this.searchfromtype, 'page': 1, size: 999});
} else {
this.getappsFun({'page': 1, size: 999});
}
}
},
auto_load(){
auto_load() {
// eslint-disable-next-line no-console
// console.log(getScrollTop() , getWindowHeight(),getScrollTop() + getWindowHeight(), getScrollHeight());
if(getScrollTop() + getWindowHeight() >= getScrollHeight()){
if (getScrollTop() + getWindowHeight() >= getScrollHeight()) {
if(this.has_next){ //
if(this.autoloadflag) {
if (this.has_next) { //
if (this.autoloadflag) {
this.autoloadflag = false;
if (this.applists.length === 0) {
this.query.page = 1;
@ -535,8 +592,8 @@
this.getappsFun(this.query);
}
}else{
if(! this.has_next){
} else {
if (!this.has_next) {
this.$message.success("已经到底啦")
}
}
@ -567,27 +624,27 @@
getapps(data => {
if (data.code === 1000) {
this.loadingobj.close();
if(this.firstloadflag){
window.addEventListener('scroll',this.auto_load);
if (this.firstloadflag) {
window.addEventListener('scroll', this.auto_load);
this.firstloadflag = false
}
this.autoloadflag = true;
if(this.uploadflag){
this.applists = data.data ;
if (this.uploadflag) {
this.applists = data.data;
this.uploadflag = false;
}else {
this.applists = this.applists.concat(data.data) ;
} else {
this.applists = this.applists.concat(data.data);
}
this.has_next = data.has_next;
this.orgapplists = this.applists.slice(); //
this.hdata = data.hdata;
this.$store.dispatch("getUser",data.userinfo);
this.$store.dispatch("getUser", data.userinfo);
this.searchapps();
let upload_domain=data.hdata.upload_domain;
if(!upload_domain){
upload_domain=location.origin;
let upload_domain = data.hdata.upload_domain;
if (!upload_domain) {
upload_domain = location.origin;
}
// this.$store.dispatch('doucurrentapp', {'firapps':1});
@ -599,22 +656,22 @@
}, parms);
},
beforeAvatarUpload(file){
beforeAvatarUpload(file) {
const loading = this.$loading({
lock: true,
text: '应用解析中',
spinner: 'el-icon-loading',
// background: 'rgba(0, 0, 0, 0.7)'
});
getappinfo(file,appinfo =>{
if(appinfo.bundleid){
getappinfo(file, appinfo => {
if (appinfo.bundleid) {
this.analyseappinfo = appinfo;
this.getuploadtoken(loading);
this.currentfile = file;
}else {
} else {
this.$message.error("应用解析失败,请检查是否为APP应用")
}
},err=>{
}, err => {
loading.close();
this.$message.error("应用解析失败,请检查是否为APP应用");
// eslint-disable-next-line no-console
@ -626,14 +683,14 @@
this.willDeleteApp = false;
deleteapp(data => {
if (data.code === 1000) {
for(let i=0;i< this.applists.length;i++){
if(this.delapp.app_id === this.applists[i].app_id){
this.applists.splice(i,1);
this.orgapplists.splice(i,1);
for (let i = 0; i < this.applists.length; i++) {
if (this.delapp.app_id === this.applists[i].app_id) {
this.applists.splice(i, 1);
this.orgapplists.splice(i, 1);
}
}
this.$message.success(this.delapp.name+'删除成功');
this.delapp={};
this.$message.success(this.delapp.name + '删除成功');
this.delapp = {};
} else {
this.$message.error('删除失败,请联系管理员');
}
@ -650,7 +707,7 @@
this.$router.push({name: 'FirAppInfostimeline', params: {id: app.app_id}})
},
appDownload(app) {
this.$router.push({name: 'FirDownload', params: { short: app.short }})
this.$router.push({name: 'FirDownload', params: {short: app.short}})
}
}, computed: {
getDelappTitle() {
@ -673,7 +730,7 @@
let ftype = '';
if (type === 1) {
ftype = '内测版'
} else if(type === 2) {
} else if (type === 2) {
ftype = '企业版'
}
return ftype
@ -684,7 +741,7 @@
autoformat: function (packname) {
if ((packname.length) > 20) {
return packname.split('').slice(0, 20).join('') + '...';
}else {
} else {
return packname
}
},
@ -697,12 +754,19 @@
}
return ftype
},
make_icon_url(icon_url){
if(!icon_url.startsWith("http")){
return location.origin+icon_url
}else {
make_icon_url(icon_url) {
if (!icon_url.startsWith("http")) {
return location.origin + icon_url
} else {
return icon_url
}
},
get_upload_text(is_new) {
if (is_new) {
return '新应用上传'
} else {
return '应用更新'
}
}
}, mounted() {
@ -710,7 +774,7 @@
this.getappsFun({});
// window.addEventListener('scroll',this.auto_load);
},
destroyed(){
destroyed() {
window.removeEventListener('scroll', this.auto_load, false);
this.loadingobj.close();
},
@ -723,8 +787,8 @@
},
// eslint-disable-next-line no-unused-vars
searchfromtype: function (val, oldVal) {
this.applists=[];
this.query.page=1;
this.applists = [];
this.query.page = 1;
// this.keysearch='';
this.searchFun();
// this.getappsFun({"type": this.searchfromtype});
@ -906,7 +970,7 @@
.page-apps .card.app .action {
position: absolute;
padding: 40px 0 40px 40px;
padding: 20px 0 40px 40px;
left: 0;
bottom: 0;
width: 100%

@ -125,7 +125,7 @@ class AppReleaseInfo(models.Model):
release_type = models.SmallIntegerField(choices=release_choices, default=0, verbose_name="版本类型")
minimum_os_version = models.CharField(max_length=64,verbose_name="应用可安装的最低系统版本")
binary_size = models.BigIntegerField(verbose_name="应用大小")
binary_url = models.CharField(max_length=128,blank=True,verbose_name="APPurl")
binary_url = models.CharField(max_length=128,blank=True,verbose_name="第三方下载URL")
icon_url = models.CharField(max_length=128,blank=True,verbose_name="图标url")
changelog = models.TextField('更新日志', blank=True, null=True, default=None, )

@ -36,9 +36,15 @@ class AppAnalyseView(APIView):
release_id = make_from_user_uuid(request.user)
png_id = make_from_user_uuid(request.user)
app_obj = Apps.objects.filter(app_id=app_uuid).first()
binary_url=''
if app_obj:
is_new=False
short = app_obj.short
app_release_obj=AppReleaseInfo.objects.filter(app_id=app_obj,is_master=True).first()
if app_release_obj:
binary_url = app_release_obj.binary_url
else:
is_new=True
short = get_random_short()
if app_type == 'iOS':
upload_key = release_id+'.ipa'
@ -63,7 +69,8 @@ class AppAnalyseView(APIView):
"upload_key":upload_key,
"png_token":png_token,
"png_key":png_key,
"storage":storage_type}
"storage":storage_type,
"is_new":is_new,"binary_url":binary_url}
else:
res.code = 1003

Loading…
Cancel
Save