diff --git a/lib/domain/income.ts b/lib/domain/income.ts index bc42e71..47c1aca 100644 --- a/lib/domain/income.ts +++ b/lib/domain/income.ts @@ -19,15 +19,17 @@ export function calculateOrderIncome(totalPrice: number, shop?: ShopCommission): } } + const commission = Number(shop.commissionValue) + if (shop.commissionType === "percentage") { return { - income: roundCurrency(totalPrice * (1 - shop.commissionValue / 100)), + income: roundCurrency(totalPrice * (1 - commission / 100)), commissionLabel: `扣除${shop.commissionValue}%抽成`, } } return { - income: roundCurrency(Math.max(0, totalPrice - shop.commissionValue)), + income: roundCurrency(Math.max(0, totalPrice - commission)), commissionLabel: `扣除¥${shop.commissionValue}固定抽成`, } } diff --git a/lib/search/search-catalog.ts b/lib/search/search-catalog.ts index 3e007e6..ca378b1 100644 --- a/lib/search/search-catalog.ts +++ b/lib/search/search-catalog.ts @@ -100,7 +100,7 @@ export function searchCatalog( __index: nextIndex++, type: "shop", shop, - rating: shop.rating, + rating: Number(shop.rating), orders: shop.totalOrders, minPrice: derived.minPrice, unit: derived.unit, @@ -148,7 +148,7 @@ export function searchCatalog( if (item.type === "player") { if (item.player.rating < minRating) return false } else { - if (item.shop.rating < minRating) return false + if (Number(item.shop.rating) < minRating) return false } return true diff --git a/lib/types.ts b/lib/types.ts index 8febf19..5d6b00d 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -9,7 +9,6 @@ export type VerificationStatus = "pending" | "approved" | "rejected" export interface User { id: SnowflakeId username: string - email?: string nickname: string avatar: string role: UserRole @@ -24,7 +23,7 @@ export interface Game { id: SnowflakeId name: string icon: string - category: "MOBA" | "FPS" | "动作" | "RPG" + category: string } export interface PlayerService { @@ -51,6 +50,7 @@ export interface Player { services: PlayerService[] shopId?: SnowflakeId shopName?: string + gender: boolean tags: string[] } @@ -60,11 +60,11 @@ export interface Shop { name: string banner?: string description: string - rating: number + rating: string totalOrders: number playerCount: number commissionType: "fixed" | "percentage" - commissionValue: number + commissionValue: string allowMultiShop: boolean allowIndependentOrders: boolean dispatchMode: "manual" | "auto" @@ -95,18 +95,14 @@ export type OrderStatus = export interface Order { id: SnowflakeId consumerId: SnowflakeId - consumerName: string playerId: SnowflakeId - playerName: string shopId?: SnowflakeId - shopName?: string service: PlayerService status: OrderStatus totalPrice: number note?: string createdAt: string acceptedAt?: string - closedAt?: string completedAt?: string } @@ -115,10 +111,8 @@ export interface Review { orderId: SnowflakeId fromUserId: SnowflakeId fromUserName: string - fromUserAvatar: string - toUserId: SnowflakeId rating: number - content?: string + content: string sealed: boolean createdAt: string } @@ -126,8 +120,6 @@ export interface Review { export interface Dispute { id: SnowflakeId orderId: SnowflakeId - initiatorId: SnowflakeId - initiatorName: string reason: string evidence: string[] status: "open" | "reviewing" | "resolved" | "appealed" @@ -135,13 +127,17 @@ export interface Dispute { createdAt: string } +export interface ChatParticipant { + id: SnowflakeId + nickname: string + avatar: string +} + interface BaseChatSession { id: SnowflakeId - participants: { id: SnowflakeId; name: string; avatar: string }[] + participants: ChatParticipant[] lastMessage?: string - lastMessageAt?: string unreadCount: number - readonly: boolean } export interface OrderChatSession extends BaseChatSession { @@ -160,8 +156,6 @@ export interface ChatMessage { id: SnowflakeId sessionId: SnowflakeId senderId: SnowflakeId - senderName: string - senderAvatar: string type: "text" | "image" | "system" content: string createdAt: string @@ -170,23 +164,20 @@ export interface ChatMessage { export interface Post { id: SnowflakeId author: User - authorRole: UserRole title: string content: string images: string[] tags: string[] - linkedOrderId?: SnowflakeId - quotedPostId?: SnowflakeId + linkedOrderId?: number + pinned: boolean likeCount: number commentCount: number liked: boolean - pinned: boolean createdAt: string } export interface Comment { id: SnowflakeId - postId: SnowflakeId author: User content: string likeCount: number @@ -207,8 +198,9 @@ export interface Notification { export interface WalletTransaction { id: SnowflakeId type: "topup" | "payment" | "income" | "withdrawal" | "refund" - amount: number + amount: string description: string + orderId?: string createdAt: string } diff --git a/tests/income-calculation.test.ts b/tests/income-calculation.test.ts index 11cf0af..5825d7d 100644 --- a/tests/income-calculation.test.ts +++ b/tests/income-calculation.test.ts @@ -5,7 +5,7 @@ describe("calculateOrderIncome", () => { it("calculates percentage commission income", () => { const result = calculateOrderIncome(100, { commissionType: "percentage", - commissionValue: 12, + commissionValue: "12", }) expect(result).toEqual({ @@ -17,7 +17,7 @@ describe("calculateOrderIncome", () => { it("calculates fixed commission income", () => { const result = calculateOrderIncome(60, { commissionType: "fixed", - commissionValue: 8, + commissionValue: "8", }) expect(result).toEqual({ @@ -38,7 +38,7 @@ describe("calculateOrderIncome", () => { it("does not return negative income for fixed commission", () => { const result = calculateOrderIncome(6, { commissionType: "fixed", - commissionValue: 8, + commissionValue: "8", }) expect(result.income).toBe(0) diff --git a/tests/search-catalog.test.ts b/tests/search-catalog.test.ts index eb16878..647c03a 100644 --- a/tests/search-catalog.test.ts +++ b/tests/search-catalog.test.ts @@ -34,6 +34,7 @@ const players: SearchCatalogData["players"] = [ }, ], shopId: "3002", + gender: true, tags: ["moba"], }, { @@ -65,6 +66,7 @@ const players: SearchCatalogData["players"] = [ }, ], shopId: "3003", + gender: true, tags: [], }, { @@ -96,6 +98,7 @@ const players: SearchCatalogData["players"] = [ }, ], shopId: "3001", + gender: false, tags: ["fps"], }, { @@ -127,6 +130,7 @@ const players: SearchCatalogData["players"] = [ }, ], shopId: "3003", + gender: true, tags: [], }, ] @@ -144,13 +148,13 @@ const shops: SearchCatalogData["shops"] = [ }, name: "CS2 Hub", description: "", - rating: 4.6, + rating: "4.6", totalOrders: 300, playerCount: 1, commissionType: "fixed", - commissionValue: 0, + commissionValue: "0", allowMultiShop: false, - allowIndependentOrders: true, + allowIndependentOrders: false, dispatchMode: "manual", announcements: [], templateConfig: { sections: [] }, @@ -167,13 +171,13 @@ const shops: SearchCatalogData["shops"] = [ }, name: "Yuki Studio", description: "", - rating: 4.2, + rating: "4.2", totalOrders: 50, playerCount: 1, commissionType: "fixed", - commissionValue: 0, + commissionValue: "0", allowMultiShop: false, - allowIndependentOrders: true, + allowIndependentOrders: false, dispatchMode: "manual", announcements: [], templateConfig: { sections: [] }, @@ -190,13 +194,13 @@ const shops: SearchCatalogData["shops"] = [ }, name: "Quiet Shop", description: "", - rating: 3.8, + rating: "3.8", totalOrders: 10, playerCount: 2, commissionType: "fixed", - commissionValue: 0, + commissionValue: "0", allowMultiShop: false, - allowIndependentOrders: true, + allowIndependentOrders: false, dispatchMode: "manual", announcements: [], templateConfig: { sections: [] },