refactor(api): add adapter layer for order/chat/review/dispute writes
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { allow, deny } from "@/lib/policy/assert"
|
||||
import { useChatStore } from "@/store/chat"
|
||||
import { useAuthStore } from "@/store/auth"
|
||||
|
||||
export function listChatSessions() {
|
||||
return useChatStore.getState().sessions
|
||||
@@ -11,3 +13,43 @@ export function getChatSessionById(sessionId: string) {
|
||||
export function listChatMessages(sessionId: string) {
|
||||
return useChatStore.getState().messages.filter((message) => message.sessionId === sessionId)
|
||||
}
|
||||
|
||||
export function sendTextMessage(sessionId: string, content: string) {
|
||||
const userId = useAuthStore.getState().user?.id
|
||||
if (!userId) return deny("AUTH_REQUIRED", "请先登录")
|
||||
|
||||
const chatState = useChatStore.getState()
|
||||
const session = chatState.sessions.find((item) => item.id === sessionId)
|
||||
if (!session) return deny("NOT_FOUND", "会话不存在")
|
||||
if (session.readonly) return deny("INVALID_STATUS", "当前会话只读")
|
||||
if (!session.participants.some((participant) => participant.id === userId)) {
|
||||
return deny("NOT_PARTICIPANT", "仅会话参与方可发送消息")
|
||||
}
|
||||
|
||||
if (!content.trim()) {
|
||||
return deny("VALIDATION_FAILED", "消息不能为空")
|
||||
}
|
||||
|
||||
chatState.sendTextMessage(sessionId, userId, content)
|
||||
return allow()
|
||||
}
|
||||
|
||||
export function sendImageMessage(sessionId: string, imageUrl: string) {
|
||||
const userId = useAuthStore.getState().user?.id
|
||||
if (!userId) return deny("AUTH_REQUIRED", "请先登录")
|
||||
|
||||
const chatState = useChatStore.getState()
|
||||
const session = chatState.sessions.find((item) => item.id === sessionId)
|
||||
if (!session) return deny("NOT_FOUND", "会话不存在")
|
||||
if (session.readonly) return deny("INVALID_STATUS", "当前会话只读")
|
||||
if (!session.participants.some((participant) => participant.id === userId)) {
|
||||
return deny("NOT_PARTICIPANT", "仅会话参与方可发送消息")
|
||||
}
|
||||
|
||||
if (!imageUrl.trim()) {
|
||||
return deny("VALIDATION_FAILED", "图片地址无效")
|
||||
}
|
||||
|
||||
chatState.sendImageMessage(sessionId, userId, imageUrl)
|
||||
return allow()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { deny } from "@/lib/policy/assert"
|
||||
import { useAuthStore } from "@/store/auth"
|
||||
import { useDisputeStore } from "@/store/disputes"
|
||||
|
||||
export function listDisputes() {
|
||||
@@ -7,3 +9,42 @@ export function listDisputes() {
|
||||
export function getDisputeByOrderId(orderId: string) {
|
||||
return useDisputeStore.getState().disputes.find((dispute) => dispute.orderId === orderId)
|
||||
}
|
||||
|
||||
export function submitDispute(input: { orderId: string; reason: string; evidence: string[] }) {
|
||||
const user = useAuthStore.getState().user
|
||||
if (!user?.id || !user.nickname) {
|
||||
return { decision: deny("AUTH_REQUIRED", "请先登录") }
|
||||
}
|
||||
|
||||
return useDisputeStore.getState().submitDispute({
|
||||
orderId: input.orderId,
|
||||
initiatorId: user.id,
|
||||
initiatorName: user.nickname,
|
||||
reason: input.reason,
|
||||
evidence: input.evidence,
|
||||
})
|
||||
}
|
||||
|
||||
export function submitDisputeResponse(input: {
|
||||
disputeId: string
|
||||
reason: string
|
||||
evidence: string[]
|
||||
}) {
|
||||
const userId = useAuthStore.getState().user?.id
|
||||
if (!userId) {
|
||||
return deny("AUTH_REQUIRED", "请先登录")
|
||||
}
|
||||
|
||||
return useDisputeStore
|
||||
.getState()
|
||||
.submitResponse(input.disputeId, userId, input.reason, input.evidence)
|
||||
}
|
||||
|
||||
export function submitDisputeAppeal(input: { disputeId: string; reason: string }) {
|
||||
const userId = useAuthStore.getState().user?.id
|
||||
if (!userId) {
|
||||
return deny("AUTH_REQUIRED", "请先登录")
|
||||
}
|
||||
|
||||
return useDisputeStore.getState().submitAppeal(input.disputeId, userId, input.reason)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { resolveOwnerShop } from "@/lib/domain/resolve-current-shop"
|
||||
import { allow, deny } from "@/lib/policy/assert"
|
||||
import type { Actor } from "@/lib/policy/actor"
|
||||
import type { PolicyDecision } from "@/lib/policy/decision"
|
||||
import type { PlayerService } from "@/lib/types"
|
||||
import { useAuthStore } from "@/store/auth"
|
||||
import { useOrderStore } from "@/store/orders"
|
||||
import { useShopStore } from "@/store/shops"
|
||||
|
||||
export function listOrders() {
|
||||
return useOrderStore.getState().orders
|
||||
@@ -11,3 +18,82 @@ export function getOrderById(orderId: string) {
|
||||
export function listOrdersByConsumer(consumerId: string) {
|
||||
return useOrderStore.getState().orders.filter((order) => order.consumerId === consumerId)
|
||||
}
|
||||
|
||||
interface CreatePaidOrderInput {
|
||||
consumerId: string
|
||||
consumerName: string
|
||||
playerId: string
|
||||
playerName: string
|
||||
shopId?: string
|
||||
shopName?: string
|
||||
service: PlayerService
|
||||
totalPrice: number
|
||||
note?: string
|
||||
}
|
||||
|
||||
function resolveActorContext(): { actor?: Actor; decision: PolicyDecision } {
|
||||
const auth = useAuthStore.getState()
|
||||
if (!auth.user?.id) {
|
||||
return { decision: deny("AUTH_REQUIRED", "请先登录") }
|
||||
}
|
||||
|
||||
const shopId =
|
||||
auth.currentRole === "owner"
|
||||
? resolveOwnerShop(auth.user.id, useShopStore.getState().shops)?.id
|
||||
: undefined
|
||||
|
||||
return {
|
||||
actor: {
|
||||
userId: auth.user.id,
|
||||
role: auth.currentRole,
|
||||
shopId,
|
||||
},
|
||||
decision: allow(),
|
||||
}
|
||||
}
|
||||
|
||||
export function createPaidOrder(input: CreatePaidOrderInput) {
|
||||
const { actor, decision } = resolveActorContext()
|
||||
if (!actor) return { decision }
|
||||
return useOrderStore.getState().createPaidOrder(input, actor)
|
||||
}
|
||||
|
||||
export function payOrder(orderId: string) {
|
||||
const { actor, decision } = resolveActorContext()
|
||||
if (!actor) return { decision }
|
||||
return useOrderStore.getState().payOrder(orderId, actor)
|
||||
}
|
||||
|
||||
export function acceptOrder(orderId: string) {
|
||||
const { actor, decision } = resolveActorContext()
|
||||
if (!actor) return { decision }
|
||||
return useOrderStore.getState().acceptOrder(orderId, actor)
|
||||
}
|
||||
|
||||
export function acceptOrderAsActor(orderId: string, actor: Actor) {
|
||||
return useOrderStore.getState().acceptOrder(orderId, actor)
|
||||
}
|
||||
|
||||
export function requestClose(orderId: string) {
|
||||
const { actor, decision } = resolveActorContext()
|
||||
if (!actor) return { decision }
|
||||
return useOrderStore.getState().requestClose(orderId, actor)
|
||||
}
|
||||
|
||||
export function confirmClose(orderId: string) {
|
||||
const { actor, decision } = resolveActorContext()
|
||||
if (!actor) return { decision }
|
||||
return useOrderStore.getState().confirmClose(orderId, actor)
|
||||
}
|
||||
|
||||
export function cancelPreAccept(orderId: string) {
|
||||
const { actor, decision } = resolveActorContext()
|
||||
if (!actor) return { decision }
|
||||
return useOrderStore.getState().cancelPreAccept(orderId, actor)
|
||||
}
|
||||
|
||||
export function markDisputed(orderId: string) {
|
||||
const { actor, decision } = resolveActorContext()
|
||||
if (!actor) return { decision }
|
||||
return useOrderStore.getState().markDisputed(orderId, actor)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { deny } from "@/lib/policy/assert"
|
||||
import { useAuthStore } from "@/store/auth"
|
||||
import { useReviewStore } from "@/store/reviews"
|
||||
|
||||
export function listReviews() {
|
||||
@@ -11,3 +13,17 @@ export function listReviewsByOrder(orderId: string) {
|
||||
export function listReviewsByTargetUser(userId: string) {
|
||||
return useReviewStore.getState().reviews.filter((review) => review.toUserId === userId)
|
||||
}
|
||||
|
||||
export function submitReview(input: { orderId: string; rating: number; content?: string }) {
|
||||
const userId = useAuthStore.getState().user?.id
|
||||
if (!userId) {
|
||||
return deny("AUTH_REQUIRED", "请先登录")
|
||||
}
|
||||
|
||||
return useReviewStore.getState().submitReview({
|
||||
orderId: input.orderId,
|
||||
fromUserId: userId,
|
||||
rating: input.rating,
|
||||
content: input.content,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user