feat(chat): migrate chat protocol to lock detail

This commit is contained in:
2026-06-24 14:06:30 +08:00
parent c280a3c1ea
commit 42c03f8901
34 changed files with 609 additions and 373 deletions
+6 -7
View File
@@ -3,24 +3,23 @@
* 原始 Dart: ChatMessage (lib/data/models/chat/chat_response.dart)
*/
import { z } from "zod";
import { ChatImageSchema, ChatLockDetailSchema } from "./chat_payloads";
export const ChatMessageSchema = z
.object({
role: z.string(),
type: z.string().default("text"),
content: z.string(),
id: z.string().default(""),
createdAt: z.string().default(""),
created_at: z.string().optional(),
imageUrl: z.string().nullable().default(null),
image_url: z.string().nullable().optional(),
isPrivate: z.boolean().nullable().default(null),
privateLocked: z.boolean().nullable().default(null),
privateHint: z.string().nullable().default(null),
audioUrl: z.string().nullable().default(null),
image: ChatImageSchema,
lockDetail: ChatLockDetailSchema,
})
.transform(({ created_at, image_url, ...data }) => ({
.transform(({ created_at, ...data }) => ({
...data,
createdAt: data.createdAt || created_at || "",
imageUrl: data.imageUrl || image_url || null,
}));
export type ChatMessageInput = z.input<typeof ChatMessageSchema>;
+34
View File
@@ -0,0 +1,34 @@
/**
* Chat wire payload fragments shared by send response and history messages.
*/
import { z } from "zod";
export const ChatImageSchema = z
.object({
type: z.string().nullable().default(null),
url: z.string().nullable().default(null),
})
.default({ type: null, url: null });
export const ChatLockDetailSchema = z
.object({
locked: z.boolean().default(false),
showContent: z.boolean().default(true),
showUpgrade: z.boolean().default(false),
reason: z.string().nullable().default(null),
hint: z.string().nullable().default(null),
detail: z.record(z.string(), z.unknown()).nullable().default(null),
})
.default({
locked: false,
showContent: true,
showUpgrade: false,
reason: null,
hint: null,
detail: null,
});
export type ChatImageInput = z.input<typeof ChatImageSchema>;
export type ChatImageData = z.output<typeof ChatImageSchema>;
export type ChatLockDetailInput = z.input<typeof ChatLockDetailSchema>;
export type ChatLockDetailData = z.output<typeof ChatLockDetailSchema>;
+3 -24
View File
@@ -3,39 +3,18 @@
* 原始 Dart: ChatSendResponse (lib/data/models/chat/chat_response.dart)
*/
import { z } from "zod";
export const ChatBlockDetailSchema = z.object({
type: z.string(),
usedToday: z.number().optional(),
usedTotal: z.number().optional(),
limit: z.number(),
});
import { ChatImageSchema, ChatLockDetailSchema } from "./chat_payloads";
export const ChatSendResponseSchema = z.object({
mode: z.string().default(""),
reply: z.string(),
voiceUrl: z.string().default(""),
audioUrl: z.string().default(""),
intimacyChange: z.number().default(0),
newIntimacy: z.number().default(0),
relationshipStage: z.string(),
currentMood: z.string().default(""),
messageId: z.string(),
isGuest: z.boolean().default(false),
// 函数式 default —— 每次 parse 时重新调 Date.now()(后端不返回 timestamp 时用当下时间)
timestamp: z.number().default(() => Date.now()),
blocked: z.boolean().nullable().default(null),
blockReason: z.string().nullable().default(null),
blockDetail: ChatBlockDetailSchema.nullable().default(null),
paywallTriggered: z.boolean().default(false),
showUpgrade: z.boolean().default(false),
imageType: z.string().nullable().default(null),
isPrivate: z.boolean().nullable().default(null),
privateLocked: z.boolean().nullable().default(null),
privateHint: z.string().nullable().default(null),
imageUrl: z.string().nullable().default(null),
image: ChatImageSchema,
lockDetail: ChatLockDetailSchema,
});
export type ChatSendResponseInput = z.input<typeof ChatSendResponseSchema>;
export type ChatSendResponseData = z.output<typeof ChatSendResponseSchema>;
export type ChatBlockDetailData = z.output<typeof ChatBlockDetailSchema>;
+1
View File
@@ -4,6 +4,7 @@
export * from "./chat_history_response";
export * from "./chat_message";
export * from "./chat_payloads";
export * from "./chat_send_response";
export * from "./chat_sync_data";
export * from "./chat_sync_request";