管理后台 实名认证页面添加

pull/10/head
youngS 4 years ago
parent 7a0c8bfce3
commit d133d0ec7b
  1. 18
      fir_admin/src/api/storage.js
  2. 15
      fir_admin/src/api/user.js
  3. 28
      fir_admin/src/router/index.js
  4. 6
      fir_admin/src/views/appinfos/AppReleaseList.vue
  5. 41
      fir_admin/src/views/appinfos/Dropdown/Comment.vue
  6. 46
      fir_admin/src/views/appinfos/Dropdown/Platform.vue
  7. 38
      fir_admin/src/views/appinfos/Dropdown/SourceUrl.vue
  8. 3
      fir_admin/src/views/appinfos/Dropdown/index.js
  9. 5
      fir_admin/src/views/appinfos/list.vue
  10. 140
      fir_admin/src/views/authentication/Detail.vue
  11. 199
      fir_admin/src/views/authentication/list.vue
  12. 140
      fir_admin/src/views/storage/Detail.vue
  13. 197
      fir_admin/src/views/storage/list.vue
  14. 5
      fir_admin/src/views/userinfos/UserDetail.vue
  15. 5
      fir_ser/admin/urls.py
  16. 73
      fir_ser/admin/views/storage.py
  17. 45
      fir_ser/admin/views/user.py
  18. 4
      fir_ser/api/models.py
  19. 45
      fir_ser/api/utils/serializer.py
  20. 8
      fir_ser/api/utils/utils.py

@ -0,0 +1,18 @@
import request from '@/utils/request'
export function getStorageInfo(query) {
return request({
url: '/storage/info',
method: 'get',
params: query
})
}
export function updateStorageInfo(data) {
return request({
url: '/storage/info',
method: 'put',
data
})
}

@ -38,3 +38,18 @@ export function updateUserInfo(data) {
data
})
}
export function getCertificationInfo(query) {
return request({
url: '/certification/info',
method: 'get',
params: query
})
}
export function updateCertificationInfo(data) {
return request({
url: '/certification/info',
method: 'put',
data
})
}

