订单页面展示

v1.0.0
youngS 4 years ago
parent 87ae640c51
commit 54e9de66b6
  1. 18
      fir_admin/src/api/order.js
  2. 13
      fir_admin/src/router/index.js
  3. 8
      fir_admin/src/utils/index.js
  4. 7
      fir_admin/src/views/appinfos/AppReleaseList.vue
  5. 7
      fir_admin/src/views/appinfos/list.vue
  6. 29
      fir_admin/src/views/authentication/list.vue
  7. 180
      fir_admin/src/views/order/Detail.vue
  8. 232
      fir_admin/src/views/order/list.vue
  9. 7
      fir_admin/src/views/userinfos/list.vue
  10. 2
      fir_ser/admin/urls.py
  11. 101
      fir_ser/admin/views/order.py
  12. 49
      fir_ser/api/migrations/0043_auto_20210420_1422.py
  13. 17
      fir_ser/api/migrations/0044_auto_20210422_1002.py
  14. 4
      fir_ser/api/models.py
  15. 23
      fir_ser/api/utils/serializer.py
  16. 2
      fir_ser/api/utils/storage/caches.py
  17. 8
      fir_ser/api/views/order.py

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

@ -172,10 +172,17 @@ export const constantRoutes = [
component: Layout, component: Layout,
children: [ children: [
{ {
path: 'index', path: 'list',
name: 'index', name: 'order_info_list',
component: () => import('@/views/form/index'), component: () => import('@/views/order/list'),
meta: { title: '订单管理', icon: 'form' } meta: { title: '订单管理', icon: 'form' }
},
{
path: 'edit/:id(\\d+)',
component: () => import('@/views/order/Detail'),
name: 'order_info_edit',
meta: { title: '编辑信息', noCache: true, activeMenu: '/order/list' },
hidden: true
} }
] ]
}, },

@ -115,3 +115,11 @@ export function param2Obj(url) {
}) })
return obj return obj
} }
export function baseFilter(id, choices) {
for (const v of choices) {
if (v.id === id) {
return v.name
}
}
}

