管理后台增加超级签开发展示

dependabot/pip/fir_ser/django-3.2.4
youngS 4 years ago
parent 5835b4d6e1
commit a59958e1af
  1. 17
      fir_admin/src/api/developer.js
  2. 17
      fir_admin/src/api/devices.js
  3. 57
      fir_admin/src/router/index.js
  4. 8
      fir_admin/src/views/order/list.vue
  5. 10
      fir_admin/src/views/storage/list.vue
  6. 117
      fir_admin/src/views/supersign/developer/Detail.vue
  7. 214
      fir_admin/src/views/supersign/developer/list.vue
  8. 90
      fir_admin/src/views/supersign/devices/list.vue
  9. 3
      fir_admin/src/views/supersign/index.vue
  10. 7
      fir_admin/src/views/userinfos/UserDetail.vue
  11. 2
      fir_admin/src/views/userinfos/list.vue
  12. 4
      fir_client/src/components/user/FirSuperSignBase.vue
  13. 3
      fir_ser/admin/urls.py
  14. 75
      fir_ser/admin/views/supersign.py
  15. 35
      fir_ser/api/utils/serializer.py

@ -0,0 +1,17 @@
import request from '@/utils/request'
export function getDeveloperInfo(query) {
return request({
url: '/developer/info',
method: 'get',
params: query
})
}
export function updatedeveloperInfo(data) {
return request({
url: '/developer/info',
method: 'put',
data
})
}

@ -0,0 +1,17 @@
import request from '@/utils/request'
export function getDevicesInfo(query) {
return request({
url: '/devices/info',
method: 'get',
params: query
})
}
export function updatedevicesInfo(data) {
return request({
url: '/devices/info',
method: 'put',
data
})
}

