diff --git a/app/(order)/order/new/page.tsx b/app/(order)/order/new/page.tsx
index 3180d88..fae9583 100644
--- a/app/(order)/order/new/page.tsx
+++ b/app/(order)/order/new/page.tsx
@@ -12,10 +12,10 @@ import { Label } from "@/components/ui/label"
import { Separator } from "@/components/ui/separator"
import { Textarea } from "@/components/ui/textarea"
import { getPlayerById, getServiceById } from "@/lib/api"
+import type { Actor } from "@/lib/policy/actor"
import { notifySuccess } from "@/lib/toast"
import { useRequireAuth } from "@/lib/use-require-auth"
import { useAuthStore } from "@/store/auth"
-import { useChatStore } from "@/store/chat"
import { useOrderStore } from "@/store/orders"
import { useWalletStore } from "@/store/wallet"
@@ -23,10 +23,8 @@ export default function NewOrderPage() {
const router = useRouter()
const searchParams = useSearchParams()
const { requireAuth } = useRequireAuth()
- const createOrder = useOrderStore((state) => state.createOrder)
- const ensureOrderSession = useChatStore((state) => state.ensureOrderSession)
+ const createPaidOrder = useOrderStore((state) => state.createPaidOrder)
const balance = useWalletStore((state) => state.balance)
- const deductBalance = useWalletStore((state) => state.deductBalance)
const serviceId = searchParams.get("serviceId")
const service = serviceId ? getServiceById(serviceId) : undefined
@@ -186,34 +184,38 @@ export default function NewOrderPage() {
size="lg"
disabled={balance < totalPrice}
onClick={() =>
- requireAuth(async () => {
- await new Promise((resolve) => setTimeout(resolve, 500))
+ requireAuth(() => {
const authUser = useAuthStore.getState().user
if (!authUser) return
- const order = createOrder({
- consumerId: authUser.id,
- consumerName: authUser.nickname,
- playerId: player.id,
- playerName: player.user.nickname,
- shopId: player.shopId,
- shopName: player.shopName,
- service,
- totalPrice,
- note,
- status: "pending_accept",
- })
-
- const paid = deductBalance(order.id, totalPrice)
- if (!paid) {
- return
+ const actor: Actor = {
+ userId: authUser.id,
+ role: "consumer",
}
- ensureOrderSession(order)
+ const result = createPaidOrder(
+ {
+ consumerId: authUser.id,
+ consumerName: authUser.nickname,
+ playerId: player.id,
+ playerName: player.user.nickname,
+ shopId: player.shopId,
+ shopName: player.shopName,
+ service,
+ totalPrice,
+ note,
+ },
+ actor,
+ )
+ if (!result.decision.ok || !result.order) {
+ return
+ }
+ const nextOrder = result.order
+
setSubmitted(true)
notifySuccess("下单成功")
setTimeout(() => {
- router.push(`/order/${order.id}`)
+ router.push(`/order/${nextOrder.id}`)
}, 800)
})
}
diff --git a/components/order-actions.tsx b/components/order-actions.tsx
index 1a58f79..63e9488 100644
--- a/components/order-actions.tsx
+++ b/components/order-actions.tsx
@@ -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 (
@@ -76,8 +113,13 @@ export default function OrderActions({