feat(health): wire H5 health page, WeChat channel, and observation API.
Expose /health and /api/health/observations behind MEMIND_HEALTH_ENABLED, redirect ordinary chat health intents without persisting, and run a dedicated WeChat menu flow with confirm-before-write semantics. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useChat } from '../context/ChatProvider';
|
||||
import { INSUFFICIENT_BALANCE_NOTICE } from '../hooks/useTKMindChat';
|
||||
import { useGoalRunBanner } from '../hooks/useGoalRunBanner';
|
||||
@@ -19,6 +20,10 @@ import { ChatHeaderMoreMenu } from './ChatHeaderMoreMenu';
|
||||
import { NotificationCenter } from './NotificationCenter';
|
||||
import { GoalRunAwaitingBanner } from './GoalRunAwaitingBanner';
|
||||
import type { MindSpaceSaveCategory } from '../types';
|
||||
import {
|
||||
HEALTH_REDIRECT_COPY,
|
||||
shouldRedirectOrdinaryChatToHealth,
|
||||
} from '../../health-intent-rules.mjs';
|
||||
|
||||
function RecentSessionRail({
|
||||
sessions,
|
||||
@@ -222,7 +227,9 @@ export function ChatView({
|
||||
uploadChatAttachment,
|
||||
followAgentRun,
|
||||
goalRunEnabled,
|
||||
healthEnabled,
|
||||
} = useChat();
|
||||
const navigate = useNavigate();
|
||||
const online = useNetworkStatus();
|
||||
const goalRunBanner = useGoalRunBanner({
|
||||
userId: user?.id,
|
||||
@@ -312,6 +319,9 @@ export function ChatView({
|
||||
...(onOpenAdmin
|
||||
? [{ id: 'admin', label: '管理', onClick: () => onOpenAdmin() }]
|
||||
: []),
|
||||
...(healthEnabled
|
||||
? [{ id: 'health', label: '健康', onClick: () => navigate('/health') }]
|
||||
: []),
|
||||
...(onLogout
|
||||
? [{ id: 'logout', label: '登出', onClick: () => onLogout(), danger: true }]
|
||||
: []),
|
||||
@@ -409,6 +419,16 @@ export function ChatView({
|
||||
管理
|
||||
</button>
|
||||
)}
|
||||
{healthEnabled && (
|
||||
<button
|
||||
type="button"
|
||||
className="ghost-btn"
|
||||
data-analytics-action="open_health"
|
||||
onClick={() => navigate('/health')}
|
||||
>
|
||||
健康
|
||||
</button>
|
||||
)}
|
||||
{onOpenSpace && (
|
||||
<button
|
||||
ref={spaceButtonRef}
|
||||
@@ -579,7 +599,12 @@ export function ChatView({
|
||||
onGrantedSkillsUpdate={onGrantedSkillsUpdate}
|
||||
onOpenRecharge={() => openRecharge(false)}
|
||||
taskLoadingTip={taskLoadingTip}
|
||||
onSubmit={(text, imageUrls, previewImageUrls, options) =>
|
||||
onSubmit={(text, imageUrls, previewImageUrls, options) => {
|
||||
if (healthEnabled && shouldRedirectOrdinaryChatToHealth(text) && !options?.selectedChatSkill) {
|
||||
window.alert(HEALTH_REDIRECT_COPY);
|
||||
navigate('/health');
|
||||
return;
|
||||
}
|
||||
void submit(
|
||||
text,
|
||||
{
|
||||
@@ -593,8 +618,8 @@ export function ChatView({
|
||||
},
|
||||
imageUrls,
|
||||
previewImageUrls,
|
||||
)
|
||||
}
|
||||
);
|
||||
}}
|
||||
onUploadImage={(file, onProgress, options) =>
|
||||
uploadChatImage(file, onProgress, { messageId: options?.messageId })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user