@ -137,18 +137,6 @@ export const constantRoutes = [
hidden: true hidden: true
} }
] ]
},
{
path: '/sign',
component: Layout,
children: [
{
path: 'index',
name: 'index',
component: () => import('@/views/form/index'),
meta: { title: '超级签名', icon: 'form' }
}
]
}, { }, {
path: '/authentication', path: '/authentication',
component: Layout, component: Layout,
@ -185,8 +173,53 @@ export const constantRoutes = [
hidden: true hidden: true
} }
] ]
}, {
path: '/supersign',
component: Layout,
redirect: '/supersign/developer',
name: '超级签名',
meta: {
title: '超级签名',
icon: 'nested'
}, },
children: [
{ {
path: 'developer',
name: 'developer',
redirect: '/supersign/developer/list',
component: () => import('@/views/supersign/index'),
children: [
{
path: 'list',
name: 'developer_user_info_list',
component: () => import('@/views/supersign/developer/list'),
meta: { title: '苹果开发者', icon: 'form' }
},
{
path: 'edit/:id(\\d+)',
component: () => import('@/views/supersign/developer/Detail'),
name: 'developer_user_info_edit',
meta: { title: '编辑信息', noCache: true, activeMenu: '/supersign/list' },
hidden: true
}
]
},
{
path: 'devices',
name: 'devices',
redirect: '/supersign/devices/list',
component: () => import('@/views/supersign/index'),
children: [
{
path: 'list',
name: 'devices_info_list',
component: () => import('@/views/supersign/devices/list'),
meta: { title: '设备消耗', icon: 'form' }
},
]
}
]
}, {
path: '/settings', path: '/settings',
component: Layout, component: Layout,
redirect: '/settings/email', redirect: '/settings/email',

@ -59,7 +59,7 @@
</el-table-column> </el-table-column>
<el-table-column label="实付金额" align="center" width="80px"> <el-table-column label="实付金额" align="center" width="80px">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.actual_amount }} {{ scope.row.actual_amount/100 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="购买数量" align="center" width="90px"> <el-table-column label="购买数量" align="center" width="90px">
@ -123,8 +123,10 @@ 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: 'created_time' },
{ label: '创建时间 Descending', key: '-reviewed_time' }, { label: '创建时间 Descending', key: '-created_time' },
{ label: '付款时间 Ascending', key: 'pay_time' },
{ label: '付款时间 Descending', key: '-pay_time' }
] ]
export default { export default {

@ -100,10 +100,10 @@ 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: 'created_time' },
{ label: '创建时间 Descending', key: '-reviewed_time' }, { label: '创建时间 Descending', key: '-created_time' },
{ label: '更新时间 Ascending', key: 'created_time' }, { label: '更新时间 Ascending', key: 'updated_time' },
{ label: '更新时间 Descending', key: '-created_time' } { label: '更新时间 Descending', key: '-updated_time' }
] ]
export default { export default {
@ -176,7 +176,7 @@ export default {
}, },
created() { created() {
this.fetchData() this.fetchData()
},mounted() { }, mounted() {
if (this.$route.query.user_id) { if (this.$route.query.user_id) {
this.listQuery.user_id = this.$route.query.user_id this.listQuery.user_id = this.$route.query.user_id
} }

@ -10,18 +10,32 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="存储名称"> <el-form-item label="issuer_id">
<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.issuer_id" />
</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-select v-model="postForm.storage_type" class="filter-item" disabled> <el-input-number v-model="postForm.usable_number" :min="0" :max="100" label="可使用设备数" />
<el-option v-for="item in postForm.storage_choices" :key="item.id" :label="item.name" :value="item.id" /> </el-col>
</el-row>
</el-form-item>
<el-form-item label="已消耗设备数">
<el-row :gutter="12">
<el-col :span="16">
<el-input-number v-model="postForm.use_number" :min="0" :max="100" label="已消耗设备数" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="账户类型">
<el-row :gutter="12">
<el-col :span="16">
<el-select v-model="postForm.auth_type" class="filter-item" disabled>
<el-option v-for="item in postForm.auth_type_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-col> </el-col>
</el-row> </el-row>
@ -40,7 +54,7 @@
</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.description" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" /> <el-input v-model="postForm.description" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" />
@ -49,61 +63,49 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="账户状态" label-width="160px">
<el-form-item label="存储访问access_key" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.access_key" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="存储访问secret_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.secret_key" /> <el-tooltip :content="postForm.is_actived|userStatusFilter" placement="top">
<el-switch
v-model="postForm.is_actived"
active-color="#13ce66"
inactive-color="#ff4949"
:active-value="true"
:inactive-value="false"
/>
</el-tooltip>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="存储空间bucket_name" label-width="160px"> <el-form-item label="证书过期时间" prop="timestamp" label-width="160px">
<el-row :gutter="12"> <el-row :gutter="20">
<el-col :span="16"> <el-col :span="8">
<el-input v-model="postForm.bucket_name" /> <el-date-picker :value="postForm.cert_expire_time" type="datetime" disabled />
</el-col>
</el-row>
</el-form-item>
<div v-if="postForm.storage_type===2">
<el-form-item label="阿里云sts_role_arn" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.sts_role_arn" />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="private_key_id" label-width="160px">
<el-form-item label="阿里云endpoint" label-width="160px">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="postForm.endpoint" /> <el-input v-model="postForm.private_key_id" />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="阿里云下载授权方式" label-width="160px"> <el-form-item label="p8key" label-width="160px">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="16">
<el-select v-model="postForm.download_auth_type" class="filter-item" style="width: 100%"> <el-input v-model="postForm.p8key" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" />
<el-option v-for="item in postForm.download_auth_type_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 v-if="postForm.download_auth_type===2" label="阿里云cnd_auth_key" label-width="160px"> <el-form-item label="certid" label-width="160px">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="postForm.cnd_auth_key" /> <el-input v-model="postForm.certid" />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
</div>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
@ -118,29 +120,36 @@
</template> </template>
<script> <script>
import { getStorageInfo, updateStorageInfo } from '@/api/storage' import { getDeveloperInfo, updatedeveloperInfo } from '@/api/developer'
const defaultForm = { const defaultForm = {
user_id: undefined, user_id: undefined,
name: undefined, is_actived: undefined,
storage_type: undefined, issuer_id: undefined,
access_key: undefined, private_key_id: undefined,
secret_key: undefined, p8key: undefined,
bucket_name: undefined, certid: undefined,
domain_name: undefined,
created_time: undefined, created_time: undefined,
description: undefined, description: undefined,
sts_role_arn: undefined, usable_number: undefined,
endpoint: undefined, use_number: undefined,
download_auth_type: undefined, auth_type: undefined,
cnd_auth_key: undefined, cert_expire_time: undefined,
updated_time: undefined, updated_time: undefined,
download_auth_type_choices: [] auth_type_choices: []
} }
export default { export default {
name: 'StorageDetail', name: 'DeveloperDetail',
components: { }, filters: {}, components: { }, filters: {
userStatusFilter(status) {
const statusMap = {
true: '激活,允许使用',
false: '禁用,禁止使用'
}
return statusMap[status]
}
},
data() { data() {
return { return {
postForm: Object.assign({}, defaultForm), postForm: Object.assign({}, defaultForm),
@ -155,7 +164,7 @@ export default {
}, },
methods: { methods: {
fetchData(id) { fetchData(id) {
getStorageInfo({ id: id }).then(response => { getDeveloperInfo({ id: id }).then(response => {
if (response.data.length === 1) { if (response.data.length === 1) {
this.postForm = response.data[0] this.postForm = response.data[0]
} }
@ -164,7 +173,7 @@ export default {
}) })
}, },
updateData() { updateData() {
updateStorageInfo(this.postForm).then(response => { updatedeveloperInfo(this.postForm).then(response => {
this.$message.success('更新成功') this.$message.success('更新成功')
this.postForm = response.data this.postForm = response.data
}).catch(err => { }).catch(err => {

@ -0,0 +1,214 @@
<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.issuer_id" placeholder="issuer_id" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.private_key_id" placeholder="private_key_id" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.certid" placeholder="证书ID" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.description" placeholder="备注" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.auth_type" placeholder="账户类型" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in auth_type_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="issuer_id" width="300">
<template slot-scope="scope">
{{ scope.row.issuer_id }}
</template>
</el-table-column>
<el-table-column label="private_key_id" align="center">
<template slot-scope="scope">
<span>{{ scope.row.private_key_id }}</span>
</template>
</el-table-column>
<el-table-column label="certid" align="center">
<template slot-scope="scope">
{{ scope.row.certid }}
</template>
</el-table-column>
<el-table-column label="可用设备数" align="center" width="100">
<template slot-scope="scope">
{{ scope.row.usable_number }}
</template>
</el-table-column>
<el-table-column label="消耗设备数" align="center" width="100">
<template slot-scope="scope">
{{ scope.row.use_number }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="账户类型" width="130" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.auth_type | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag>
</template>
</el-table-column>
<el-table-column class-name="status-col" label="是否激活" width="80" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.is_actived | statusFilter">{{ scope.row.is_actived }}</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.updated_time">
<span>{{ scope.row.cert_expire_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: 'developer_user_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 { getDeveloperInfo } from '@/api/developer'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import waves from '@/directive/waves' // waves directive
const sortOptions = [
{ label: '创建时间 Ascending', key: 'created_time' },
{ label: '创建时间 Descending', key: '-created_time' },
{ label: '更新时间 Ascending', key: 'updated_time' },
{ label: '更新时间 Descending', key: '-updated_time' },
{ label: '证书过期时间 Ascending', key: 'cert_expire_time' },
{ label: '证书过期时间 Descending', key: '-cert_expire_time' }
]
export default {
name: 'StorageInfo',
components: { Pagination },
directives: { waves },
filters: {
formatTime(time) {
return time.split('T')[0]
},
certStatusFilter(status) {
const statusMap = {
'0': 'danger',
'1': 'success',
'2': 'gray',
'3': 'info'
}
return statusMap[status]
},
certLableFilter(row) {
for (const v of row.auth_type_choices) {
if (v.id === row.auth_type) {
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,
sort: '-created_time',
issuer_id: undefined,
private_key_id: undefined,
certid: undefined,
description: undefined,
user_id: undefined,
auth_type: undefined
},
sortOptions,
auth_type_choices: []
}
},
created() {
this.fetchData()
},
methods: {
handleFilter() {
this.listQuery.page = 1
this.fetchData()
},
fetchData() {
this.listLoading = true
getDeveloperInfo(this.listQuery).then(response => {
this.list = response.data
if (this.list && this.list.length > 0) {
this.auth_type_choices = this.list[0].auth_type_choices
}
this.total = response.total
this.listLoading = false
})
}
}
}
</script>

@ -2,13 +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.bucket_name" placeholder="bucket_name" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" /> <el-input v-model="listQuery.issuer_id" placeholder="开发者issuer_id" style="width: 300px;" 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.udid" placeholder="设备UDID" 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-input v-model="listQuery.name" placeholder="应用名称" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.domain_name" placeholder="下载域名" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" /> <el-input v-model="listQuery.bundle_id" placeholder="BundleID" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.storage_type" placeholder="存储类型" clearable class="filter-item" style="width: 140px" @change="handleFilter"> <el-input v-model="listQuery.short" placeholder="短连接" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-option v-for="item in storage_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-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" />
</el-select> </el-select>
@ -37,54 +36,52 @@
</router-link> </router-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="存储名称"> <el-table-column label="应用ID" width="100" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.name }} <router-link :to="{name: 'app_info_edit',params:{id:scope.row.app_id}}">
<el-link type="primary"> {{ scope.row.app_id }}</el-link>
</router-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="存储访问access_key" align="center"> <el-table-column label="开发者issuer_id" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.access_key }}</span> <router-link :to="{name: 'developer_user_info_edit',params:{id:scope.row.developer_pk}}">
<el-link type="primary"> {{ scope.row.developer_id }}</el-link>
</router-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="存储空间bucket_name" align="center"> <el-table-column label="应用名称" align="center" >
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.bucket_name }} {{ scope.row.bundle_name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="下载域名" align="center"> <el-table-column label="短连接" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.domain_name }} {{ scope.row.short }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column class-name="status-col" label="存储类型" width="95" align="center"> <el-table-column label="BundleID" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="scope.row.storage_type | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag> {{ scope.row.bundle_id }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="created_time" label="创建时间" width="120"> <el-table-column label="设备UDID" align="center" width="350">
<template slot-scope="scope"> <template slot-scope="scope">
<i class="el-icon-time" /> {{ scope.row.device_udid }}
<el-tooltip :content="scope.row.created_time">
<span>{{ scope.row.created_time|formatTime }}</span>
</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.updated_time"> <el-tooltip :content="scope.row.created_time">
<span>{{ scope.row.updated_time|formatTime }}</span> <span>{{ scope.row.created_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: 'storage_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 type="danger" size="mini" @click="deleteApp(scope.row.id)">
删除 删除
</el-button> </el-button>
@ -97,19 +94,17 @@
</template> </template>
<script> <script>
import { getStorageInfo } from '@/api/storage' import { getDevicesInfo } from '@/api/devices'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination import Pagination from '@/components/Pagination' // secondary package based on el-pagination
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: 'created_time' },
{ label: '创建时间 Descending', key: '-reviewed_time' }, { label: '创建时间 Descending', key: '-created_time' }
{ label: '更新时间 Ascending', key: 'created_time' },
{ label: '更新时间 Descending', key: '-created_time' }
] ]
export default { export default {
name: 'StorageInfo', name: 'DevicesInfo',
components: { Pagination }, components: { Pagination },
directives: { waves }, directives: { waves },
filters: { filters: {
@ -126,8 +121,8 @@ export default {
return statusMap[status] return statusMap[status]
}, },
certLableFilter(row) { certLableFilter(row) {
for (const v of row.storage_choices) { for (const v of row.auth_type_choices) {
if (v.id === row.storage_type) { if (v.id === row.auth_type) {
return v.name return v.name
} }
} }
@ -163,16 +158,15 @@ export default {
listQuery: { listQuery: {
page: 1, page: 1,
limit: 10, limit: 10,
name: undefined,
sort: '-created_time', sort: '-created_time',
bucket_name: undefined, issuer_id: undefined,
access_key: undefined, short: undefined,
storage_type: undefined, bundle_id: undefined,
domain_name: undefined, name: undefined,
user_id: undefined user_id: undefined,
udid: undefined
}, },
sortOptions, sortOptions
storage_choices: []
} }
}, },
created() { created() {
@ -185,10 +179,10 @@ export default {
}, },
fetchData() { fetchData() {
this.listLoading = true this.listLoading = true
getStorageInfo(this.listQuery).then(response => { getDevicesInfo(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.storage_choices = this.list[0].storage_choices this.auth_type_choices = this.list[0].auth_type_choices
} }
this.total = response.total this.total = response.total
this.listLoading = false this.listLoading = false

@ -0,0 +1,3 @@
<template>
<router-view />
</template>

@ -238,8 +238,7 @@
<script> <script>
import { validURL } from '@/utils/validate' import { validURL } from '@/utils/validate'
import { getUserInfos, updateUserInfo } from '@/api/user' import { getUserInfos, updateUserInfo } from '@/api/user'
import { getStorageInfo,changeStorageInfo } from '@/api/storage' import { getStorageInfo, changeStorageInfo } from '@/api/storage'
import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
const defaultForm = { const defaultForm = {
email: undefined, email: undefined,
@ -268,7 +267,7 @@ const defaultForm = {
export default { export default {
name: 'UserDetail', name: 'UserDetail',
components: { CommentDropdown, PlatformDropdown, SourceUrlDropdown }, filters: { components: { }, filters: {
userStatusFilter(status) { userStatusFilter(status) {
const statusMap = { const statusMap = {
true: '激活,允许登录', true: '激活,允许登录',
@ -342,7 +341,7 @@ export default {
}, },
methods: { methods: {
changeStorageData(force) { changeStorageData(force) {
changeStorageInfo({id: this.postForm.id, use_storage_id: this.postForm.storage,force: force}).then(response => { changeStorageInfo({ id: this.postForm.id, use_storage_id: this.postForm.storage, force: force }).then(response => {
this.$message.success('存储数据迁移并设置刷新成功') this.$message.success('存储数据迁移并设置刷新成功')
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)

@ -144,7 +144,7 @@ export default {
return statusMap[status] return statusMap[status]
}, },
certLableFilter(row) { certLableFilter(row) {
return baseFilter(row.certification,row.certification_status_choices) return baseFilter(row.certification, row.certification_status_choices)
} }
}, },
data() { data() {

@ -24,7 +24,7 @@
</div> </div>
<el-form-item label-width="110px" label="设备数量" style="text-align: left"> <el-form-item label-width="110px" label="设备数量" style="text-align: left">
<el-input-number v-model="editdeveloperinfo.usable_number" :min="0" :max="100" label="设备数量"></el-input-number> <el-input-number v-model="editdeveloperinfo.usable_number" :min="0" :max="100" label="设备数量"/>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="备注"> <el-form-item label-width="110px" label="备注">
@ -220,7 +220,7 @@
</div> </div>
<el-form-item label-width="110px" label="设备数量" style="text-align: left"> <el-form-item label-width="110px" label="设备数量" style="text-align: left">
<el-input-number v-model="editdeveloperinfo.usable_number" :min="0" :max="100" label="设备数量"></el-input-number> <el-input-number v-model="editdeveloperinfo.usable_number" :min="0" :max="100" label="设备数量"/>
</el-form-item> </el-form-item>
<el-form-item label-width="110px" label="备注"> <el-form-item label-width="110px" label="备注">

@ -19,6 +19,7 @@ from admin.views.user import UserInfoView, UserCertificationInfoView
from admin.views.app import AppInfoView, AppReleaseInfoView from admin.views.app import AppInfoView, AppReleaseInfoView
from admin.views.storage import StorageInfoView, StorageChangeView from admin.views.storage import StorageInfoView, StorageChangeView
from admin.views.order import OrderPayView, OrderInfoView from admin.views.order import OrderPayView, OrderInfoView
from admin.views.supersign import DeveloperInfoView,DevicesInfoView
urlpatterns = [ urlpatterns = [
# path("",include(router.urls)), # path("",include(router.urls)),
@ -33,5 +34,7 @@ urlpatterns = [
re_path("^storage/info", StorageInfoView.as_view()), re_path("^storage/info", StorageInfoView.as_view()),
re_path("^storage/change", StorageChangeView.as_view()), re_path("^storage/change", StorageChangeView.as_view()),
re_path("^order/info", OrderInfoView.as_view()), re_path("^order/info", OrderInfoView.as_view()),
re_path("^developer/info", DeveloperInfoView.as_view()),
re_path("^devices/info", DevicesInfoView.as_view()),
] ]

@ -5,11 +5,12 @@
# date: 2021/4/11 # date: 2021/4/11
from django.contrib import auth from django.contrib import auth
from api.models import Token, UserInfo, APPSuperSignUsedInfo from api.models import Token, APPSuperSignUsedInfo, AppIOSDeveloperInfo
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.baseutils import get_dict_from_filter_fields
from api.utils.serializer import AdminStorageSerializer, AdminUserCertificationSerializer from api.utils.serializer import AdminDeveloperSerializer, AdminUserCertificationSerializer, \
AdminSuperSignUsedSerializer
from django.core.cache import cache from django.core.cache import cache
from rest_framework.views import APIView from rest_framework.views import APIView
import binascii import binascii
@ -32,19 +33,19 @@ class AppsPageNumber(PageNumberPagination):
max_page_size = None # 最大页码数限制 max_page_size = None # 最大页码数限制
class StorageInfoView(APIView): class DeveloperInfoView(APIView):
authentication_classes = [AdminTokenAuthentication, ] authentication_classes = [AdminTokenAuthentication, ]
def get(self, request): def get(self, request):
res = BaseResponse() res = BaseResponse()
filter_fields = ["id", "user_id", "name", "storage_type", "access_key", "bucket_name"] filter_fields = ["id", "user_id", "issuer_id", "private_key_id", "certid", "description", "auth_type"]
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params) filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
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 = AppIOSDeveloperInfo.objects.filter(**filter_data).order_by(sort)
page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request, page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request,
view=self) view=self)
serializer = AdminStorageSerializer(page_serializer, many=True) serializer = AdminDeveloperSerializer(page_serializer, many=True)
res.data = serializer.data res.data = serializer.data
res.total = obj_list.count() res.total = obj_list.count()
return Response(res.dict) return Response(res.dict)
@ -57,10 +58,68 @@ class StorageInfoView(APIView):
res.code = 1003 res.code = 1003
res.msg = "参数错误" res.msg = "参数错误"
return Response(res.dict) return Response(res.dict)
obj = AppStorage.objects.filter(pk=pk).first() obj = AppIOSDeveloperInfo.objects.filter(pk=pk).first()
if obj: if obj:
data['pk'] = pk data['pk'] = pk
serializer = AdminStorageSerializer(obj, data=data, partial=True) serializer = AdminDeveloperSerializer(obj, data=data, partial=True)
if serializer.is_valid():
serializer.save()
res.data = serializer.data
return Response(res.dict)
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)
class DevicesInfoView(APIView):
authentication_classes = [AdminTokenAuthentication, ]
def get(self, request):
res = BaseResponse()
filter_fields = ["id", "user_id", "issuer_id", "udid", "name", "bundle_id", "short"]
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
sort = request.query_params.get("sort", "-created_time")
page_obj = AppsPageNumber()
if 'udid' in filter_data:
filter_data["udid__udid"] = filter_data['udid']
del filter_data['udid']
if 'name' in filter_data:
filter_data["app_id__name"] = filter_data['name']
del filter_data['name']
if 'bundle_id' in filter_data:
filter_data["app_id__bundle_id"] = filter_data['bundle_id']
del filter_data['bundle_id']
if 'short' in filter_data:
filter_data["app_id__short"] = filter_data['short']
del filter_data['short']
if 'issuer_id' in filter_data:
filter_data["developerid__issuer_id"] = filter_data['issuer_id']
del filter_data['issuer_id']
obj_list = APPSuperSignUsedInfo.objects.filter(**filter_data).order_by(sort)
page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request,
view=self)
serializer = AdminSuperSignUsedSerializer(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)
obj = AppIOSDeveloperInfo.objects.filter(pk=pk).first()
if obj:
data['pk'] = pk
serializer = AdminDeveloperSerializer(obj, data=data, partial=True)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
res.data = serializer.data res.data = serializer.data

@ -407,6 +407,16 @@ class DeveloperSerializer(serializers.ModelSerializer):
def get_developer_used_other_number(self, obj): def get_developer_used_other_number(self, obj):
return get_developer_udided(obj)[0] return get_developer_udided(obj)[0]
class AdminDeveloperSerializer(DeveloperSerializer):
class Meta:
model = models.AppIOSDeveloperInfo
# depth = 1
exclude = [ "p8key",]
auth_type_choices = serializers.SerializerMethodField()
def get_auth_type_choices(self, obj):
return get_choices_dict(obj.auth_type_choices)
class SuperSignUsedSerializer(serializers.ModelSerializer): class SuperSignUsedSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -435,6 +445,31 @@ class SuperSignUsedSerializer(serializers.ModelSerializer):
return obj.app_id.name return obj.app_id.name
class AdminSuperSignUsedSerializer(SuperSignUsedSerializer):
class Meta:
model = models.APPSuperSignUsedInfo
fields = ["created_time", "device_udid", "device_name", "developer_id", "bundle_id", "bundle_name","app_id","id","user_id","short","developer_pk"]
app_id = serializers.SerializerMethodField()
def get_app_id(self, obj):
return obj.app_id.pk
user_id = serializers.SerializerMethodField()
def get_user_id(self, obj):
return obj.user_id.pk
short = serializers.SerializerMethodField()
def get_short(self, obj):
return obj.app_id.short
developer_pk = serializers.SerializerMethodField()
def get_developer_pk(self, obj):
return obj.developerid.pk
class DeviceUDIDSerializer(serializers.ModelSerializer): class DeviceUDIDSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.AppUDID model = models.AppUDID

Loading…
Cancel
Save