feat: soften quota messaging

This commit is contained in:
2026-07-31 16:10:35 +08:00
parent 4e872febd5
commit ec9f8a015a
4 changed files with 34 additions and 4 deletions

View File

@@ -226,7 +226,10 @@ class ChatService:
@staticmethod @staticmethod
def _ensure_quota(user: User) -> None: def _ensure_quota(user: User) -> None:
if user.daily_chat_used >= user.daily_chat_limit: if user.daily_chat_used >= user.daily_chat_limit:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="今日提问次数已用完") raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="今天的陪伴对话已经比较多了,建议先消化当前回答和功课;如需继续使用,可以联系运营老师确认权益。",
)
@staticmethod @staticmethod
def _ensure_topic_quota(db: Session, user: User, session: ChatSession, entitlement) -> None: def _ensure_topic_quota(db: Session, user: User, session: ChatSession, entitlement) -> None:

View File

@@ -24,8 +24,18 @@ const hasEntitlement = computed(() => Boolean(props.entitlement));
const displayUsed = computed(() => props.entitlement?.monthlyTopicUsed ?? props.used); const displayUsed = computed(() => props.entitlement?.monthlyTopicUsed ?? props.used);
const displayLimit = computed(() => props.entitlement?.monthlyTopicLimit ?? props.limit); const displayLimit = computed(() => props.entitlement?.monthlyTopicLimit ?? props.limit);
const exhausted = computed(() => displayLimit.value !== null && displayLimit.value > 0 && displayUsed.value >= displayLimit.value); const exhausted = computed(() => displayLimit.value !== null && displayLimit.value > 0 && displayUsed.value >= displayLimit.value);
const title = computed(() => props.entitlement ? "本月主题额度" : "当前会话额度"); const nearLimit = computed(() => displayLimit.value !== null && displayLimit.value > 0 && displayUsed.value / displayLimit.value >= 0.8);
const limitText = computed(() => displayLimit.value === null ? "不限" : String(displayLimit.value)); const title = computed(() => props.entitlement ? "本月主题使用情况" : "今日陪伴使用情况");
const usageText = computed(() => {
if (displayLimit.value === null) return props.entitlement ? "本月不限" : "不限";
if (props.entitlement) return `已使用 ${displayUsed.value}/${displayLimit.value} 个主题`;
return `今日 ${displayUsed.value}/${displayLimit.value}`;
});
const guidanceText = computed(() => {
if (exhausted.value) return "本月深度主题使用较多,建议先完成已有功课;如需继续高频陪伴,可联系运营老师确认权益。";
if (nearLimit.value) return "本月深度主题接近上限,可以先沉淀已有主题,再继续新的议题。";
return "";
});
</script> </script>
<template> <template>
@@ -65,7 +75,8 @@ const limitText = computed(() => displayLimit.value === null ? "不限" : String
> >
{{ generatingShareDraft ? '生成中' : '分享稿' }} {{ generatingShareDraft ? '生成中' : '分享稿' }}
</button> </button>
<strong>{{ displayUsed }}/{{ limitText }}</strong> <strong>{{ usageText }}</strong>
</div> </div>
<p v-if="guidanceText" class="session-quota-guidance">{{ guidanceText }}</p>
</section> </section>
</template> </template>

View File

@@ -1215,6 +1215,14 @@ textarea:focus-visible {
font-size: 13px; font-size: 13px;
} }
.session-quota-guidance {
flex-basis: 100%;
margin: -2px 0 0 26px;
color: #6c8078;
font-size: 12px;
line-height: 1.55;
}
.session-quota > div { .session-quota > div {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -1276,6 +1284,10 @@ textarea:focus-visible {
color: var(--chat-danger); color: var(--chat-danger);
} }
.session-quota.exhausted .session-quota-guidance {
color: var(--chat-danger);
}
.message-list { .message-list {
min-height: 0; min-height: 0;
overflow-x: hidden; overflow-x: hidden;

View File

@@ -583,6 +583,10 @@ Agent 已经可以:
- 权益不足时提示清楚; - 权益不足时提示清楚;
- 基础版和深度版提示不同。 - 基础版和深度版提示不同。
#### 开发进度
- 2026-07-31用户端额度条已改为“本月主题使用情况 / 今日陪伴使用情况”,接近上限时给出先沉淀/消化功课的提醒;后端每日额度超限文案已从“次数用完”改为陪伴式权益确认提示。主题额度超限已使用柔性文案。
--- ---
### 09. 成本统计与模型分流 ### 09. 成本统计与模型分流