mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-12 02:06:37 +08:00
149 lines
4.5 KiB
TypeScript
149 lines
4.5 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import { useState, useCallback } from "react"
|
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
|
import { TransactionService } from "@/lib/services"
|
|
import type { Order } from "@/lib/services"
|
|
import { TransactionTableList } from "@/components/common/general/table-data"
|
|
import { AlertTriangle } from "lucide-react"
|
|
import { toast } from "sonner"
|
|
|
|
const DISPUTE_PAGE_SIZE = 20
|
|
|
|
/**
|
|
* 服务争议对话框模式
|
|
*/
|
|
type DisputeDialogMode = 'pending' | 'my-disputes'
|
|
|
|
/**
|
|
* 服务争议对话框属性
|
|
*/
|
|
interface DisputeDialogProps {
|
|
/** 对话框模式 */
|
|
mode: DisputeDialogMode
|
|
/** 是否打开 */
|
|
open: boolean
|
|
/** 打开状态变化回调 */
|
|
onOpenChange: (open: boolean) => void
|
|
}
|
|
|
|
/**
|
|
* 争议对话框组件
|
|
* 支持两种模式:待处理的服务争议(服务提供者)和我发起的服务争议(积分消费者)
|
|
*/
|
|
export function DisputeDialog({ mode, open, onOpenChange }: DisputeDialogProps) {
|
|
const [disputes, setDisputes] = useState<Order[]>([])
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState<Error | null>(null)
|
|
|
|
const fetchDisputes = useCallback(async (page: number = 1) => {
|
|
try {
|
|
setLoading(true)
|
|
setError(null)
|
|
|
|
let result
|
|
let filteredOrders: Order[] = []
|
|
|
|
if (mode === 'pending') {
|
|
result = await TransactionService.getTransactions({
|
|
page,
|
|
page_size: DISPUTE_PAGE_SIZE,
|
|
types: ['receive'],
|
|
statuses: ['disputing']
|
|
})
|
|
filteredOrders = result.orders
|
|
const uniqueOrders = new Map()
|
|
filteredOrders.forEach(order => uniqueOrders.set(order.id, order))
|
|
filteredOrders = Array.from(uniqueOrders.values())
|
|
} else {
|
|
const paymentResult = await TransactionService.getTransactions({
|
|
page,
|
|
page_size: Math.ceil(DISPUTE_PAGE_SIZE / 2),
|
|
types: ['payment']
|
|
})
|
|
|
|
const onlineResult = await TransactionService.getTransactions({
|
|
page,
|
|
page_size: Math.ceil(DISPUTE_PAGE_SIZE / 2),
|
|
types: ['online']
|
|
})
|
|
|
|
const allOrders = [...paymentResult.orders, ...onlineResult.orders]
|
|
const uniqueOrders = new Map()
|
|
allOrders.forEach(order => uniqueOrders.set(order.id, order))
|
|
|
|
filteredOrders = Array.from(uniqueOrders.values()).filter((order: Order) =>
|
|
order.status === 'disputing' || order.status === 'refused' || order.status === 'refund'
|
|
)
|
|
|
|
filteredOrders.sort((a, b) =>
|
|
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
|
)
|
|
|
|
const startIndex = (page - 1) * DISPUTE_PAGE_SIZE
|
|
filteredOrders = filteredOrders.slice(startIndex, startIndex + DISPUTE_PAGE_SIZE)
|
|
|
|
result = {
|
|
orders: filteredOrders,
|
|
total: allOrders.filter((order: Order) =>
|
|
order.status === 'disputing' || order.status === 'refused' || order.status === 'refund'
|
|
).length,
|
|
page,
|
|
page_size: DISPUTE_PAGE_SIZE
|
|
}
|
|
}
|
|
|
|
setDisputes(filteredOrders)
|
|
} catch (err) {
|
|
const error = err as Error
|
|
setError(error)
|
|
toast.error('获取争议数据失败', {
|
|
description: error.message || '无法加载争议列表'
|
|
})
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}, [mode])
|
|
|
|
React.useEffect(() => {
|
|
if (open) {
|
|
fetchDisputes(1)
|
|
} else {
|
|
setDisputes([])
|
|
setError(null)
|
|
}
|
|
}, [open, fetchDisputes])
|
|
|
|
const handleRetry = () => {
|
|
fetchDisputes(1)
|
|
}
|
|
|
|
const dialogTitle = mode === 'pending' ? '待处理的争议' : '我发起的争议'
|
|
const dialogDescription = mode === 'pending'
|
|
? '您作为服务提供者,需要处理所有争议中的活动'
|
|
: '您作为积分消费者发起的所有争议'
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>{dialogTitle}</DialogTitle>
|
|
<DialogDescription>{dialogDescription}</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="flex-1 overflow-y-auto">
|
|
<TransactionTableList
|
|
loading={loading}
|
|
error={error}
|
|
transactions={disputes}
|
|
onRetry={handleRetry}
|
|
emptyIcon={AlertTriangle}
|
|
emptyDescription={mode === 'pending' ? '暂无待处理的争议' : '暂无您发起的争议'}
|
|
/>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|