存储参数修改

pull/10/head
youngS 4 years ago
parent d133d0ec7b
commit ac77e8b36a
  1. 77
      fir_admin/src/components/JsonEditor/index.vue
  2. 2
      fir_admin/src/views/authentication/Detail.vue
  3. 2
      fir_admin/src/views/authentication/list.vue
  4. 99
      fir_admin/src/views/storage/Detail.vue
  5. 70
      fir_admin/src/views/storage/list.vue
  6. 61
      fir_client/src/components/user/FirUserStorage.vue
  7. 13
      fir_ser/admin/views/app.py
  8. 22
      fir_ser/admin/views/storage.py
  9. 17
      fir_ser/admin/views/user.py
  10. 15
      fir_ser/api/models.py
  11. 9
      fir_ser/api/utils/baseutils.py
  12. 23
      fir_ser/api/utils/serializer.py
  13. 22
      fir_ser/api/utils/storage/storage.py
  14. 20
      fir_ser/api/utils/utils.py
  15. 12
      fir_ser/api/views/storage.py

@ -0,0 +1,77 @@
<template>
<div class="json-editor">
<textarea ref="textarea" />
</div>
</template>
<script>
import CodeMirror from 'codemirror'
import 'codemirror/addon/lint/lint.css'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/rubyblue.css'
require('script-loader!jsonlint')
import 'codemirror/mode/javascript/javascript'
import 'codemirror/addon/lint/lint'
import 'codemirror/addon/lint/json-lint'
export default {
name: 'JsonEditor',
/* eslint-disable vue/require-prop-types */
props: ['value'],
data() {
return {
jsonEditor: false
}
},
watch: {
value(value) {
const editorValue = this.jsonEditor.getValue()
if (value !== editorValue) {
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2))
}
}
},
mounted() {
this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
lineNumbers: true,
mode: 'application/json',
gutters: ['CodeMirror-lint-markers'],
theme: 'rubyblue',
lint: true
})
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2))
this.jsonEditor.on('change', cm => {
this.$emit('changed', cm.getValue())
this.$emit('input', cm.getValue())
})
},
methods: {
getValue() {
return this.jsonEditor.getValue()
}
}
}
</script>
<style lang="scss" scoped>
.json-editor {
height: 100%;
position: relative;
::v-deep {
.CodeMirror {
height: auto;
min-height: 300px;
}
.CodeMirror-scroll {
min-height: 300px;
}
.cm-s-rubyblue span.cm-string {
color: #F08047;
}
}
}
</style>

