fix: v3.0 bug修复——分享权限区分、session_not_found友好提示、图片识别配置
This commit is contained in:
parent
3340b6ace3
commit
dfce4fc88f
@ -1,6 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
import Starfield from '../../components/Starfield';
|
import Starfield from '../../components/Starfield';
|
||||||
|
|
||||||
const ZODIAC_SYMBOL = {
|
const ZODIAC_SYMBOL = {
|
||||||
@ -81,6 +82,11 @@ export default function ReportPreviewPage() {
|
|||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
const headerRef = useRef(null);
|
const headerRef = useRef(null);
|
||||||
const [headerVisible, setHeaderVisible] = useState(false);
|
const [headerVisible, setHeaderVisible] = useState(false);
|
||||||
|
const [showShare, setShowShare] = useState(false);
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
const [showRestart, setShowRestart] = useState(false);
|
||||||
|
const [isOwner, setIsOwner] = useState(false);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
@ -112,7 +118,12 @@ export default function ReportPreviewPage() {
|
|||||||
setData(d.report);
|
setData(d.report);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (d?.status === 'error') throw new Error(d?.error || '生成失败');
|
if (d?.status === 'error') {
|
||||||
|
if (d?.error === 'session_not_found') {
|
||||||
|
throw new Error('SESSION_NOT_FOUND');
|
||||||
|
}
|
||||||
|
throw new Error(d?.error || '生成失败');
|
||||||
|
}
|
||||||
// generating 或 not_started → 等2秒再试
|
// generating 或 not_started → 等2秒再试
|
||||||
if (attempt < 29) {
|
if (attempt < 29) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
@ -123,7 +134,13 @@ export default function ReportPreviewPage() {
|
|||||||
finally { setLoading(false); }
|
finally { setLoading(false); }
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => { load(); }, [sid]);
|
useEffect(() => {
|
||||||
|
if (sid) {
|
||||||
|
const localSid = localStorage.getItem('lingjing_sid') || '';
|
||||||
|
setIsOwner(localSid === sid);
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
}, [sid]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="relative min-h-screen overflow-hidden bg-[#05030f] text-white">
|
<main className="relative min-h-screen overflow-hidden bg-[#05030f] text-white">
|
||||||
@ -133,7 +150,7 @@ export default function ReportPreviewPage() {
|
|||||||
<header ref={headerRef} className="mb-8 text-center"
|
<header ref={headerRef} className="mb-8 text-center"
|
||||||
style={{ opacity: headerVisible ? 1 : 0, transform: headerVisible ? 'translateY(0)' : 'translateY(-20px)', transition: 'opacity 0.8s ease, transform 0.8s ease' }}>
|
style={{ opacity: headerVisible ? 1 : 0, transform: headerVisible ? 'translateY(0)' : 'translateY(-20px)', transition: 'opacity 0.8s ease, transform 0.8s ease' }}>
|
||||||
<p className="text-xs tracking-[0.3em] text-white/35">LINGJING REPORT</p>
|
<p className="text-xs tracking-[0.3em] text-white/35">LINGJING REPORT</p>
|
||||||
<h1 className="mt-2 text-3xl font-light tracking-widest">你的灵镜报告</h1>
|
<h1 className="mt-2 text-3xl font-light tracking-widest">{isOwner ? '你的灵镜报告' : 'ta的灵镜报告'}</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@ -145,8 +162,18 @@ export default function ReportPreviewPage() {
|
|||||||
) : null}
|
) : null}
|
||||||
{error ? (
|
{error ? (
|
||||||
<div className="mx-auto max-w-xl rounded-2xl border border-white/10 bg-white/5 p-6 text-center">
|
<div className="mx-auto max-w-xl rounded-2xl border border-white/10 bg-white/5 p-6 text-center">
|
||||||
<p className="text-red-300">{error}</p>
|
{error === 'SESSION_NOT_FOUND' ? (
|
||||||
<button className="mt-4 rounded-xl border border-white/20 px-4 py-2 text-sm" onClick={load}>重试</button>
|
<>
|
||||||
|
<p className="text-white/70 mb-2">找不到你的报告记录</p>
|
||||||
|
<p className="text-xs text-white/40 mb-4">可能是之前的对话已过期</p>
|
||||||
|
<button className="rounded-xl border border-white/20 bg-white/10 px-5 py-2.5 text-sm text-white" onClick={() => { localStorage.removeItem('lingjing_sid'); router.replace('/chat'); }}>重新开始</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<p className="text-red-300">{error}</p>
|
||||||
|
<button className="mt-4 rounded-xl border border-white/20 px-4 py-2 text-sm" onClick={load}>重试</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@ -311,7 +338,97 @@ export default function ReportPreviewPage() {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{/* 底部操作区(仅本人可见) */}
|
||||||
|
{!loading && !error && data && isOwner ? (
|
||||||
|
<div className="mt-10 flex flex-col items-center gap-4 pb-12">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowShare(true)}
|
||||||
|
className="w-full max-w-xs rounded-full border border-white/30 bg-white/10 py-3 text-sm tracking-widest text-white/90 backdrop-blur-sm transition hover:bg-white/20"
|
||||||
|
>
|
||||||
|
分享给朋友
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowRestart(true)}
|
||||||
|
className="text-xs text-white/30 underline underline-offset-4 hover:text-white/50 transition"
|
||||||
|
>
|
||||||
|
重新开始
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 分享弹窗 */}
|
||||||
|
{showShare ? (
|
||||||
|
<div className="fixed inset-0 z-50 flex items-end justify-center bg-black/60 backdrop-blur-sm" onClick={() => setShowShare(false)}>
|
||||||
|
<div className="w-full max-w-lg rounded-t-3xl bg-[#0e0b1f] border-t border-white/10 p-6 pb-10" onClick={e => e.stopPropagation()}>
|
||||||
|
<h3 className="text-center text-base font-semibold text-white mb-1">分享给朋友</h3>
|
||||||
|
<p className="text-center text-xs text-white/40 mb-5">朋友可以直接看到你的完整报告</p>
|
||||||
|
<div className="flex items-center gap-2 rounded-xl border border-white/15 bg-white/5 px-4 py-3 mb-4">
|
||||||
|
<p className="flex-1 truncate text-xs text-white/60 font-mono">
|
||||||
|
{typeof window !== 'undefined' ? window.location.href : ''}
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
navigator.clipboard.writeText(window.location.href).then(() => {
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="shrink-0 rounded-lg bg-white/15 px-3 py-1.5 text-xs text-white hover:bg-white/25 transition"
|
||||||
|
>
|
||||||
|
{copied ? '已复制 ✓' : '复制链接'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className="text-center text-xs text-white/30">朋友看完可以在页面底部做自己的报告</p>
|
||||||
|
<button onClick={() => setShowShare(false)} className="mt-5 w-full rounded-full border border-white/15 py-3 text-sm text-white/50 hover:text-white/80 transition">关闭</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{/* 重做确认弹窗 */}
|
||||||
|
{showRestart ? (
|
||||||
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm" onClick={() => setShowRestart(false)}>
|
||||||
|
<div className="w-full max-w-sm mx-4 rounded-2xl bg-[#0e0b1f] border border-white/10 p-6" onClick={e => e.stopPropagation()}>
|
||||||
|
<h3 className="text-base font-semibold text-white mb-2">重新开始?</h3>
|
||||||
|
<p className="text-sm text-white/50 leading-6 mb-6">重新开始会生成全新报告,当前报告不会保留,确定吗?</p>
|
||||||
|
<div className="flex gap-3">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowRestart(false)}
|
||||||
|
className="flex-1 rounded-full border border-white/20 py-2.5 text-sm text-white/60 hover:text-white/90 transition"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
localStorage.removeItem('lingjing_sid');
|
||||||
|
router.replace('/chat');
|
||||||
|
}}
|
||||||
|
className="flex-1 rounded-full bg-white/15 py-2.5 text-sm text-white hover:bg-white/25 transition"
|
||||||
|
>
|
||||||
|
确定重新开始
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{/* 分享页底部引导(仅非本人查看时显示) */}
|
||||||
|
{!isOwner ? (
|
||||||
|
<div className="relative z-10 border-t border-white/5 bg-[#05030f] px-4 py-8 text-center">
|
||||||
|
<p className="text-sm text-white/40 mb-4">看完 ta 的报告?来做你自己的</p>
|
||||||
|
<button
|
||||||
|
onClick={() => { localStorage.removeItem('lingjing_sid'); router.push('/chat'); }}
|
||||||
|
className="rounded-full border border-white/20 px-8 py-3 text-sm text-white/80 hover:bg-white/10 transition"
|
||||||
|
>
|
||||||
|
开始我的灵镜报告 →
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user