refactor(orders): replace local state machine with minimal cache

Strip store/orders.ts to a thin local cache with setOrders and
updateOrder only. Remove all client-side state transition logic,
actor validation, chat sync, notification generation, and wallet
integration — these are now handled by the backend API.

Fix components/order-actions.tsx and stores that depended on
the removed order store methods (markDisputed, autoTimeout*).
This commit is contained in:
zetaloop
2026-05-01 04:13:55 +08:00
parent 452004b194
commit cf0fea9926
6 changed files with 135 additions and 505 deletions
+54 -63
View File
@@ -13,7 +13,6 @@ import type { ApiDecision } from "@/lib/errors"
import { notifyInfo, notifySuccess } from "@/lib/toast"
import type { Order, OrderStatus } from "@/lib/types"
import { useAuthStore } from "@/store/auth"
import { useOrderStore } from "@/store/orders"
import {
AlertTriangle,
CheckCircle2,
@@ -31,7 +30,8 @@ interface OrderActionsProps {
order?: Order
onOrderChange?: (order: Order) => void
initialStatus: OrderStatus
chatSessionId?: string
chatTargetId?: string
isPlayerParticipant?: boolean
serviceId: string
}
@@ -44,14 +44,14 @@ export default function OrderActions({
order: orderProp,
onOrderChange,
initialStatus,
chatSessionId,
chatTargetId,
isPlayerParticipant,
serviceId,
}: OrderActionsProps) {
const currentUserId = useAuthStore((state) => state.user?.id)
const storeOrder = useOrderStore((state) => state.orders.find((item) => item.id === orderId))
const order = orderProp ?? storeOrder
const order = orderProp
const [dispatchMode, setDispatchMode] = useState<"manual" | "auto" | null>(null)
const resolvedChatSessionId = chatSessionId
const resolvedChatTargetId = chatTargetId
useEffect(() => {
if (!order?.shopId) return
@@ -79,8 +79,9 @@ export default function OrderActions({
}, [order?.shopId])
const status = order?.status ?? initialStatus
const isConsumer = order?.consumerId === currentUserId
const isPlayer = order?.playerId === currentUserId
const isConsumer = String(order?.consumerId) === currentUserId
const isPlayer = isPlayerParticipant === true
const isParticipant = isConsumer || isPlayer
type ActionResult = { decision: ApiDecision; order?: Order }
@@ -110,34 +111,18 @@ export default function OrderActions({
return (
<div className="flex flex-wrap items-center gap-2">
{status === "pending_payment" && isConsumer && (
<>
<Button
variant="outline"
className="border-border/60"
onClick={() => {
if (!currentUserId) {
notifyInfo("请先登录")
return
}
runAction("订单已取消", cancelPreAccept(orderId))
}}
>
<XCircle className="mr-1 h-4 w-4" />
</Button>
<Button
onClick={() => {
if (!currentUserId) {
notifyInfo("请先登录")
return
}
runAction("订单支付成功", payOrder(orderId))
}}
>
<CheckCircle2 className="mr-1 h-4 w-4" />
</Button>
</>
<Button
onClick={() => {
if (!currentUserId) {
notifyInfo("请先登录")
return
}
runAction("订单支付成功", payOrder(orderId))
}}
>
<CheckCircle2 className="mr-1 h-4 w-4" />
</Button>
)}
{status === "pending_accept" && (
@@ -181,9 +166,9 @@ export default function OrderActions({
</>
)}
{(status === "in_progress" || status === "pending_close") && resolvedChatSessionId && (
{(status === "in_progress" || status === "pending_close") && resolvedChatTargetId && (
<Button variant="outline" className="border-border/60" asChild>
<Link href={`/chat/${resolvedChatSessionId}`}>
<Link href={`/chat/${resolvedChatTargetId}?orderId=${orderId}`}>
<MessageSquare className="mr-1 h-4 w-4" />
</Link>
@@ -192,24 +177,28 @@ export default function OrderActions({
{status === "in_progress" && (
<>
<Button
onClick={() => {
if (!currentUserId) {
notifyInfo("请先登录")
return
}
{isPlayer && (
<Button
onClick={() => {
if (!currentUserId) {
notifyInfo("请先登录")
return
}
runAction("已发起结单", requestClose(orderId))
}}
>
</Button>
<Button variant="destructive" asChild>
<Link href={`/dispute/${orderId}`}>
<AlertTriangle className="mr-1 h-4 w-4" />
</Link>
</Button>
runAction("已发起结单", requestClose(orderId))
}}
>
</Button>
)}
{isParticipant && (
<Button variant="destructive" asChild>
<Link href={`/dispute/${orderId}`}>
<AlertTriangle className="mr-1 h-4 w-4" />
</Link>
</Button>
)}
</>
)}
@@ -228,16 +217,18 @@ export default function OrderActions({
</Button>
)}
<Button variant="destructive" asChild>
<Link href={`/dispute/${orderId}`}>
<AlertTriangle className="mr-1 h-4 w-4" />
</Link>
</Button>
{isParticipant && (
<Button variant="destructive" asChild>
<Link href={`/dispute/${orderId}`}>
<AlertTriangle className="mr-1 h-4 w-4" />
</Link>
</Button>
)}
</>
)}
{status === "pending_review" && (
{status === "pending_review" && isParticipant && (
<Button asChild>
<Link href={`/review/${orderId}`}>
<Star className="mr-1 h-4 w-4" />
@@ -264,7 +255,7 @@ export default function OrderActions({
</Button>
)}
{status === "disputed" && (
{status === "disputed" && isParticipant && (
<Button variant="outline" className="border-border/60" asChild>
<Link href={`/dispute/${orderId}`}></Link>
</Button>