refactor(order): rewrite store around state machine transitions
This commit is contained in:
@@ -10,10 +10,12 @@ import {
|
||||
XCircle,
|
||||
} from "lucide-react"
|
||||
import Link from "next/link"
|
||||
import { useEffect } from "react"
|
||||
import { useCallback, useEffect } from "react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { notifySuccess } from "@/lib/toast"
|
||||
import type { Actor } from "@/lib/policy/actor"
|
||||
import { notifyInfo, notifySuccess } from "@/lib/toast"
|
||||
import type { OrderStatus } from "@/lib/types"
|
||||
import { useAuthStore } from "@/store/auth"
|
||||
import { useChatStore } from "@/store/chat"
|
||||
import { useOrderStore } from "@/store/orders"
|
||||
import { useShopStore } from "@/store/shops"
|
||||
@@ -35,10 +37,21 @@ export default function OrderActions({
|
||||
chatSessionId,
|
||||
serviceId,
|
||||
}: OrderActionsProps) {
|
||||
const currentRole = useAuthStore((state) => state.currentRole)
|
||||
const currentUserId = useAuthStore((state) => state.user?.id)
|
||||
const payOrder = useOrderStore((state) => state.payOrder)
|
||||
const acceptOrder = useOrderStore((state) => state.acceptOrder)
|
||||
const requestClose = useOrderStore((state) => state.requestClose)
|
||||
const confirmClose = useOrderStore((state) => state.confirmClose)
|
||||
const cancelPreAccept = useOrderStore((state) => state.cancelPreAccept)
|
||||
const order = useOrderStore((state) => state.orders.find((item) => item.id === orderId))
|
||||
const updateOrderStatus = useOrderStore((state) => state.updateOrderStatus)
|
||||
const sessions = useChatStore((state) => state.sessions)
|
||||
const ensureOrderSession = useChatStore((state) => state.ensureOrderSession)
|
||||
const actorShopId = useShopStore((state) => {
|
||||
if (!currentUserId || currentRole !== "owner") return undefined
|
||||
const owned = state.shops.find((shop) => shop.owner.id === currentUserId)
|
||||
return owned?.id
|
||||
})
|
||||
const dispatchMode = useShopStore((state) => {
|
||||
if (!order?.shopId) return "manual"
|
||||
const shop = state.shops.find((item) => item.id === order.shopId)
|
||||
@@ -49,6 +62,25 @@ export default function OrderActions({
|
||||
sessions.find((session) => session.type === "order" && session.orderId === orderId)?.id
|
||||
|
||||
const status = order?.status ?? initialStatus
|
||||
const actor: Actor | undefined = currentUserId
|
||||
? {
|
||||
userId: currentUserId,
|
||||
role: currentRole,
|
||||
shopId: actorShopId,
|
||||
}
|
||||
: undefined
|
||||
|
||||
const handleDecision = useCallback(
|
||||
(okMessage: string, result: { decision: { ok: boolean; message?: string } }) => {
|
||||
if (result.decision.ok) {
|
||||
showFeedback(okMessage)
|
||||
return
|
||||
}
|
||||
|
||||
notifyInfo(result.decision.message ?? "当前操作不允许")
|
||||
},
|
||||
[],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (chatSessionId || !order || resolvedChatSessionId) return
|
||||
@@ -62,12 +94,17 @@ export default function OrderActions({
|
||||
if (dispatchMode !== "auto") return
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
updateOrderStatus(orderId, "in_progress")
|
||||
showFeedback("系统已自动派单")
|
||||
const systemActor: Actor = {
|
||||
userId: order.playerId,
|
||||
role: "player",
|
||||
shopId: order.shopId,
|
||||
}
|
||||
const result = acceptOrder(orderId, systemActor)
|
||||
handleDecision("系统已自动派单", result)
|
||||
}, 3000)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [dispatchMode, order, orderId, updateOrderStatus])
|
||||
}, [acceptOrder, dispatchMode, handleDecision, order, orderId])
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
@@ -76,8 +113,13 @@ export default function OrderActions({
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
updateOrderStatus(orderId, "cancelled")
|
||||
showFeedback("订单已取消")
|
||||
if (!actor) {
|
||||
notifyInfo("请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
const result = cancelPreAccept(orderId, actor)
|
||||
handleDecision("订单已取消", result)
|
||||
}}
|
||||
>
|
||||
<XCircle className="mr-1 h-4 w-4" />
|
||||
@@ -85,7 +127,13 @@ export default function OrderActions({
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
updateOrderStatus(orderId, "pending_accept")
|
||||
if (!actor) {
|
||||
notifyInfo("请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
const result = payOrder(orderId, actor)
|
||||
handleDecision("订单支付成功", result)
|
||||
}}
|
||||
>
|
||||
<CheckCircle2 className="mr-1 h-4 w-4" />
|
||||
@@ -99,8 +147,13 @@ export default function OrderActions({
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
updateOrderStatus(orderId, "cancelled")
|
||||
showFeedback("订单已取消")
|
||||
if (!actor) {
|
||||
notifyInfo("请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
const result = cancelPreAccept(orderId, actor)
|
||||
handleDecision("订单已取消", result)
|
||||
}}
|
||||
>
|
||||
<XCircle className="mr-1 h-4 w-4" />
|
||||
@@ -114,8 +167,13 @@ export default function OrderActions({
|
||||
) : (
|
||||
<Button
|
||||
onClick={() => {
|
||||
updateOrderStatus(orderId, "in_progress")
|
||||
showFeedback("已接单")
|
||||
if (!actor) {
|
||||
notifyInfo("请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
const result = acceptOrder(orderId, actor)
|
||||
handleDecision("已接单", result)
|
||||
}}
|
||||
>
|
||||
<CheckCircle2 className="mr-1 h-4 w-4" />
|
||||
@@ -138,8 +196,13 @@ export default function OrderActions({
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
updateOrderStatus(orderId, "pending_close")
|
||||
showFeedback("已发起结单")
|
||||
if (!actor) {
|
||||
notifyInfo("请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
const result = requestClose(orderId, actor)
|
||||
handleDecision("已发起结单", result)
|
||||
}}
|
||||
>
|
||||
发起结单
|
||||
@@ -157,7 +220,13 @@ export default function OrderActions({
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
updateOrderStatus(orderId, "pending_review")
|
||||
if (!actor) {
|
||||
notifyInfo("请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
const result = confirmClose(orderId, actor)
|
||||
handleDecision("已确认结单", result)
|
||||
}}
|
||||
>
|
||||
确认结单
|
||||
|
||||
Reference in New Issue
Block a user