add default storage

storage_cloud
nineven 5 years ago
parent be4c0fa661
commit 33f26558ea
  1. 66
      fir_client/src/components/FirApps.vue
  2. 2
      fir_client/src/utils/index.js
  3. 28
      fir_ser/api/migrations/0015_auto_20200326_1454.py
  4. 23
      fir_ser/api/models.py
  5. 21
      fir_ser/api/utils/app/apputils.py
  6. 6
      fir_ser/api/utils/auth.py
  7. 40
      fir_ser/api/utils/storage/storage.py
  8. 4
      fir_ser/api/views/download.py
  9. 32
      fir_ser/api/views/login.py
  10. 17
      fir_ser/api/views/uploads.py
  11. 27
      fir_ser/fir_ser/settings.py

@ -397,25 +397,29 @@
firstloadflag:true, firstloadflag:true,
currentfile:null, currentfile:null,
uploadprocess:0, uploadprocess:0,
uploadsuccess:0 uploadsuccess:0,
loadingobj:null
} }
}, methods: { }, methods: {
updateappinfo(file){
this.uploadsuccess +=1;
if(this.uploadsuccess === 2){
this.$message.success(file.name + '上传成功');
analyseApps(data => {
if (data.code === 1000) {
let app_uuid = this.analyseappinfo.app_uuid;
this.closeUpload();
this.$router.push({name: 'FirAppInfostimeline', params: {id: app_uuid}});
}
},{'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 // eslint-disable-next-line no-unused-vars,no-unreachable
uploadqiniuoss(file,certinfo,this,res=>{ uploadqiniuoss(file,certinfo,this,res=>{
this.uploadsuccess +=1; this.updateappinfo(file)
if(this.uploadsuccess === 2){
this.$message.success(file.name + '上传成功');
analyseApps(data => {
if (data.code === 1000) {
let app_uuid = this.analyseappinfo.app_uuid;
this.closeUpload();
this.$router.push({name: 'FirAppInfostimeline', params: {id: app_uuid}});
}
},{'methods':'PUT','data':this.analyseappinfo});
}
},process=>{ },process=>{
if(this.uploadsuccess === 1) { if(this.uploadsuccess === 1) {
this.uploadprocess = process; this.uploadprocess = process;
@ -424,46 +428,27 @@
}else if(this.analyseappinfo.storage === 2){ }else if(this.analyseappinfo.storage === 2){
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
uploadaliyunoss(file,certinfo,this,res=>{ uploadaliyunoss(file,certinfo,this,res=>{
this.uploadsuccess +=1; this.updateappinfo(file)
if(this.uploadsuccess === 2){
this.$message.success(file.name + '上传成功');
analyseApps(data => {
if (data.code === 1000) {
let app_uuid = this.analyseappinfo.app_uuid;
this.closeUpload();
this.$router.push({name: 'FirAppInfostimeline', params: {id: app_uuid}});
}
},{'methods':'PUT','data':this.analyseappinfo});
}
},process=>{ },process=>{
if(this.uploadsuccess === 1) { if(this.uploadsuccess === 1) {
this.uploadprocess = process; this.uploadprocess = process;
} }
}); });
}else { }else {
// //
certinfo.upload_url = getuploadurl(); certinfo.upload_url = getuploadurl();
certinfo.ftype = 'app';
certinfo.app_id = this.analyseappinfo.app_uuid;
// eslint-disable-next-line no-unused-vars,no-unreachable // eslint-disable-next-line no-unused-vars,no-unreachable
uploadlocalstorage(file,certinfo,this,res=>{ uploadlocalstorage(file,certinfo,this,res=>{
this.uploadsuccess +=1; this.updateappinfo(file)
if(this.uploadsuccess === 2){
this.$message.success(file.name + '上传成功');
analyseApps(data => {
if (data.code === 1000) {
let app_uuid = this.analyseappinfo.app_uuid;
this.closeUpload();
this.$router.push({name: 'FirAppInfostimeline', params: {id: app_uuid}});
}
},{'methods':'PUT','data':this.analyseappinfo});
}
},process=>{ },process=>{
if(this.uploadsuccess === 1) { if(this.uploadsuccess === 1) {
this.uploadprocess = process; this.uploadprocess = process;
} }
}) })
} }
}, },
getuploadtoken(loading){ getuploadtoken(loading){
analyseApps(data =>{ analyseApps(data =>{
@ -573,7 +558,7 @@
}, },
getappsFun(parms) { getappsFun(parms) {
const loading = this.$loading({ this.loadingobj = this.$loading({
lock: true, lock: true,
text: '加载中', text: '加载中',
spinner: 'el-icon-loading', spinner: 'el-icon-loading',
@ -581,7 +566,7 @@
}); });
getapps(data => { getapps(data => {
if (data.code === 1000) { if (data.code === 1000) {
loading.close(); this.loadingobj.close();
if(this.firstloadflag){ if(this.firstloadflag){
window.addEventListener('scroll',this.auto_load); window.addEventListener('scroll',this.auto_load);
this.firstloadflag = false this.firstloadflag = false
@ -608,12 +593,13 @@
// this.$store.dispatch('doucurrentapp', {'firapps':1}); // this.$store.dispatch('doucurrentapp', {'firapps':1});
} else { } else {
this.loadingobj.close();
this.$router.push({name: 'FirLogin'}); this.$router.push({name: 'FirLogin'});
} }
}, parms); }, parms);
}, },
beforeAvatarUpload(file){ beforeAvatarUpload(file){
const loading = this.$loading({ const loading = this.$loading({
lock: true, lock: true,
text: '应用解析中', text: '应用解析中',
@ -636,7 +622,6 @@
}); });
return false; return false;
}, },
delApp() { delApp() {
this.willDeleteApp = false; this.willDeleteApp = false;
deleteapp(data => { deleteapp(data => {
@ -727,6 +712,7 @@
}, },
destroyed(){ destroyed(){
window.removeEventListener('scroll', this.auto_load, false); window.removeEventListener('scroll', this.auto_load, false);
this.loadingobj.close();
}, },
watch: { watch: {

@ -149,7 +149,7 @@ export function uploadaliyunoss(file,certinfo,app,successcallback,processcallbac
}; };
const options = { const options = {
progress, progress,
partSize: 1000 * 1024, partSize: 1024 * 1024 / 4,
// meta: { // meta: {
// year: 2017, // year: 2017,
// people: 'test', // people: 'test',

@ -0,0 +1,28 @@
# Generated by Django 3.0.3 on 2020-03-26 06:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0014_userinfo_storage'),
]
operations = [
migrations.AddField(
model_name='userinfo',
name='history_release_limit',
field=models.IntegerField(blank=True, default=10, null=True, verbose_name='app 历史记录版本'),
),
migrations.AlterField(
model_name='userinfo',
name='all_download_times',
field=models.BigIntegerField(default=0, verbose_name='总共下载次数'),
),
migrations.AlterField(
model_name='userinfo',
name='head_img',
field=models.CharField(default='head_img.jpeg', max_length=256, verbose_name='个人头像'),
),
]

@ -22,33 +22,26 @@ class UserInfo(AbstractUser):
uid = models.CharField(max_length=64, unique=True) # user_id,唯一标识 uid = models.CharField(max_length=64, unique=True) # user_id,唯一标识
mobile = models.BigIntegerField(verbose_name="手机", unique=True, help_text="用于手机验证码登录", null=True) mobile = models.BigIntegerField(verbose_name="手机", unique=True, help_text="用于手机验证码登录", null=True)
qq = models.BigIntegerField(verbose_name="QQ", blank=True, null=True, db_index=True) qq = models.BigIntegerField(verbose_name="QQ", blank=True, null=True, db_index=True)
is_active = models.BooleanField(default=True, verbose_name="账户状态") is_active = models.BooleanField(default=True, verbose_name="账户状态,默认启用")
job = models.TextField("职位", max_length=128, blank=True, null=True) job = models.TextField("职位", max_length=128, blank=True, null=True)
company = models.CharField("公司", max_length=128, blank=True, null=True) company = models.CharField("公司", max_length=128, blank=True, null=True)
gender_choices = ((0, '保密'), (1, ''), (2, '')) gender_choices = ((0, '保密'), (1, ''), (2, ''))
gender = models.SmallIntegerField(choices=gender_choices, default=0, verbose_name="性别") gender = models.SmallIntegerField(choices=gender_choices, default=0, verbose_name="性别")
# password = models.CharField('password', max_length=128,
# help_text=mark_safe('''<a class='btn-link' href='set_password'>重置密码</a>'''))
head_img = models.CharField(max_length=256, default='head_img.jpeg', head_img = models.CharField(max_length=256, default='head_img.jpeg',
verbose_name="个人头像") verbose_name="个人头像")
role_choices = ((0, '普通会员'), (1, 'VIP'), (2, 'SVIP'), (3, '管理员')) role_choices = ((0, '普通会员'), (1, 'VIP'), (2, 'SVIP'), (3, '管理员'))
role = models.SmallIntegerField(choices=role_choices, default=0, verbose_name="角色") role = models.SmallIntegerField(choices=role_choices, default=0, verbose_name="角色")
memo = models.TextField('备注', blank=True, null=True, default=None, ) memo = models.TextField('备注', blank=True, null=True, default=None, )
date_joined = models.DateTimeField(auto_now_add=True, verbose_name="注册时间") date_joined = models.DateTimeField(auto_now_add=True, verbose_name="注册时间")
download_times = models.IntegerField(default=100, verbose_name="下载次数") download_times = models.IntegerField(default=100, verbose_name="下载次数")
all_download_times = models.IntegerField(default=0, verbose_name="总共下载次数") all_download_times = models.BigIntegerField(default=0, verbose_name="总共下载次数")
domain_name = models.CharField(verbose_name="域名",blank=True,null=True,max_length=64) domain_name = models.CharField(verbose_name="域名",blank=True,null=True,max_length=64)
history_release_limit = models.IntegerField(default=10,verbose_name="app 历史记录版本",blank=True,null=True)
storage = models.OneToOneField(to='AppStorage',related_name='app_storage', storage = models.OneToOneField(to='AppStorage',related_name='app_storage',
on_delete=models.SET_NULL, verbose_name="存储",null=True) on_delete=models.SET_NULL, verbose_name="存储",null=True,blank=True)
# is_staff = models.BooleanField(verbose_name='staff status', default=False, help_text='决定着用户是否可登录管理后台')
# weixin = models.CharField(max_length=128, blank=True, null=True, db_index=True, verbose_name="微信")
# signature = models.CharField('个人签名', blank=True, null=True, max_length=255)
# openid = models.CharField(max_length=128, blank=True, null=True)
# alipay_card = models.CharField(max_length=128, blank=True, null=True, verbose_name="支付宝账户")
class Meta: class Meta:
verbose_name = '账户信息' verbose_name = '账户信息'
@ -155,7 +148,9 @@ class AppStorage(models.Model):
secret_key =models.CharField(max_length=128,blank=True, null=True, verbose_name="存储访问secret") secret_key =models.CharField(max_length=128,blank=True, null=True, verbose_name="存储访问secret")
bucket_name=models.CharField(max_length=128,blank=True, null=True, verbose_name="存储空间bucket_name") bucket_name=models.CharField(max_length=128,blank=True, null=True, verbose_name="存储空间bucket_name")
additionalparameters = models.TextField(max_length=256,blank=True, null=True,verbose_name="额外参数", additionalparameters = models.TextField(max_length=256,blank=True, null=True,verbose_name="额外参数",
help_text='阿里云:{"sts_role_arn":"arn信息","endpoint":""} 七牛云:{"domain_name":""}') help_text='阿里云:{"sts_role_arn":"arn信息","endpoint":""} '
' 七牛云:{"domain_name":""} '
'本地存储:{"domain_name":""}')
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
description = models.TextField('备注', blank=True, null=True, default=None, ) description = models.TextField('备注', blank=True, null=True, default=None, )
@ -164,4 +159,4 @@ class AppStorage(models.Model):
verbose_name_plural = "存储配置" verbose_name_plural = "存储配置"
def __str__(self): def __str__(self):
return "%s %s" % (self.name,self.user_id.get_username()) return "%s %s" % (self.user_id.get_username(),self.name)

@ -134,6 +134,7 @@ def SaveAppInfos(app_file_name,user_obj,appinfo,bundle_id,app_img,short,size):
app_uuid = make_app_uuid(user_obj,bundle_id+app_file_name.split(".")[1]) app_uuid = make_app_uuid(user_obj,bundle_id+app_file_name.split(".")[1])
##判断是否存在该app ##判断是否存在该app
appmobj = Apps.objects.filter(app_id=app_uuid, user_id=user_obj).first() appmobj = Apps.objects.filter(app_id=app_uuid, user_id=user_obj).first()
storage = Storage(user_obj)
if not appmobj: if not appmobj:
appdata = { appdata = {
"app_id": app_uuid, "app_id": app_uuid,
@ -148,7 +149,6 @@ def SaveAppInfos(app_file_name,user_obj,appinfo,bundle_id,app_img,short,size):
appmobj = Apps.objects.create(**appdata) appmobj = Apps.objects.create(**appdata)
except Exception as e: except Exception as e:
print(e) print(e)
storage = Storage(user_obj)
storage.delete_file(app_file_name) storage.delete_file(app_file_name)
storage.delete_file(app_img) storage.delete_file(app_img)
return return
@ -178,3 +178,22 @@ def SaveAppInfos(app_file_name,user_obj,appinfo,bundle_id,app_img,short,size):
} }
AppReleaseInfo.objects.create(**release_data) AppReleaseInfo.objects.create(**release_data)
try:
history_release_limit = int(user_obj.history_release_limit)
except Exception as e:
print(e)
return
if history_release_limit == 0:
pass
else:
release_queryset = AppReleaseInfo.objects.filter(app_id=appmobj).order_by("-created_time")
if release_queryset.count() > history_release_limit:
flag = 0
for release_obj in release_queryset:
flag +=1
if flag > history_release_limit:
storage.delete_file(release_obj.release_id,appmobj.type)
storage.delete_file(release_obj.icon_url)
release_obj.delete()

@ -63,4 +63,8 @@ class ExpiringTokenAuthentication(BaseAuthentication):
raise AuthenticationFailed({"code": 1001, "error": "无效的token"}) raise AuthenticationFailed({"code": 1001, "error": "无效的token"})
if user_name != token_obj.user.username: if user_name != token_obj.user.username:
raise AuthenticationFailed({"code": 1001, "error": "token校验失败"}) raise AuthenticationFailed({"code": 1001, "error": "token校验失败"})
return token_obj.user, token_obj if token_obj.user.is_active:
return token_obj.user, token_obj
else:
raise AuthenticationFailed({"code": 1001, "error": "用户被禁用"})

@ -9,17 +9,18 @@ from .aliyunApi import AliYunOss
from .qiniuApi import QiNiuOss from .qiniuApi import QiNiuOss
from .localApi import LocalStorage from .localApi import LocalStorage
import json import json
from fir_ser import settings
class Storage(object): class Storage(object):
def __init__(self, user): def __init__(self, user):
self.storage = self.get_storage(user) self.storage = self.get_storage(user)
def get_upload_token(self, filename, expires=1800): def get_upload_token(self, filename, expires=600):
if self.storage: if self.storage:
return self.storage.get_upload_token(filename, expires) return self.storage.get_upload_token(filename, expires)
def get_download_url(self, filename, expires=1800,ftype=None): def get_download_url(self, filename, expires=600,ftype=None):
if self.storage: if self.storage:
return self.storage.get_download_url(filename, expires,ftype) return self.storage.get_download_url(filename, expires,ftype)
@ -33,10 +34,10 @@ class Storage(object):
return self.storage.del_file(filename) return self.storage.del_file(filename)
def get_storage(self, user): def get_storage(self, user):
storage_obj = user.storage self.storage_obj = user.storage
if storage_obj: if self.storage_obj:
auth = self.get_storage_auth(storage_obj) auth = self.get_storage_auth(self.storage_obj)
storage_type = storage_obj.storage_type storage_type = self.storage_obj.storage_type
if storage_type == 1: if storage_type == 1:
new_storage_obj = QiNiuOss(**auth) new_storage_obj = QiNiuOss(**auth)
elif storage_type == 2: elif storage_type == 2:
@ -44,8 +45,35 @@ class Storage(object):
else: else:
new_storage_obj = LocalStorage(**auth) new_storage_obj = LocalStorage(**auth)
return new_storage_obj return new_storage_obj
else:
return self.get_default_storage()
def get_default_storage(self):
admin_storage = UserInfo.objects.first().storage
if admin_storage:
return self.get_storage(UserInfo)
else:
storage_lists = settings.THIRD_PART_CONFIG.get('storage')
for storage in storage_lists:
if storage.get("active",None):
storage_type= storage.get('type',None)
auth = storage.get('auth',{})
if storage_type == 1:
new_storage_obj = QiNiuOss(**auth)
elif storage_type == 2:
new_storage_obj = AliYunOss(**auth)
else:
new_storage_obj = LocalStorage(**auth)
return new_storage_obj
return None return None
def get_storage_type(self):
if self.storage_obj:
return self.storage_obj.storage_type
def get_storage_auth(self, storage_obj): def get_storage_auth(self, storage_obj):
auth_dict = { auth_dict = {
'access_key': storage_obj.access_key, 'access_key': storage_obj.access_key,

@ -104,8 +104,12 @@ class InstallView(APIView):
if dtoken.verify_token(downtoken,release_id): if dtoken.verify_token(downtoken,release_id):
app_obj = Apps.objects.filter(app_id=app_id,short=short).first() app_obj = Apps.objects.filter(app_id=app_id,short=short).first()
if app_obj: if app_obj:
app_obj.count_hits = app_obj.count_hits+1 app_obj.count_hits = app_obj.count_hits+1
app_obj.save() app_obj.save()
app_obj.user_id.all_download_times = app_obj.user_id.all_download_times+1
app_obj.user_id.save()
release_obj = AppReleaseInfo.objects.filter(app_id=app_obj,release_id=release_id).first() release_obj = AppReleaseInfo.objects.filter(app_id=app_obj,release_id=release_id).first()
if release_obj: if release_obj:
storage = Storage(app_obj.user_id) storage = Storage(app_obj.user_id)

@ -36,23 +36,27 @@ class LoginView(APIView):
password = receive.get("password") password = receive.get("password")
user = auth.authenticate(username=username, password=password) user = auth.authenticate(username=username, password=password)
if user is not None: if user is not None:
# update the token if user.is_active:
key = self.generate_key()
now = datetime.datetime.now() # update the token
Token.objects.update_or_create(user=user, defaults={"access_token": key, "created": now}) key = self.generate_key()
user_info = UserInfo.objects.get(pk=user.pk) now = datetime.datetime.now()
Token.objects.update_or_create(user=user, defaults={"access_token": key, "created": now})
serializer = UserInfoSerializer(user_info,) user_info = UserInfo.objects.get(pk=user.pk)
data = serializer.data
serializer = UserInfoSerializer(user_info,)
response.msg = "验证成功!" data = serializer.data
response.userinfo = data
response.token = key response.msg = "验证成功!"
response.userinfo = data
response.token = key
else:
response.msg = "用户被禁用"
response.code = 1002
else: else:
try: try:
UserInfo.objects.get(username=username) UserInfo.objects.get(username=username)
response.msg = "密码错误!" response.msg = "密码错误或者!"
response.code = 1002 response.code = 1002
except UserInfo.DoesNotExist: except UserInfo.DoesNotExist:
response.msg = "用户不存在!" response.msg = "用户不存在!"

@ -6,7 +6,7 @@
from api.utils.app.apputils import get_random_short,SaveAppInfos from api.utils.app.apputils import get_random_short,SaveAppInfos
from api.utils.storage.storage import Storage from api.utils.storage.storage import Storage
from api.models import Apps,AppReleaseInfo from api.models import Apps,AppReleaseInfo,UserInfo
from api.utils.app.randomstrings import make_app_uuid from api.utils.app.randomstrings import make_app_uuid
from rest_framework.views import APIView from rest_framework.views import APIView
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
@ -45,8 +45,8 @@ class AppAnalyseView(APIView):
upload_key = release_id+'.apk' upload_key = release_id+'.apk'
png_key = png_id+'.png' png_key = png_id+'.png'
storage = Storage(request.user) storage = Storage(request.user)
storage_type =storage.get_storage_type()
storage_type = request.user.storage.storage_type
if storage_type == 1: if storage_type == 1:
upload_token = storage.get_upload_token(upload_key) upload_token = storage.get_upload_token(upload_key)
png_token = storage.get_upload_token(png_key) png_token = storage.get_upload_token(png_key)
@ -123,7 +123,7 @@ class UploadView(APIView):
else: else:
upload_key = make_from_user_uuid(request.user)+'.'+app_type upload_key = make_from_user_uuid(request.user)+'.'+app_type
upload_token = storage.get_upload_token(upload_key) upload_token = storage.get_upload_token(upload_key)
storage_type = request.user.storage.storage_type storage_type = storage.get_storage_type()
res.data = {"domain_name": request.user.domain_name, res.data = {"domain_name": request.user.domain_name,
"upload_token": upload_token, "upload_token": upload_token,
"upload_key": upload_key, "upload_key": upload_key,
@ -164,11 +164,12 @@ class UploadView(APIView):
app_id = certinfo.get("app_id", None) app_id = certinfo.get("app_id", None)
ftype = certinfo.get("ftype",None) ftype = certinfo.get("ftype",None)
if ftype and ftype == 'app': if ftype and ftype == 'app':
app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first() pass
if not app_obj: # app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first()
res.code = 1006 # if not app_obj:
res.msg = '该应用不存在' # res.code = 1006
return Response(res.dict) # res.msg = '该应用不存在'
# return Response(res.dict)
elif ftype and ftype == 'head': elif ftype and ftype == 'head':
if request.user.uid != app_id: if request.user.uid != app_id:
res.code = 1007 res.code = 1007

@ -168,23 +168,14 @@ THIRD_PART_CONFIG = {
"GEE_TEST": { "GEE_TEST": {
}, },
# 支付宝支付相关配置 # APP存储配置
"ALI_PAY": { 'storage': [
# 默认使用配置 {
"default": { 'name': 'local',
"version": "1.0", # 支付宝支付调用的接口版本(固定值1.0) 'type': 0,
"debug": True, # 是否启用调试模式(False是正式环境) 'auth': {'domain_name': 'http://127.0.0.1:8000'}, # 正式环境需要填写正式的访问域名
"app_id": "2016091800539084", # 支付宝分配给开发者的应用ID(启用线上环境请更改), 'active': True
"app_private_key_path": os.path.join(
BASE_DIR, 'keys', 'app_private_2048.txt'
), # APP应用的私钥
"alipay_public_key_path": os.path.join(
BASE_DIR, 'keys', 'alipay_public_2048.txt'
), # 支付宝的公钥
"callback_url": "http://47.94.172.250:8804/api/v1/trade/alipay/", # 添加回调域名
},
# 目前针对支付业务进行切换
"pay": {
} }
} ]
} }

Loading…
Cancel
Save