@ -100,7 +100,7 @@ const defaultForm = {
} }
export default { export default {
name: 'AppReleaseDetail', name: 'CertificationDetail',
components: { }, filters: { components: { }, filters: {
}, },
data() { data() {

@ -110,7 +110,7 @@ const sortOptions = [
] ]
export default { export default {
name: 'AppInfo', name: 'CertificationInfo',
components: { Pagination }, components: { Pagination },
directives: { waves }, directives: { waves },
filters: { filters: {

@ -10,67 +10,76 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="真实姓名"> <el-form-item label="存储名称">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="postForm.name" /> <el-input v-model="postForm.name" />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="身份证号码"> <el-form-item label="存储类型">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="postForm.card" /> <el-select v-model="postForm.storage_type" class="filter-item" placeholder="Please select">
<el-option v-for="item in postForm.storage_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="居住地址"> <el-form-item label="存储额外参数">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="21">
<el-input v-model="postForm.addr" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="实名认证"> <div class="editor-container">
<el-row :gutter="12"> <json-editor ref="jsonEditor" v-model="postForm.additionalparameters" />
<el-col :span="16"> </div>
<el-select v-model="postForm.status" class="filter-item" placeholder="Please select">
<el-option v-for="item in postForm.certification_status_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="提交时间" prop="timestamp"> </el-col>
<el-col :span="12">
<el-form-item label="创建时间" prop="timestamp" label-width="160px">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-date-picker :value="postForm.created_time" type="datetime" disabled /> <el-date-picker :value="postForm.created_time" type="datetime" disabled />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="审核时间" prop="timestamp"> <el-form-item label="更新时间" prop="timestamp" label-width="160px">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-date-picker :value="postForm.reviewed_time" type="datetime" disabled /> <el-date-picker :value="postForm.updated_time" type="datetime" disabled />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="审核备注"> <el-form-item label="存储访问access_key" label-width="160px">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="postForm.msg" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" placeholder="Please input" /> <el-input v-model="postForm.access_key" />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
</el-col> <el-form-item label="存储访问secret_key" label-width="160px">
<el-col :span="12"> <el-row :gutter="12">
<el-form-item label="实名认证照片"> <el-col :span="16">
<div v-for="info in postForm.certification_infos" :key="info.name" style="width: 320px; height: 340px;float: left;border: #409EFF 1px solid;text-align: center;margin-left: 20px;margin-bottom: 20px"> <el-input v-model="postForm.secret_key" />
<el-image :src="info.certification_url" :preview-src-list="[info.certification_url]" fit="contain" style="width: 260px; height: 260px" /> </el-col>
<el-link :underline="false"> {{ info.name }}</el-link> </el-row>
</div> </el-form-item>
<el-form-item label="存储空间bucket_name" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.bucket_name" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="存储描述信息" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.description" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" placeholder="Please input" />
</el-col>
</el-row>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
@ -85,29 +94,31 @@
</template> </template>
<script> <script>
import { getCertificationInfo, updateCertificationInfo } from '@/api/user' import { getStorageInfo, updateStorageInfo } from '@/api/storage'
import JsonEditor from '@/components/JsonEditor'
const defaultForm = { const defaultForm = {
user_id: undefined, user_id: undefined,
name: undefined, name: undefined,
card: undefined, storage_type: undefined,
addr: undefined, access_key: undefined,
mobile: undefined, secret_key: undefined,
status: undefined, bucket_name: undefined,
msg: undefined, domain_name: undefined,
created_time: undefined, created_time: undefined,
reviewed_time: undefined description: undefined,
updated_time: undefined
} }
export default { export default {
name: 'AppReleaseDetail', name: 'StorageDetail',
components: { }, filters: { components: { JsonEditor }, filters: {
}, },
data() { data() {
return { return {
postForm: Object.assign({}, defaultForm), postForm: Object.assign({}, defaultForm),
loading: false, loading: false,
is_edit: false is_edit: false,
} }
}, },
computed: { computed: {
@ -118,18 +129,20 @@ export default {
}, },
methods: { methods: {
fetchData(id) { fetchData(id) {
getCertificationInfo({ id: id }).then(response => { getStorageInfo({ id: id }).then(response => {
if (response.data.length === 1) { if (response.data.length === 1) {
this.postForm = response.data[0] this.postForm = response.data[0]
this.postForm.additionalparameters = this.postForm.additionalparameter
} }
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
}) })
}, },
updateData() { updateData() {
updateCertificationInfo(this.postForm).then(response => { updateStorageInfo(this.postForm).then(response => {
this.$message.success('更新成功') this.$message.success('更新成功')
this.postForm = response.data this.postForm = response.data
this.postForm.additionalparameters = this.postForm.additionalparameter
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
}) })
@ -138,3 +151,9 @@ export default {
} }
</script> </script>
<style scoped>
.editor-container{
position: relative;
height: 100%;
}
</style>

@ -2,11 +2,12 @@
<div class="app-container"> <div class="app-container">
<div class="filter-container"> <div class="filter-container">
<el-input v-model="listQuery.user_id" placeholder="用户ID" style="width: 140px;" class="filter-item" clearable @keyup.enter.native="handleFilter" /> <el-input v-model="listQuery.user_id" placeholder="用户ID" style="width: 140px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.card" placeholder="身份证" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" /> <el-input v-model="listQuery.bucket_name" placeholder="bucket_name" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.name" placeholder="姓名" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" /> <el-input v-model="listQuery.access_key" placeholder="access_key" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.mobile" placeholder="手机号码" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" /> <el-input v-model="listQuery.name" placeholder="存储名称" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.status" placeholder="实名认证状态" clearable class="filter-item" style="width: 140px" @change="handleFilter"> <el-input v-model="listQuery.domain_name" placeholder="下载域名" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-option v-for="item in certification_status_choices" :key="item.id" :label="item.name" :value="item.id" /> <el-select v-model="listQuery.storage_type" placeholder="存储类型" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in storage_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
<el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter"> <el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
<el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" /> <el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" />
@ -36,32 +37,32 @@
</router-link> </router-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="真实姓名"> <el-table-column label="存储名称">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.name }} {{ scope.row.name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="身份证号码" align="center"> <el-table-column label="存储访问access_key" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.card }}</span> <span>{{ scope.row.access_key }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="居住地" align="center"> <el-table-column label="存储空间bucket_name" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.addr }} {{ scope.row.bucket_name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="手机号码" align="center"> <el-table-column label="下载域名" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.mobile }} {{ scope.row.domain_name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column class-name="status-col" label="实名认证" width="95" align="center"> <el-table-column class-name="status-col" label="存储类型" width="95" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="scope.row.status | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag> <el-tag :type="scope.row.storage_type | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="created_time" label="提交时间" width="120"> <el-table-column align="center" prop="created_time" label="创建时间" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<i class="el-icon-time" /> <i class="el-icon-time" />
<el-tooltip :content="scope.row.created_time"> <el-tooltip :content="scope.row.created_time">
@ -69,17 +70,17 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="created_time" label="审核时间" width="120"> <el-table-column align="center" prop="created_time" label="更新时间" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<i class="el-icon-time" /> <i class="el-icon-time" />
<el-tooltip :content="scope.row.reviewed_time"> <el-tooltip :content="scope.row.updated_time">
<span>{{ scope.row.reviewed_time|formatTime }}</span> <span>{{ scope.row.updated_time|formatTime }}</span>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<router-link :to="{name: 'user_authentication_info_edit',params:{id:scope.row.id}}"> <router-link :to="{name: 'storage_info_edit',params:{id:scope.row.id}}">
<el-button type="primary" size="mini"> <el-button type="primary" size="mini">
查看编辑 查看编辑
</el-button> </el-button>
@ -101,14 +102,14 @@ import Pagination from '@/components/Pagination' // secondary package based on e
import waves from '@/directive/waves' // waves directive import waves from '@/directive/waves' // waves directive
const sortOptions = [ const sortOptions = [
{ label: '审核时间 Ascending', key: 'reviewed_time' }, { label: '创建时间 Ascending', key: 'reviewed_time' },
{ label: '审核时间 Descending', key: '-reviewed_time' }, { label: '创建时间 Descending', key: '-reviewed_time' },
{ label: '提交时间 Ascending', key: 'created_time' }, { label: '更新时间 Ascending', key: 'created_time' },
{ label: '提交时间 Descending', key: '-created_time' } { label: '更新时间 Descending', key: '-created_time' }
] ]
export default { export default {
name: 'AppInfo', name: 'StorageInfo',
components: { Pagination }, components: { Pagination },
directives: { waves }, directives: { waves },
filters: { filters: {
@ -117,16 +118,16 @@ export default {
}, },
certStatusFilter(status) { certStatusFilter(status) {
const statusMap = { const statusMap = {
'-1': 'info', '0': 'danger',
'1': 'success', '1': 'success',
'0': 'gray', '2': 'gray',
'2': 'danger' '3': 'info'
} }
return statusMap[status] return statusMap[status]
}, },
certLableFilter(row) { certLableFilter(row) {
for (const v of row.certification_status_choices) { for (const v of row.storage_choices) {
if (v.id === row.status) { if (v.id === row.storage_type) {
return v.name return v.name
} }
} }
@ -164,13 +165,14 @@ export default {
limit: 10, limit: 10,
name: undefined, name: undefined,
sort: '-created_time', sort: '-created_time',
card: undefined, bucket_name: undefined,
mobile: undefined, access_key: undefined,
status: undefined, storage_type: undefined,
domain_name: undefined,
user_id: undefined user_id: undefined
}, },
sortOptions, sortOptions,
certification_status_choices: [] storage_choices: []
} }
}, },
created() { created() {
@ -186,7 +188,7 @@ export default {
getStorageInfo(this.listQuery).then(response => { getStorageInfo(this.listQuery).then(response => {
this.list = response.data this.list = response.data
if (this.list && this.list.length > 0) { if (this.list && this.list.length > 0) {
this.certification_status_choices = this.list[0].certification_status_choices this.storage_choices = this.list[0].storage_choices
} }
this.total = response.total this.total = response.total
this.listLoading = false this.listLoading = false

@ -35,27 +35,28 @@
<div v-if="editstorageinfo.storage_type === 2"> <div v-if="editstorageinfo.storage_type === 2">
<el-form-item label-width="110px" label="sts_role_arn"> <el-form-item label-width="110px" label="sts_role_arn">
<el-input :disabled='disabled' <el-input :disabled='disabled'
v-model="editstorageinfo.additionalparameter.sts_role_arn"></el-input> v-model="editstorageinfo.sts_role_arn"></el-input>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="endpoint"> <el-form-item label-width="110px" label="endpoint">
<el-input :disabled='disabled' <el-input :disabled='disabled'
v-model="editstorageinfo.additionalparameter.endpoint"></el-input> v-model="editstorageinfo.endpoint"></el-input>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="下载授权方式"> <el-form-item label-width="110px" label="下载授权方式">
<el-select v-model="editstorageinfo.additionalparameter.download_auth_type" <el-select v-model="editstorageinfo.download_auth_type"
placeholder="下载授权方式" placeholder="下载授权方式"
style="width: 80%" :disabled="disabled"> style="width: 80%" :disabled="disabled">
<el-option v-for="st in download_auth_type_list" :key="st.id" :label="st.name" <el-option v-for="st in editstorageinfo.download_auth_type_choices" :key="st.id"
:label="st.name"
:value="st.id"></el-option> :value="st.id"></el-option>
</el-select> </el-select>
<el-form-item label-width="120px" style="margin-top: 10px;margin-left: 70px;width: 60%" <el-form-item label-width="120px" style="margin-top: 10px;margin-left: 70px;width: 60%"
label="CDN鉴权主KEY" label="CDN鉴权主KEY"
v-if="editstorageinfo.additionalparameter.download_auth_type === 2"> v-if="editstorageinfo.download_auth_type === 2">
<el-input :disabled='disabled' placeholder="CDN鉴权主KEY" <el-input :disabled='disabled' placeholder="CDN鉴权主KEY"
v-model="editstorageinfo.additionalparameter.cnd_auth_key"/> v-model="editstorageinfo.cnd_auth_key"/>
</el-form-item> </el-form-item>
</el-form-item> </el-form-item>
@ -137,26 +138,27 @@
<div v-if="storageinfo.storage_type === 2"> <div v-if="storageinfo.storage_type === 2">
<el-form-item label-width="110px" label="sts_role_arn"> <el-form-item label-width="110px" label="sts_role_arn">
<el-input :disabled='Sdisabled' <el-input :disabled='Sdisabled'
v-model="storageinfo.additionalparameter.sts_role_arn"></el-input> v-model="storageinfo.sts_role_arn"></el-input>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="endpoint"> <el-form-item label-width="110px" label="endpoint">
<el-input :disabled='Sdisabled' <el-input :disabled='Sdisabled'
v-model="storageinfo.additionalparameter.endpoint"></el-input> v-model="storageinfo.endpoint"></el-input>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="下载授权方式"> <el-form-item label-width="110px" label="下载授权方式">
<el-select v-model="storageinfo.additionalparameter.download_auth_type" <el-select v-model="storageinfo.download_auth_type"
placeholder="下载授权方式" placeholder="下载授权方式"
style="width: 100%" :disabled="disabled"> style="width: 100%" :disabled="disabled">
<el-option v-for="st in download_auth_type_list" :key="st.id" :label="st.name" <el-option v-for="st in storageinfo.download_auth_type_choices" :key="st.id"
:label="st.name"
:value="st.id"></el-option> :value="st.id"></el-option>
</el-select> </el-select>
<el-form-item label-width="120px" style="margin-top: 10px;width: 100%" label="CDN鉴权主KEY" <el-form-item label-width="120px" style="margin-top: 10px;width: 100%" label="CDN鉴权主KEY"
v-if="storageinfo.additionalparameter.download_auth_type === 2"> v-if="storageinfo.download_auth_type === 2">
<el-input :disabled='disabled' placeholder="CDN鉴权主KEY" <el-input :disabled='disabled' placeholder="CDN鉴权主KEY"
v-model="storageinfo.additionalparameter.cnd_auth_key"/> v-model="storageinfo.cnd_auth_key"/>
</el-form-item> </el-form-item>
</el-form-item> </el-form-item>
@ -265,27 +267,28 @@
<div v-if="editstorageinfo.storage_type === 2"> <div v-if="editstorageinfo.storage_type === 2">
<el-form-item label-width="110px" label="sts_role_arn"> <el-form-item label-width="110px" label="sts_role_arn">
<el-input <el-input
v-model="editstorageinfo.additionalparameter.sts_role_arn"></el-input> v-model="editstorageinfo.sts_role_arn"></el-input>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="endpoint"> <el-form-item label-width="110px" label="endpoint">
<el-input <el-input
v-model="editstorageinfo.additionalparameter.endpoint"></el-input> v-model="editstorageinfo.endpoint"></el-input>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="下载授权方式"> <el-form-item label-width="110px" label="下载授权方式">
<el-select v-model="editstorageinfo.additionalparameter.download_auth_type" <el-select v-model="editstorageinfo.download_auth_type"
placeholder="下载授权方式" placeholder="下载授权方式"
style="width: 80%"> style="width: 80%">
<el-option v-for="st in download_auth_type_list" :key="st.id" :label="st.name" <el-option v-for="st in editstorageinfo.download_auth_type_choices" :key="st.id"
:label="st.name"
:value="st.id"></el-option> :value="st.id"></el-option>
</el-select> </el-select>
<el-form-item label-width="120px" style="margin-top: 10px;margin-left: 70px;width: 60%" <el-form-item label-width="120px" style="margin-top: 10px;margin-left: 70px;width: 60%"
label="CDN鉴权主KEY" label="CDN鉴权主KEY"
v-if="editstorageinfo.additionalparameter.download_auth_type === 2"> v-if="editstorageinfo.download_auth_type === 2">
<el-input placeholder="CDN鉴权主KEY" <el-input placeholder="CDN鉴权主KEY"
v-model="editstorageinfo.additionalparameter.cnd_auth_key"/> v-model="editstorageinfo.cnd_auth_key"/>
</el-form-item> </el-form-item>
</el-form-item> </el-form-item>
@ -308,7 +311,7 @@
<script> <script>
import {getStorageinfo} from "@/restful"; import {getStorageinfo} from "@/restful";
import {deepCopy} from "@/utils"; import {deepCopy, getUserInfoFun} from "@/utils";
export default { export default {
name: "FirUserStorage", name: "FirUserStorage",
@ -320,19 +323,15 @@
org_storage_id: 0, org_storage_id: 0,
title: '', title: '',
dialogstorageVisible: false, dialogstorageVisible: false,
editstorageinfo: {'additionalparameter': {}}, editstorageinfo: {},
selectlabel: "", selectlabel: "",
storageinfo: {'additionalparameter': {}}, storageinfo: {},
storage_list: [], storage_list: [],
disabled: true, disabled: true,
isaddflag: false, isaddflag: false,
activeName: 'change', activeName: 'change',
storage_info_lists: [], storage_info_lists: [],
is_admin_storage: false, is_admin_storage: false,
download_auth_type_list: [{id: 1, name: 'OSS模式: 需要把OSS权限开启私有模式'}, {
id: 2,
name: 'CDN模式: 请先配置好阿里云CDN,开启阿里云OSS私有Bucket回源,将使用鉴权A方式'
},],
loading: false, loading: false,
} }
}, methods: { }, methods: {
@ -348,12 +347,6 @@
this.dialogstorageVisible = true; this.dialogstorageVisible = true;
this.editstorageinfo = deepCopy(editstorageinfo); this.editstorageinfo = deepCopy(editstorageinfo);
this.isaddflag = false; this.isaddflag = false;
}, add_storage_click() {
this.title = '新增存储';
this.disabled = false;
this.dialogstorageVisible = true;
this.editstorageinfo = {'additionalparameter': {download_auth_type: 1}};
this.isaddflag = true;
}, },
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
handleClick(tab, event) { handleClick(tab, event) {
@ -520,8 +513,9 @@
if (data.code === 1000) { if (data.code === 1000) {
this.storage_list = data.storage_list; this.storage_list = data.storage_list;
this.editstorageinfo = { this.editstorageinfo = {
'additionalparameter': {download_auth_type: 1}, download_auth_type: 1,
storage_type: this.storage_list[0].id storage_type: this.storage_list[0].id,
download_auth_type_choices: data.download_auth_type_choices
}; };
this.isaddflag = true; this.isaddflag = true;
} else { } else {
@ -531,6 +525,7 @@
} }
}, },
}, mounted() { }, mounted() {
getUserInfoFun(this);
if (this.$route.params.act) { if (this.$route.params.act) {
let activeName = this.$route.params.act; let activeName = this.$route.params.act;
let activeName_list = ["change", "edit", "add"]; let activeName_list = ["change", "edit", "add"];

@ -20,6 +20,7 @@ from api.utils.storage.caches import login_auth_failed, del_cache_response_by_sh
import logging import logging
from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
from api.utils.baseutils import get_dict_from_filter_fields
from api.base_views import app_delete from api.base_views import app_delete
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -37,12 +38,8 @@ class AppInfoView(APIView):
def get(self, request): def get(self, request):
res = BaseResponse() res = BaseResponse()
filter_data = {}
filter_fields = ["id", "type", "name", "short", "bundle_id", "domain_name", "user_id", "status"] filter_fields = ["id", "type", "name", "short", "bundle_id", "domain_name", "user_id", "status"]
for filed in filter_fields: filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
sort = request.query_params.get("sort", "-updated_time") sort = request.query_params.get("sort", "-updated_time")
page_obj = AppsPageNumber() page_obj = AppsPageNumber()
obj_list = Apps.objects.filter(**filter_data).order_by(sort) obj_list = Apps.objects.filter(**filter_data).order_by(sort)
@ -91,12 +88,8 @@ class AppReleaseInfoView(APIView):
def get(self, request): def get(self, request):
res = BaseResponse() res = BaseResponse()
filter_data = {}
filter_fields = ["id", "release_id", "app_id"] filter_fields = ["id", "release_id", "app_id"]
for filed in filter_fields: filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
sort = request.query_params.get("sort", "-created_time") sort = request.query_params.get("sort", "-created_time")
if not filter_data.get('app_id', None): if not filter_data.get('app_id', None):
res.code = 1003 res.code = 1003

@ -8,6 +8,7 @@ from django.contrib import auth
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
from api.utils.baseutils import get_dict_from_filter_fields
from api.utils.serializer import AdminStorageSerializer, AdminUserCertificationSerializer from api.utils.serializer import AdminStorageSerializer, AdminUserCertificationSerializer
from django.core.cache import cache from django.core.cache import cache
from rest_framework.views import APIView from rest_framework.views import APIView
@ -36,12 +37,8 @@ class StorageInfoView(APIView):
def get(self, request): def get(self, request):
res = BaseResponse() res = BaseResponse()
filter_data = {} filter_fields = ["id", "user_id", "name", "storage_type", "access_key", "bucket_name"]
filter_fileds = ["id", "user_id", "name", "storage_type", "access_key", "bucket_name"] filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
for filed in filter_fileds:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
sort = request.query_params.get("sort", "-created_time") sort = request.query_params.get("sort", "-created_time")
page_obj = AppsPageNumber() page_obj = AppsPageNumber()
obj_list = AppStorage.objects.filter(**filter_data).order_by(sort) obj_list = AppStorage.objects.filter(**filter_data).order_by(sort)
@ -60,14 +57,15 @@ class StorageInfoView(APIView):
res.code = 1003 res.code = 1003
res.msg = "参数错误" res.msg = "参数错误"
return Response(res.dict) return Response(res.dict)
user_obj = UserInfo.objects.filter(pk=pk).first() obj = AppStorage.objects.filter(pk=pk).first()
if user_obj: if obj:
data['pk'] = pk data['pk'] = pk
users_serializer = AdminStorageSerializer(user_obj, data=data, partial=True) serializer = AdminStorageSerializer(obj, data=data, partial=True)
if users_serializer.is_valid(): if serializer.is_valid():
users_serializer.save() serializer.save()
res.data = users_serializer.data res.data = serializer.data
return Response(res.dict) return Response(res.dict)
print(serializer.errors)
res.code = 1004 res.code = 1004
res.msg = "数据校验失败" res.msg = "数据校验失败"
return Response(res.dict) return Response(res.dict)

@ -8,6 +8,7 @@ from django.contrib import auth
from api.models import Token, UserInfo, UserCertificationInfo from api.models import Token, UserInfo, UserCertificationInfo
from rest_framework.response import Response from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication from api.utils.auth import AdminTokenAuthentication
from api.utils.baseutils import get_dict_from_filter_fields
from api.utils.serializer import AdminUserInfoSerializer, AdminUserCertificationSerializer from api.utils.serializer import AdminUserInfoSerializer, AdminUserCertificationSerializer
from django.core.cache import cache from django.core.cache import cache
from rest_framework.views import APIView from rest_framework.views import APIView
@ -36,12 +37,8 @@ class UserInfoView(APIView):
def get(self, request): def get(self, request):
res = BaseResponse() res = BaseResponse()
filter_data = {} filter_fields = ["id", "mobile", "username", "email", "first_name"]
filter_fileds = ["id", "mobile", "username", "email", "first_name"] filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
for filed in filter_fileds:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
sort = request.query_params.get("sort", "-date_joined") sort = request.query_params.get("sort", "-date_joined")
certification = request.query_params.get("certification", None) certification = request.query_params.get("certification", None)
if certification: if certification:
@ -87,12 +84,8 @@ class UserCertificationInfoView(APIView):
def get(self, request): def get(self, request):
res = BaseResponse() res = BaseResponse()
filter_data = {} filter_fields = ["id", "card", "name", "status"]
filter_fileds = ["id", "card", "name", "status"] filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
for filed in filter_fileds:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
sort = request.query_params.get("sort", "-created_time") sort = request.query_params.get("sort", "-created_time")
page_obj = AppsPageNumber() page_obj = AppsPageNumber()
obj_list = UserCertificationInfo.objects.filter(**filter_data).order_by(sort) obj_list = UserCertificationInfo.objects.filter(**filter_data).order_by(sort)

@ -185,8 +185,14 @@ class AppStorage(models.Model):
domain_name = models.CharField(max_length=128, blank=True, null=True, verbose_name="下载域名", domain_name = models.CharField(max_length=128, blank=True, null=True, verbose_name="下载域名",
help_text='fly-storage.dvcloud.xin,可以自定义端口') help_text='fly-storage.dvcloud.xin,可以自定义端口')
is_https = models.BooleanField(default=True, verbose_name="是否支持https") is_https = models.BooleanField(default=True, verbose_name="是否支持https")
additionalparameters = models.TextField(blank=True, null=True, verbose_name="额外参数",
help_text='阿里云:{"sts_role_arn":"arn信息","endpoint":""} ', default=None) sts_role_arn = models.CharField(max_length=128, blank=True, null=True, verbose_name="阿里云sts_role_arn")
endpoint = models.CharField(max_length=128, blank=True, null=True, verbose_name="阿里云endpoint")
download_auth_type_choices = ((1, 'OSS模式: 需要把OSS权限开启私有模式'), (2, 'CDN模式: 请先配置好阿里云CDN,开启阿里云OSS私有Bucket回源,将使用鉴权A方式'))
download_auth_type = models.SmallIntegerField(choices=download_auth_type_choices, default=1,
verbose_name="阿里云下载授权方式")
cnd_auth_key = models.CharField(max_length=128, blank=True, null=True, verbose_name="阿里云cnd_auth_key")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间") updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
description = models.TextField('备注', blank=True, null=True, default='') description = models.TextField('备注', blank=True, null=True, default='')
@ -198,6 +204,11 @@ class AppStorage(models.Model):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if self.storage_type in (1, 2): if self.storage_type in (1, 2):
if self.bucket_name and self.secret_key and self.access_key: if self.bucket_name and self.secret_key and self.access_key:
if self.storage_type == 2:
if not self.sts_role_arn or not self.endpoint:
return
if self.download_auth_type == 2 and not self.cnd_auth_key:
return
return super(AppStorage, self).save(*args, **kwargs) return super(AppStorage, self).save(*args, **kwargs)
else: else:
return return

@ -79,3 +79,12 @@ def is_valid_email(email):
return True return True
except ValidationError: except ValidationError:
return False return False
def get_dict_from_filter_fields(filter_fields, data):
filter_data = {}
for filed in filter_fields:
f_value = data.get(filed, None)
if f_value:
filter_data[filed] = f_value
return filter_data

@ -341,16 +341,11 @@ class StorageSerializer(serializers.ModelSerializer):
exclude = ["user_id"] exclude = ["user_id"]
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)
additionalparameters = serializers.CharField(write_only=True)
additionalparameter = serializers.SerializerMethodField(read_only=True)
def get_additionalparameter(self, obj): download_auth_type_choices = serializers.SerializerMethodField()
infos = {}
try: def get_download_auth_type_choices(self, obj):
infos = json.loads(obj.additionalparameters) return get_choices_dict(obj.download_auth_type_choices)
except Exception as e:
logger.error("%s additionalparameter loads failed Exception:%s" % (obj.additionalparameters, e))
return infos
def create(self, validated_data): def create(self, validated_data):
if self.context.get("user_obj", None) and self.context.get("user_obj") != "undefined": if self.context.get("user_obj", None) and self.context.get("user_obj") != "undefined":
@ -367,6 +362,16 @@ class AdminStorageSerializer(StorageSerializer):
fields = "__all__" fields = "__all__"
read_only_fields = ["id", "user_id", "updated_time", "created_time"] read_only_fields = ["id", "user_id", "updated_time", "created_time"]
additionalparameters = serializers.CharField()
storage_choices = serializers.SerializerMethodField()
def validate_additionalparameters(self, additionalparameters):
print(additionalparameters)
return json.dumps(additionalparameters)
def get_storage_choices(self, obj):
return get_choices_dict(obj.storage_choices)
class DeveloperSerializer(serializers.ModelSerializer): class DeveloperSerializer(serializers.ModelSerializer):
class Meta: class Meta:

@ -9,6 +9,7 @@ from .aliyunApi import AliYunOss, AliYunCdn
from .qiniuApi import QiNiuOss from .qiniuApi import QiNiuOss
from .localApi import LocalStorage from .localApi import LocalStorage
import json, time, base64 import json, time, base64
from api.utils.baseutils import get_dict_from_filter_fields
from fir_ser.settings import THIRD_PART_CONFIG, CACHE_KEY_TEMPLATE from fir_ser.settings import THIRD_PART_CONFIG, CACHE_KEY_TEMPLATE
from django.core.cache import cache from django.core.cache import cache
import logging import logging
@ -80,7 +81,7 @@ class Storage(object):
self.storage_obj = None self.storage_obj = None
if self.storage_obj: if self.storage_obj:
auth = self.get_storage_auth(self.storage_obj) auth = self.get_storage_auth()
storage_key = "_".join([CACHE_KEY_TEMPLATE.get('user_storage_key'), user.uid, storage_key = "_".join([CACHE_KEY_TEMPLATE.get('user_storage_key'), user.uid,
base64.b64encode(json.dumps(auth).encode("utf-8")).decode("utf-8")[0:64]]) base64.b64encode(json.dumps(auth).encode("utf-8")).decode("utf-8")[0:64]])
storage_type = self.storage_obj.storage_type storage_type = self.storage_obj.storage_type
@ -141,21 +142,10 @@ class Storage(object):
if self.storage: if self.storage:
return self.storage.storage_type return self.storage.storage_type
def get_storage_auth(self, storage_obj): def get_storage_auth(self):
auth_dict = { filter_fields = ['access_key', 'secret_key', 'bucket_name', 'domain_name', 'is_https', 'endpoint',
'access_key': storage_obj.access_key, 'sts_role_arn', 'cnd_auth_key', 'download_auth_type']
'secret_key': storage_obj.secret_key, return get_dict_from_filter_fields(filter_fields, self.storage_obj.__dict__)
'bucket_name': storage_obj.bucket_name,
'domain_name': storage_obj.domain_name,
'is_https': storage_obj.is_https
}
try:
additionalparameters = json.loads(storage_obj.additionalparameters)
except Exception as e:
logger.error("%s get_storage_auth additionalparameters %s loads failed Exception:%s" % (
storage_obj.user_id, storage_obj.additionalparameters, e))
additionalparameters = {}
return {**auth_dict, **additionalparameters}
def get_local_storage(clean_cache=False): def get_local_storage(clean_cache=False):

@ -172,26 +172,6 @@ def delete_app_screenshots_files(storage_obj, app_obj):
screenshot_obj.delete() screenshot_obj.delete()
def check_storage_additionalparameter(request, res):
data = request.data
try:
extra_parameters = data.get('additionalparameter', '')
if extra_parameters:
if not extra_parameters.get("download_auth_type", None):
extra_parameters['download_auth_type'] = 1
if extra_parameters.get("download_auth_type", None) == 2:
if not extra_parameters.get("cnd_auth_key", None):
logger.error("user %s add new storage failed" % (request.user))
res.msg = "cdn 鉴权KEY 缺失"
res.code = 1006
return False, res
data['additionalparameters'] = json.dumps(extra_parameters)
except Exception as e:
logger.error("user:%s additionalparameters %s dumps failed Exception:%s" % (
request.user, data.get('additionalparameter', ''), e))
return True, data
def change_storage_and_change_head_img(user_obj, new_storage_obj): def change_storage_and_change_head_img(user_obj, new_storage_obj):
migrating_storage_file_data(user_obj, user_obj.head_img, new_storage_obj) migrating_storage_file_data(user_obj, user_obj.head_img, new_storage_obj)

@ -10,8 +10,8 @@ from api.utils.auth import ExpiringTokenAuthentication, StoragePermission
from rest_framework.response import Response from rest_framework.response import Response
from api.utils.storage.caches import del_cache_storage from api.utils.storage.caches import del_cache_storage
from api.models import AppStorage, UserInfo from api.models import AppStorage, UserInfo
from api.utils.utils import upload_oss_default_head_img, check_storage_additionalparameter, \ from api.utils.utils import upload_oss_default_head_img, \
change_storage_and_change_head_img, migrating_storage_data, clean_storage_data change_storage_and_change_head_img, migrating_storage_data, clean_storage_data, get_choices_dict
from api.utils.serializer import StorageSerializer from api.utils.serializer import StorageSerializer
import logging import logging
@ -32,6 +32,7 @@ class StorageView(APIView):
act = request.query_params.get("act", None) act = request.query_params.get("act", None)
if act == 'storage_type': if act == 'storage_type':
res.download_auth_type_choices = get_choices_dict(AppStorage.download_auth_type_choices)
return Response(res.dict) return Response(res.dict)
# [1,2] 表示七牛存储和阿里云存储 # [1,2] 表示七牛存储和阿里云存储
@ -63,9 +64,6 @@ class StorageView(APIView):
res = BaseResponse() res = BaseResponse()
data = request.data data = request.data
logger.info("user %s add new storage data:%s" % (request.user, data)) logger.info("user %s add new storage data:%s" % (request.user, data))
status, data = check_storage_additionalparameter(request, res)
if not status:
return Response(data.dict)
serializer = StorageSerializer(data=data, context={'user_obj': request.user}) serializer = StorageSerializer(data=data, context={'user_obj': request.user})
if serializer.is_valid(): if serializer.is_valid():
storage_obj = serializer.save() storage_obj = serializer.save()
@ -92,7 +90,6 @@ class StorageView(APIView):
res = BaseResponse() res = BaseResponse()
data = request.data data = request.data
logger.info("user %s update storage data:%s" % (request.user, data)) logger.info("user %s update storage data:%s" % (request.user, data))
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:
@ -135,9 +132,6 @@ class StorageView(APIView):
res.msg = '存储正在使用中,无法修改' res.msg = '存储正在使用中,无法修改'
res.code = 1007 res.code = 1007
return Response(res.dict) return Response(res.dict)
status, data = check_storage_additionalparameter(request, res)
if not status:
return Response(data.dict)
storage_obj = AppStorage.objects.filter(id=storage_id, user_id=request.user).first() storage_obj = AppStorage.objects.filter(id=storage_id, user_id=request.user).first()
storage_obj_bak = AppStorage.objects.filter(id=storage_id, user_id=request.user).first() storage_obj_bak = AppStorage.objects.filter(id=storage_id, user_id=request.user).first()
serializer = StorageSerializer(instance=storage_obj, data=data, context={'user_obj': request.user}, serializer = StorageSerializer(instance=storage_obj, data=data, context={'user_obj': request.user},

Loading…
Cancel
Save