feat(order): add sealed review reveal, timeout rules, and dispatch behavior

This commit is contained in:
zetaloop
2026-02-22 08:16:35 +08:00
parent 33b7e4d0b9
commit a7d56240ff
5 changed files with 288 additions and 19 deletions
+65
View File
@@ -2,6 +2,7 @@ import { create } from "zustand"
import { generateId } from "@/lib/id"
import { mockOrders } from "@/lib/mock"
import type { Order, OrderStatus, PlayerService } from "@/lib/types"
import { useWalletStore } from "@/store/wallet"
interface CreateOrderInput {
consumerId: string
@@ -22,6 +23,44 @@ interface OrderState {
updateOrderStatus: (orderId: string, status: OrderStatus) => void
}
const orderTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
function clearOrderTimeout(orderId: string) {
const timer = orderTimeouts.get(orderId)
if (!timer) return
clearTimeout(timer)
orderTimeouts.delete(orderId)
}
function scheduleOrderTimeout(orderId: string, status: OrderStatus) {
clearOrderTimeout(orderId)
if (status !== "pending_accept" && status !== "pending_close") {
return
}
const timer = setTimeout(() => {
const state = useOrderStore.getState()
const order = state.orders.find((item) => item.id === orderId)
if (!order || order.status !== status) {
orderTimeouts.delete(orderId)
return
}
if (status === "pending_accept") {
state.updateOrderStatus(orderId, "cancelled")
}
if (status === "pending_close") {
state.updateOrderStatus(orderId, "pending_review")
}
orderTimeouts.delete(orderId)
}, 30000)
orderTimeouts.set(orderId, timer)
}
export const useOrderStore = create<OrderState>((set) => ({
orders: mockOrders,
createOrder: (input) => {
@@ -44,6 +83,8 @@ export const useOrderStore = create<OrderState>((set) => ({
orders: [order, ...state.orders],
}))
scheduleOrderTimeout(order.id, order.status)
return order
},
updateOrderStatus: (orderId, status) =>
@@ -60,6 +101,12 @@ export const useOrderStore = create<OrderState>((set) => ({
status,
acceptedAt: order.acceptedAt ?? now,
}
case "pending_close":
return {
...order,
status,
closedAt: order.closedAt ?? now,
}
case "pending_review":
return {
...order,
@@ -67,6 +114,9 @@ export const useOrderStore = create<OrderState>((set) => ({
closedAt: order.closedAt ?? now,
}
case "completed":
if (order.status !== "completed") {
useWalletStore.getState().addIncome(order.id, order.totalPrice)
}
return {
...order,
status,
@@ -82,3 +132,18 @@ export const useOrderStore = create<OrderState>((set) => ({
}),
})),
}))
useOrderStore.subscribe((state, prevState) => {
state.orders.forEach((order) => {
const prevOrder = prevState.orders.find((item) => item.id === order.id)
if (!prevOrder || prevOrder.status !== order.status) {
scheduleOrderTimeout(order.id, order.status)
}
})
prevState.orders.forEach((order) => {
if (!state.orders.some((item) => item.id === order.id)) {
clearOrderTimeout(order.id)
}
})
})