账单
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user