feat(mobile): 接入移动端订单与消息中心
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
|
||||
|
||||
import { apiClient, unwrapData } from '@/shared/api/client'
|
||||
import type { ApiResponse } from '@/shared/api/types'
|
||||
import type { UserOrderDetail, UserOrderPage } from '@/features/orders/types'
|
||||
|
||||
export const MY_ORDER_PAGE_SIZE = 20
|
||||
|
||||
export function fetchMyOrders(page = 1, pageSize = MY_ORDER_PAGE_SIZE) {
|
||||
return unwrapData<Partial<UserOrderPage>>(
|
||||
apiClient.get<ApiResponse<Partial<UserOrderPage>>>('/orders', {
|
||||
params: { page, page_size: pageSize },
|
||||
})
|
||||
).then(data => ({
|
||||
items: data.items ?? [],
|
||||
total: data.total ?? 0,
|
||||
page: data.page ?? page,
|
||||
page_size: data.page_size ?? pageSize,
|
||||
}))
|
||||
}
|
||||
|
||||
export function useMyOrders(enabled = true) {
|
||||
return useInfiniteQuery({
|
||||
queryKey: ['my-orders'],
|
||||
queryFn: ({ pageParam }) => fetchMyOrders(pageParam, MY_ORDER_PAGE_SIZE),
|
||||
initialPageParam: 1,
|
||||
getNextPageParam: last =>
|
||||
last.page * last.page_size < last.total ? last.page + 1 : undefined,
|
||||
enabled,
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchMyOrder(id: number | string) {
|
||||
return unwrapData<UserOrderDetail>(apiClient.get<ApiResponse<UserOrderDetail>>(`/orders/${id}`))
|
||||
}
|
||||
|
||||
export function useMyOrder(id?: string, enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: ['my-order', id],
|
||||
queryFn: () => fetchMyOrder(id as string),
|
||||
enabled: Boolean(id) && enabled,
|
||||
})
|
||||
}
|
||||
|
||||
export async function cancelMyOrder(id: number | string) {
|
||||
await apiClient.post(`/orders/${id}/cancel`)
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
export type MobileTone = 'default' | 'primary' | 'success' | 'warning' | 'danger'
|
||||
|
||||
export interface MobileStatus {
|
||||
label: string
|
||||
tone: MobileTone
|
||||
}
|
||||
|
||||
const orderStatus: Record<string, MobileStatus> = {
|
||||
pending_payment: { label: '待支付', tone: 'warning' },
|
||||
pending_handoff: { label: '待交接', tone: 'primary' },
|
||||
renting: { label: '使用中', tone: 'primary' },
|
||||
overdue: { label: '已逾期', tone: 'danger' },
|
||||
pending_checkout_confirm: { label: '待确认结账', tone: 'warning' },
|
||||
pending_checkout_accept: { label: '待确认修正', tone: 'warning' },
|
||||
checkout_disputing: { label: '结账争议', tone: 'danger' },
|
||||
disputing: { label: '申诉中', tone: 'danger' },
|
||||
completed: { label: '已完成', tone: 'success' },
|
||||
cancelled: { label: '已取消', tone: 'default' },
|
||||
closed: { label: '已关闭', tone: 'default' },
|
||||
abnormal: { label: '客服处理中', tone: 'danger' },
|
||||
}
|
||||
|
||||
const handoffStatus: Record<string, MobileStatus> = {
|
||||
none: { label: '未开始', tone: 'default' },
|
||||
pending_owner: { label: '待号主交接', tone: 'primary' },
|
||||
owner_timeout: { label: '交接超时', tone: 'danger' },
|
||||
pending_renter_confirm: { label: '待确认收号', tone: 'primary' },
|
||||
received: { label: '已收号', tone: 'success' },
|
||||
return_overdue: { label: '归还逾期', tone: 'danger' },
|
||||
pending_owner_checkout: { label: '待号主结账', tone: 'warning' },
|
||||
pending_renter_checkout: { label: '待确认修正', tone: 'warning' },
|
||||
checkout_disputed: { label: '结账争议', tone: 'danger' },
|
||||
returned: { label: '已归还', tone: 'success' },
|
||||
renter_confirm_timeout: { label: '确认超时', tone: 'danger' },
|
||||
owner_return_confirm_timeout: { label: '结账超时', tone: 'danger' },
|
||||
owner_checkout_confirm_timeout: { label: '结账超时', tone: 'danger' },
|
||||
cancelled: { label: '已取消', tone: 'default' },
|
||||
admin_closed: { label: '已关闭', tone: 'default' },
|
||||
admin_abnormal: { label: '客服处理中', tone: 'danger' },
|
||||
arbitrated: { label: '已仲裁', tone: 'success' },
|
||||
}
|
||||
|
||||
const settlementStatus: Record<string, MobileStatus> = {
|
||||
unsettled: { label: '未结算', tone: 'default' },
|
||||
pending: { label: '待结算', tone: 'warning' },
|
||||
frozen: { label: '冻结中', tone: 'danger' },
|
||||
settled: { label: '已结算', tone: 'success' },
|
||||
refunded: { label: '已退款', tone: 'primary' },
|
||||
cancelled: { label: '结算已取消', tone: 'default' },
|
||||
closed: { label: '结算已关闭', tone: 'default' },
|
||||
disputed: { label: '争议中', tone: 'danger' },
|
||||
arbitrated: { label: '已仲裁', tone: 'success' },
|
||||
}
|
||||
|
||||
const checkoutStatus: Record<string, MobileStatus> = {
|
||||
submitted: { label: '等待确认', tone: 'warning' },
|
||||
countered: { label: '已修正', tone: 'warning' },
|
||||
accepted: { label: '已接受', tone: 'success' },
|
||||
disputed: { label: '争议中', tone: 'danger' },
|
||||
settled: { label: '仲裁结案', tone: 'success' },
|
||||
}
|
||||
|
||||
function read(map: Record<string, MobileStatus>, value?: string | null): MobileStatus {
|
||||
if (!value) return { label: '—', tone: 'default' }
|
||||
return map[value] ?? { label: value, tone: 'default' }
|
||||
}
|
||||
|
||||
export function orderStatusMeta(value?: string | null) {
|
||||
return read(orderStatus, value)
|
||||
}
|
||||
|
||||
export function handoffStatusMeta(value?: string | null) {
|
||||
return read(handoffStatus, value)
|
||||
}
|
||||
|
||||
export function settlementStatusMeta(value?: string | null) {
|
||||
return read(settlementStatus, value)
|
||||
}
|
||||
|
||||
export function checkoutStatusMeta(value?: string | null) {
|
||||
return read(checkoutStatus, value)
|
||||
}
|
||||
|
||||
export function roleLabel(role?: string | null) {
|
||||
if (role === 'owner') return '我出租的'
|
||||
if (role === 'renter') return '我租的'
|
||||
return '订单'
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
export interface UserOrderListItem {
|
||||
id: number
|
||||
order_no: string
|
||||
listing_id: number
|
||||
listing_no: string
|
||||
role: 'owner' | 'renter' | string
|
||||
title: string
|
||||
server_region: string
|
||||
login_platform: string
|
||||
rental_days?: number
|
||||
daily_loss_m?: number
|
||||
display_amount_cent: number
|
||||
deposit_amount_cent: number
|
||||
deposit_waived_amount_cent: number
|
||||
status: string
|
||||
handoff_status: string
|
||||
can_hide?: boolean
|
||||
payment_deadline_at?: string
|
||||
distribution_site_id?: number | null
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface UserOrderPage {
|
||||
items: UserOrderListItem[]
|
||||
total: number
|
||||
page: number
|
||||
page_size: number
|
||||
}
|
||||
|
||||
export interface UserCheckout {
|
||||
id: number
|
||||
status: string
|
||||
round_count: number
|
||||
max_rounds: number
|
||||
content: string
|
||||
consumable_amount_cent: number
|
||||
coin_consumed_m: number
|
||||
other_amount_cent: number
|
||||
deposit_deduct_amount_cent: number
|
||||
renter_refund_amount_cent?: number | null
|
||||
owner_income_amount_cent?: number | null
|
||||
shortfall_cent: number
|
||||
overshoot_amount_cent: number
|
||||
owner_adjustment_reason?: string
|
||||
renter_confirmed_at?: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface UserActiveDispute {
|
||||
id: number
|
||||
type: string
|
||||
status: string
|
||||
initiator_type: string
|
||||
}
|
||||
|
||||
export interface UserOrderDetail {
|
||||
id: number
|
||||
order_no: string
|
||||
listing_id: number
|
||||
listing_no: string
|
||||
owner_id: number
|
||||
renter_id: number
|
||||
title: string
|
||||
server_region: string
|
||||
login_platform: string
|
||||
price_role?: string
|
||||
rented_at?: string | null
|
||||
estimated_duration_hours: number
|
||||
estimated_end_at?: string | null
|
||||
display_amount_cent: number
|
||||
rent_amount_cent?: number | null
|
||||
owner_rent_amount_cent?: number | null
|
||||
deposit_amount_cent: number
|
||||
deposit_waived_amount_cent: number
|
||||
platform_fee_cent?: number | null
|
||||
status: string
|
||||
handoff_status: string
|
||||
handoff_mode: string
|
||||
settlement_mode: string
|
||||
settlement_status: string
|
||||
refund_status?: string
|
||||
refund_amount_cent: number
|
||||
payment_deadline_at?: string | null
|
||||
active_dispute?: UserActiveDispute | null
|
||||
checkout?: UserCheckout | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
Reference in New Issue
Block a user