fix(dispute): enforce participant checks and phase constraints
This commit is contained in:
@@ -17,6 +17,7 @@ import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { DISPUTE_TO_RESOLVED_MS } from "@/lib/config/demo-timers"
|
||||
import { notifyInfo } from "@/lib/toast"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
@@ -108,13 +109,17 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!userId || !userName || !reason.trim()) return
|
||||
submitDispute({
|
||||
const result = submitDispute({
|
||||
orderId: id,
|
||||
initiatorId: userId,
|
||||
initiatorName: userName,
|
||||
reason,
|
||||
evidence: files,
|
||||
})
|
||||
if (!result.decision.ok) {
|
||||
notifyInfo(result.decision.message ?? "提交争议失败")
|
||||
return
|
||||
}
|
||||
router.replace(`/dispute/${id}?submitted=1`)
|
||||
}
|
||||
|
||||
@@ -128,13 +133,26 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
|
||||
)
|
||||
}
|
||||
|
||||
const isParticipant = Boolean(
|
||||
userId && (order.consumerId === userId || order.playerId === userId),
|
||||
)
|
||||
if (!isParticipant) {
|
||||
return (
|
||||
<div className="container mx-auto py-8 px-4 max-w-lg text-center text-muted-foreground">
|
||||
仅该订单参与方可访问争议页面
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (existingDispute) {
|
||||
const isInitiator = userId === existingDispute.initiatorId
|
||||
const canRespond =
|
||||
isParticipant &&
|
||||
!isInitiator &&
|
||||
!existingDispute.respondentReason &&
|
||||
(existingDispute.status === "open" || existingDispute.status === "reviewing")
|
||||
const canAppeal = existingDispute.status === "resolved" && !existingDispute.appealedAt
|
||||
const canAppeal =
|
||||
isParticipant && existingDispute.status === "resolved" && !existingDispute.appealedAt
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-8 px-4 max-w-2xl">
|
||||
@@ -267,9 +285,18 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
|
||||
</div>
|
||||
)}
|
||||
<Button
|
||||
onClick={() =>
|
||||
submitResponse(existingDispute.id, responseReason, responseFiles)
|
||||
}
|
||||
onClick={() => {
|
||||
if (!userId) return
|
||||
const decision = submitResponse(
|
||||
existingDispute.id,
|
||||
userId,
|
||||
responseReason,
|
||||
responseFiles,
|
||||
)
|
||||
if (!decision.ok) {
|
||||
notifyInfo(decision.message ?? "提交回应失败")
|
||||
}
|
||||
}}
|
||||
disabled={!responseReason.trim()}
|
||||
>
|
||||
提交回应
|
||||
@@ -308,7 +335,13 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
|
||||
/>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => submitAppeal(existingDispute.id, appealReason)}
|
||||
onClick={() => {
|
||||
if (!userId) return
|
||||
const decision = submitAppeal(existingDispute.id, userId, appealReason)
|
||||
if (!decision.ok) {
|
||||
notifyInfo(decision.message ?? "提交申诉失败")
|
||||
}
|
||||
}}
|
||||
disabled={!appealReason.trim()}
|
||||
>
|
||||
提交申诉
|
||||
|
||||
Reference in New Issue
Block a user