管理后台存储迁移逻辑处理

v1.0.0
youngS 4 years ago
parent e25046df93
commit 87ae640c51
  1. 7
      fir_admin/src/api/storage.js
  2. 38
      fir_admin/src/views/userinfos/UserDetail.vue
  3. 3
      fir_ser/admin/urls.py
  4. 33
      fir_ser/admin/views/storage.py
  5. 2
      fir_ser/admin/views/user.py
  6. 41
      fir_ser/api/base_views.py
  7. 11
      fir_ser/api/utils/baseutils.py
  8. 1
      fir_ser/api/utils/serializer.py
  9. 14
      fir_ser/api/utils/utils.py
  10. 36
      fir_ser/api/views/storage.py

@ -16,3 +16,10 @@ export function updateStorageInfo(data) {
}) })
} }
export function changeStorageInfo(data) {
return request({
url: '/storage/change',
method: 'put',
data
})
}

@ -138,9 +138,8 @@
:inactive-value="false" :inactive-value="false"
/> />
</el-tooltip> </el-tooltip>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="5">
<el-select v-model="postForm.storage" filterable> <el-select v-model="postForm.storage" filterable>
<el-option-group <el-option-group
v-for="storage_group in storage_selection" v-for="storage_group in storage_selection"
@ -156,10 +155,20 @@
</el-option-group> </el-option-group>
</el-select> </el-select>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="4">
<el-button type="primary" style="margin-left: 20px" @click="changeStorageData(null)">
迁移数据
</el-button>
</el-col>
<el-col :span="4">
<el-button type="primary" style="margin-left: 20px" @click="changeStorageData(force)">
强制切换
</el-button>
</el-col>
<el-col :span="5">
<router-link :to="{name: 'storage_info_list',query:{user_id:postForm.id}}"> <router-link :to="{name: 'storage_info_list',query:{user_id:postForm.id}}">
<el-button type="primary" style="margin-left: 20px"> <el-button type="primary" style="margin-left: 20px">
查看私有存储信息 查看存储信息
</el-button> </el-button>
</router-link> </router-link>
</el-col> </el-col>
@ -229,7 +238,7 @@
<script> <script>
import { validURL } from '@/utils/validate' import { validURL } from '@/utils/validate'
import { getUserInfos, updateUserInfo } from '@/api/user' import { getUserInfos, updateUserInfo } from '@/api/user'
import { getStorageInfo } from '@/api/storage' import { getStorageInfo,changeStorageInfo } from '@/api/storage'
import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown' import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
const defaultForm = { const defaultForm = {
@ -332,6 +341,13 @@ export default {
} }
}, },
methods: { methods: {
changeStorageData(force) {
changeStorageInfo({id: this.postForm.id, use_storage_id: this.postForm.storage,force: force}).then(response => {
this.$message.success('存储数据迁移并设置刷新成功')
}).catch(err => {
console.log(err)
})
},
fetchStorageData(user_id) { fetchStorageData(user_id) {
getStorageInfo({ user_id: user_id }).then(response => { getStorageInfo({ user_id: user_id }).then(response => {
if (response.storage_selection) { if (response.storage_selection) {
@ -341,15 +357,18 @@ export default {
console.log(err) console.log(err)
}) })
}, },
setStorageInfo() {
if (!this.postForm.storage) {
this.postForm.storage = -1
}
this.fetchStorageData(this.postForm.id)
},
fetchData(id) { fetchData(id) {
getUserInfos({ id: id }).then(response => { getUserInfos({ id: id }).then(response => {
if (response.data.length === 1) { if (response.data.length === 1) {
this.postForm = response.data[0] this.postForm = response.data[0]
if (!this.postForm.storage) {
this.postForm.storage = -1
}
this.certification_status_choices = this.postForm.certification_status_choices this.certification_status_choices = this.postForm.certification_status_choices
this.fetchStorageData(this.postForm.id) this.setStorageInfo()
} }
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
@ -359,6 +378,7 @@ export default {
updateUserInfo(this.postForm).then(response => { updateUserInfo(this.postForm).then(response => {
this.$message.success('更新成功') this.$message.success('更新成功')
this.postForm = response.data this.postForm = response.data
this.setStorageInfo()
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
}) })

@ -17,7 +17,7 @@ from django.urls import re_path
from admin.views.login import LoginView, LoginUserView from admin.views.login import LoginView, LoginUserView
from admin.views.user import UserInfoView, UserCertificationInfoView from admin.views.user import UserInfoView, UserCertificationInfoView
from admin.views.app import AppInfoView, AppReleaseInfoView from admin.views.app import AppInfoView, AppReleaseInfoView
from admin.views.storage import StorageInfoView from admin.views.storage import StorageInfoView, StorageChangeView
urlpatterns = [ urlpatterns = [
# path("",include(router.urls)), # path("",include(router.urls)),
@ -30,5 +30,6 @@ urlpatterns = [
re_path("^app/release/info", AppReleaseInfoView.as_view()), re_path("^app/release/info", AppReleaseInfoView.as_view()),
re_path("^certification/info", UserCertificationInfoView.as_view()), re_path("^certification/info", UserCertificationInfoView.as_view()),
re_path("^storage/info", StorageInfoView.as_view()), re_path("^storage/info", StorageInfoView.as_view()),
re_path("^storage/change", StorageChangeView.as_view()),
] ]

@ -5,6 +5,8 @@
# date: 2021/4/11 # date: 2021/4/11
from django.contrib import auth from django.contrib import auth
from api.base_views import storage_change
from api.models import Token, UserInfo, AppStorage from api.models import Token, UserInfo, AppStorage
from rest_framework.response import Response from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication from api.utils.auth import AdminTokenAuthentication
@ -47,7 +49,7 @@ class StorageInfoView(APIView):
view=self) view=self)
serializer = AdminStorageSerializer(page_serializer, many=True) serializer = AdminStorageSerializer(page_serializer, many=True)
res.data = serializer.data res.data = serializer.data
res.storage_selection = format_storage_selection(serializer.data,serializer.data[0].get('storage_choices')) res.storage_selection = format_storage_selection(serializer.data, serializer.data[0].get('storage_choices'))
res.total = obj_list.count() res.total = obj_list.count()
return Response(res.dict) return Response(res.dict)
@ -60,7 +62,7 @@ class StorageInfoView(APIView):
res.msg = "参数错误" res.msg = "参数错误"
return Response(res.dict) return Response(res.dict)
obj = AppStorage.objects.filter(pk=pk).first() obj = AppStorage.objects.filter(pk=pk).first()
if obj: if obj and obj.user_id_id != obj.pk:
data['pk'] = pk data['pk'] = pk
serializer = AdminStorageSerializer(obj, data=data, partial=True) serializer = AdminStorageSerializer(obj, data=data, partial=True)
if serializer.is_valid(): if serializer.is_valid():
@ -70,3 +72,30 @@ class StorageInfoView(APIView):
res.code = 1004 res.code = 1004
res.msg = "数据校验失败" res.msg = "数据校验失败"
return Response(res.dict) return Response(res.dict)
class StorageChangeView(APIView):
authentication_classes = [AdminTokenAuthentication, ]
def put(self, request):
res = BaseResponse()
data = request.data
pk = data.get("id", None)
if not pk:
res.code = 1003
res.msg = "参数错误"
return Response(res.dict)
obj = UserInfo.objects.filter(pk=pk).first()
if obj:
logger.info("user %s update storage data:%s" % (obj, data))
use_storage_id = data.get("use_storage_id", None)
force = data.get("force", None)
if use_storage_id:
if not storage_change(use_storage_id, obj, force):
res.code = 1006
res.msg = '修改失败'
return Response(res.dict)
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)

@ -49,7 +49,7 @@ class UserInfoView(APIView):
page_obj = AppsPageNumber() page_obj = AppsPageNumber()
obj_list = UserInfo.objects.filter(**filter_data).order_by(sort) obj_list = UserInfo.objects.filter(**filter_data).order_by(sort)
page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request, page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request,
view=self) view=self)
serializer = AdminUserInfoSerializer(page_serializer, many=True) serializer = AdminUserInfoSerializer(page_serializer, many=True)
res.data = serializer.data res.data = serializer.data
res.total = obj_list.count() res.total = obj_list.count()

@ -11,13 +11,15 @@ from rest_framework.response import Response
from django.db.models import Sum from django.db.models import Sum
from api.utils.app.supersignutils import IosUtils, resign_by_app_obj from api.utils.app.supersignutils import IosUtils, resign_by_app_obj
from api.utils.storage.storage import Storage from api.utils.storage.storage import Storage
from api.utils.storage.caches import del_cache_response_by_short, get_app_today_download_times, del_cache_by_delete_app from api.utils.storage.caches import del_cache_response_by_short, get_app_today_download_times, del_cache_by_delete_app, \
from api.models import Apps, AppReleaseInfo, APPToDeveloper, AppIOSDeveloperInfo, UserInfo, AppScreenShot del_cache_storage
from api.models import Apps, AppReleaseInfo, APPToDeveloper, AppIOSDeveloperInfo, UserInfo, AppScreenShot, AppStorage
from api.utils.serializer import AppsSerializer, AppReleaseSerializer from api.utils.serializer import AppsSerializer, AppReleaseSerializer
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
import logging import logging
from fir_ser.settings import SERVER_DOMAIN from fir_ser.settings import SERVER_DOMAIN
from api.utils.utils import delete_local_files, delete_app_screenshots_files from api.utils.utils import delete_local_files, delete_app_screenshots_files, change_storage_and_change_head_img, \
migrating_storage_data, clean_storage_data, check_storage_is_new_storage
from api.utils.baseutils import is_valid_domain from api.utils.baseutils import is_valid_domain
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -101,3 +103,36 @@ def app_release_delete(app_obj, release_id, storage):
del_cache_response_by_short(app_obj.app_id) del_cache_response_by_short(app_obj.app_id)
return res return res
def storage_change(use_storage_id, user_obj, force):
if use_storage_id:
if user_obj.storage and use_storage_id == user_obj.storage.id:
return True
try:
if use_storage_id == -1:
change_storage_and_change_head_img(user_obj, None)
if migrating_storage_data(user_obj, None, False):
if check_storage_is_new_storage(user_obj, None):
clean_storage_data(user_obj)
UserInfo.objects.filter(pk=user_obj.pk).update(storage=None)
else:
new_storage_obj = AppStorage.objects.filter(pk=use_storage_id).first()
change_storage_and_change_head_img(user_obj, new_storage_obj)
if migrating_storage_data(user_obj, new_storage_obj, False):
if check_storage_is_new_storage(user_obj, new_storage_obj):
clean_storage_data(user_obj)
UserInfo.objects.filter(pk=user_obj.pk).update(storage_id=use_storage_id)
except Exception as e:
logger.error("update user %s storage failed Exception:%s" % (user_obj, e))
if force:
if use_storage_id == -1:
UserInfo.objects.filter(pk=user_obj.pk).update(storage=None)
else:
UserInfo.objects.filter(pk=user_obj.pk).update(storage_id=use_storage_id)
else:
return False
del_cache_storage(user_obj)
return True

@ -17,9 +17,9 @@ logger = logging.getLogger(__name__)
def get_app_d_count_by_app_id(app_id): def get_app_d_count_by_app_id(app_id):
d_count = 1 d_count = 1
binary_size = AppReleaseInfo.objects.filter(is_master=True, app_id__app_id=app_id).values('binary_size') binary_size = AppReleaseInfo.objects.filter(is_master=True, app_id__app_id=app_id).values('binary_size').first()
if binary_size and binary_size > 0: if binary_size and binary_size.get('binary_size', 0) > 0:
d_count += binary_size // 1024 // 1024 // 100 d_count += binary_size.get('binary_size') // 1024 // 1024 // 100
return d_count return d_count
@ -95,8 +95,9 @@ def format_storage_selection(storage_info_list, storage_choice_list):
for storage_choice in storage_choice_list: for storage_choice in storage_choice_list:
storage_choice['storage_info'] = [] storage_choice['storage_info'] = []
for storage_info in storage_info_list: for storage_info in storage_info_list:
if storage_info.get('storage_type') == storage_choice.get('id',): if storage_info.get('storage_type') == storage_choice.get('id', ):
storage_choice['storage_info'].append({'name': storage_info.get('name', ''), 'id': storage_info.get('id', '')}) storage_choice['storage_info'].append(
{'name': storage_info.get('name', ''), 'id': storage_info.get('id', '')})
for storage_choice in storage_choice_list: for storage_choice in storage_choice_list:
if not storage_choice['storage_info']: if not storage_choice['storage_info']:
storage_choice_list.remove(storage_choice) storage_choice_list.remove(storage_choice)

@ -7,6 +7,7 @@ from api.utils.storage.storage import Storage
from api.utils.utils import get_developer_udided, get_choices_dict, get_choices_name_from_key from api.utils.utils import get_developer_udided, get_choices_dict, get_choices_name_from_key
from api.utils.storage.caches import get_user_free_download_times, get_user_cert_auth_status from api.utils.storage.caches import get_user_free_download_times, get_user_cert_auth_status
import os, json, logging import os, json, logging
logger = logging.getLogger(__file__) logger = logging.getLogger(__file__)
token_obj = DownloadToken() token_obj = DownloadToken()

@ -199,6 +199,17 @@ def download_files_form_oss(storage_obj, org_file):
return False return False
def check_storage_is_new_storage(user_obj, new_storage_obj):
old_storage_obj = Storage(user_obj)
if not new_storage_obj:
new_storage_obj = Storage(user_obj, None, True)
else:
new_storage_obj = Storage(user_obj, new_storage_obj)
if old_storage_obj.get_storage_type() == new_storage_obj.get_storage_type():
return False
return True
def migrating_storage_file_data(user_obj, filename, new_storage_obj, clean_old_data=True): def migrating_storage_file_data(user_obj, filename, new_storage_obj, clean_old_data=True):
local_file_full_path = os.path.join(MEDIA_ROOT, filename) local_file_full_path = os.path.join(MEDIA_ROOT, filename)
old_storage_obj = Storage(user_obj) old_storage_obj = Storage(user_obj)
@ -262,9 +273,12 @@ def migrating_storage_data(user_obj, new_storage_obj, clean_old_data):
def clean_storage_data(user_obj, storage_obj=None): def clean_storage_data(user_obj, storage_obj=None):
storage_obj = Storage(user_obj, storage_obj) storage_obj = Storage(user_obj, storage_obj)
logger.info("%s clean_storage_data %s" % (user_obj, storage_obj))
for app_release_obj in AppReleaseInfo.objects.filter(app_id__user_id=user_obj).all(): for app_release_obj in AppReleaseInfo.objects.filter(app_id__user_id=user_obj).all():
storage_obj.delete_file(app_release_obj.release_id, app_release_obj.release_type) storage_obj.delete_file(app_release_obj.release_id, app_release_obj.release_type)
storage_obj.delete_file(app_release_obj.icon_url) storage_obj.delete_file(app_release_obj.icon_url)
for screenshot_obj in AppScreenShot.objects.filter(app_id=app_release_obj.app_id).all():
storage_obj.delete_file(screenshot_obj.screenshot_url)
for apptodev_obj in APPToDeveloper.objects.filter(app_id=app_release_obj.app_id).all(): for apptodev_obj in APPToDeveloper.objects.filter(app_id=app_release_obj.app_id).all():
storage_obj.delete_file(apptodev_obj.binary_file, app_release_obj.release_type) storage_obj.delete_file(apptodev_obj.binary_file, app_release_obj.release_type)
return True return True

@ -5,6 +5,8 @@
# date: 2020/3/4 # date: 2020/3/4
from rest_framework.views import APIView from rest_framework.views import APIView
from api.base_views import storage_change
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
from api.utils.auth import ExpiringTokenAuthentication, StoragePermission from api.utils.auth import ExpiringTokenAuthentication, StoragePermission
from rest_framework.response import Response from rest_framework.response import Response
@ -93,37 +95,9 @@ class StorageView(APIView):
use_storage_id = data.get("use_storage_id", None) use_storage_id = data.get("use_storage_id", None)
force = data.get("force", None) force = data.get("force", None)
if use_storage_id: if use_storage_id:
if request.user.storage and use_storage_id == request.user.storage.id: if not storage_change(use_storage_id, request.user, force):
return Response(res.dict) res.code = 1006
try: res.msg = '修改失败'
if use_storage_id == -1:
change_storage_and_change_head_img(request.user, None)
if migrating_storage_data(request.user, None, False):
clean_storage_data(request.user)
UserInfo.objects.filter(pk=request.user.pk).update(storage=None)
else:
new_storage_obj = AppStorage.objects.filter(pk=use_storage_id).first()
change_storage_and_change_head_img(request.user, new_storage_obj)
if migrating_storage_data(request.user, new_storage_obj, False):
clean_storage_data(request.user)
UserInfo.objects.filter(pk=request.user.pk).update(storage_id=use_storage_id)
del_cache_storage(request.user)
except Exception as e:
logger.error("update user %s storage failed Exception:%s" % (request.user, e))
if force:
if use_storage_id == -1:
UserInfo.objects.filter(pk=request.user.pk).update(storage=None)
else:
UserInfo.objects.filter(pk=request.user.pk).update(storage_id=use_storage_id)
clean_storage_data(request.user)
else:
res.code = 1006
res.msg = '修改失败'
del_cache_storage(request.user)
return Response(res.dict) return Response(res.dict)
storage_id = data.get("id", None) storage_id = data.get("id", None)

Loading…
Cancel
Save