@ -124,10 +124,17 @@ export const constantRoutes = [
component: Layout,
children: [
{
path: 'index',
name: 'index',
component: () => import('@/views/form/index'),
path: 'list',
name: 'storage_info_list',
component: () => import('@/views/storage/list'),
meta: { title: '存储管理', icon: 'form' }
},
{
path: 'edit/:id(\\d+)',
component: () => import('@/views/storage/Detail'),
name: 'storage_info_edit',
meta: { title: '编辑信息', noCache: true, activeMenu: '/storage/list' },
hidden: true
}
]
},
@ -143,14 +150,21 @@ export const constantRoutes = [
}
]
}, {
path: '/certification',
path: '/authentication',
component: Layout,
children: [
{
path: 'index',
name: 'index',
component: () => import('@/views/form/index'),
path: 'list',
name: 'user_authentication_info_list',
component: () => import('@/views/authentication/list'),
meta: { title: '用户实名认证', icon: 'form' }
},
{
path: 'edit/:id(\\d+)',
component: () => import('@/views/authentication/Detail'),
name: 'user_authentication_info_edit',
meta: { title: '编辑信息', noCache: true, activeMenu: '/authentication/list' },
hidden: true
}
]
}, {

@ -89,7 +89,7 @@ import waves from '@/directive/waves' // waves directive
const sortOptions = [
{ label: '上传时间 Ascending', key: 'created_time' },
{ label: '上传时间 Descending', key: '-created_time' },
{ label: '上传时间 Descending', key: '-created_time' }
]
export default {
@ -119,7 +119,7 @@ export default {
'0': 'info',
'1': 'success',
'2': 'gray',
'3': 'danger',
'3': 'danger'
}
return statusMap[status]
}
@ -134,7 +134,7 @@ export default {
limit: 10,
app_id: undefined,
release_id: undefined,
sort: '-created_time',
sort: '-created_time'
},
sortOptions,
type_choices: [],

@ -1,41 +0,0 @@
<template>
<el-dropdown :show-timeout="100" trigger="click">
<el-button plain>
{{ !comment_disabled?'Comment: opened':'Comment: closed' }}
<i class="el-icon-caret-bottom el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown" class="no-padding">
<el-dropdown-item>
<el-radio-group v-model="comment_disabled" style="padding: 10px;">
<el-radio :label="true">
Close comment
</el-radio>
<el-radio :label="false">
Open comment
</el-radio>
</el-radio-group>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default: false
}
},
computed: {
comment_disabled: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>

@ -1,46 +0,0 @@
<template>
<el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click">
<el-button plain>
Platfroms({{ platforms.length }})
<i class="el-icon-caret-bottom el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown" class="no-border">
<el-checkbox-group v-model="platforms" style="padding: 5px 15px;">
<el-checkbox v-for="item in platformsOptions" :key="item.key" :label="item.key">
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
props: {
value: {
required: true,
default: () => [],
type: Array
}
},
data() {
return {
platformsOptions: [
{ key: 'a-platform', name: 'a-platform' },
{ key: 'b-platform', name: 'b-platform' },
{ key: 'c-platform', name: 'c-platform' }
]
}
},
computed: {
platforms: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>

@ -1,38 +0,0 @@
v<template>
<el-dropdown :show-timeout="100" trigger="click">
<el-button plain>
Link
<i class="el-icon-caret-bottom el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px">
<el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri">
<el-input v-model="source_uri" placeholder="Please enter the content">
<template slot="prepend">
URL
</template>
</el-input>
</el-form-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
}
},
computed: {
source_uri: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>

@ -1,3 +0,0 @@
export { default as CommentDropdown } from './Comment'
export { default as PlatformDropdown } from './Platform'
export { default as SourceUrlDropdown } from './SourceUrl'

@ -196,7 +196,6 @@ export default {
},
methods: {
deleteApp(app_id) {
this.$confirm('此操作将永久删除该应用, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@ -212,8 +211,8 @@ export default {
this.$message({
type: 'info',
message: '已取消删除'
});
});
})
})
},
handleFilter() {
this.listQuery.page = 1

@ -0,0 +1,140 @@
<template>
<div class="app-container">
<el-form ref="postForm" :model="postForm" label-width="100px" :disabled="!is_edit">
<el-row>
<el-col :span="12">
<el-form-item label="用户ID">
<el-row :gutter="12">
<el-col :span="16">
<el-input :value="postForm.user_id" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="真实姓名">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.name" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="身份证号码">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.card" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="居住地址">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.addr" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="实名认证">
<el-row :gutter="12">
<el-col :span="16">
<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-row>
</el-form-item>
<el-form-item label="提交时间" prop="timestamp">
<el-row :gutter="20">
<el-col :span="8">
<el-date-picker :value="postForm.created_time" type="datetime" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="审核时间" prop="timestamp">
<el-row :gutter="20">
<el-col :span="8">
<el-date-picker :value="postForm.reviewed_time" type="datetime" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="审核备注">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.msg" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" placeholder="Please input" />
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实名认证照片">
<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-image :src="info.certification_url" :preview-src-list="[info.certification_url]" fit="contain" style="width: 260px; height: 260px" />
<el-link :underline="false"> {{ info.name }}</el-link>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-col :span="9" style="float: right">
<el-button v-if="!is_edit" type="primary" @click="is_edit=true">修改</el-button>
<div v-else>
<el-button type="primary" @click="is_edit=false">取消</el-button>
<el-button type="primary" @click="updateData">保存修改</el-button>
</div>
</el-col>
</div>
</template>
<script>
import { getCertificationInfo, updateCertificationInfo } from '@/api/user'
const defaultForm = {
user_id: undefined,
name: undefined,
card: undefined,
addr: undefined,
mobile: undefined,
status: undefined,
msg: undefined,
created_time: undefined,
reviewed_time: undefined
}
export default {
name: 'AppReleaseDetail',
components: { }, filters: {
},
data() {
return {
postForm: Object.assign({}, defaultForm),
loading: false,
is_edit: false
}
},
computed: {
},
created() {
const id = this.$route.params && this.$route.params.id
this.fetchData(id)
},
methods: {
fetchData(id) {
getCertificationInfo({ id: id }).then(response => {
if (response.data.length === 1) {
this.postForm = response.data[0]
}
}).catch(err => {
console.log(err)
})
},
updateData() {
updateCertificationInfo(this.postForm).then(response => {
this.$message.success('更新成功')
this.postForm = response.data
}).catch(err => {
console.log(err)
})
}
}
}
</script>

@ -0,0 +1,199 @@
<template>
<div class="app-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.card" placeholder="身份证" 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.mobile" 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-option v-for="item in certification_status_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<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-select>
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
Search
</el-button>
</div>
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
stripe
>
<el-table-column align="center" label="ID" width="90">
<template slot-scope="scope">
{{ scope.row.id }}
</template>
</el-table-column>
<el-table-column label="用户ID" width="100" align="center">
<template slot-scope="scope">
<router-link :to="{name: 'user_info_edit',params:{id:scope.row.user_id}}">
<el-link type="primary"> {{ scope.row.user_id }}</el-link>
</router-link>
</template>
</el-table-column>
<el-table-column label="真实姓名">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column label="身份证号码" align="center">
<template slot-scope="scope">
<span>{{ scope.row.card }}</span>
</template>
</el-table-column>
<el-table-column label="居住地" align="center">
<template slot-scope="scope">
{{ scope.row.addr }}
</template>
</el-table-column>
<el-table-column label="手机号码" align="center">
<template slot-scope="scope">
{{ scope.row.mobile }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="实名认证" width="95" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_time" label="提交时间" width="120">
<template slot-scope="scope">
<i class="el-icon-time" />
<el-tooltip :content="scope.row.created_time">
<span>{{ scope.row.created_time|formatTime }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column align="center" prop="created_time" label="审核时间" width="120">
<template slot-scope="scope">
<i class="el-icon-time" />
<el-tooltip :content="scope.row.reviewed_time">
<span>{{ scope.row.reviewed_time|formatTime }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template slot-scope="scope">
<router-link :to="{name: 'user_authentication_info_edit',params:{id:scope.row.id}}">
<el-button type="primary" size="mini">
查看编辑
</el-button>
</router-link>
<el-button type="danger" size="mini" @click="deleteApp(scope.row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="fetchData" />
</div>
</template>
<script>
import { getCertificationInfo } from '@/api/user'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import waves from '@/directive/waves' // waves directive
const sortOptions = [
{ label: '审核时间 Ascending', key: 'reviewed_time' },
{ label: '审核时间 Descending', key: '-reviewed_time' },
{ label: '提交时间 Ascending', key: 'created_time' },
{ label: '提交时间 Descending', key: '-created_time' }
]
export default {
name: 'AppInfo',
components: { Pagination },
directives: { waves },
filters: {
formatTime(time) {
return time.split('T')[0]
},
certStatusFilter(status) {
const statusMap = {
'-1': 'info',
'1': 'success',
'0': 'gray',
'2': 'danger'
}
return statusMap[status]
},
certLableFilter(row) {
for (const v of row.certification_status_choices) {
if (v.id === row.status) {
return v.name
}
}
},
statusFilter(status) {
const statusMap = {
true: 'success',
false: 'danger'
}
return statusMap[status]
},
appStatusNameFilter(row) {
for (const r of row.status_choices) {
if (r.id === row.status) {
return r.name
}
}
},
appStatusFilter(status) {
const statusMap = {
'0': 'danger',
'1': 'success',
'2': 'gray'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true,
total: 0,
listQuery: {
page: 1,
limit: 10,
name: undefined,
sort: '-created_time',
card: undefined,
mobile: undefined,
status: undefined,
user_id: undefined
},
sortOptions,
certification_status_choices: []
}
},
created() {
this.fetchData()
},
methods: {
handleFilter() {
this.listQuery.page = 1
this.fetchData()
},
fetchData() {
this.listLoading = true
getCertificationInfo(this.listQuery).then(response => {
this.list = response.data
if (this.list && this.list.length > 0) {
this.certification_status_choices = this.list[0].certification_status_choices
}
this.total = response.total
this.listLoading = false
})
}
}
}
</script>

@ -0,0 +1,140 @@
<template>
<div class="app-container">
<el-form ref="postForm" :model="postForm" label-width="100px" :disabled="!is_edit">
<el-row>
<el-col :span="12">
<el-form-item label="用户ID">
<el-row :gutter="12">
<el-col :span="16">
<el-input :value="postForm.user_id" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="真实姓名">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.name" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="身份证号码">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.card" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="居住地址">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.addr" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="实名认证">
<el-row :gutter="12">
<el-col :span="16">
<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-row>
</el-form-item>
<el-form-item label="提交时间" prop="timestamp">
<el-row :gutter="20">
<el-col :span="8">
<el-date-picker :value="postForm.created_time" type="datetime" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="审核时间" prop="timestamp">
<el-row :gutter="20">
<el-col :span="8">
<el-date-picker :value="postForm.reviewed_time" type="datetime" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="审核备注">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.msg" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" placeholder="Please input" />
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实名认证照片">
<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-image :src="info.certification_url" :preview-src-list="[info.certification_url]" fit="contain" style="width: 260px; height: 260px" />
<el-link :underline="false"> {{ info.name }}</el-link>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-col :span="9" style="float: right">
<el-button v-if="!is_edit" type="primary" @click="is_edit=true">修改</el-button>
<div v-else>
<el-button type="primary" @click="is_edit=false">取消</el-button>
<el-button type="primary" @click="updateData">保存修改</el-button>
</div>
</el-col>
</div>
</template>
<script>
import { getCertificationInfo, updateCertificationInfo } from '@/api/user'
const defaultForm = {
user_id: undefined,
name: undefined,
card: undefined,
addr: undefined,
mobile: undefined,
status: undefined,
msg: undefined,
created_time: undefined,
reviewed_time: undefined
}
export default {
name: 'AppReleaseDetail',
components: { }, filters: {
},
data() {
return {
postForm: Object.assign({}, defaultForm),
loading: false,
is_edit: false
}
},
computed: {
},
created() {
const id = this.$route.params && this.$route.params.id
this.fetchData(id)
},
methods: {
fetchData(id) {
getCertificationInfo({ id: id }).then(response => {
if (response.data.length === 1) {
this.postForm = response.data[0]
}
}).catch(err => {
console.log(err)
})
},
updateData() {
updateCertificationInfo(this.postForm).then(response => {
this.$message.success('更新成功')
this.postForm = response.data
}).catch(err => {
console.log(err)
})
}
}
}
</script>

@ -0,0 +1,197 @@
<template>
<div class="app-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.card" placeholder="身份证" 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.mobile" 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-option v-for="item in certification_status_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<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-select>
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
Search
</el-button>
</div>
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
stripe
>
<el-table-column align="center" label="ID" width="90">
<template slot-scope="scope">
{{ scope.row.id }}
</template>
</el-table-column>
<el-table-column label="用户ID" width="100" align="center">
<template slot-scope="scope">
<router-link :to="{name: 'user_info_edit',params:{id:scope.row.user_id}}">
<el-link type="primary"> {{ scope.row.user_id }}</el-link>
</router-link>
</template>
</el-table-column>
<el-table-column label="真实姓名">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column label="身份证号码" align="center">
<template slot-scope="scope">
<span>{{ scope.row.card }}</span>
</template>
</el-table-column>
<el-table-column label="居住地" align="center">
<template slot-scope="scope">
{{ scope.row.addr }}
</template>
</el-table-column>
<el-table-column label="手机号码" align="center">
<template slot-scope="scope">
{{ scope.row.mobile }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="实名认证" width="95" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_time" label="提交时间" width="120">
<template slot-scope="scope">
<i class="el-icon-time" />
<el-tooltip :content="scope.row.created_time">
<span>{{ scope.row.created_time|formatTime }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column align="center" prop="created_time" label="审核时间" width="120">
<template slot-scope="scope">
<i class="el-icon-time" />
<el-tooltip :content="scope.row.reviewed_time">
<span>{{ scope.row.reviewed_time|formatTime }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template slot-scope="scope">
<router-link :to="{name: 'user_authentication_info_edit',params:{id:scope.row.id}}">
<el-button type="primary" size="mini">
查看编辑
</el-button>
</router-link>
<el-button type="danger" size="mini" @click="deleteApp(scope.row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="fetchData" />
</div>
</template>
<script>
import { getStorageInfo } from '@/api/storage'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import waves from '@/directive/waves' // waves directive
const sortOptions = [
{ label: '审核时间 Ascending', key: 'reviewed_time' },
{ label: '审核时间 Descending', key: '-reviewed_time' },
{ label: '提交时间 Ascending', key: 'created_time' },
{ label: '提交时间 Descending', key: '-created_time' }
]
export default {
name: 'AppInfo',
components: { Pagination },
directives: { waves },
filters: {
formatTime(time) {
return time.split('T')[0]
},
certStatusFilter(status) {
const statusMap = {
'-1': 'info',
'1': 'success',
'0': 'gray',
'2': 'danger'
}
return statusMap[status]
},
certLableFilter(row) {
for (const v of row.certification_status_choices) {
if (v.id === row.status) {
return v.name
}
}
},
statusFilter(status) {
const statusMap = {
true: 'success',
false: 'danger'
}
return statusMap[status]
},
appStatusNameFilter(row) {
for (const r of row.status_choices) {
if (r.id === row.status) {
return r.name
}
}
},
appStatusFilter(status) {
const statusMap = {
'0': 'danger',
'1': 'success',
'2': 'gray'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true,
total: 0,
listQuery: {
page: 1,
limit: 10,
name: undefined,
sort: '-created_time',
card: undefined,
mobile: undefined,
status: undefined,
user_id: undefined
},
sortOptions,
certification_status_choices: []
}
},
created() {
this.fetchData()
},
methods: {
handleFilter() {
this.listQuery.page = 1
this.fetchData()
},
fetchData() {
this.listLoading = true
getStorageInfo(this.listQuery).then(response => {
this.list = response.data
if (this.list && this.list.length > 0) {
this.certification_status_choices = this.list[0].certification_status_choices
}
this.total = response.total
this.listLoading = false
})
}
}
}
</script>

@ -56,6 +56,11 @@
<el-select v-model="postForm.certification" class="filter-item" placeholder="Please select" :disabled="postForm.certification === -1">
<el-option v-for="item in postForm.certification_status_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<router-link v-if="postForm.certification_id" :to="{name: 'user_authentication_info_edit',params:{id:postForm.certification_id.id}}">
<el-button type="primary">
审核认证信息
</el-button>
</router-link>
</el-col>
<el-col v-if="postForm.certification === -1" span="16">
<el-link :underline="false"> 用户需要先提交认证信息才可以进行认证修改</el-link>

@ -15,8 +15,9 @@ Including another URLconf
"""
from django.urls import re_path
from admin.views.login import LoginView, LoginUserView
from admin.views.user import UserInfoView
from admin.views.user import UserInfoView, UserCertificationInfoView
from admin.views.app import AppInfoView, AppReleaseInfoView
from admin.views.storage import StorageInfoView
urlpatterns = [
# path("",include(router.urls)),
@ -27,5 +28,7 @@ urlpatterns = [
re_path("^userinfo", UserInfoView.as_view()),
re_path("^app/info", AppInfoView.as_view()),
re_path("^app/release/info", AppReleaseInfoView.as_view()),
re_path("^certification/info", UserCertificationInfoView.as_view()),
re_path("^storage/info", StorageInfoView.as_view()),
]

@ -0,0 +1,73 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 4月
# author: liuyu
# date: 2021/4/11
from django.contrib import auth
from api.models import Token, UserInfo, AppStorage
from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication
from api.utils.serializer import AdminStorageSerializer, AdminUserCertificationSerializer
from django.core.cache import cache
from rest_framework.views import APIView
import binascii
import os, datetime
from api.utils.utils import get_captcha, valid_captcha, get_choices_dict
from api.utils.response import BaseResponse
from fir_ser.settings import CACHE_KEY_TEMPLATE, LOGIN
from api.utils.storage.caches import login_auth_failed
import logging
from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle
from rest_framework.pagination import PageNumberPagination
logger = logging.getLogger(__name__)
class AppsPageNumber(PageNumberPagination):
page_size = 20 # 每页显示多少条
page_size_query_param = 'limit' # URL中每页显示条数的参数
page_query_param = 'page' # URL中页码的参数
max_page_size = None # 最大页码数限制
class StorageInfoView(APIView):
authentication_classes = [AdminTokenAuthentication, ]
def get(self, request):
res = BaseResponse()
filter_data = {}
filter_fileds = ["id", "user_id", "name", "storage_type", "access_key", "bucket_name"]
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")
page_obj = AppsPageNumber()
obj_list = AppStorage.objects.filter(**filter_data).order_by(sort)
page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request,
view=self)
serializer = AdminStorageSerializer(page_serializer, many=True)
res.data = serializer.data
res.total = obj_list.count()
return Response(res.dict)
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)
user_obj = UserInfo.objects.filter(pk=pk).first()
if user_obj:
data['pk'] = pk
users_serializer = AdminStorageSerializer(user_obj, data=data, partial=True)
if users_serializer.is_valid():
users_serializer.save()
res.data = users_serializer.data
return Response(res.dict)
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)

@ -8,7 +8,7 @@ from django.contrib import auth
from api.models import Token, UserInfo, UserCertificationInfo
from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication
from api.utils.serializer import AdminUserInfoSerializer
from api.utils.serializer import AdminUserInfoSerializer, AdminUserCertificationSerializer
from django.core.cache import cache
from rest_framework.views import APIView
import binascii
@ -80,3 +80,46 @@ class UserInfoView(APIView):
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)
class UserCertificationInfoView(APIView):
authentication_classes = [AdminTokenAuthentication, ]
def get(self, request):
res = BaseResponse()
filter_data = {}
filter_fileds = ["id", "card", "name", "status"]
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")
page_obj = AppsPageNumber()
obj_list = UserCertificationInfo.objects.filter(**filter_data).order_by(sort)
page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request,
view=self)
users_serializer = AdminUserCertificationSerializer(page_serializer, many=True)
res.data = users_serializer.data
res.total = obj_list.count()
return Response(res.dict)
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 = UserCertificationInfo.objects.filter(id=pk).first()
if obj:
data['pk'] = pk
users_serializer = AdminUserCertificationSerializer(obj, data=data, partial=True)
if users_serializer.is_valid():
users_serializer.save()
res.data = users_serializer.data
return Response(res.dict)
print(users_serializer.errors)
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)

@ -404,10 +404,10 @@ class UserCertificationInfo(models.Model):
related_name='certification')
name = models.CharField(max_length=128, null=False, verbose_name="真实姓名")
card = models.CharField(max_length=128, null=False, verbose_name="身份证号码")
addr = models.CharField(max_length=128, null=False, verbose_name="居住地")
addr = models.CharField(max_length=128, null=False, verbose_name="居住地")
mobile = models.BigIntegerField(verbose_name="手机号码", unique=True, null=False)
status_choices = ((-1, '待认证'), (0, '认证中'), (1, '认证成功'), (2, '认证失败'))
status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="审核状态")
status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="认证状态")
msg = models.CharField(max_length=512, null=True, blank=True, verbose_name="备注")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
reviewed_time = models.DateTimeField(auto_now_add=False, verbose_name="审核时间")

@ -4,7 +4,7 @@ from api.utils.app.apputils import bytes2human
from api.utils.TokenManager import DownloadToken
from api.utils.app.supersignutils import get_redirect_server_domain
from api.utils.storage.storage import Storage
from api.utils.utils import get_developer_udided, get_choices_dict
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
import os, json, logging
@ -20,7 +20,7 @@ def get_download_url_from_context(self, obj, key, url, force_new=False):
if self.context.get("storage", None) and self.context.get("storage") != "undefined":
storage = self.context.get("storage", None)
else:
if isinstance(obj, models.Apps):
if isinstance(obj, models.Apps) or isinstance(obj, models.UserCertificationInfo):
storage = Storage(obj.user_id)
elif isinstance(obj, models.AppReleaseInfo):
storage = Storage(obj.app_id.user_id)
@ -83,7 +83,7 @@ class AdminUserInfoSerializer(UserInfoSerializer):
read_only_fields = ["id", "head_img", "free_download_times", "last_login",
"is_superuser", "last_name", "is_staff", "uid", "storage_active", "supersign_active",
"date_joined", "download_times", "all_download_times", "storage", "groups",
"user_permissions"]
"user_permissions", "certification_id"]
gender_choices = serializers.SerializerMethodField()
@ -105,6 +105,11 @@ class AdminUserInfoSerializer(UserInfoSerializer):
def get_certification_status_choices(self, obj):
return get_choices_dict(models.UserCertificationInfo.status_choices)
certification_id = serializers.SerializerMethodField()
def get_certification_id(self, obj):
return models.UserCertificationInfo.objects.filter(user_id=obj).values('id').first()
def update(self, instance, validated_data):
return super(AdminUserInfoSerializer, self).update(instance, validated_data)
@ -322,7 +327,6 @@ class AdminAppReleaseSerializer(AppReleaseSerializer):
return get_choices_dict(obj.release_choices)
def update(self, instance, validated_data):
print(validated_data)
if validated_data.get("is_master", False):
models.AppReleaseInfo.objects.filter(app_id=instance.app_id).update(**{"is_master": False})
else:
@ -357,6 +361,13 @@ class StorageSerializer(serializers.ModelSerializer):
return None
class AdminStorageSerializer(StorageSerializer):
class Meta:
model = models.AppStorage
fields = "__all__"
read_only_fields = ["id", "user_id", "updated_time", "created_time"]
class DeveloperSerializer(serializers.ModelSerializer):
class Meta:
model = models.AppIOSDeveloperInfo
@ -447,3 +458,29 @@ class UserCertificationSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserCertificationInfo
exclude = ["id", "user_id", "created_time"]
class AdminUserCertificationSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserCertificationInfo
fields = "__all__"
read_only_fields = ["id", "user_id", "reviewed_time", "created_time"]
certification_status_choices = serializers.SerializerMethodField()
def get_certification_status_choices(self, obj):
return get_choices_dict(obj.status_choices)
certification_infos = serializers.SerializerMethodField()
def get_certification_infos(self, obj):
result = []
for c_info in models.CertificationInfo.objects.filter(user_id=obj.user_id).all():
result.append({
'name': get_choices_name_from_key(models.CertificationInfo.type_choices, c_info.type),
'certification_url': get_download_url_from_context(self, obj, '', c_info.certification_url)
})
return result
def update(self, instance, validated_data):
return super(AdminUserCertificationSerializer, self).update(instance, validated_data)

@ -304,3 +304,11 @@ def get_choices_dict(choices):
for choice in choices_org_list:
result.append({'id': choice[0], 'name': choice[1]})
return result
def get_choices_name_from_key(choices, key):
choices_org_list = list(choices)
for choice in choices_org_list:
if choice[0] == key:
return choice[1]
return ''

Loading…
Cancel
Save