优化存储逻辑和展示页面

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="设备数量"
prop="number"
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
:formatter="deviceformatter"
@ -1939,6 +1945,14 @@ export default {
}
},
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) {
personalConfigInfo(data => {
if (data.code === 1000) {
@ -2071,6 +2085,9 @@ export default {
DeviceTransferBillInfo(data => {
if (data.code === 1000) {
this.transferInfo = data.data
if (this.transferInfo.number) {
this.target_number = this.transferInfo.number
}
this.cantransfer = false
} else {
this.cantransfer = true

@ -193,22 +193,50 @@
</el-dialog>
<el-tabs v-model="activeName" tab-position="top" type="border-card" @tab-click="handleClick">
<el-tab-pane label="存储选择" name="change">
存储选择
<el-select v-model="use_storage_id" :placeholder="selectlabel" filterable style="width: 400px"
@change="select_storage">
<el-option-group
v-for="storage_group in fstorage_lists"
:key="storage_group.group_name"
:label="storage_group.group_name">
<el-option
v-for="storage in storage_group.storages"
:key="storage.id"
:label="format_s_name(storage)"
:value="storage.id">
</el-option>
</el-option-group>
</el-select>
<el-tab-pane label="存储选择" name="change">'
<el-row :gutter="24">
<el-col :span="14">
存储选择
<el-select v-model="use_storage_id" :placeholder="selectlabel" filterable style="width: 400px"
@change="select_storage">
<el-option-group
v-for="storage_group in fstorage_lists"
:key="storage_group.group_name"
:label="storage_group.group_name">
<el-option
v-for="storage in storage_group.storages"
:key="storage.id"
:label="format_s_name(storage)"
:value="storage.id">
</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">
<el-button style="margin-left: 10px"
type="info"
@ -234,7 +262,7 @@
<!-- </el-button>-->
</div>
<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;">
<el-form-item label="存储最大容量" label-width="110px" style="text-align: left">
@ -245,64 +273,66 @@
可用容量{{ diskSize(storageinfo.max_storage_capacity - storageinfo.used_number) }}
</el-tag>
</el-form-item>
<el-form-item label="存储类型" label-width="110px">
<el-select v-model="storageinfo.storage_type" :disabled='Sdisabled' placeholder="存储类型"
style="margin-left: -60px">
<el-option v-for="st in storage_list" :key="st.id" :label="st.name"
:value="st.id"/>
</el-select>
</el-form-item>
<div v-if="storageinfo.storage_type">
<el-form-item label="存储名称" label-width="110px">
<el-input v-model="storageinfo.name" :disabled='Sdisabled'/>
<div v-if="storageinfo.id && storageinfo.id !==-1">
<el-divider/>
<el-form-item label="存储类型" label-width="110px">
<el-select v-model="storageinfo.storage_type" :disabled='Sdisabled' placeholder="存储类型"
style="margin-left: -60px">
<el-option v-for="st in storage_list" :key="st.id" :label="st.name"
:value="st.id"/>
</el-select>
</el-form-item>
<el-form-item label="key" label-width="110px">
<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">
<div v-if="storageinfo.storage_type === 2">
<el-form-item label="sts_role_arn" label-width="110px">
<el-input v-model="storageinfo.sts_role_arn"
:disabled='Sdisabled'/>
<el-form-item label="存储名称" label-width="110px">
<el-input v-model="storageinfo.name" :disabled='Sdisabled'/>
</el-form-item>
<el-form-item label="endpoint" label-width="110px">
<el-input v-model="storageinfo.endpoint"
:disabled='Sdisabled'/>
<el-form-item label="key" label-width="110px">
<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>
<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>
<div v-if="storageinfo.storage_type === 2">
<el-form-item label="sts_role_arn" label-width="110px">
<el-input v-model="storageinfo.sts_role_arn"
:disabled='Sdisabled'/>
</el-form-item>
<el-form-item label="endpoint" label-width="110px">
<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>
</div>
<el-form-item label="备注" label-width="110px">
<el-input v-model="storageinfo.description" :disabled='Sdisabled'/>
</el-form-item>
</div>
<el-form-item label="备注" label-width="110px">
<el-input v-model="storageinfo.description" :disabled='Sdisabled'/>
</el-form-item>
</div>
</el-form>
@ -719,7 +749,7 @@ export default {
dialogstorageVisible: false,
editstorageinfo: {},
selectlabel: "",
storageinfo: {},
storageinfo: {'used_number': 0, 'max_storage_capacity': 1},
storage_list: [],
endpoint_list: [],
disabled: true,
@ -735,12 +765,36 @@ export default {
}, methods: {
format_time,
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() {
const loading = this.$loading({
lock: true,
text: '执行中,请耐心等待...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
configStorageData(res => {
loading.close()
if (res.code === 1000) {
this.$message.success("操作成功")
this.storage_config = res.data
} else {
this.$message.error("获取数据失败了," + res.msg)
this.$message.error("操作失败了," + res.msg)
}
}, {"methods": "PUT", "data": this.storage_config})
},
@ -767,8 +821,8 @@ export default {
this.use_storage_id = row.storage_id;
} else {
this.use_storage_id = data.storage;
this.formatStorageId()
}
this.formatStorageId()
if (row && row.target_user) {
this.target_uid = row.target_user.uid
this.checkuid(this.target_uid)
@ -781,7 +835,7 @@ export default {
}, {"methods": 'GET', "data": {'act': 'storage_group', 'is_default': false}});
},
editShareStorage(row) {
if (row.status !== 1) return
// if (row.status !== 1) return
if (!row.cancel) return
this.shareStorage(row)
},
@ -938,6 +992,7 @@ export default {
return
}
}
this.editstorageinfo.storage_capacity = this.editstorageinfo.max_storage_capacity
getStorageinfo(data => {
if (data.code === 1000) {
this.$message.success('操作成功');
@ -1039,10 +1094,10 @@ export default {
this.getstorageinfobyid(a);
},
getstorageinfobyid(id) {
if (id === -1) {
this.storageinfo = {}
return
}
// if (id === -1) {
// this.storageinfo = {}
// return
// }
this.target_number = parseInt(this.getSizeFromId() / 1024 / 1024)
getStorageinfo(data => {
if (data.code === 1000) {
@ -1147,6 +1202,13 @@ export default {
computed: {
watchObj() {
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', '')
if storage_type == 2 and 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:
attrs['max_storage_capacity'] = max_storage_capacity * 1024 * 1024
elif max_storage_capacity == 0:
attrs['max_storage_capacity'] = Config.STORAGE_OSS_CAPACITY
else:
del attrs['max_storage_capacity']
del attrs['storage_capacity']
return attrs
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()
used = serializers.SerializerMethodField()
used_number = serializers.SerializerMethodField()
shared = serializers.SerializerMethodField()
max_storage_capacity = serializers.SerializerMethodField()
def get_used(self, obj):
return obj.app_storage.count()
@ -395,6 +396,9 @@ class StorageSerializer(serializers.ModelSerializer):
def get_used_number(self, obj):
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()
# 加上此选项,会导致update获取不到值
# def get_secret_key(self, obj):

@ -87,6 +87,26 @@ class StorageView(APIView):
if act == 'storage_group':
res.storage_group_list = get_storage_group(request, res, self.storage_type, is_default == 'true')
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] 表示七牛存储和阿里云存储
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()
if share_obj:
# 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.description = f'{user_obj.first_name} 共享给 {to_user_obj.first_name} {share_obj.number} Mb存储空间 '
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')
if history_release_limit:
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:
logger.warning(f"update user history_release_limit failed Exception:{e}")
history_release_limit = request.user.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)

@ -240,7 +240,6 @@ class BillTransferSerializer(serializers.ModelSerializer):
target_user = serializers.SerializerMethodField()
cancel = serializers.SerializerMethodField()
number = serializers.SerializerMethodField()
status_display = serializers.CharField(source='get_status_display')
def get_target_user(self, obj):
@ -252,12 +251,6 @@ class BillTransferSerializer(serializers.ModelSerializer):
def get_cancel(self, obj):
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 Meta:

@ -700,9 +700,7 @@ class DeviceTransferBillView(APIView):
bill_obj = IosDeveloperBill.objects.filter(user_id=user_obj, to_user_id=to_user_obj,
status=2).first()
if bill_obj:
bill_obj.number = number + bill_obj.number
if bill_obj.number >= all_balance:
bill_obj.number = all_balance
bill_obj.number = number if number < all_balance else all_balance
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.save(update_fields=['number', 'remote_addr', 'description'])

Loading…
Cancel
Save