管理后台增加域名功能

publicsignpoll
youngS 3 years ago
parent b10a40d177
commit 2feda8800c
  1. 25
      fir_admin/src/api/domain.js
  2. 14
      fir_admin/src/api/order.js
  3. 31
      fir_admin/src/router/index.js
  4. 1
      fir_admin/src/views/appinfos/list.vue
  5. 4
      fir_admin/src/views/authentication/list.vue
  6. 145
      fir_admin/src/views/domain/Detail.vue
  7. 193
      fir_admin/src/views/domain/list.vue
  8. 18
      fir_admin/src/views/order/list.vue
  9. 4
      fir_admin/src/views/storage/list.vue
  10. 34
      fir_admin/src/views/userinfos/UserDetail.vue
  11. 8
      fir_admin/src/views/userinfos/list.vue
  12. 4
      fir_ser/admin/urls.py
  13. 83
      fir_ser/admin/views/domain.py
  14. 48
      fir_ser/admin/views/order.py
  15. 4
      fir_ser/api/utils/baseutils.py
  16. 12
      fir_ser/api/utils/serializer.py
  17. 1
      fir_ser/api/utils/storage/caches.py

@ -0,0 +1,25 @@
import request from '@/utils/request'
export function getDomainInfos(query) {
return request({
url: '/domain/info',
method: 'get',
params: query
})
}
export function updateDomainInfo(data) {
return request({
url: '/domain/info',
method: 'put',
data
})
}
export function deleteDomain(data) {
return request({
url: '/domain/info',
method: 'delete',
data
})
}

@ -15,4 +15,18 @@ export function updateOrderInfo(data) {
data data
}) })
} }
export function deleteOrderInfo(data) {
return request({
url: '/order/info',
method: 'delete',
data
})
}
export function createOrderInfo(data) {
return request({
url: '/order/info',
method: 'post',
data
})
}