@ -84,6 +84,7 @@
<script> <script>
import { getAppReleaseInfos } from '@/api/app' import { getAppReleaseInfos } from '@/api/app'
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
@ -108,11 +109,7 @@ export default {
return statusMap[status] return statusMap[status]
}, },
appStatusNameFilter(row) { appStatusNameFilter(row) {
for (const r of row.release_choices) { return baseFilter(row.release_type, row.release_choices)
if (r.id === row.release_type) {
return r.name
}
}
}, },
appStatusFilter(status) { appStatusFilter(status) {
const statusMap = { const statusMap = {

@ -128,6 +128,7 @@
<script> <script>
import { getAppInfos, deleteApp } from '@/api/app' import { getAppInfos, deleteApp } from '@/api/app'
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
@ -156,11 +157,7 @@ export default {
return statusMap[status] return statusMap[status]
}, },
appStatusNameFilter(row) { appStatusNameFilter(row) {
for (const r of row.status_choices) { return baseFilter(row.status,row.status_choices)
if (r.id === row.status) {
return r.name
}
}
}, },
appStatusFilter(status) { appStatusFilter(status) {
const statusMap = { const statusMap = {

@ -99,6 +99,7 @@
<script> <script>
import { getCertificationInfo } from '@/api/user' import { getCertificationInfo } from '@/api/user'
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
@ -127,33 +128,7 @@ export default {
return statusMap[status] return statusMap[status]
}, },
certLableFilter(row) { certLableFilter(row) {
for (const v of row.certification_status_choices) { return baseFilter(row.status, 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() { data() {

@ -0,0 +1,180 @@
<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.payment_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.payment_type" class="filter-item" disabled>
<el-option v-for="item in postForm.payment_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-form-item label="支付时间" prop="timestamp">
<el-row :gutter="20">
<el-col :span="8">
<el-date-picker :value="postForm.pay_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.description" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" />
</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.order_number" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="第3方订单号" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.payment_number" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="支付金额" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.actual_amount" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="购买数量" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.actual_download_times" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="赠送数量" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.actual_download_gift_times" disabled />
</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.order_type" class="filter-item" disabled>
<el-option v-for="item in postForm.order_type_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</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.status" class="filter-item">
<el-option v-for="item in postForm.status_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</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 { getOrderInfo, updateOrderInfo } from '@/api/order'
const defaultForm = {
user_id: undefined,
payment_type: undefined,
payment_number: undefined,
payment_name: undefined,
order_number: undefined,
actual_amount: undefined,
actual_download_times: undefined,
actual_download_gift_times: undefined,
description: undefined,
status: undefined,
order_type: undefined,
pay_time: undefined,
created_time: undefined
}
export default {
name: 'OrderDetail',
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) {
getOrderInfo({ id: id }).then(response => {
if (response.data.length === 1) {
this.postForm = response.data[0]
}
}).catch(err => {
console.log(err)
})
},
updateData() {
updateOrderInfo(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,232 @@
<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.payment_number" placeholder="payment_number" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.order_number" placeholder="order_number" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.payment_name" placeholder="支付商家" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.payment_type" placeholder="支付类型" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in payment_type_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-select v-model="listQuery.status" placeholder="订单状态" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in status_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-select v-model="listQuery.order_type" placeholder="订单类型" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in order_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="支付商家" width="80px">
<template slot-scope="scope">
{{ scope.row.payment_name }}
</template>
</el-table-column>
<el-table-column label="订单号" align="center">
<template slot-scope="scope">
<span>{{ scope.row.order_number }}</span>
</template>
</el-table-column>
<el-table-column label="第三方订单号" align="center">
<template slot-scope="scope">
<span>{{ scope.row.payment_number }}</span>
</template>
</el-table-column>
<el-table-column label="实付金额" align="center" width="80px">
<template slot-scope="scope">
{{ scope.row.actual_amount }}
</template>
</el-table-column>
<el-table-column label="购买数量" align="center" width="90px">
<template slot-scope="scope">
{{ scope.row.actual_download_times }}
</template>
</el-table-column>
<el-table-column label="赠送数量" align="center" width="90px">
<template slot-scope="scope">
{{ scope.row.actual_download_gift_times }}
</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.payment_type | payStatusFilter">{{ scope.row| payLableFilter }}</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.status | certStatusFilter">{{ 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 align="center" prop="created_time" label="支付时间" width="120">
<template slot-scope="scope">
<i class="el-icon-time" />
<el-tooltip :content="scope.row.pay_time">
<span>{{ scope.row.pay_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: 'order_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 { getOrderInfo } from '@/api/order'
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: 'reviewed_time' },
{ label: '创建时间 Descending', key: '-reviewed_time' },
]
export default {
name: 'OrderInfo',
components: { Pagination },
directives: { waves },
filters: {
formatTime(time) {
if (time) {
return time.split('T')[0]
}
},
payStatusFilter(status) {
const statusMap = {
'0': 'gray',
'1': 'success' }
return statusMap[status]
},
certStatusFilter(status) {
const statusMap = {
'0': 'success',
'1': 'info',
'2': 'gray' }
return statusMap[status]
},
payLableFilter(row) {
return baseFilter(row.payment_type, row.payment_type_choices)
},
statusLableFilter(row) {
return baseFilter(row.status, row.status_choices)
},
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,
user_id: undefined,
sort: '-created_time',
payment_type: undefined,
payment_name: undefined,
payment_number: undefined,
order_number: undefined,
status: undefined,
order_type: undefined
},
sortOptions,
payment_type_choices: [],
status_choices: [],
order_type_choices: []
}
},
created() {
this.fetchData()
}, mounted() {
if (this.$route.query.user_id) {
this.listQuery.user_id = this.$route.query.user_id
}
},
methods: {
handleFilter() {
this.listQuery.page = 1
this.fetchData()
},
fetchData() {
this.listLoading = true
getOrderInfo(this.listQuery).then(response => {
this.list = response.data
if (this.list && this.list.length > 0) {
this.payment_type_choices = this.list[0].payment_type_choices
this.status_choices = this.list[0].status_choices
this.order_type_choices = this.list[0].order_type_choices
}
this.total = response.total
this.listLoading = false
})
}
}
}
</script>

@ -108,6 +108,7 @@
<script> <script>
import { getUserInfos } from '@/api/user' import { getUserInfos } from '@/api/user'
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
@ -143,11 +144,7 @@ export default {
return statusMap[status] return statusMap[status]
}, },
certLableFilter(row) { certLableFilter(row) {
for (const v of row.certification_status_choices) { return baseFilter(row.certification,row.certification_status_choices)
if (v.id === row.certification) {
return v.name
}
}
} }
}, },
data() { data() {

@ -18,6 +18,7 @@ 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
urlpatterns = [ urlpatterns = [
# path("",include(router.urls)), # path("",include(router.urls)),
@ -31,5 +32,6 @@ urlpatterns = [
re_path("^certification/info", UserCertificationInfoView.as_view()), re_path("^certification/info", UserCertificationInfoView.as_view()),
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()),
] ]

@ -0,0 +1,101 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 4月
# author: liuyu
# date: 2021/4/11
from django.contrib import auth
from api.base_views import storage_change
from api.models import Token, UserInfo, Order
from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication
from api.utils.baseutils import get_dict_from_filter_fields
from api.utils.serializer import AdminStorageSerializer, AdminUserCertificationSerializer, AdminOrdersSerializer
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
from api.utils.baseutils import format_storage_selection
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 OrderInfoView(APIView):
authentication_classes = [AdminTokenAuthentication, ]
def get(self, request):
res = BaseResponse()
filter_fields = ["id", "user_id", "payment_type", "payment_name", "payment_number", "order_number", "status",
"order_type"]
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
sort = request.query_params.get("sort", "-created_time")
page_obj = AppsPageNumber()
obj_list = Order.objects.filter(**filter_data).order_by(sort)
page_serializer = page_obj.paginate_queryset(queryset=obj_list, request=request,
view=self)
serializer = AdminOrdersSerializer(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 = Order.objects.filter(pk=pk).first()
if obj:
data['pk'] = pk
serializer = AdminOrdersSerializer(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 OrderPayView(APIView):
authentication_classes = [AdminTokenAuthentication, ]
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 = UserInfo.objects.filter(pk=pk).first()
if obj:
logger.info("user %s update storage data:%s" % (obj, data))
use_storage_id = data.get("use_storage_id", None)
force = data.get("force", None)
if use_storage_id:
if not storage_change(use_storage_id, obj, force):
res.code = 1006
res.msg = '修改失败'
return Response(res.dict)
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)

@ -0,0 +1,49 @@
# Generated by Django 3.0.3 on 2021-04-20 14:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0042_order_payment_name'),
]
operations = [
migrations.RemoveField(
model_name='appstorage',
name='additionalparameters',
),
migrations.AddField(
model_name='appstorage',
name='cnd_auth_key',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='阿里云cnd_auth_key'),
),
migrations.AddField(
model_name='appstorage',
name='download_auth_type',
field=models.SmallIntegerField(
choices=[(1, 'OSS模式: 需要把OSS权限开启私有模式'), (2, 'CDN模式: 请先配置好阿里云CDN,开启阿里云OSS私有Bucket回源,将使用鉴权A方式')],
default=1, verbose_name='阿里云下载授权方式'),
),
migrations.AddField(
model_name='appstorage',
name='endpoint',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='阿里云endpoint'),
),
migrations.AddField(
model_name='appstorage',
name='sts_role_arn',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='阿里云sts_role_arn'),
),
migrations.AlterField(
model_name='usercertificationinfo',
name='addr',
field=models.CharField(max_length=128, verbose_name='居住地址'),
),
migrations.AlterField(
model_name='usercertificationinfo',
name='status',
field=models.SmallIntegerField(choices=[(-1, '待认证'), (0, '认证中'), (1, '认证成功'), (2, '认证失败')], default=0,
verbose_name='认证状态'),
),
]

@ -0,0 +1,17 @@
# Generated by Django 3.0.3 on 2021-04-22 10:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0043_auto_20210420_1422'),
]
operations = [
migrations.RenameField(
model_name='order',
old_name='account',
new_name='user_id',
),
]

@ -368,7 +368,7 @@ class Order(models.Model):
payment_number = models.CharField(max_length=128, verbose_name="支付第3方订单号", null=True, blank=True) payment_number = models.CharField(max_length=128, verbose_name="支付第3方订单号", null=True, blank=True)
payment_name = models.CharField(max_length=128, verbose_name="支付商家名称", null=True, blank=True) payment_name = models.CharField(max_length=128, verbose_name="支付商家名称", null=True, blank=True)
order_number = models.CharField(max_length=128, verbose_name="订单号", unique=True) # 考虑到订单合并支付的问题 order_number = models.CharField(max_length=128, verbose_name="订单号", unique=True) # 考虑到订单合并支付的问题
account = models.ForeignKey("UserInfo", on_delete=models.CASCADE) user_id = models.ForeignKey("UserInfo", on_delete=models.CASCADE)
actual_amount = models.BigIntegerField(verbose_name="实付金额,单位分") actual_amount = models.BigIntegerField(verbose_name="实付金额,单位分")
actual_download_times = models.BigIntegerField(verbose_name="实际购买的数量", default=0) actual_download_times = models.BigIntegerField(verbose_name="实际购买的数量", default=0)
actual_download_gift_times = models.BigIntegerField(verbose_name="实际赠送的数量", default=0) actual_download_gift_times = models.BigIntegerField(verbose_name="实际赠送的数量", default=0)
@ -383,7 +383,7 @@ class Order(models.Model):
def __str__(self): def __str__(self):
return "%s-%s-%s" % (self.account, self.order_number, self.actual_amount / 100) return "%s-%s-%s" % (self.user_id, self.order_number, self.actual_amount / 100)
class Price(models.Model): class Price(models.Model):

@ -448,6 +448,29 @@ class OrdersSerializer(serializers.ModelSerializer):
exclude = ["id"] exclude = ["id"]
class AdminOrdersSerializer(serializers.ModelSerializer):
class Meta:
model = models.Order
fields = "__all__"
read_only_fields = ["id", "user_id", "updated_time", "created_time", "payment_number", "order_number",
"payment_name", "actual_amount", "actual_download_times", "actual_download_gift_times"]
payment_type_choices = serializers.SerializerMethodField()
def get_payment_type_choices(self, obj):
return get_choices_dict(obj.payment_type_choices)
status_choices = serializers.SerializerMethodField()
def get_status_choices(self, obj):
return get_choices_dict(obj.status_choices)
order_type_choices = serializers.SerializerMethodField()
def get_order_type_choices(self, obj):
return get_choices_dict(obj.order_type_choices)
class CertificationSerializer(serializers.ModelSerializer): class CertificationSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.CertificationInfo model = models.CertificationInfo

@ -415,7 +415,7 @@ def update_order_info(user_id, out_trade_no, payment_number, payment_type):
with cache.lock("%s_%s" % ('user_order_', out_trade_no)): with cache.lock("%s_%s" % ('user_order_', out_trade_no)):
try: try:
user_obj = UserInfo.objects.filter(pk=user_id).first() user_obj = UserInfo.objects.filter(pk=user_id).first()
order_obj = Order.objects.filter(account=user_obj, order_number=out_trade_no).first() order_obj = Order.objects.filter(user_id=user_obj, order_number=out_trade_no).first()
if order_obj: if order_obj:
if order_obj.status == 1: if order_obj.status == 1:
download_times = order_obj.actual_download_times + order_obj.actual_download_gift_times download_times = order_obj.actual_download_times + order_obj.actual_download_gift_times

@ -32,7 +32,7 @@ class OrderView(APIView):
def get(self, request): def get(self, request):
res = BaseResponse() res = BaseResponse()
order_id = request.query_params.get("order_id", None) order_id = request.query_params.get("order_id", None)
order_obj_lists = Order.objects.filter(account=request.user) order_obj_lists = Order.objects.filter(user_id=request.user)
if order_id: if order_id:
order_obj_lists = order_obj_lists.filter(order_number=order_id) order_obj_lists = order_obj_lists.filter(order_number=order_id)
page_obj = PageNumber() page_obj = PageNumber()
@ -56,7 +56,7 @@ class OrderView(APIView):
order_number = request.data.get("order_number", None) order_number = request.data.get("order_number", None)
if (price_id and pay_id) or order_number: if (price_id and pay_id) or order_number:
price_obj = Price.objects.filter(name=price_id).first() price_obj = Price.objects.filter(name=price_id).first()
order_obj = Order.objects.filter(account=request.user, order_number=order_number).first() order_obj = Order.objects.filter(user_id=request.user, order_number=order_number).first()
if order_obj and order_obj.status in [1, 2] and order_obj.payment_name: if order_obj and order_obj.status in [1, 2] and order_obj.payment_name:
pay_obj = get_pay_obj_form_name(order_obj.payment_name) pay_obj = get_pay_obj_form_name(order_obj.payment_name)
pay_url = pay_obj.get_pay_pc_url(order_number, int(order_obj.actual_amount), pay_url = pay_obj.get_pay_pc_url(order_number, int(order_obj.actual_amount),
@ -71,7 +71,7 @@ class OrderView(APIView):
pay_obj = get_pay_obj_form_name(pay_id) pay_obj = get_pay_obj_form_name(pay_id)
pay_url = pay_obj.get_pay_pc_url(order_number, int(actual_amount), {'user_id': request.user.id}) pay_url = pay_obj.get_pay_pc_url(order_number, int(actual_amount), {'user_id': request.user.id})
Order.objects.create(payment_type=get_payment_type(pay_obj.p_type), order_number=order_number, Order.objects.create(payment_type=get_payment_type(pay_obj.p_type), order_number=order_number,
account=request.user, status=1, order_type=0, actual_amount=actual_amount, user_id=request.user, status=1, order_type=0, actual_amount=actual_amount,
actual_download_times=price_obj.package_size, payment_name=pay_obj.name, actual_download_times=price_obj.package_size, payment_name=pay_obj.name,
actual_download_gift_times=price_obj.download_count_gift) actual_download_gift_times=price_obj.download_count_gift)
res.data = pay_url res.data = pay_url
@ -95,7 +95,7 @@ class OrderView(APIView):
order_number = request.data.get("order_number", None) order_number = request.data.get("order_number", None)
act = request.data.get("act", None) act = request.data.get("act", None)
if order_number: if order_number:
order_obj = Order.objects.filter(account=request.user, order_number=order_number).first() order_obj = Order.objects.filter(user_id=request.user, order_number=order_number).first()
if order_obj: if order_obj:
try: try:
if act == 'cancel' and order_obj.status != 0: if act == 'cancel' and order_obj.status != 0:

Loading…
Cancel
Save