# 接口组合使用场景 本文档详细描述 @repo/sdk 中各接口的组合使用场景,帮助理解业务流程中接口之间的依赖关系。 > **推荐**:所有示例都使用 `root.get(Controller)` 方式调用,并复用 SDK 导出的类型。 ## 目录 1. [模板运行完整流程](#1-模板运行完整流程) 2. [模板社交互动流程](#2-模板社交互动流程) 3. [项目管理与标签流程](#3-项目管理与标签流程) 4. [文件上传与处理流程](#4-文件上传与处理流程) 5. [分类标签管理流程](#5-分类标签管理流程) 6. [消息通知处理流程](#6-消息通知处理流程) 7. [用户收藏夹管理流程](#7-用户收藏夹管理流程) 8. [AI 内容生成流程](#8-ai-内容生成流程) 9. [权限角色管理流程](#9-权限角色管理流程) --- ## 1. 模板运行完整流程 **场景**:用户选择模板,填写表单,生成内容,保存到项目 **涉及控制器**: - `TemplateController` - `AigcController` - `FileController` - `TemplateGenerationController` - `ProjectController` ### 流程图 ``` 用户选择模板 ↓ TemplateController.get(templateId) ↓ 用户填写表单(根据 formSchema) ↓ TemplateController.run({ templateId, formData, projectId? }) ↓ 返回 generationId 轮询任务状态 ↓ AigcController.getTaskStatus(taskId) ↓ status === 'COMPLETED' 获取生成结果 ↓ FileController.convertToWebp({ videoUrl }) [可选:格式转换] ↓ ProjectController.update({ id, resultUrl }) [保存到项目] ``` ### 代码示例 ```typescript import { root } from '@repo/core' import { TemplateController, AigcController, FileController, ProjectController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { TemplateDetail, Project, GetTaskStatusResult, ConvertToWebpRequest } from '@repo/sdk' async function runTemplateWorkflow(templateId: string, formData: Record) { // 使用 root.get 获取控制器(类型安全) const templateCtrl = root.get(TemplateController) const aigcCtrl = root.get(AigcController) const fileCtrl = root.get(FileController) const projectCtrl = root.get(ProjectController) // 1. 获取模板详情(了解表单结构) const template: TemplateDetail = await templateCtrl.get(templateId) console.log('模板表单结构:', template.formSchema) // 2. 创建项目(可选,用于保存结果) const project: Project = await projectCtrl.create({ title: `基于 ${template.title} 的创作`, content: { templateId, formData }, sourceTemplateId: templateId }) // 3. 运行模板 const { generationId } = await templateCtrl.run({ templateId, formData, projectId: project.id }) // 4. 轮询任务状态 let taskStatus: GetTaskStatusResult = await aigcCtrl.getTaskStatus(generationId) while (taskStatus.status === 'PENDING' || taskStatus.status === 'PROCESSING') { await new Promise(resolve => setTimeout(resolve, 2000)) taskStatus = await aigcCtrl.getTaskStatus(generationId) console.log(`进度: ${taskStatus.progress || 0}%`) } if (taskStatus.status === 'FAILED') { throw new Error(`生成失败: ${taskStatus.error_message}`) } // 5. 处理生成结果(转换为 WebP 格式) const webpResult = await fileCtrl.convertToWebp({ videoUrl: taskStatus.result_url!, quality: 80, compressionLevel: 4, loop: true, resolution: '720p', fps: 15 }) // 6. 更新项目结果 await projectCtrl.update({ id: project.id, resultUrl: webpResult.data }) return { project, generationId, resultUrl: webpResult.data } } ``` ### 重新运行场景 ```typescript import { root } from '@repo/core' import { TemplateController } from '@repo/sdk' // 基于历史生成记录重新运行 async function rerunFromHistory(generationId: string) { const templateCtrl = root.get(TemplateController) // 直接使用历史记录的参数重新运行 const { generationId: newId } = await templateCtrl.rerun({ generationId }) // 继续轮询新任务... return newId } ``` --- ## 2. 模板社交互动流程 **场景**:用户浏览模板列表,点赞、收藏、评论 **涉及控制器**: - `TemplateController` - `TemplateSocialController` ### 流程图 ``` 获取模板列表 ↓ TemplateController.list({ page, limit }) ↓ 批量检查社交状态 ↓ TemplateSocialController.checkLikedBatch({ templateIds }) TemplateSocialController.checkFavoritedBatch({ templateIds }) ↓ 用户交互 ↓ 点赞: TemplateSocialController.like({ templateId }) 收藏: TemplateSocialController.favorite({ templateId }) 评论: TemplateSocialController.createComment({ templateId, content }) ``` ### 代码示例 ```typescript import { root } from '@repo/core' import { TemplateController, TemplateSocialController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { TemplateDetail, ListTemplatesResult, CheckLikedBatchResponse, CheckFavoritedBatchResponse, TemplateComment, GetCommentsResponse } from '@repo/sdk' // 获取模板列表并附加社交状态 async function getTemplatesWithSocialStatus(page: number = 1) { const templateCtrl = root.get(TemplateController) const socialCtrl = root.get(TemplateSocialController) // 1. 获取模板列表 const { templates, total }: ListTemplatesResult = await templateCtrl.list({ page, limit: 20, sortBy: 'likeCount', sortOrder: 'desc' }) const templateIds = templates.map(t => t.id) // 2. 批量检查点赞和收藏状态 const [likedStatus, favoritedStatus]: [CheckLikedBatchResponse, CheckFavoritedBatchResponse] = await Promise.all([ socialCtrl.checkLikedBatch({ templateIds }), socialCtrl.checkFavoritedBatch({ templateIds }) ]) // 3. 合并状态到模板数据 const templatesWithStatus = templates.map(template => ({ ...template, isLiked: likedStatus.results[template.id] || false, isFavorited: favoritedStatus.results[template.id] || false })) return { templates: templatesWithStatus, total } } // 点赞/取消点赞 async function toggleLike(templateId: string, isCurrentlyLiked: boolean): Promise { const socialCtrl = root.get(TemplateSocialController) if (isCurrentlyLiked) { await socialCtrl.unlike({ templateId }) } else { await socialCtrl.like({ templateId }) } return !isCurrentlyLiked } // 获取评论列表(含回复) async function getCommentsWithReplies(templateId: string): Promise { const socialCtrl = root.get(TemplateSocialController) // 1. 获取顶级评论(自动包含前3条回复) const { comments, total } = await socialCtrl.getComments({ templateId, page: 1, limit: 20 }) // 2. 对于回复数超过3的评论,加载更多回复 for (const comment of comments) { if (comment.replyCount && comment.replyCount > 3) { const { replies } = await socialCtrl.getCommentReplies({ commentId: comment.id, page: 1, limit: 50 }) comment.replies = replies } } return { comments, total } } // 发表评论或回复 async function postComment(templateId: string, content: string, parentId?: string): Promise { const socialCtrl = root.get(TemplateSocialController) const comment = await socialCtrl.createComment({ templateId, content, parentId // 如果是回复,传入父评论ID }) return comment } ``` --- ## 3. 项目管理与标签流程 **场景**:用户创建项目,使用标签分类管理 **涉及控制器**: - `ProjectController` - `ProjectTagController` ### 流程图 ``` 创建用户标签 ↓ ProjectTagController.create({ name, color }) ↓ 创建项目 ↓ ProjectController.create({ title, content }) ↓ 给项目添加标签 ↓ ProjectTagController.addToProject({ projectId, tagId }) ↓ 按标签筛选项目 ↓ ProjectController.list({ tagId }) ``` ### 代码示例 ```typescript import { root } from '@repo/core' import { ProjectController, ProjectTagController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { Project, CreateProjectInput, ListProjectsResult, UserTag, TransferProjectResult } from '@repo/sdk' // 初始化用户标签系统 async function initUserTags(): Promise { const tagCtrl = root.get(ProjectTagController) // 创建默认标签 const defaultTags = [ { name: '收藏夹', color: '#FF6B6B' }, { name: '工作', color: '#4ECDC4' }, { name: '个人', color: '#45B7D1' }, { name: '灵感', color: '#96CEB4' } ] const tags = await Promise.all( defaultTags.map(tag => tagCtrl.create(tag)) ) return tags } // 创建项目并分类 async function createProjectWithTags( projectData: CreateProjectInput, tagIds: string[] ): Promise { const projectCtrl = root.get(ProjectController) const tagCtrl = root.get(ProjectTagController) // 1. 创建项目 const project: Project = await projectCtrl.create(projectData) // 2. 批量设置标签 await tagCtrl.setProjectTags({ projectId: project.id, tagIds }) return project } // 获取用户所有标签及项目数量 async function getTagsWithProjectCount(): Promise> { const tagCtrl = root.get(ProjectTagController) const projectCtrl = root.get(ProjectController) // 1. 获取所有标签 const tags = await tagCtrl.list() // 2. 获取每个标签下的项目数量 const tagsWithCount = await Promise.all( tags.map(async tag => { const { total } = await projectCtrl.list({ tagId: tag.id, limit: 1 }) return { ...tag, projectCount: total } }) ) return tagsWithCount } // 项目转移(复制到其他用户) async function copyProjectToUser(projectId: string, targetUserId: string): Promise { const projectCtrl = root.get(ProjectController) const result = await projectCtrl.transfer({ projectId, targetUserId, mode: 'copy' // 'transfer' 会移动所有权,'copy' 会复制 }) return result } ``` --- ## 4. 文件上传与处理流程 **场景**:用户上传文件,进行格式转换和处理 **涉及控制器**: - `FileController` - `FFmpegController`(视频合成) ### 流程图 ``` 用户选择文件 ↓ FileController.uploadS3(formData) ↓ 返回文件URL 选择处理方式 ↓ ├─ 压缩视频: FileController.compressVideo({ videoUrl, quality }) ├─ 转WebP: FileController.convertToWebp({ videoUrl, ... }) ├─ 转ANI: FileController.convertToAni({ videoUrl }) ├─ 加水印: FileController.convertToWatermark({ videoUrl, watermarkUrl }) └─ 视频合成: FFmpegController.concat({ videoUrls }) ``` ### 代码示例 ```typescript import { root } from '@repo/core' import { FileController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { FileUploadResponse, VideoCompressRequest, ConvertToWebpRequest, ConvertToWatermarkRequest } from '@repo/sdk' // 上传文件 async function uploadFile(file: File): Promise { const fileCtrl = root.get(FileController) const formData = new FormData() formData.append('file', file) const result: FileUploadResponse = await fileCtrl.uploadS3(formData) if (!result.status) { throw new Error(result.msg) } return result.data // 文件URL } // 完整的视频处理流程 async function processVideo(file: File, options: { compress?: boolean; addWatermark?: boolean; watermarkUrl?: string; convertToWebp?: boolean; }): Promise { const fileCtrl = root.get(FileController) // 1. 上传原始文件 let videoUrl = await uploadFile(file) // 2. 压缩视频(可选) if (options.compress) { const compressed = await fileCtrl.compressVideo({ videoUrl, quality: 'medium' }) videoUrl = compressed.data } // 3. 添加水印(可选) if (options.addWatermark && options.watermarkUrl) { const watermarked = await fileCtrl.convertToWatermark({ videoUrl, watermarkUrl: options.watermarkUrl, position: 'bottomRight' }) videoUrl = watermarked.data } // 4. 转换为 WebP(可选) if (options.convertToWebp) { const webp = await fileCtrl.convertToWebp({ videoUrl, quality: 80, compressionLevel: 4, loop: true, resolution: '720p', fps: 15 }) videoUrl = webp.data } return videoUrl } // 一键上传并转换为 ANI 格式 async function uploadAndConvertToAni(file: File): Promise { const fileCtrl = root.get(FileController) const formData = new FormData() formData.append('file', file) // 使用组合接口,一步完成上传和转换 const result = await fileCtrl.uploadAndConvertToAni(formData) return result.data } ``` --- ## 5. 分类标签管理流程 **场景**:管理员管理模板分类和标签体系 **涉及控制器**: - `CategoryController` - `TagController` ### 流程图 ``` 创建分类 ↓ CategoryController.create({ name, nameEn }) ↓ 创建标签 ↓ TagController.create({ name, nameEn }) ↓ 关联标签到分类 ↓ TagController.updateCategoryTag({ tagId, categoryId, sortOrder }) ↓ 调整排序 ↓ CategoryController.batchUpdateSortOrder({ items }) CategoryController.batchUpdateTagSortOrder({ categoryId, items }) ``` ### 代码示例 ```typescript import { root } from '@repo/core' import { CategoryController, TagController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { Category, Tag, ListCategoriesWithTagsResult } from '@repo/sdk' // 创建完整的分类标签体系 async function setupCategorySystem(): Promise<{ categories: Category[]; tags: Tag[] }> { const categoryCtrl = root.get(CategoryController) const tagCtrl = root.get(TagController) // 1. 创建分类 const categories: Category[] = await Promise.all([ categoryCtrl.create({ name: '热门推荐', nameEn: 'Hot', sortOrder: 1 }), categoryCtrl.create({ name: '视频生成', nameEn: 'Video', sortOrder: 2 }), categoryCtrl.create({ name: '图片生成', nameEn: 'Image', sortOrder: 3 }) ]) // 2. 创建标签 const tags: Tag[] = await Promise.all([ tagCtrl.create({ name: '人物', nameEn: 'Portrait' }), tagCtrl.create({ name: '风景', nameEn: 'Landscape' }), tagCtrl.create({ name: '动漫', nameEn: 'Anime' }), tagCtrl.create({ name: '写实', nameEn: 'Realistic' }) ]) // 3. 关联标签到分类 const videoCategory = categories[1] for (let i = 0; i < tags.length; i++) { await tagCtrl.updateCategoryTag({ tagId: tags[i].id, categoryId: videoCategory.id, sortOrder: i + 1 }) } return { categories, tags } } // 获取分类及其标签(用于前端导航) async function getCategoryNavigation(): Promise { const categoryCtrl = root.get(CategoryController) const { categories }: ListCategoriesWithTagsResult = await categoryCtrl.listWithTags({ page: 1, limit: 100 }) return categories } // 获取分类下的模板(带分页) async function getCategoryTemplates(categoryId: string, page: number = 1) { const categoryCtrl = root.get(CategoryController) const category: Category = await categoryCtrl.getById( categoryId, page, 20, 'sortOrder', 'asc' ) return { category, templates: category.templates || [] } } // 批量调整分类排序 async function reorderCategories(items: Array<{ id: string; sortOrder: number }>): Promise { const categoryCtrl = root.get(CategoryController) await categoryCtrl.batchUpdateSortOrder({ items }) } ``` --- ## 6. 消息通知处理流程 **场景**:用户查看和管理消息通知 **涉及控制器**: - `MessageController` - `AnnouncementController` ### 流程图 ``` 获取未读数量 ↓ MessageController.getUnreadCount() AnnouncementController.getUnreadCount() ↓ 获取消息列表 ↓ MessageController.list({ type, isRead }) ↓ 标记已读 ↓ MessageController.markRead({ id }) MessageController.batchMarkRead({ ids }) ``` ### 代码示例 ```typescript import { root } from '@repo/core' import { MessageController, AnnouncementController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { Message, UnreadCountResult, ListMessagesResult } from '@repo/sdk' // 获取所有未读通知数量 async function getAllUnreadCounts() { const messageCtrl = root.get(MessageController) const announcementCtrl = root.get(AnnouncementController) const [messageUnread, announcementUnread]: [UnreadCountResult, number] = await Promise.all([ messageCtrl.getUnreadCount(), announcementCtrl.getUnreadCount() ]) return { messages: messageUnread, announcements: announcementUnread, total: messageUnread.total + announcementUnread } } // 获取分类消息 async function getMessagesByType(type: 'SYSTEM' | 'ACTIVITY' | 'BILLING' | 'MARKETING'): Promise { const messageCtrl = root.get(MessageController) const { messages, total } = await messageCtrl.list({ type, page: 1, limit: 50 }) return { messages, total } } // 一键已读所有消息 async function markAllAsRead(): Promise { const messageCtrl = root.get(MessageController) // 获取所有未读消息 const { messages } = await messageCtrl.list({ isRead: false, limit: 1000 }) if (messages.length === 0) return // 批量标记已读 await messageCtrl.batchMarkRead({ ids: messages.map(m => m.id) }) } // 消息中心完整数据 async function getMessageCenter() { const messageCtrl = root.get(MessageController) const announcementCtrl = root.get(AnnouncementController) const [ unreadCount, systemMessages, activityMessages, billingMessages, announcements ] = await Promise.all([ messageCtrl.getUnreadCount(), messageCtrl.list({ type: 'SYSTEM', limit: 10 }), messageCtrl.list({ type: 'ACTIVITY', limit: 10 }), messageCtrl.list({ type: 'BILLING', limit: 10 }), announcementCtrl.list({ page: 1, limit: 5 }) ]) return { unreadCount, systemMessages: systemMessages.messages, activityMessages: activityMessages.messages, billingMessages: billingMessages.messages, announcements: announcements.announcements } } ``` --- ## 7. 用户收藏夹管理流程 **场景**:用户管理收藏的模板和喜欢的内容 **涉及控制器**: - `TemplateSocialController` - `TemplateController` ### 代码示例 ```typescript import { root } from '@repo/core' import { TemplateSocialController, TemplateController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { TemplateDetail, GetUserFavoritesResponse, GetUserLikesResponse } from '@repo/sdk' // 获取用户收藏列表(带模板详情) async function getUserFavorites(page: number = 1): Promise<{ templates: TemplateDetail[]; total: number }> { const socialCtrl = root.get(TemplateSocialController) const templateCtrl = root.get(TemplateController) // 1. 获取收藏列表 const { favorites, total }: GetUserFavoritesResponse = await socialCtrl.getUserFavorites({ page, limit: 20 }) // 2. 获取模板详情 const templates: TemplateDetail[] = await Promise.all( favorites.map(fav => templateCtrl.get(fav.templateId)) ) return { templates, total } } // 获取用户喜欢列表 async function getUserLikes(page: number = 1): Promise { const socialCtrl = root.get(TemplateSocialController) const { likes, total } = await socialCtrl.getUserLikes({ page, limit: 20 }) return { likes, total } } // 收藏/取消收藏 async function toggleFavorite(templateId: string, isCurrentlyFavorited: boolean): Promise { const socialCtrl = root.get(TemplateSocialController) if (isCurrentlyFavorited) { await socialCtrl.unfavorite({ templateId }) } else { await socialCtrl.favorite({ templateId }) } return !isCurrentlyFavorited } ``` --- ## 8. AI 内容生成流程 **场景**:直接使用 AI 模型生成图片或视频 **涉及控制器**: - `AigcController` - `ChatController` ### 代码示例 ```typescript import { root } from '@repo/core' import { AigcController, ChatController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { AigcModel, GetModelsResult, SubmitTaskBody, GetTaskStatusResult, ChatRequest, ChatResponse } from '@repo/sdk' // 获取可用模型列表 async function getAvailableModels(category?: 'image' | 'video'): Promise> { const aigcCtrl = root.get(AigcController) const { models }: GetModelsResult = await aigcCtrl.getModels(category) // 按提供商分组 const groupedModels = models.reduce((acc, model) => { const provider = model.provider if (!acc[provider]) acc[provider] = [] acc[provider].push(model) return acc }, {} as Record) return groupedModels } // 生成图片 async function generateImage(prompt: string, modelName: string, options?: { aspectRatio?: string; watermark?: boolean; }): Promise { const aigcCtrl = root.get(AigcController) // 1. 提交任务 const { task_id } = await aigcCtrl.submitTask({ mode: 'image', model_name: modelName, prompt, aspect_ratio: options?.aspectRatio || '1:1', watermark: options?.watermark ?? false }) // 2. 轮询状态 let status: GetTaskStatusResult = await aigcCtrl.getTaskStatus(task_id) while (status.status === 'PENDING' || status.status === 'PROCESSING') { await new Promise(resolve => setTimeout(resolve, 2000)) status = await aigcCtrl.getTaskStatus(task_id) } if (status.status === 'FAILED') { throw new Error(status.error_message) } return status.result_url } // AI 对话(支持图片输入) async function chat(prompt: string, options?: { modelName?: string; images?: string[]; stream?: boolean; }): Promise { const chatCtrl = root.get(ChatController) const response: ChatResponse = await chatCtrl.chat({ prompt, model_name: options?.modelName || 'gpt-4o', img_list: options?.images, stream: options?.stream ?? false }) return response.data } // 图生图 async function imageToImage(imageUrl: string, prompt: string, modelName: string): Promise { const aigcCtrl = root.get(AigcController) const { task_id } = await aigcCtrl.submitTask({ mode: 'image', model_name: modelName, prompt, img_url: imageUrl }) // 轮询状态 let status: GetTaskStatusResult = await aigcCtrl.getTaskStatus(task_id) while (status.status === 'PENDING' || status.status === 'PROCESSING') { await new Promise(resolve => setTimeout(resolve, 2000)) status = await aigcCtrl.getTaskStatus(task_id) } return status.result_url } ``` --- ## 9. 权限角色管理流程 **场景**:管理员配置系统权限和角色 **涉及控制器**: - `PermissionController` - `RoleController` ### 代码示例 ```typescript import { root } from '@repo/core' import { PermissionController, RoleController } from '@repo/sdk' // 复用 SDK 导出的类型 import type { Permission, RoleWithPermissions } from '@repo/sdk' // 初始化权限系统 async function initPermissionSystem(): Promise<{ permissions: Permission[]; roles: RoleWithPermissions[] }> { const permCtrl = root.get(PermissionController) const roleCtrl = root.get(RoleController) // 1. 创建基础权限 const permissions: Permission[] = await Promise.all([ permCtrl.create({ resource: 'project', action: 'create' }), permCtrl.create({ resource: 'project', action: 'read' }), permCtrl.create({ resource: 'project', action: 'update' }), permCtrl.create({ resource: 'project', action: 'delete' }), permCtrl.create({ resource: 'template', action: 'run' }), permCtrl.create({ resource: 'category', action: 'create' }), permCtrl.create({ resource: 'category', action: 'update' }) ]) // 2. 创建角色 const userRole = await roleCtrl.create({ name: 'user', displayName: '普通用户', description: '基础用户权限' }) const adminRole = await roleCtrl.create({ name: 'admin', displayName: '管理员', description: '管理员权限' }) // 3. 分配权限给角色 await roleCtrl.updatePermissions({ roleId: userRole.id, permissionIds: permissions .filter(p => p.resource === 'project' || p.action === 'run') .map(p => p.id) }) await roleCtrl.updatePermissions({ roleId: adminRole.id, permissionIds: permissions.map(p => p.id) }) return { permissions, roles: [userRole, adminRole] } } // 获取角色及其权限 async function getRolesWithPermissions(): Promise { const roleCtrl = root.get(RoleController) const { roles } = await roleCtrl.list() return roles } ``` --- ## 接口依赖关系总结 | 主流程 | 依赖接口 | 说明 | |--------|----------|------| | 模板运行 | Template → AIGC → File → Project | 完整的内容生成流程 | | 社交互动 | Template → TemplateSocial | 点赞、收藏、评论 | | 项目管理 | Project ↔ ProjectTag | 双向关联 | | 文件处理 | File(多个方法链式调用) | 上传→压缩→转换→水印 | | 分类标签 | Category ↔ Tag | 多对多关联 | | 消息通知 | Message + Announcement | 并行获取 | | AI 生成 | AIGC + Chat | 独立或组合使用 | | 权限管理 | Permission → Role | 权限分配给角色 |