89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
/**
|
|
* 发送消息响应
|
|
*
|
|
*/
|
|
import { z } from "zod";
|
|
import {
|
|
booleanOrFalse,
|
|
booleanOrTrue,
|
|
numberOrLazy,
|
|
numberOrZero,
|
|
stringOrEmpty,
|
|
} from "../../nullable-defaults";
|
|
import { ChatImageSchema, ChatLockDetailSchema } from "../chat_payloads";
|
|
import { ChatActionSchema } from "../chat_action";
|
|
|
|
export const PaymentGuidanceSceneSchema = z.enum([
|
|
"vip",
|
|
"insufficientCredits",
|
|
"chatInterrupted",
|
|
"voiceLocked",
|
|
"imageLocked",
|
|
"privateMessageLocked",
|
|
"historyLocked",
|
|
"privateZoneLocked",
|
|
"unknownLock",
|
|
"whyPay",
|
|
"leavingAfterCredits",
|
|
"paymentIssue",
|
|
"externalRisk",
|
|
"purchaseOptions",
|
|
]);
|
|
|
|
export const PaymentGuidanceSchema = z
|
|
.object({
|
|
guidanceId: z.string().min(1),
|
|
characterId: z.string().min(1),
|
|
characterName: z.string().min(1),
|
|
scene: PaymentGuidanceSceneSchema,
|
|
mode: z.enum(["guide", "careOnly", "issueSupport", "riskReminder"]),
|
|
title: z.string().nullable().default(null),
|
|
copy: z.string().min(1),
|
|
ctaLabel: z.string().nullable().default(null),
|
|
purchaseOptions: z.array(z.enum(["vip", "topup"])).readonly(),
|
|
target: z.enum(["subscription", "giftCatalog"]).nullable().default(null),
|
|
ruleId: z.string().min(1),
|
|
})
|
|
.readonly();
|
|
|
|
export type PaymentGuidance = z.output<typeof PaymentGuidanceSchema>;
|
|
|
|
export const CommercialActionSchema = z
|
|
.object({
|
|
actionId: z.string().min(1),
|
|
type: z.enum(["giftOffer", "privateAlbumOffer", "discountOffer"]),
|
|
copy: z.string().min(1),
|
|
ctaLabel: z.string().min(1),
|
|
target: z.enum(["giftCatalog", "privateZone", "discountConsent"]),
|
|
ruleId: z.string().min(1),
|
|
})
|
|
.readonly();
|
|
|
|
export type CommercialAction = z.output<typeof CommercialActionSchema>;
|
|
|
|
export const ChatSendResponseSchema = z
|
|
.object({
|
|
reply: stringOrEmpty,
|
|
audioUrl: stringOrEmpty,
|
|
messageId: stringOrEmpty,
|
|
isGuest: booleanOrFalse,
|
|
// 函数式 default —— 每次 parse 时重新调 Date.now()(后端不返回 timestamp 时用当下时间)
|
|
timestamp: numberOrLazy(() => Date.now()),
|
|
image: ChatImageSchema,
|
|
lockDetail: ChatLockDetailSchema,
|
|
canSendMessage: booleanOrTrue,
|
|
creditBalance: numberOrZero,
|
|
creditsCharged: numberOrZero,
|
|
requiredCredits: numberOrZero,
|
|
shortfallCredits: numberOrZero,
|
|
commercialAction: CommercialActionSchema.nullish().default(null),
|
|
paymentGuidance: PaymentGuidanceSchema.nullish().default(null),
|
|
chatAction: ChatActionSchema.nullish().default(null),
|
|
})
|
|
.readonly();
|
|
|
|
export type ChatSendResponseInput = z.input<typeof ChatSendResponseSchema>;
|
|
export type ChatSendResponseData = z.output<typeof ChatSendResponseSchema>;
|
|
|
|
export type ChatSendResponse = ChatSendResponseData;
|