From 12284290cceef1e1a3222b25e0362deb8bc7ecd7 Mon Sep 17 00:00:00 2001 From: zetaloop Date: Thu, 23 Apr 2026 21:15:11 +0800 Subject: [PATCH] refactor(store): adapt Zustand stores to backend-aligned types - orders: remove name fields from creation, keep dispatchMode logic - chat: remove readonly/senderName/senderAvatar references - reviews: remove fromUserAvatar/toUserId, simplify participant check - disputes: remove initiatorId/initiatorName from creation - posts: remove authorRole/quotedPostId, keep linkedOrderId as number - comments: remove postId from creation - wallet: use string amounts --- store/chat.ts | 46 +++++++--------------------------------------- store/comments.ts | 1 - store/disputes.ts | 17 +++++++---------- store/orders.ts | 35 +---------------------------------- store/posts.ts | 10 +++------- store/reviews.ts | 34 +++++----------------------------- store/wallet.ts | 10 +++++----- 7 files changed, 28 insertions(+), 125 deletions(-) diff --git a/store/chat.ts b/store/chat.ts index 133631d..d74b138 100644 --- a/store/chat.ts +++ b/store/chat.ts @@ -14,10 +14,6 @@ function resolveAvatar(_userId: string) { return "" } -function shouldReadonly(status: Order["status"]) { - return status === "pending_review" || status === "completed" || status === "cancelled" -} - export const useChatStore = create((set, get) => ({ sessions: [], messages: [], @@ -26,17 +22,8 @@ export const useChatStore = create((set, get) => ({ (session) => session.type === "order" && session.orderId === order.id, ) - const readonly = shouldReadonly(order.status) - if (existing) { - if (existing.readonly !== readonly) { - set((state) => ({ - sessions: state.sessions.map((session) => - session.id === existing.id ? { ...session, readonly } : session, - ), - })) - } - return get().sessions.find((session) => session.id === existing.id) ?? existing + return existing } const session: ChatSession = { @@ -46,17 +33,16 @@ export const useChatStore = create((set, get) => ({ participants: [ { id: order.consumerId, - name: order.consumerName, + nickname: "", avatar: resolveAvatar(order.consumerId), }, { id: order.playerId, - name: order.playerName, + nickname: "", avatar: resolveAvatar(order.playerId), }, ], unreadCount: 0, - readonly, } set((state) => ({ @@ -69,7 +55,7 @@ export const useChatStore = create((set, get) => ({ const text = content.trim() if (!text) return const session = get().sessions.find((item) => item.id === sessionId) - if (!session || session.readonly) return + if (!session) return const sender = session.participants.find((participant) => participant.id === actorId) if (!sender) return @@ -79,8 +65,6 @@ export const useChatStore = create((set, get) => ({ id: generateId("msg"), sessionId, senderId: actorId, - senderName: sender.name, - senderAvatar: sender.avatar, type: "text", content: text, createdAt: now, @@ -88,22 +72,14 @@ export const useChatStore = create((set, get) => ({ set((state) => ({ messages: [...state.messages, message], - sessions: state.sessions.map((session) => - session.id === sessionId - ? { - ...session, - lastMessage: text, - lastMessageAt: now, - } - : session, - ), + sessions: state.sessions.map((s) => (s.id === sessionId ? { ...s, lastMessage: text } : s)), })) }, sendImageMessage: (sessionId, actorId, imageUrl) => { const content = imageUrl.trim() if (!content) return const session = get().sessions.find((item) => item.id === sessionId) - if (!session || session.readonly) return + if (!session) return const sender = session.participants.find((participant) => participant.id === actorId) if (!sender) return @@ -113,8 +89,6 @@ export const useChatStore = create((set, get) => ({ id: generateId("msg"), sessionId, senderId: actorId, - senderName: sender.name, - senderAvatar: sender.avatar, type: "image", content, createdAt: now, @@ -123,13 +97,7 @@ export const useChatStore = create((set, get) => ({ set((state) => ({ messages: [...state.messages, message], sessions: state.sessions.map((item) => - item.id === sessionId - ? { - ...item, - lastMessage: "[图片]", - lastMessageAt: now, - } - : item, + item.id === sessionId ? { ...item, lastMessage: "[图片]" } : item, ), })) }, diff --git a/store/comments.ts b/store/comments.ts index bf0acd3..78d84ab 100644 --- a/store/comments.ts +++ b/store/comments.ts @@ -16,7 +16,6 @@ export const useCommentStore = create((set) => ({ const comment: Comment = { id: generateId("comment"), - postId, author, content: normalizedContent, likeCount: 0, diff --git a/store/disputes.ts b/store/disputes.ts index b882e7a..84bad09 100644 --- a/store/disputes.ts +++ b/store/disputes.ts @@ -28,8 +28,6 @@ export interface DisputeRecord extends Dispute { interface SubmitDisputeInput { orderId: string - initiatorId: string - initiatorName: string reason: string evidence: string[] } @@ -180,7 +178,7 @@ export const useDisputeStore = create((set, get) => { return { decision: deny(400, "请填写争议原因") } } - const actor = resolveParticipantActor(input.orderId, input.initiatorId) + const actor = resolveParticipantActor(input.orderId, useAuthStore.getState().user?.id ?? "") if (!actor) { return { decision: deny(403, "仅订单参与方可发起争议") } } @@ -194,8 +192,6 @@ export const useDisputeStore = create((set, get) => { const dispute: DisputeRecord = { id: generateId("disp"), orderId: input.orderId, - initiatorId: input.initiatorId, - initiatorName: input.initiatorName, reason: input.reason.trim(), evidence: input.evidence, status: "open", @@ -205,7 +201,7 @@ export const useDisputeStore = create((set, get) => { { id: generateId("timeline"), type: "created", - content: `${input.initiatorName} 提交争议`, + content: "争议已提交", createdAt, }, ], @@ -221,15 +217,16 @@ export const useDisputeStore = create((set, get) => { return deny(404, "争议不存在") } + const order = useOrderStore.getState().orders.find((item) => item.id === dispute.orderId) + if (!order) { + return deny(404, "关联订单不存在") + } + const actor = resolveParticipantActor(dispute.orderId, actorId) if (!actor) { return deny(403, "仅订单参与方可提交回应") } - if (actorId === dispute.initiatorId) { - return deny(403, "争议发起方不可提交回应") - } - if (dispute.respondentReason) { return deny(400, "回应已提交") } diff --git a/store/orders.ts b/store/orders.ts index 03a7593..de42010 100644 --- a/store/orders.ts +++ b/store/orders.ts @@ -14,7 +14,6 @@ import { useChatStore } from "@/store/chat" import { useNotificationStore } from "@/store/notifications" import { usePlayerStore } from "@/store/players" import { useServiceStore } from "@/store/services" -import { useShopStore } from "@/store/shops" import { useWalletStore } from "@/store/wallet" import { create } from "zustand" @@ -112,22 +111,15 @@ function applyStatus(order: Order, status: OrderStatus): Order { acceptedAt: order.acceptedAt ?? now, } case "pending_close": - return { - ...order, - status, - closedAt: order.closedAt ?? now, - } case "pending_review": return { ...order, status, - closedAt: order.closedAt ?? now, } case "completed": return { ...order, status, - closedAt: order.closedAt ?? now, completedAt: order.completedAt ?? now, } default: @@ -205,7 +197,7 @@ function notifyOrderStatus(order: Order) { }, in_progress: { title: "订单已接单", - content: `${order.playerName} 已开始服务`, + content: `订单 ${order.service.title} 已开始服务`, }, pending_close: { title: "订单发起结单", @@ -332,10 +324,6 @@ export const useOrderStore = create((set, get) => { return { decision: deny(400, "店铺信息与打手不匹配") } } - const resolvedShopName = resolvedShopId - ? useShopStore.getState().shops.find((item) => item.id === resolvedShopId)?.name - : undefined - const quantity = Number.isFinite(input.quantity) ? Math.floor(input.quantity) : Number.NaN if (!quantity || quantity < 1) { return { decision: deny(400, "数量不合法") } @@ -345,11 +333,8 @@ export const useOrderStore = create((set, get) => { const order: Order = { id: generateId("ord"), consumerId: consumer.id, - consumerName: consumer.nickname, playerId: player.id, - playerName: player.user.nickname, shopId: resolvedShopId, - shopName: resolvedShopName, service, status: "pending_payment", totalPrice, @@ -395,10 +380,6 @@ export const useOrderStore = create((set, get) => { return { decision: deny(400, "店铺信息与打手不匹配") } } - const resolvedShopName = resolvedShopId - ? useShopStore.getState().shops.find((item) => item.id === resolvedShopId)?.name - : undefined - const quantity = Number.isFinite(input.quantity) ? Math.floor(input.quantity) : Number.NaN if (!quantity || quantity < 1) { return { decision: deny(400, "数量不合法") } @@ -420,11 +401,8 @@ export const useOrderStore = create((set, get) => { const order: Order = { id: orderId, consumerId: consumer.id, - consumerName: consumer.nickname, playerId: player.id, - playerName: player.user.nickname, shopId: resolvedShopId, - shopName: resolvedShopName, service, status: "pending_accept", totalPrice, @@ -465,17 +443,6 @@ useOrderStore.subscribe((state, prevState) => { const prevOrder = prevState.orders.find((item) => item.id === order.id) if (!prevOrder || prevOrder.status !== order.status) { scheduleOrderTimeout(order.id, order.status) - if (order.status === "pending_accept" && order.shopId) { - const shop = useShopStore.getState().shops.find((s) => s.id === order.shopId) - if (shop?.dispatchMode === "auto") { - setTimeout(() => { - const current = useOrderStore.getState().orders.find((o) => o.id === order.id) - if (!current || current.status !== "pending_accept") return - const actor: Actor = { userId: order.playerId, role: "player", shopId: order.shopId } - useOrderStore.getState().acceptOrder(order.id, actor) - }, 3000) - } - } } }) prevState.orders.forEach((order) => { diff --git a/store/posts.ts b/store/posts.ts index d828f46..7d8e423 100644 --- a/store/posts.ts +++ b/store/posts.ts @@ -1,16 +1,14 @@ import { generateId } from "@/lib/id" -import type { Post, User, UserRole } from "@/lib/types" +import type { Post, User } from "@/lib/types" import { create } from "zustand" interface CreatePostInput { author: User - authorRole: UserRole title: string content: string images: string[] tags: string[] linkedOrderId?: string - quotedPostId?: string } interface PostState { @@ -26,17 +24,15 @@ export const usePostStore = create((set) => ({ const post: Post = { id: generateId("post"), author: input.author, - authorRole: input.authorRole, title: input.title.trim(), content: input.content.trim(), images: input.images, tags: input.tags, - linkedOrderId: input.linkedOrderId, - quotedPostId: input.quotedPostId, + linkedOrderId: input.linkedOrderId ? Number(input.linkedOrderId) : undefined, + pinned: false, likeCount: 0, commentCount: 0, liked: false, - pinned: false, createdAt: new Date().toISOString(), } diff --git a/store/reviews.ts b/store/reviews.ts index 801171c..30b2233 100644 --- a/store/reviews.ts +++ b/store/reviews.ts @@ -19,29 +19,6 @@ interface ReviewState { hasUserReviewed: (orderId: string, userId: string) => boolean } -function resolveOrderUser(orderId: string, userId: string) { - const order = useOrderStore.getState().orders.find((item) => item.id === orderId) - if (!order) return null - - if (order.consumerId === userId) { - return { - fromUserName: order.consumerName, - toUserId: order.playerId, - toUserName: order.playerName, - } - } - - if (order.playerId === userId) { - return { - fromUserName: order.playerName, - toUserId: order.consumerId, - toUserName: order.consumerName, - } - } - - return null -} - export const useReviewStore = create((set, get) => ({ reviews: [], getReviewsByOrder: (orderId) => get().reviews.filter((review) => review.orderId === orderId), @@ -65,8 +42,9 @@ export const useReviewStore = create((set, get) => ({ return deny(400, "仅待评价订单可提交评价") } - const relation = resolveOrderUser(input.orderId, input.fromUserId) - if (!relation) { + const isParticipant = + order.consumerId === input.fromUserId || order.playerId === input.fromUserId + if (!isParticipant) { return deny(403, "仅订单参与方可评价") } @@ -81,11 +59,9 @@ export const useReviewStore = create((set, get) => ({ id: generateId("rev"), orderId: input.orderId, fromUserId: input.fromUserId, - fromUserName: relation.fromUserName, - fromUserAvatar: "", - toUserId: relation.toUserId, + fromUserName: "", rating: input.rating, - content: input.content?.trim() || undefined, + content: input.content?.trim() ?? "", sealed: true, createdAt, } diff --git a/store/wallet.ts b/store/wallet.ts index e9a5cd1..efdbbc9 100644 --- a/store/wallet.ts +++ b/store/wallet.ts @@ -27,7 +27,7 @@ export const useWalletStore = create((set, get) => ({ { id: generateId("tx"), type: "topup", - amount, + amount: String(amount), description: "充值", createdAt: now, }, @@ -43,7 +43,7 @@ export const useWalletStore = create((set, get) => ({ { id: generateId("tx"), type: "withdrawal", - amount: -amount, + amount: String(-amount), description: "提现到银行卡", createdAt: now, }, @@ -69,7 +69,7 @@ export const useWalletStore = create((set, get) => ({ { id: generateId("tx"), type: "payment", - amount: -amount, + amount: String(-amount), description: `支付订单 ${orderId}`, createdAt: now, }, @@ -100,7 +100,7 @@ export const useWalletStore = create((set, get) => ({ { id: generateId("tx"), type: "refund", - amount, + amount: String(amount), description: `订单 ${orderId} 退款`, createdAt: now, }, @@ -130,7 +130,7 @@ export const useWalletStore = create((set, get) => ({ { id: generateId("tx"), type: "income", - amount: income, + amount: String(income), description: `订单 ${orderId} 收入(${commissionLabel})`, createdAt: now, },