Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-book
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-book
Commits
1710568d
提交
1710568d
authored
8月 11, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 添加订单导出和删除功能,更新订单查询条件,优化订单列表视图
上级
73818823
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
109 行增加
和
12 行删除
+109
-12
api.ts
apps/admin/src/modules/books/orders/api.ts
+18
-0
query.ts
apps/admin/src/modules/books/orders/query.ts
+3
-0
OrdersListView.tsx
apps/admin/src/modules/books/orders/views/OrdersListView.tsx
+81
-6
userStore.ts
apps/admin/src/stores/userStore.ts
+1
-0
vite.config.js
apps/admin/vite.config.js
+6
-6
没有找到文件。
apps/admin/src/modules/books/orders/api.ts
浏览文件 @
1710568d
...
...
@@ -16,6 +16,10 @@ export interface OrderRow {
status_name
?:
string
pay_type
?:
number
|
string
pay_type_name
?:
string
transaction_id
?:
string
|
number
trade_no
?:
string
|
number
original_transaction_id
?:
string
|
number
transaction_no
?:
string
rating
?:
number
}
...
...
@@ -69,6 +73,14 @@ export async function getOrders(query: OrdersQuery): Promise<OrdersListResult> {
return
{
rows
:
data
.
list
??
[],
total
:
data
.
total
??
0
}
}
export
async
function
exportOrders
(
query
:
OrdersQuery
)
{
const
data
=
await
getPayload
<
{
name
?:
string
;
download_url
?:
string
}
>
(
'/api/admin/order/export'
,
query
,
)
return
data
}
export
function
getSalesStatistics
()
{
return
getPayload
<
SalesStatisticsResult
>
(
'/api/admin/order/salesStatistics'
)
}
...
...
@@ -78,3 +90,9 @@ export async function refundOrder(id: number, refund_reason?: string) {
notifySuccess
(
response
.
message
)
return
true
}
export
async
function
deleteOrder
(
id
:
number
)
{
const
response
=
await
axios
.
post
(
'/api/admin/order/del'
,
{
id
})
notifySuccess
(
response
.
message
)
return
true
}
apps/admin/src/modules/books/orders/query.ts
浏览文件 @
1710568d
...
...
@@ -2,6 +2,7 @@ import type { Dayjs } from 'dayjs'
export
interface
OrdersFilters
{
book_name
?:
string
members_name
?:
string
status
?:
string
|
null
pay_type
?:
string
|
null
pay_time
?:
[
Dayjs
|
null
,
Dayjs
|
null
]
|
null
...
...
@@ -11,6 +12,7 @@ export interface OrdersQuery {
page
:
number
page_size
:
number
book_name
?:
string
members_name
?:
string
status
?:
string
pay_type
?:
string
start_pay
?:
number
...
...
@@ -26,6 +28,7 @@ interface BuildOrdersQueryInput {
export
function
buildOrdersQuery
({
page
,
pageSize
,
filters
}:
BuildOrdersQueryInput
):
OrdersQuery
{
const
query
:
OrdersQuery
=
{
page
,
page_size
:
pageSize
}
if
(
filters
.
book_name
)
query
.
book_name
=
filters
.
book_name
if
(
filters
.
members_name
)
query
.
members_name
=
filters
.
members_name
if
(
filters
.
status
)
query
.
status
=
filters
.
status
if
(
filters
.
pay_type
)
query
.
pay_type
=
filters
.
pay_type
if
(
filters
.
pay_time
?.[
0
]
&&
filters
.
pay_time
[
1
])
{
...
...
apps/admin/src/modules/books/orders/views/OrdersListView.tsx
浏览文件 @
1710568d
import
{
Button
,
DatePicker
,
Input
,
Rate
,
Select
,
Tooltip
}
from
'antd'
import
{
Button
,
DatePicker
,
Input
,
Popconfirm
,
Rate
,
Select
,
Tooltip
}
from
'antd'
import
{
DownloadOutlined
}
from
'@ant-design/icons'
import
type
{
ColumnsType
}
from
'antd/es/table'
import
{
saveAs
}
from
'file-saver'
import
{
useState
}
from
'react'
import
wechatIcon
from
'@/assets/images/vx.png'
...
...
@@ -8,17 +10,23 @@ import coinIcon from '@/assets/images/money.png'
import
appleIcon
from
'@/assets/images/apple.svg'
import
{
AppList
,
type
AppListFilterItem
}
from
'@/components/AppList'
import
{
usePermission
}
from
'@/hooks/usePermission'
import
{
useUserStore
}
from
'@/stores/userStore'
import
{
refundOrder
,
type
OrderRow
}
from
'../api'
import
{
deleteOrder
,
exportOrders
,
refundOrder
,
type
OrderRow
}
from
'../api'
import
RefundDrawer
from
'../components/RefundDrawer'
import
type
{
OrdersFilters
}
from
'../query'
import
{
buildOrdersQuery
,
type
OrdersFilters
}
from
'../query'
import
{
useOrdersList
}
from
'../useOrdersList'
const
{
RangePicker
}
=
DatePicker
export
default
function
OrdersListView
()
{
const
list
=
useOrdersList
()
const
checkPermission
=
usePermission
()
const
userInfo
=
useUserStore
((
state
)
=>
state
.
userInfo
)
const
[
refundId
,
setRefundId
]
=
useState
<
number
|
null
>
(
null
)
const
[
exporting
,
setExporting
]
=
useState
(
false
)
const
[
deletingId
,
setDeletingId
]
=
useState
<
number
|
null
>
(
null
)
const
canDelete
=
userInfo
.
tel
===
'13811534871'
const
submitRefund
=
async
({
refund_reason
}:
{
refund_reason
?:
string
})
=>
{
if
(
refundId
===
null
)
return
...
...
@@ -28,6 +36,29 @@ export default function OrdersListView() {
setRefundId
(
null
)
}
const
handleExport
=
async
()
=>
{
setExporting
(
true
)
try
{
const
result
=
await
exportOrders
(
buildOrdersQuery
({
page
:
1
,
pageSize
:
list
.
pageSize
,
filters
:
list
.
filters
}),
)
if
(
!
result
.
name
||
!
result
.
download_url
)
return
saveAs
(
`/api/admin
${
result
.
download_url
}
`
,
result
.
name
)
}
finally
{
setExporting
(
false
)
}
}
const
handleDelete
=
async
(
id
:
number
)
=>
{
setDeletingId
(
id
)
try
{
await
deleteOrder
(
id
)
list
.
refresh
()
}
finally
{
setDeletingId
(
null
)
}
}
const
columns
:
ColumnsType
<
OrderRow
>
=
[
{
title
:
'订单编号'
,
key
:
'id'
,
dataIndex
:
'id'
,
align
:
'center'
},
{
title
:
'书籍名称'
,
key
:
'book_name'
,
dataIndex
:
'book_name'
,
align
:
'center'
,
width
:
150
},
...
...
@@ -74,6 +105,13 @@ export default function OrdersListView() {
)
},
},
{
title
:
'交易流水号'
,
key
:
'transaction_no'
,
dataIndex
:
'transaction_no'
,
align
:
'center'
,
width
:
180
,
},
{
title
:
'评价'
,
key
:
'rating'
,
...
...
@@ -88,9 +126,21 @@ export default function OrdersListView() {
dataIndex
:
'handle'
,
align
:
'center'
,
render
:
(
_
,
record
)
=>
checkPermission
(
'/books/order-management/refund'
)
&&
Number
(
record
.
status
)
===
3
?
(
<>
{
checkPermission
(
'/books/order-management/refund'
)
&&
Number
(
record
.
status
)
===
3
?
(
<
Button
onClick=
{
()
=>
setRefundId
(
record
.
id
)
}
>
退款
</
Button
>
)
:
null
,
)
:
null
}
{
canDelete
&&
checkPermission
(
'/books/order-management/delete'
)
?
(
<
Popconfirm
title=
'确定删除这个订单吗?'
okText=
'删除'
cancelText=
'取消'
onConfirm=
{
()
=>
handleDelete
(
record
.
id
)
}
>
<
Button
danger
style=
{
{
marginLeft
:
8
}
}
loading=
{
deletingId
===
record
.
id
}
>
删除
</
Button
>
</
Popconfirm
>
)
:
null
}
</>,
},
]
...
...
@@ -109,6 +159,19 @@ export default function OrdersListView() {
/>
),
},
{
name
:
'members_name'
,
label
:
'购买人'
,
render
:
(
field
)
=>
(
<
Input
allowClear
autoComplete=
"off"
placeholder=
"请输入购买人名称"
value=
{
field
.
value
??
''
}
onChange=
{
(
event
)
=>
field
.
onChange
(
event
.
target
.
value
)
}
/>
),
},
{
name
:
'status'
,
label
:
'支付状态'
,
...
...
@@ -167,7 +230,7 @@ export default function OrdersListView() {
<
AppList
<
OrderRow
,
OrdersFilters
>
rowKey="id"
columns=
{
columns
}
data=
{
{
rows
:
list
.
rows
,
total
:
list
.
total
,
loading
:
list
.
loading
,
error
:
list
.
error
}
}
data=
{
{
rows
:
list
.
rows
,
total
:
list
.
total
,
loading
:
list
.
loading
||
exporting
,
error
:
list
.
error
}
}
filters=
{
{
value
:
list
.
filters
,
items
:
filterItems
,
...
...
@@ -183,6 +246,18 @@ export default function OrdersListView() {
onChange
:
list
.
changePage
,
onPageSizeChange
:
list
.
changePageSize
,
}
}
toolbar=
{
checkPermission
(
'/books/order-management/export'
)
?
(
<
Button
type=
'primary'
icon=
{
<
DownloadOutlined
/>
}
loading=
{
exporting
}
onClick=
{
handleExport
}
>
导出
</
Button
>
)
:
null
}
onRetry=
{
list
.
retry
}
/
>
<
RefundDrawer
open=
{
refundId
!==
null
}
onClose=
{
()
=>
setRefundId
(
null
)
}
onSubmit=
{
submitRefund
}
/>
...
...
apps/admin/src/stores/userStore.ts
浏览文件 @
1710568d
...
...
@@ -10,6 +10,7 @@ export interface TreeChapter {
export
interface
UserInfo
{
id
?:
number
type
?:
number
tel
?:
string
[
key
:
string
]:
unknown
}
...
...
apps/admin/vite.config.js
浏览文件 @
1710568d
...
...
@@ -15,13 +15,13 @@ export default defineConfig(() => {
port
:
5174
,
strictPort
:
true
,
proxy
:
{
'/api/admin'
:
{
target
:
'http://127.0.0.1:7419'
,
changeOrigin
:
true
,
secure
:
false
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
admin/
,
''
),
},
'/api'
:
'https://zijingebook.ezijing.com'
,
// '/api/admin': {
// target: 'http://127.0.0.1:7419',
// changeOrigin: true,
// secure: false,
// rewrite: (path) => path.replace(/^\/api\/admin/, ''),
// },
},
},
build
:
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论