This commit is contained in:
liu
2026-08-14 20:21:50 +08:00
parent 4a5b7003ca
commit 03434feb35
21 changed files with 1513 additions and 629 deletions
+70 -44
View File
@@ -4,46 +4,46 @@ import { View, Text, ScrollView } from '@tarojs/components'
import { Empty, Popup } from '@antmjs/vantui'
import useAuthStore from '@/stores/auth/useAuthStore'
import { cancelOrderApi, getOrderDetailApi, getOrderListApi } from '@/services/order'
import { ORDER_NAV_ITEMS, ORDER_STATUS_MAP } from '@/types/order'
import type { Order, OrderStatus } from '@/types/order'
import { ORDER_STATUS_FILTERS, ORDER_STATUS_TEXT } from '@/types/order'
import type { OrderDetail, OrderListItem, OrderStatus } from '@/types/order'
import './index.less'
const PAGE_SIZE = 10
/**
* 订单列表页(框架)
* 入口:/pages/order-list/index?status=0|1|2|3|9|all
* status 与 ORDER_NAV_ITEMS 映射(业务语言 → 后端枚举),缺省为全部
* 订单列表页
* 入口:/pages/order-list/index?status=0|1|2|3|4|9|all
* 状态文案一律使用接口返回的 status_name(详情接口无该字段时沿用列表行)
*/
export default function OrderListPage() {
const router = useRouter()
const token = useAuthStore(s => s.token)
/** 当前状态筛选(undefined = 全部) */
const [status, setStatus] = useState<number | undefined>(undefined)
const [orders, setOrders] = useState<Order[]>([])
const [status, setStatus] = useState<OrderStatus | undefined>(undefined)
const [orders, setOrders] = useState<OrderListItem[]>([])
const [page, setPage] = useState(1)
const [total, setTotal] = useState(0)
const [loading, setLoading] = useState(false)
const [finished, setFinished] = useState(false)
const loadingRef = useRef(false)
/** 订单详情弹层 */
/** 订单详情弹层statusName 沿用列表行,详情接口不返回 status_name */
const [showDetail, setShowDetail] = useState(false)
const [orderDetail, setOrderDetail] = useState<Order | null>(null)
const [orderDetail, setOrderDetail] = useState<OrderDetail | null>(null)
const [detailStatusName, setDetailStatusName] = useState('')
const loggedIn = !!token
/** 解析路由参数中的 status'all' / 数字 / 缺省 → undefined */
const parseStatus = useCallback((raw?: string): number | undefined => {
const parseStatus = useCallback((raw?: string): OrderStatus | undefined => {
if (!raw || raw === 'all' || raw === '') return undefined
const num = Number(raw)
return Number.isNaN(num) ? undefined : num
return Number.isNaN(num) ? undefined : (num as OrderStatus)
}, [])
/** 拉取订单列表 */
const loadOrders = useCallback(
async (pageNum: number, reset: boolean, statusParam?: number) => {
async (pageNum: number, reset: boolean, statusParam?: OrderStatus) => {
if (!loggedIn || loadingRef.current) return
loadingRef.current = true
setLoading(true)
@@ -53,11 +53,10 @@ export default function OrderListPage() {
page: pageNum,
pageSize: PAGE_SIZE,
})
const { data, total: totalCount } = res.data
const { data, total } = res.data
setOrders(prev => (reset ? data : [...prev, ...data]))
setTotal(totalCount)
setPage(pageNum)
setFinished(pageNum * PAGE_SIZE >= totalCount)
setFinished(pageNum * PAGE_SIZE >= total)
} catch {
// 错误已由 request 层 toast
} finally {
@@ -82,7 +81,7 @@ export default function OrderListPage() {
/** 切换状态筛选 */
const handleStatusTap = useCallback(
(value?: number) => {
(value?: OrderStatus) => {
setStatus(value)
setFinished(false)
loadOrders(1, true, value)
@@ -91,19 +90,20 @@ export default function OrderListPage() {
)
/** 查看订单详情 */
const handleOrderTap = useCallback(async (order: Order) => {
const handleOrderTap = useCallback(async (order: OrderListItem) => {
try {
const res = await getOrderDetailApi(order.id)
setOrderDetail(res.data)
setDetailStatusName(order.status_name)
setShowDetail(true)
} catch {
// 错误已由 request 层 toast
}
}, [])
/** 取消订单(仅待汇总可取消) */
/** 取消订单(仅待接单可取消,以 can_cancel 为准 */
const handleCancelOrder = useCallback(
(order: Order) => {
(order: OrderListItem) => {
Taro.showModal({
title: '取消订单',
content: `确定取消订单 ${order.order_no} 吗?`,
@@ -123,6 +123,11 @@ export default function OrderListPage() {
[loadOrders, status],
)
/** 跳转关联账单详情 */
const handleBillTap = useCallback((billId: number) => {
Taro.navigateTo({ url: `/pages/bill-detail/index?id=${billId}` })
}, [])
const goLogin = useCallback(() => {
Taro.navigateTo({ url: '/pages/login/index' })
}, [])
@@ -131,17 +136,11 @@ export default function OrderListPage() {
<View className='order-list-page'>
{/* ========== 状态筛选 ========== */}
<ScrollView scrollX className='status-scroll'>
<View
className={`status-chip ${status === undefined ? 'active' : ''}`}
onClick={() => handleStatusTap(undefined)}
>
<Text></Text>
</View>
{ORDER_NAV_ITEMS.map(item => (
{ORDER_STATUS_FILTERS.map(item => (
<View
key={item.key}
className={`status-chip ${status === item.status ? 'active' : ''}`}
onClick={() => handleStatusTap(item.status)}
key={item.label}
className={`status-chip ${status === item.value ? 'active' : ''}`}
onClick={() => handleStatusTap(item.value)}
>
<Text>{item.label}</Text>
</View>
@@ -164,25 +163,47 @@ export default function OrderListPage() {
<View key={order.id} className='order-item' onClick={() => handleOrderTap(order)}>
<View className='order-item__header'>
<Text className='order-item__no'>{order.order_no}</Text>
<Text className='order-item__status'>{ORDER_STATUS_MAP[order.status]}</Text>
<Text className={`order-item__status order-item__status--${order.status}`}>
{order.status_name}
</Text>
</View>
{/* 商品预览(仅前 3 条,完整明细见详情) */}
<Text className='order-item__preview'>
{order.items.map(i => `${i.product_name}×${i.quantity}`).join('、')}
{order.item_count > 3 ? `${order.item_count}` : ''}
</Text>
<View className='order-item__body'>
<Text className='order-item__date'>{order.order_date}</Text>
<Text className='order-item__date'> {order.order_date}</Text>
<View className='order-item__amounts'>
<Text className='order-item__qty'> {order.total_quantity} </Text>
<Text className='order-item__amount'>{order.total_amount}</Text>
</View>
</View>
{order.remark && <Text className='order-item__remark'>{order.remark}</Text>}
{order.status === 0 && (
<View
className='order-item__cancel'
onClick={e => {
e.stopPropagation()
handleCancelOrder(order)
}}
>
{(order.can_cancel || order.bill_id > 0) && (
<View className='order-item__footer'>
{order.bill_id > 0 && (
<View
className='order-item__bill'
onClick={e => {
e.stopPropagation()
handleBillTap(order.bill_id)
}}
>
</View>
)}
{order.can_cancel && (
<View
className='order-item__cancel'
onClick={e => {
e.stopPropagation()
handleCancelOrder(order)
}}
>
</View>
)}
</View>
)}
</View>
@@ -207,8 +228,10 @@ export default function OrderListPage() {
<View className='detail-popup'>
<Text className='detail-popup__title'>{orderDetail.order_no}</Text>
<View className='detail-popup__meta'>
<Text>{orderDetail.order_date}</Text>
<Text className='detail-popup__status'>{ORDER_STATUS_MAP[orderDetail.status]}</Text>
<Text>{orderDetail.order_date} {orderDetail.created_at}</Text>
<Text className='detail-popup__status'>
{detailStatusName || ORDER_STATUS_TEXT[orderDetail.status] || ''}
</Text>
</View>
<ScrollView scrollY className='detail-popup__list'>
{(orderDetail.items ?? []).map(item => (
@@ -216,13 +239,16 @@ export default function OrderListPage() {
<View className='detail-popup__item-info'>
<Text className='detail-popup__item-name'>{item.product_name}</Text>
<Text className='detail-popup__item-spec'>
{item.product_spec} {item.price} × {item.quantity}
{item.product_spec ? `${item.product_spec} ` : ''}{item.price}/{item.unit} × {item.quantity}
</Text>
</View>
<Text className='detail-popup__item-amount'>{item.amount}</Text>
</View>
))}
</ScrollView>
{orderDetail.remark && (
<Text className='detail-popup__remark'>{orderDetail.remark}</Text>
)}
<View className='detail-popup__footer'>
<Text className='detail-popup__total'> {orderDetail.total_amount}</Text>
</View>