import React, { useCallback, useEffect, useState } from 'react'; import StudioInsertionPopup from './StudioInsertionPopup'; import './StudioBindingPreviewPopup.css'; const CHARACTER_FIELDS = [ { key: 'description', label: '描述' }, { key: 'personality', label: '性格' }, { key: 'scenario', label: '场景' }, { key: 'first_mes', label: '开场白' }, { key: 'mes_example', label: '对话示例' }, ]; function StudioBindingPreviewPopup({ open, characterName, worldbookName, onClose, }) { const [tab, setTab] = useState('character'); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [character, setCharacter] = useState(null); const [entries, setEntries] = useState([]); const [expandedEntryUid, setExpandedEntryUid] = useState(null); const loadData = useCallback(async () => { if (!characterName && !worldbookName) return; setLoading(true); setError(''); try { const tasks = []; if (characterName) { tasks.push( fetch(`/api/characters/${encodeURIComponent(characterName)}`) .then(async (res) => { if (!res.ok) throw new Error('加载角色卡失败'); return res.json(); }) .then(setCharacter) ); } else { setCharacter(null); } if (worldbookName) { tasks.push( fetch( `/api/worldbooks/${encodeURIComponent(worldbookName)}/entries?page=1&page_size=50` ) .then(async (res) => { if (!res.ok) throw new Error('加载世界书条目失败'); return res.json(); }) .then((data) => setEntries(data.entries || [])) ); } else { setEntries([]); } await Promise.all(tasks); } catch (e) { setError(e.message || '加载绑定资源失败'); } finally { setLoading(false); } }, [characterName, worldbookName]); useEffect(() => { if (open) { setTab('character'); setExpandedEntryUid(null); loadData(); } }, [open, loadData]); const title = characterName ? `绑定预览 · ${characterName}` : '绑定预览'; return ( {() => (
{loading ? (

加载中…

) : error ? (

{error}

) : tab === 'character' ? (
{!character ? (

暂无绑定角色卡

) : ( <>
{character.avatar ? ( ) : (
🎭
)}

{character.name}

{worldbookName ? (

世界书:{worldbookName}

) : null}
{CHARACTER_FIELDS.map(({ key, label }) => { const value = (character[key] || '').trim(); if (!value) return null; return (

{label}

{value}
); })} )}
) : (
{!worldbookName ? (

暂无绑定世界书

) : entries.length === 0 ? (

世界书「{worldbookName}」暂无条目

) : (
    {entries.map((entry) => { const expanded = expandedEntryUid === entry.uid; const comment = entry.comment || entry.key?.join?.(', ') || '未命名条目'; return (
  • {expanded ? (
                                {entry.content || '(空内容)'}
                              
    ) : null}
  • ); })}
)}
)}
)}
); } export default StudioBindingPreviewPopup;