优化存储逻辑和展示页面

dependabot/npm_and_yarn/fir_admin/eventsource-1.1.1
nineven 3 years ago
parent a5b73c3695
commit c36ab08f35
  1. 19
      fir_client/src/components/user/FirSuperSignBase.vue
  2. 202
      fir_client/src/components/user/FirUserStorage.vue
  3. 10
      fir_ser/api/utils/serializer.py
  4. 29
      fir_ser/api/views/storage.py
  5. 7
      fir_ser/xsign/utils/serializer.py
  6. 4
      fir_ser/xsign/views/supersign.py

@ -1373,7 +1373,13 @@
label="设备数量" label="设备数量"
prop="number" prop="number"
width="100"> width="100">
<template slot-scope="scope">
<el-popover content="点击修改共享设备数量" trigger="hover">
<el-link slot="reference" :underline="false" @click="editShareDevice(scope.row)">
<span v-if="scope.row.cancel">-</span> {{ scope.row.number }}
</el-link>
</el-popover>
</template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
:formatter="deviceformatter" :formatter="deviceformatter"
@ -1939,6 +1945,14 @@ export default {
} }
}, },
methods: { methods: {
editShareDevice(row) {
// if (row.status !== 2) return
if (!row.cancel) return
this.target_number = row.number;
this.target_uid = row.target_user.uid
this.checkuid(this.target_uid)
this.transferVisible = true
},
changeSignConfig(info) { changeSignConfig(info) {
personalConfigInfo(data => { personalConfigInfo(data => {
if (data.code === 1000) { if (data.code === 1000) {
@ -2071,6 +2085,9 @@ export default {
DeviceTransferBillInfo(data => { DeviceTransferBillInfo(data => {
if (data.code === 1000) { if (data.code === 1000) {
this.transferInfo = data.data this.transferInfo = data.data
if (this.transferInfo.number) {
this.target_number = this.transferInfo.number
}
this.cantransfer = false this.cantransfer = false
} else { } else {
this.cantransfer = true this.cantransfer = true

@ -193,22 +193,50 @@
</el-dialog> </el-dialog>
<el-tabs v-model="activeName" tab-position="top" type="border-card" @tab-click="handleClick"> <el-tabs v-model="activeName" tab-position="top" type="border-card" @tab-click="handleClick">
<el-tab-pane label="存储选择" name="change"> <el-tab-pane label="存储选择" name="change">'
存储选择 <el-row :gutter="24">
<el-select v-model="use_storage_id" :placeholder="selectlabel" filterable style="width: 400px" <el-col :span="14">
@change="select_storage"> 存储选择
<el-option-group <el-select v-model="use_storage_id" :placeholder="selectlabel" filterable style="width: 400px"
v-for="storage_group in fstorage_lists" @change="select_storage">
:key="storage_group.group_name" <el-option-group
:label="storage_group.group_name"> v-for="storage_group in fstorage_lists"
<el-option :key="storage_group.group_name"
v-for="storage in storage_group.storages" :label="storage_group.group_name">
:key="storage.id" <el-option
:label="format_s_name(storage)" v-for="storage in storage_group.storages"
:value="storage.id"> :key="storage.id"
</el-option> :label="format_s_name(storage)"
</el-option-group> :value="storage.id">
</el-select> </el-option>
</el-option-group>
</el-select>
</el-col>
<el-col :span="10">
<el-popover
placement="top-start"
trigger="hover">
<div>
<el-link :underline="false">存储最大容量空间 {{ diskSize(storageinfo.max_storage_capacity) }}</el-link>
<el-link :underline="false">已经使用容量 {{ diskSize(storageinfo.used_number) }}</el-link>
<el-link :underline="false">当前可用容量
{{ diskSize(storageinfo.max_storage_capacity - storageinfo.used_number) }}
</el-link>
</div>
<el-link slot="reference" :underline="false" style="font-size: small">
还剩{{ diskSize(storageinfo.max_storage_capacity - storageinfo.used_number) }} 可用
</el-link>
</el-popover>
<el-progress
:color="storage_usedColor"
:percentage="percentage"
:stroke-width="16"
:text-inside="true" status="success" style="width: 80%"
type="line"/>
</el-col>
</el-row>
<div v-if="use_storage_id!==org_storage_id" style="margin-top: 20px"> <div v-if="use_storage_id!==org_storage_id" style="margin-top: 20px">
<el-button style="margin-left: 10px" <el-button style="margin-left: 10px"
type="info" type="info"
@ -234,7 +262,7 @@
<!-- </el-button>--> <!-- </el-button>-->
</div> </div>
<el-divider/> <el-divider/>
<el-form v-if="storageinfo.id && storageinfo.id !==-1" ref="storageinfoform" :model="storageinfo" <el-form ref="storageinfoform" :model="storageinfo"
label-width="80px" style="width: 39%;margin:0 auto;"> label-width="80px" style="width: 39%;margin:0 auto;">
<el-form-item label="存储最大容量" label-width="110px" style="text-align: left"> <el-form-item label="存储最大容量" label-width="110px" style="text-align: left">
@ -245,64 +273,66 @@
可用容量{{ diskSize(storageinfo.max_storage_capacity - storageinfo.used_number) }} 可用容量{{ diskSize(storageinfo.max_storage_capacity - storageinfo.used_number) }}
</el-tag> </el-tag>
</el-form-item> </el-form-item>
<div v-if="storageinfo.id && storageinfo.id !==-1">
<el-form-item label="存储类型" label-width="110px"> <el-divider/>
<el-select v-model="storageinfo.storage_type" :disabled='Sdisabled' placeholder="存储类型" <el-form-item label="存储类型" label-width="110px">
style="margin-left: -60px"> <el-select v-model="storageinfo.storage_type" :disabled='Sdisabled' placeholder="存储类型"
<el-option v-for="st in storage_list" :key="st.id" :label="st.name" style="margin-left: -60px">
:value="st.id"/> <el-option v-for="st in storage_list" :key="st.id" :label="st.name"
</el-select> :value="st.id"/>
</el-form-item> </el-select>
<div v-if="storageinfo.storage_type">
<el-form-item label="存储名称" label-width="110px">
<el-input v-model="storageinfo.name" :disabled='Sdisabled'/>
</el-form-item> </el-form-item>
<el-form-item label="key" label-width="110px"> <div v-if="storageinfo.storage_type">
<el-input v-model="storageinfo.access_key" :disabled='Sdisabled'/>
</el-form-item>
<el-form-item label="bucket_name" label-width="110px">
<el-input v-model="storageinfo.bucket_name" :disabled='Sdisabled'/>
</el-form-item>
<el-form-item label="下载域名" label-width="110px">
<el-input v-model="storageinfo.domain_name" :disabled='Sdisabled'/>
</el-form-item>
<div v-if="storageinfo.storage_type === 2"> <el-form-item label="存储名称" label-width="110px">
<el-form-item label="sts_role_arn" label-width="110px"> <el-input v-model="storageinfo.name" :disabled='Sdisabled'/>
<el-input v-model="storageinfo.sts_role_arn"
:disabled='Sdisabled'/>
</el-form-item> </el-form-item>
<el-form-item label="endpoint" label-width="110px"> <el-form-item label="key" label-width="110px">
<el-input v-model="storageinfo.endpoint" <el-input v-model="storageinfo.access_key" :disabled='Sdisabled'/>
:disabled='Sdisabled'/> </el-form-item>
<el-form-item label="bucket_name" label-width="110px">
<el-input v-model="storageinfo.bucket_name" :disabled='Sdisabled'/>
</el-form-item>
<el-form-item label="下载域名" label-width="110px">
<el-input v-model="storageinfo.domain_name" :disabled='Sdisabled'/>
</el-form-item> </el-form-item>
<el-form-item label="下载授权方式" label-width="110px"> <div v-if="storageinfo.storage_type === 2">
<el-select v-model="storageinfo.download_auth_type" <el-form-item label="sts_role_arn" label-width="110px">
:disabled="disabled" <el-input v-model="storageinfo.sts_role_arn"
placeholder="下载授权方式" style="width: 100%"> :disabled='Sdisabled'/>
<el-option v-for="st in storageinfo.download_auth_type_choices" :key="st.id" </el-form-item>
:label="st.name"
:value="st.id"/> <el-form-item label="endpoint" label-width="110px">
</el-select> <el-input v-model="storageinfo.endpoint"
:disabled='Sdisabled'/>
</el-form-item>
<el-form-item label="下载授权方式" label-width="110px">
<el-select v-model="storageinfo.download_auth_type"
:disabled="disabled"
placeholder="下载授权方式" style="width: 100%">
<el-option v-for="st in storageinfo.download_auth_type_choices" :key="st.id"
:label="st.name"
:value="st.id"/>
</el-select>
<el-form-item v-if="storageinfo.download_auth_type === 2" label="CDN鉴权主KEY" label-width="120px"
style="margin-top: 10px;width: 100%">
<el-input v-model="storageinfo.cnd_auth_key" :disabled='disabled'
placeholder="CDN鉴权主KEY"/>
</el-form-item>
<el-form-item v-if="storageinfo.download_auth_type === 2" label="CDN鉴权主KEY" label-width="120px"
style="margin-top: 10px;width: 100%">
<el-input v-model="storageinfo.cnd_auth_key" :disabled='disabled'
placeholder="CDN鉴权主KEY"/>
</el-form-item> </el-form-item>
</div>
<el-form-item label="备注" label-width="110px">
<el-input v-model="storageinfo.description" :disabled='Sdisabled'/>
</el-form-item> </el-form-item>
</div> </div>
<el-form-item label="备注" label-width="110px">
<el-input v-model="storageinfo.description" :disabled='Sdisabled'/>
</el-form-item>
</div> </div>
</el-form> </el-form>
@ -719,7 +749,7 @@ export default {
dialogstorageVisible: false, dialogstorageVisible: false,
editstorageinfo: {}, editstorageinfo: {},
selectlabel: "", selectlabel: "",
storageinfo: {}, storageinfo: {'used_number': 0, 'max_storage_capacity': 1},
storage_list: [], storage_list: [],
endpoint_list: [], endpoint_list: [],
disabled: true, disabled: true,
@ -735,12 +765,36 @@ export default {
}, methods: { }, methods: {
format_time, format_time,
diskSize, diskSize,
storage_usedColor(percentage) {
if (percentage < 20) {
return '#6f7ad3';
} else if (percentage < 40) {
return '#1989fa';
} else if (percentage < 60) {
return '#5cb87a';
} else if (percentage < 80) {
return '#e6a23c';
} else if (percentage < 90) {
return '#E63918';
} else {
return '#F50346';
}
},
updateConfig() { updateConfig() {
const loading = this.$loading({
lock: true,
text: '执行中,请耐心等待...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
configStorageData(res => { configStorageData(res => {
loading.close()
if (res.code === 1000) { if (res.code === 1000) {
this.$message.success("操作成功")
this.storage_config = res.data this.storage_config = res.data
} else { } else {
this.$message.error("获取数据失败了," + res.msg) this.$message.error("操作失败了," + res.msg)
} }
}, {"methods": "PUT", "data": this.storage_config}) }, {"methods": "PUT", "data": this.storage_config})
}, },
@ -767,8 +821,8 @@ export default {
this.use_storage_id = row.storage_id; this.use_storage_id = row.storage_id;
} else { } else {
this.use_storage_id = data.storage; this.use_storage_id = data.storage;
this.formatStorageId()
} }
this.formatStorageId()
if (row && row.target_user) { if (row && row.target_user) {
this.target_uid = row.target_user.uid this.target_uid = row.target_user.uid
this.checkuid(this.target_uid) this.checkuid(this.target_uid)
@ -781,7 +835,7 @@ export default {
}, {"methods": 'GET', "data": {'act': 'storage_group', 'is_default': false}}); }, {"methods": 'GET', "data": {'act': 'storage_group', 'is_default': false}});
}, },
editShareStorage(row) { editShareStorage(row) {
if (row.status !== 1) return // if (row.status !== 1) return
if (!row.cancel) return if (!row.cancel) return
this.shareStorage(row) this.shareStorage(row)
}, },
@ -938,6 +992,7 @@ export default {
return return
} }
} }
this.editstorageinfo.storage_capacity = this.editstorageinfo.max_storage_capacity
getStorageinfo(data => { getStorageinfo(data => {
if (data.code === 1000) { if (data.code === 1000) {
this.$message.success('操作成功'); this.$message.success('操作成功');
@ -1039,10 +1094,10 @@ export default {
this.getstorageinfobyid(a); this.getstorageinfobyid(a);
}, },
getstorageinfobyid(id) { getstorageinfobyid(id) {
if (id === -1) { // if (id === -1) {
this.storageinfo = {} // this.storageinfo = {}
return // return
} // }
this.target_number = parseInt(this.getSizeFromId() / 1024 / 1024) this.target_number = parseInt(this.getSizeFromId() / 1024 / 1024)
getStorageinfo(data => { getStorageinfo(data => {
if (data.code === 1000) { if (data.code === 1000) {
@ -1147,6 +1202,13 @@ export default {
computed: { computed: {
watchObj() { watchObj() {
return [this.editstorageinfo.endpoint, this.editstorageinfo.bucket_name, this.editstorageinfo.download_auth_type] return [this.editstorageinfo.endpoint, this.editstorageinfo.bucket_name, this.editstorageinfo.download_auth_type]
},
percentage() {
let p = parseInt(this.storageinfo.used_number * 100 / this.storageinfo.max_storage_capacity);
if (p < 0 || p >= 100) {
p = 100
}
return p
} }
} }
} }

@ -370,21 +370,22 @@ class StorageSerializer(serializers.ModelSerializer):
storage_type = attrs.get('storage_type', '') storage_type = attrs.get('storage_type', '')
if storage_type == 2 and endpoint not in Config.STORAGE_ALLOW_ENDPOINT: if storage_type == 2 and endpoint not in Config.STORAGE_ALLOW_ENDPOINT:
raise ValidationError(f'endpoint [{endpoint}] not in {Config.STORAGE_ALLOW_ENDPOINT}') raise ValidationError(f'endpoint [{endpoint}] not in {Config.STORAGE_ALLOW_ENDPOINT}')
max_storage_capacity = attrs.get('max_storage_capacity', -1) max_storage_capacity = attrs.get('storage_capacity', -1)
if max_storage_capacity != -1: if max_storage_capacity != -1:
attrs['max_storage_capacity'] = max_storage_capacity * 1024 * 1024 attrs['max_storage_capacity'] = max_storage_capacity * 1024 * 1024
elif max_storage_capacity == 0: elif max_storage_capacity == 0:
attrs['max_storage_capacity'] = Config.STORAGE_OSS_CAPACITY attrs['max_storage_capacity'] = Config.STORAGE_OSS_CAPACITY
else: else:
del attrs['max_storage_capacity'] del attrs['storage_capacity']
return attrs return attrs
storage_type_display = serializers.CharField(source="get_storage_type_display", read_only=True) storage_type_display = serializers.CharField(source="get_storage_type_display", read_only=True)
storage_capacity = serializers.IntegerField(write_only=True)
download_auth_type_choices = serializers.SerializerMethodField() download_auth_type_choices = serializers.SerializerMethodField()
used = serializers.SerializerMethodField() used = serializers.SerializerMethodField()
used_number = serializers.SerializerMethodField() used_number = serializers.SerializerMethodField()
shared = serializers.SerializerMethodField() shared = serializers.SerializerMethodField()
max_storage_capacity = serializers.SerializerMethodField()
def get_used(self, obj): def get_used(self, obj):
return obj.app_storage.count() return obj.app_storage.count()
@ -395,6 +396,9 @@ class StorageSerializer(serializers.ModelSerializer):
def get_used_number(self, obj): def get_used_number(self, obj):
return get_user_storage_used(obj.app_storage.all()) return get_user_storage_used(obj.app_storage.all())
def get_max_storage_capacity(self, obj):
return obj.max_storage_capacity if obj.max_storage_capacity != 0 else Config.STORAGE_OSS_CAPACITY
# secret_key = serializers.SerializerMethodField() # secret_key = serializers.SerializerMethodField()
# 加上此选项,会导致update获取不到值 # 加上此选项,会导致update获取不到值
# def get_secret_key(self, obj): # def get_secret_key(self, obj):

@ -87,6 +87,26 @@ class StorageView(APIView):
if act == 'storage_group': if act == 'storage_group':
res.storage_group_list = get_storage_group(request, res, self.storage_type, is_default == 'true') res.storage_group_list = get_storage_group(request, res, self.storage_type, is_default == 'true')
return Response(res.dict) return Response(res.dict)
if pk:
if pk == '-1':
storage_capacity = request.user.storage_capacity
default_storage = {
'id': -1,
'max_storage_capacity': storage_capacity if storage_capacity != 0 else Config.STORAGE_FREE_CAPACITY,
'used_number': get_user_storage_used(request.user)
}
res.data = [default_storage]
return Response(res.dict)
else:
share_obj = StorageShareInfo.objects.filter(to_user_id=request.user, storage_id_id=pk, status=1).first()
if share_obj:
default_storage = {
'id': -1,
'max_storage_capacity': share_obj.number,
'used_number': get_user_storage_used(request.user)
}
res.data = [default_storage]
return Response(res.dict)
# [1,2] 表示七牛存储和阿里云存储 # [1,2] 表示七牛存储和阿里云存储
storage_queruset = AppStorage.objects.filter(user_id=request.user, storage_type__in=self.storage_type) storage_queruset = AppStorage.objects.filter(user_id=request.user, storage_type__in=self.storage_type)
@ -308,7 +328,7 @@ class ShareStorageView(APIView):
status=1, storage_id=storage_obj).first() status=1, storage_id=storage_obj).first()
if share_obj: if share_obj:
# number += share_obj.number # number += share_obj.number
share_obj.number = number if number < storage_capacity else storage_capacity share_obj.number = number
share_obj.remote_addr = get_real_ip_address(request) share_obj.remote_addr = get_real_ip_address(request)
share_obj.description = f'{user_obj.first_name} 共享给 {to_user_obj.first_name} {share_obj.number} Mb存储空间 ' share_obj.description = f'{user_obj.first_name} 共享给 {to_user_obj.first_name} {share_obj.number} Mb存储空间 '
share_obj.save(update_fields=['number', 'remote_addr', 'description']) share_obj.save(update_fields=['number', 'remote_addr', 'description'])
@ -409,10 +429,15 @@ class StorageConfigView(APIView):
history_release_limit = request.data.get('user_history_limit') history_release_limit = request.data.get('user_history_limit')
if history_release_limit: if history_release_limit:
try: try:
history_release_limit = int(history_release_limit) history_release_limit = int(history_release_limit) if int(
history_release_limit) > 0 else request.user.history_release_limit
except Exception as e: except Exception as e:
logger.warning(f"update user history_release_limit failed Exception:{e}") logger.warning(f"update user history_release_limit failed Exception:{e}")
history_release_limit = request.user.history_release_limit history_release_limit = request.user.history_release_limit
UserInfo.objects.filter(pk=request.user.pk).update(history_release_limit=abs(history_release_limit)) UserInfo.objects.filter(pk=request.user.pk).update(history_release_limit=abs(history_release_limit))
app_obj_lists = Apps.objects.filter(user_id=request.user).all()
for app_obj in app_obj_lists:
clean_history_apps(app_obj, request.user, abs(history_release_limit))
return self.get(request) return self.get(request)

@ -240,7 +240,6 @@ class BillTransferSerializer(serializers.ModelSerializer):
target_user = serializers.SerializerMethodField() target_user = serializers.SerializerMethodField()
cancel = serializers.SerializerMethodField() cancel = serializers.SerializerMethodField()
number = serializers.SerializerMethodField()
status_display = serializers.CharField(source='get_status_display') status_display = serializers.CharField(source='get_status_display')
def get_target_user(self, obj): def get_target_user(self, obj):
@ -252,12 +251,6 @@ class BillTransferSerializer(serializers.ModelSerializer):
def get_cancel(self, obj): def get_cancel(self, obj):
return self.context.get('user_obj').pk == obj.user_id.pk return self.context.get('user_obj').pk == obj.user_id.pk
def get_number(self, obj):
if self.get_cancel(obj):
return -obj.number
else:
return obj.number
class AppleDeveloperToAppUseSerializer(serializers.ModelSerializer): class AppleDeveloperToAppUseSerializer(serializers.ModelSerializer):
class Meta: class Meta:

@ -700,9 +700,7 @@ class DeviceTransferBillView(APIView):
bill_obj = IosDeveloperBill.objects.filter(user_id=user_obj, to_user_id=to_user_obj, bill_obj = IosDeveloperBill.objects.filter(user_id=user_obj, to_user_id=to_user_obj,
status=2).first() status=2).first()
if bill_obj: if bill_obj:
bill_obj.number = number + bill_obj.number bill_obj.number = number if number < all_balance else all_balance
if bill_obj.number >= all_balance:
bill_obj.number = all_balance
bill_obj.remote_addr = get_real_ip_address(request) bill_obj.remote_addr = get_real_ip_address(request)
bill_obj.description = f'{user_obj.first_name} 共享给 {to_user_obj.first_name} {bill_obj.number} 设备数' bill_obj.description = f'{user_obj.first_name} 共享给 {to_user_obj.first_name} {bill_obj.number} 设备数'
bill_obj.save(update_fields=['number', 'remote_addr', 'description']) bill_obj.save(update_fields=['number', 'remote_addr', 'description'])

Loading…
Cancel
Save