@ -155,7 +155,8 @@ export const constantRoutes = [
hidden: true hidden: true
} }
] ]
}, { },
{
path: '/order', path: '/order',
component: Layout, component: Layout,
children: [ children: [
@ -173,7 +174,27 @@ export const constantRoutes = [
hidden: true hidden: true
} }
] ]
}, { },
{
path: '/domain',
component: Layout,
children: [
{
path: 'list',
name: 'domain_info_list',
component: () => import('@/views/domain/list'),
meta: { title: '下载域名管理', icon: 'form' }
},
{
path: 'edit/:id(\\d+)',
component: () => import('@/views/domain/Detail'),
name: 'domain_info_edit',
meta: { title: '编辑信息', noCache: true, activeMenu: '/domain/list' },
hidden: true
}
]
},
{
path: '/supersign', path: '/supersign',
component: Layout, component: Layout,
redirect: '/supersign/developer', redirect: '/supersign/developer',
@ -215,11 +236,12 @@ export const constantRoutes = [
name: 'devices_info_list', name: 'devices_info_list',
component: () => import('@/views/supersign/devices/list'), component: () => import('@/views/supersign/devices/list'),
meta: { title: '设备消耗', icon: 'form' } meta: { title: '设备消耗', icon: 'form' }
}, }
] ]
} }
] ]
}, { },
{
path: '/settings', path: '/settings',
component: Layout, component: Layout,
redirect: '/settings/email', redirect: '/settings/email',
@ -264,7 +286,6 @@ export const constantRoutes = [
} }
] ]
}, },
{ {
path: '/nested', path: '/nested',
component: Layout, component: Layout,

@ -190,6 +190,7 @@ export default {
}, },
created() { created() {
this.listQuery.user_id = this.$route.params && this.$route.params.user_id this.listQuery.user_id = this.$route.params && this.$route.params.user_id
this.listQuery.id = this.$route.params && this.$route.params.app_id
this.fetchData() this.fetchData()
}, },
methods: { methods: {

@ -86,9 +86,7 @@
查看编辑 查看编辑
</el-button> </el-button>
</router-link> </router-link>
<el-button type="danger" size="mini" @click="deleteApp(scope.row.id)">
删除
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

@ -0,0 +1,145 @@
<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 v-if="postForm.app_info&& postForm.app_info.app_id" label="应用ID">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.app_id" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item v-if="postForm.app_info&& postForm.app_info.app_id" label="应用名称">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.app_info.name" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="域名类型">
<el-row :gutter="12">
<el-col :span="16">
<el-select v-model="postForm.domain_type" class="filter-item" disabled>
<el-option v-for="item in postForm.domain_type_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-col>
<el-col :span="12">
<el-form-item label="绑定的域名" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.domain_name" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="绑定状态" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-select v-model="postForm.is_enable" class="filter-item">
<el-option v-for="item in domain_state_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="CnameID" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.cname_id" disabled />
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-col :span="9" style="float: right">
<el-button v-if="!is_edit" type="primary" :disabled="postForm.id === postForm.used_id" @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 { getDomainInfos, updateDomainInfo } from '@/api/domain'
const domain_state_choices = [
{ id: false, name: '继续绑定' },
{ id: true, name: '绑定成功' }
]
const defaultForm = {
user_id: undefined,
app_info: undefined,
domain_type: undefined,
domain_name: undefined,
cname_id: undefined,
is_enable: undefined,
domain_type_choices: undefined,
created_time: undefined
}
export default {
name: 'OrderDetail',
components: { }, filters: {},
data() {
return {
postForm: Object.assign({}, defaultForm),
loading: false,
is_edit: false,
domain_state_choices
}
},
computed: {},
created() {
const id = this.$route.params && this.$route.params.id
this.fetchData(id)
},
methods: {
fetchData(id) {
getDomainInfos({ id: id }).then(response => {
if (response.data.length === 1) {
this.postForm = response.data[0]
}
}).catch(err => {
console.log(err)
})
},
updateData() {
updateDomainInfo(this.postForm).then(response => {
this.$message.success('更新成功')
this.postForm = response.data
}).catch(err => {
console.log(err)
})
}
}
}
</script>
<style scoped>
.editor-container {
position: relative;
height: 100%;
}
</style>

@ -0,0 +1,193 @@
<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.domain_name" placeholder="下载域名" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.app_name" placeholder="应用名称" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.domain_type" placeholder="下载域名类型" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in domain_type_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-select v-model="listQuery.is_enable" placeholder="域名绑定状态" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in domain_state_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="下载域名" min-width="280px">
<template slot-scope="scope">
{{ scope.row.domain_name }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="下载域名类型" width="160" align="center">
<template slot-scope="scope">
<router-link v-if="scope.row.domain_type===2" :to="{name: 'app_info_list',params:{user_id:scope.row.user_id,app_id:scope.row.app_id}}">
<el-tag :type="scope.row.domain_type | domainStatusFilter">{{ scope.row| domainLableFilter }}</el-tag>
</router-link>
<el-tag v-else :type="scope.row.domain_type | domainStatusFilter">{{ scope.row| domainLableFilter }}</el-tag>
</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.is_enable | statusFilter">{{ scope.row| statusLableFilter }}</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 label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template slot-scope="scope">
<router-link :to="{name: 'domain_info_edit',params:{id:scope.row.id}}">
<el-button type="primary" size="mini">
查看编辑
</el-button>
</router-link>
<el-button type="danger" size="mini" @click="remove_domain(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 { getDomainInfos, deleteDomain } from '@/api/domain'
import { baseFilter } from '@/utils'
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' }
]
const domain_state_choices = [
{ id: false, name: '继续绑定' },
{ id: true, name: '绑定成功' }
]
export default {
name: 'DomainInfo',
components: { Pagination },
directives: { waves },
filters: {
formatTime(time) {
if (time) {
return time.split('T')[0]
}
},
domainStatusFilter(status) {
const statusMap = {
'1': 'success',
'0': 'gray',
'2': 'info' }
return statusMap[status]
},
domainLableFilter(row) {
if (row.domain_type === 2) {
return '应用' + row.app_info.name + '域名'
}
return baseFilter(row.domain_type, row.domain_type_choices)
},
statusLableFilter(row) {
return baseFilter(row.is_enable, domain_state_choices)
},
statusFilter(status) {
const statusMap = {
true: 'success',
false: 'danger'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true,
total: 0,
listQuery: {
page: 1,
limit: 10,
user_id: undefined,
sort: '-created_time',
domain_name: undefined,
app_name: undefined,
domain_type: undefined,
is_enable: undefined
},
sortOptions,
domain_type_choices: [],
domain_state_choices
}
},
created() {
this.fetchData()
}, mounted() {
if (this.$route.params.user_id) {
this.listQuery.user_id = this.$route.params.user_id
}
console.log(this.$router)
},
methods: {
remove_domain(domain_id) {
deleteDomain({ id: domain_id }).then(response => {
this.list = response.data
if (this.list && this.list.length > 0) {
this.domain_type_choices = this.list[0].domain_type_choices
}
this.total = response.total
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.fetchData()
},
fetchData() {
this.listLoading = true
getDomainInfos(this.listQuery).then(response => {
this.list = response.data
if (this.list && this.list.length > 0) {
this.domain_type_choices = this.list[0].domain_type_choices
}
this.total = response.total
this.listLoading = false
})
}
}
}
</script>

@ -105,7 +105,7 @@
查看编辑 查看编辑
</el-button> </el-button>
</router-link> </router-link>
<el-button type="danger" size="mini" @click="deleteApp(scope.row.id)"> <el-button type="danger" size="mini" @click="remove_order_info(scope.row)">
删除 删除
</el-button> </el-button>
</template> </template>
@ -117,7 +117,7 @@
</template> </template>
<script> <script>
import { getOrderInfo } from '@/api/order' import { getOrderInfo, deleteOrderInfo } from '@/api/order'
import { baseFilter } from '@/utils' import { baseFilter } from '@/utils'
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
@ -207,11 +207,21 @@ export default {
created() { created() {
this.fetchData() this.fetchData()
}, mounted() { }, mounted() {
if (this.$route.query.user_id) { if (this.$route.params.user_id) {
this.listQuery.user_id = this.$route.query.user_id this.listQuery.user_id = this.$route.params.user_id
} }
}, },
methods: { methods: {
remove_order_info(order_info) {
deleteOrderInfo({ id: order_info.id }).then(response => {
this.list = response.data
if (response.code === 1000) {
this.fetchData()
} else {
this.$message.error('操作失败了 ' + response.msg)
}
})
},
handleFilter() { handleFilter() {
this.listQuery.page = 1 this.listQuery.page = 1
this.fetchData() this.fetchData()

@ -83,9 +83,7 @@
查看编辑 查看编辑
</el-button> </el-button>
</router-link> </router-link>
<el-button type="danger" size="mini" @click="deleteApp(scope.row.id)">
删除
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

@ -194,7 +194,9 @@
<el-form-item label="下载域名" prop="domain_name"> <el-form-item label="下载域名" prop="domain_name">
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="postForm.domain_name" /> <router-link v-if="postForm.id" :to="{name: 'domain_info_list',params:{user_id:postForm.id}}">
<el-button type="primary">查看下载域名绑定信息</el-button>
</router-link>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
@ -204,7 +206,9 @@
<el-input :value="postForm.download_times" disabled /> <el-input :value="postForm.download_times" disabled />
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-button>后台充值</el-button> <router-link v-if="postForm.id" :to="{name: 'order_info_list',params:{user_id:postForm.id}}">
<el-button type="primary">查看充值订单信息</el-button>
</router-link>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
@ -225,7 +229,11 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<el-col :span="9" style="float: right"> <el-col :span="9" style="float: right">
<el-col :span="8">
<el-button @click="add_amount_download_times(postForm.id)">下载次数充值</el-button>
</el-col>
<el-button v-if="!is_edit" type="primary" @click="is_edit=true">修改</el-button> <el-button v-if="!is_edit" type="primary" @click="is_edit=true">修改</el-button>
<div v-else> <div v-else>
<el-button type="primary" @click="is_edit=false">取消</el-button> <el-button type="primary" @click="is_edit=false">取消</el-button>
@ -238,6 +246,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 { createOrderInfo } from '@/api/order'
import { getStorageInfo, changeStorageInfo } from '@/api/storage' import { getStorageInfo, changeStorageInfo } from '@/api/storage'
const defaultForm = { const defaultForm = {
@ -259,6 +268,7 @@ const defaultForm = {
date_joined: undefined, date_joined: undefined,
storage_active: undefined, storage_active: undefined,
storage: undefined, storage: undefined,
certification_id: undefined,
supersign_active: undefined, supersign_active: undefined,
role_choices: [], role_choices: [],
gender_choices: [], gender_choices: [],
@ -340,6 +350,26 @@ export default {
} }
}, },
methods: { methods: {
add_amount_download_times(user_id) {
this.$prompt('请输入要充值的下载次数', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(({ value }) => {
createOrderInfo({ id: user_id, amount: parseInt(value) }).then(res => {
if (res.code === 1000) {
this.$message.success('下载次数充值成功')
this.fetchData(user_id)
}
})
}).catch((e) => {
console.log(e)
this.$message({
type: 'info',
message: '取消充值'
})
})
},
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('存储数据迁移并设置刷新成功')

@ -34,12 +34,12 @@
<el-image :src="scope.row.head_img" :preview-src-list="[scope.row.head_img]" fit="contain" style="width: 80px; height: 80px" /> <el-image :src="scope.row.head_img" :preview-src-list="[scope.row.head_img]" fit="contain" style="width: 80px; height: 80px" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="登录名"> <el-table-column label="登录名" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.username }} {{ scope.row.username }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="昵称"> <el-table-column label="昵称" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.first_name }} {{ scope.row.first_name }}
</template> </template>
@ -49,7 +49,7 @@
<span>{{ scope.row.mobile }}</span> <span>{{ scope.row.mobile }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="邮箱" width="210" align="center"> <el-table-column label="邮箱" width="200" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.email }} {{ scope.row.email }}
</template> </template>
@ -104,7 +104,7 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="100" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" width="110" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<router-link :to="{name: 'user_info_edit',params:{id:scope.row.id}}"> <router-link :to="{name: 'user_info_edit',params:{id:scope.row.id}}">
<el-button type="primary" size="mini"> <el-button type="primary" size="mini">

@ -18,8 +18,9 @@ from admin.views.login import LoginView, LoginUserView
from admin.views.user import UserInfoView, UserCertificationInfoView 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 OrderInfoView
from admin.views.supersign import DeveloperInfoView, DevicesInfoView from admin.views.supersign import DeveloperInfoView, DevicesInfoView
from admin.views.domain import DomainNameInfoView
urlpatterns = [ urlpatterns = [
# path("",include(router.urls)), # path("",include(router.urls)),
@ -36,5 +37,6 @@ urlpatterns = [
re_path("^order/info", OrderInfoView.as_view()), re_path("^order/info", OrderInfoView.as_view()),
re_path("^developer/info", DeveloperInfoView.as_view()), re_path("^developer/info", DeveloperInfoView.as_view()),
re_path("^devices/info", DevicesInfoView.as_view()), re_path("^devices/info", DevicesInfoView.as_view()),
re_path("^domain/info", DomainNameInfoView.as_view()),
] ]

@ -0,0 +1,83 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 4月
# author: liuyu
# date: 2021/4/11
from api.models import UserDomainInfo
from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication
from api.utils.serializer import AdminDomainNameSerializer
from rest_framework.views import APIView
from api.utils.response import BaseResponse
from api.utils.storage.caches import del_cache_response_by_short, reset_app_wx_easy_type
import logging
from rest_framework.pagination import PageNumberPagination
from api.utils.baseutils import get_dict_from_filter_fields
from api.base_views import app_delete
logger = logging.getLogger(__name__)
class PageNumber(PageNumberPagination):
page_size = 20 # 每页显示多少条
page_size_query_param = 'limit' # URL中每页显示条数的参数
page_query_param = 'page' # URL中页码的参数
max_page_size = None # 最大页码数限制
class DomainNameInfoView(APIView):
authentication_classes = [AdminTokenAuthentication, ]
def get(self, request):
res = BaseResponse()
filter_fields = ["id", "domain_name", "app_name", "domain_type", "user_id", "is_enable"]
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
app_name = filter_data.get('app_name', None)
if app_name:
filter_data["app_id__name__contains"] = filter_data['app_name']
del filter_data['app_name']
sort = request.query_params.get("sort", "-created_time")
page_obj = PageNumber()
obj_list = UserDomainInfo.objects.filter(**filter_data).order_by(sort)
page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request,
view=self)
serializer = AdminDomainNameSerializer(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 = UserDomainInfo.objects.filter(pk=pk).first()
if obj:
data['pk'] = pk
serializer_obj = AdminDomainNameSerializer(obj, data=data, partial=True)
if serializer_obj.is_valid():
serializer_obj.save()
res.data = serializer_obj.data
reset_app_wx_easy_type(obj.user_id, obj.app_id)
return Response(res.dict)
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)
def delete(self, request):
res = BaseResponse()
data = request.data
pk = data.get("id", None)
if not pk:
res.code = 1003
res.msg = "参数错误"
else:
user_domain_obj = UserDomainInfo.objects.filter(pk=pk).first()
reset_app_wx_easy_type(user_domain_obj.user_id, user_domain_obj.app_id)
user_domain_obj.delete()
return self.get(request)
return Response(res.dict)

@ -16,10 +16,10 @@ from django.core.cache import cache
from rest_framework.views import APIView from rest_framework.views import APIView
import binascii import binascii
import os, datetime import os, datetime
from api.utils.utils import get_captcha, valid_captcha, get_choices_dict from api.utils.utils import get_captcha, valid_captcha, get_choices_dict, get_order_num
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
from fir_ser.settings import CACHE_KEY_TEMPLATE, LOGIN from fir_ser.settings import CACHE_KEY_TEMPLATE, LOGIN
from api.utils.storage.caches import login_auth_failed from api.utils.storage.caches import login_auth_failed, update_order_info
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
@ -28,7 +28,7 @@ from api.utils.baseutils import format_storage_selection
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AppsPageNumber(PageNumberPagination): class PageNumber(PageNumberPagination):
page_size = 20 # 每页显示多少条 page_size = 20 # 每页显示多少条
page_size_query_param = 'limit' # URL中每页显示条数的参数 page_size_query_param = 'limit' # URL中每页显示条数的参数
page_query_param = 'page' # URL中页码的参数 page_query_param = 'page' # URL中页码的参数
@ -44,7 +44,7 @@ class OrderInfoView(APIView):
"order_type"] "order_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 = PageNumber()
obj_list = Order.objects.filter(**filter_data).order_by(sort) obj_list = Order.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)
@ -62,10 +62,15 @@ class OrderInfoView(APIView):
res.msg = "参数错误" res.msg = "参数错误"
return Response(res.dict) return Response(res.dict)
obj = Order.objects.filter(pk=pk).first() obj = Order.objects.filter(pk=pk).first()
old_status = obj.status
new_status = data.get('status', -99)
if obj: if obj:
data['pk'] = pk data['pk'] = pk
serializer = AdminOrdersSerializer(obj, data=data, partial=True) serializer = AdminOrdersSerializer(obj, data=data, partial=True)
if serializer.is_valid(): if serializer.is_valid():
if old_status != new_status and new_status == 0:
update_order_info(obj.user_id.pk, obj.order_number, obj.order_number, obj.payment_type)
else:
serializer.save() serializer.save()
res.data = serializer.data res.data = serializer.data
return Response(res.dict) return Response(res.dict)
@ -73,29 +78,40 @@ class OrderInfoView(APIView):
res.msg = "数据校验失败" res.msg = "数据校验失败"
return Response(res.dict) return Response(res.dict)
def delete(self, request):
res = BaseResponse()
data = request.data
pk = data.get("id", None)
if not pk:
res.code = 1003
res.msg = "参数错误"
else:
order_obj = Order.objects.filter(pk=pk).first()
order_obj.delete()
return Response(res.dict)
class OrderPayView(APIView): def post(self, request):
authentication_classes = [AdminTokenAuthentication, ]
def put(self, request):
res = BaseResponse() res = BaseResponse()
data = request.data data = request.data
pk = data.get("id", None) pk = data.get("id", None)
amount = data.get("amount", 0)
if not pk: if not pk:
res.code = 1003 res.code = 1003
res.msg = "参数错误" res.msg = "参数错误"
return Response(res.dict) return Response(res.dict)
obj = UserInfo.objects.filter(pk=pk).first() obj = UserInfo.objects.filter(pk=pk).first()
if obj: if obj:
logger.info(f"user {obj} update storage data:{data}") if amount > 0:
use_storage_id = data.get("use_storage_id", None) order_number = get_order_num()
force = data.get("force", None) order_obj = Order.objects.create(payment_type=2, order_number=order_number, payment_number=order_number,
if use_storage_id: user_id=obj, status=1, order_type=1, actual_amount=0,
if not storage_change(use_storage_id, obj, force): actual_download_times=amount, payment_name='后台管理员充值',
res.code = 1006 actual_download_gift_times=0)
res.msg = '修改失败' if update_order_info(obj.pk, order_obj.order_number, order_obj.order_number, order_obj.payment_type):
return Response(res.dict) return Response(res.dict)
else:
res.code = 1005
res.msg = "订单创建失败"
res.code = 1004 res.code = 1004
res.msg = "数据校验失败" res.msg = "数据校验失败"
return Response(res.dict) return Response(res.dict)

@ -129,6 +129,10 @@ def get_dict_from_filter_fields(filter_fields, data):
for filed in filter_fields: for filed in filter_fields:
f_value = data.get(filed, None) f_value = data.get(filed, None)
if f_value: if f_value:
if f_value == 'true':
f_value = True
if f_value == 'false':
f_value = False
filter_data[filed] = f_value filter_data[filed] = f_value
return filter_data return filter_data

@ -604,3 +604,15 @@ class DomainNameSerializer(serializers.ModelSerializer):
} }
return app_info return app_info
return {} return {}
class AdminDomainNameSerializer(DomainNameSerializer):
class Meta:
model = models.UserDomainInfo
fields = "__all__"
read_only_fields = ["id", "app_id", "domain_type", "created_time", "cname_id"]
domain_type_choices = serializers.SerializerMethodField()
def get_domain_type_choices(self, obj):
return get_choices_dict(obj.domain_type_choices)

@ -435,7 +435,6 @@ def update_order_info(user_id, out_trade_no, payment_number, payment_type):
try: try:
order_obj.status = 0 order_obj.status = 0
order_obj.payment_type = payment_type order_obj.payment_type = payment_type
order_obj.order_type = 0
order_obj.payment_number = payment_number order_obj.payment_number = payment_number
now = timezone.now() now = timezone.now()
if not timezone.is_naive(now): if not timezone.is_naive(now):

Loading…
Cancel
Save