fix(chat): handle guest total limit
This commit is contained in:
@@ -43,10 +43,15 @@ export function ChatScreen() {
|
||||
// isGuest 派生(chat-screen 是唯一知道这个值的地方 —— chat 机器无 isGuest 字段)
|
||||
const isGuest = deriveIsGuest(authState.loginStatus);
|
||||
|
||||
// 消息数量限制由后端统一返回 blocked/daily_limit,前端不再处理本地额度。
|
||||
const showDailyLimitBanner =
|
||||
// 消息数量限制由后端统一返回 blocked,前端不再处理本地额度。
|
||||
const showMessageLimitBanner =
|
||||
state.paywallTriggered &&
|
||||
state.paywallReason === "daily_limit";
|
||||
(state.paywallReason === "daily_limit" ||
|
||||
state.paywallReason === "total_limit");
|
||||
const messageLimitTitle =
|
||||
state.paywallReason === "total_limit"
|
||||
? "The limit for free chat times\nhas been reached"
|
||||
: undefined;
|
||||
const showPhotoPaywallBanner =
|
||||
state.paywallTriggered && state.paywallReason === "photo_paywall";
|
||||
const showPrivatePaywallBanner =
|
||||
@@ -168,8 +173,9 @@ export function ChatScreen() {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{showDailyLimitBanner ? (
|
||||
{showMessageLimitBanner ? (
|
||||
<ChatQuotaExhaustedBanner
|
||||
title={messageLimitTitle}
|
||||
/>
|
||||
) : (
|
||||
<ChatInputBar disabled={state.isReplyingAI} />
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"success": true,
|
||||
"data": {
|
||||
"mode": "http",
|
||||
"type": "text",
|
||||
"reply": "",
|
||||
"voiceUrl": "",
|
||||
"audioUrl": "",
|
||||
"intimacyChange": 0,
|
||||
"newIntimacy": 0,
|
||||
"relationshipStage": "密友",
|
||||
"currentMood": "happy",
|
||||
"messageId": "",
|
||||
"isGuest": true,
|
||||
"timestamp": 1782197944984,
|
||||
"blocked": true,
|
||||
"blockReason": "total_limit",
|
||||
"blockDetail": {
|
||||
"type": "guest_total_msg_limit",
|
||||
"usedTotal": 12,
|
||||
"limit": 5
|
||||
},
|
||||
"paywallTriggered": false,
|
||||
"showUpgrade": false,
|
||||
"imageType": null,
|
||||
"imageUrl": null
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,8 @@ import { z } from "zod";
|
||||
|
||||
export const ChatBlockDetailSchema = z.object({
|
||||
type: z.string(),
|
||||
usedToday: z.number(),
|
||||
usedToday: z.number().optional(),
|
||||
usedTotal: z.number().optional(),
|
||||
limit: z.number(),
|
||||
});
|
||||
|
||||
|
||||
@@ -103,7 +103,12 @@ export function applyHttpSendOutput(
|
||||
): Partial<ChatState> {
|
||||
const { response, reply } = output;
|
||||
|
||||
if (response.blocked === true && response.blockReason === "daily_limit") {
|
||||
const isMessageLimitBlocked =
|
||||
response.blocked === true &&
|
||||
(response.blockReason === "daily_limit" ||
|
||||
response.blockReason === "total_limit");
|
||||
|
||||
if (isMessageLimitBlocked) {
|
||||
const detail = response.blockDetail;
|
||||
const lastMessage = context.messages[context.messages.length - 1];
|
||||
const messages =
|
||||
@@ -115,9 +120,19 @@ export function applyHttpSendOutput(
|
||||
messages,
|
||||
isReplyingAI: false,
|
||||
paywallTriggered: true,
|
||||
paywallReason: "daily_limit",
|
||||
paywallReason:
|
||||
response.blockReason === "total_limit" ? "total_limit" : "daily_limit",
|
||||
paywallDetail: detail
|
||||
? { usedToday: detail.usedToday, limit: detail.limit }
|
||||
? {
|
||||
type: detail.type,
|
||||
...(detail.usedToday != null
|
||||
? { usedToday: detail.usedToday }
|
||||
: {}),
|
||||
...(detail.usedTotal != null
|
||||
? { usedTotal: detail.usedTotal }
|
||||
: {}),
|
||||
limit: detail.limit,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,8 +19,20 @@ export interface ChatState {
|
||||
*/
|
||||
wsConnected: boolean;
|
||||
paywallTriggered: boolean;
|
||||
paywallReason: "daily_limit" | "photo_paywall" | "private_paywall" | null;
|
||||
paywallDetail: { usedToday: number; limit: number } | null;
|
||||
paywallReason:
|
||||
| "daily_limit"
|
||||
| "total_limit"
|
||||
| "photo_paywall"
|
||||
| "private_paywall"
|
||||
| null;
|
||||
paywallDetail:
|
||||
| {
|
||||
type?: string;
|
||||
usedToday?: number;
|
||||
usedTotal?: number;
|
||||
limit: number;
|
||||
}
|
||||
| null;
|
||||
unlockingPrivateMessageId: string | null;
|
||||
isLoadingMore: boolean;
|
||||
hasMore: boolean;
|
||||
|
||||
Reference in New Issue
Block a user