# Clannad_v3.1.png 案例分析与落地要点 ## 目标角色卡概览 - **图像**:@docs/Clannad_v3.1.png(图片来源、版权信息见下方字段) - **风格**:Clannad 系列日系校园少女题材,具有较强的情感表达与背景设定需求 - **已知需求**:在云酒馆系统中以“前端卡”方式呈现,并能注入背景信息、变量、互动 UI --- ## 10.1 数据字段与数据模型需求 | 字段名 | 说明 | 备注 | |--------|------|------| | portrait_url | 图片主地址 | 建议使用 CDN 托管,支持 webp/AVIF 高效格式 | | portrait_alt | 无障碍文本描述 | 供屏幕阅读器使用,描述角色外观特征 | | thumbnail_url | 缩略图地址 | 列表页展示使用,建议 200x200 以内 | | portrait_caption | 图片简短说明 | 显示在图片下方的简短描述 | | image_source | 版权信息/出处 | 记录图片来源、授权信息 | | worldbook_id | 关联的 Worldbook | 用于注入背景设定 | | worldbook_entries | 世界书条目集合 | 用于背景信息注入 | | name | 角色名称 | 现有字段 | | description | 角色描述 | 现有字段 | | personality | 性格设定 | 现有字段 | | scenario | 场景设定 | 现有字段 | | first_mes | 开场白 | 现有字段 | | mes_example | 对话示例 | 现有字段 | | system_prompt | 系统提示词 | 现有字段 | | extensions | 扩展数据 | MVU 相关字段 | | variables | 变量定义 | MVU 相关字段 | --- ## 10.2 后端改动要点 ### 10.2.1 数据模型扩展 在 `model/app/ai_character.go` 中新增以下字段: ```go type AICharacter struct { // ... 现有字段 ... // 图片相关字段 PortraitURL string `json:"portraitUrl" gorm:"type:varchar(500)"` PortraitAlt string `json:"portraitAlt" gorm:"type:varchar(200)"` ThumbnailURL string `json:"thumbnailUrl" gorm:"type:varchar(500)"` PortraitCaption string `json:"portraitCaption" gorm:"type:varchar(200)"` ImageSource string `json:"imageSource" gorm:"type:varchar(500)"` // 版权信息 // Worldbook 关联 WorldbookID *uint `json:"worldbookId"` } ``` ### 10.2.2 API 接口 - **上传图片**:`POST /api/v1/app/character/:id/portrait` - 鉴权:需要用户登录 - 校验:文件大小(建议最大 5MB)、格式(支持 jpg/png/webp/gif) - 返回:portrait_url、thumbnail_url - **获取角色图片信息**:`GET /api/v1/app/character/:id` - 返回字段包含 portrait_url、portrait_alt、thumbnail_url、portrait_caption、image_source ### 10.2.3 Worldbook 关联增强 在 `conversation.go` 的 system prompt 构建流程中,增加对角色关联 Worldbook 的背景注入: - 读取 `character.WorldbookID` - 通过 WorldbookEngine 查询对应的启用条目 - 将背景信息注入到 system_prompt 中(需控制 token budget) ### 10.2.4 数据迁移 为现有角色卡补充默认字段值: ```sql ALTER TABLE ai_characters ADD COLUMN IF NOT EXISTS portrait_url VARCHAR(500), ADD COLUMN IF NOT EXISTS portrait_alt VARCHAR(200), ADD COLUMN IF NOT EXISTS thumbnail_url VARCHAR(500), ADD COLUMN IF NOT EXISTS portrait_caption VARCHAR(200), ADD COLUMN IF NOT EXISTS image_source VARCHAR(500), ADD COLUMN IF NOT EXISTS worldbook_id UINT REFERENCES worldbooks(id); ``` --- ## 10.3 前端实现要点 ### 10.3.1 角色卡片组件 在 `web-app/src/components/` 中新增或扩展角色卡片组件: ```tsx interface CharacterCardProps { portraitUrl?: string; portraitAlt?: string; thumbnailUrl?: string; portraitCaption?: string; // ... 其他字段 } const CharacterPortrait: React.FC = ({ portraitUrl, portraitAlt, thumbnailUrl, portraitCaption }) => { if (!portraitUrl) return null; return (
{portraitAlt {portraitCaption && (

{portraitCaption}

)}
); }; ``` ### 10.3.2 样式隔离 使用 CSS Modules 或在组件级别定义样式: ```css /* CharacterPortrait.module.css */ .character-portrait { display: flex; flex-direction: column; align-items: center; } .portrait-image { max-width: 300px; border-radius: 8px; } .portrait-caption { font-size: 14px; color: #666; margin-top: 8px; } ``` ### 10.3.3 沙箱渲染 对于需要执行脚本的前端卡,使用 iframe 沙箱: ```tsx const FrontendCardSandbox: React.FC<{ htmlContent: string }> = ({ htmlContent }) => { return (