25 KiB
25 KiB
接口组合使用场景
本文档详细描述 @repo/sdk 中各接口的组合使用场景,帮助理解业务流程中接口之间的依赖关系。
推荐:所有示例都使用
root.get(Controller)方式调用,并复用 SDK 导出的类型。
目录
1. 模板运行完整流程
场景:用户选择模板,填写表单,生成内容,保存到项目
涉及控制器:
TemplateControllerAigcControllerFileControllerTemplateGenerationControllerProjectController
流程图
用户选择模板
↓
TemplateController.get(templateId)
↓
用户填写表单(根据 formSchema)
↓
TemplateController.run({ templateId, formData, projectId? })
↓ 返回 generationId
轮询任务状态
↓
AigcController.getTaskStatus(taskId)
↓ status === 'COMPLETED'
获取生成结果
↓
FileController.convertToWebp({ videoUrl }) [可选:格式转换]
↓
ProjectController.update({ id, resultUrl }) [保存到项目]
代码示例
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<string, any>) {
// 使用 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
}
}
重新运行场景
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. 模板社交互动流程
场景:用户浏览模板列表,点赞、收藏、评论
涉及控制器:
TemplateControllerTemplateSocialController
流程图
获取模板列表
↓
TemplateController.list({ page, limit })
↓
批量检查社交状态
↓
TemplateSocialController.checkLikedBatch({ templateIds })
TemplateSocialController.checkFavoritedBatch({ templateIds })
↓
用户交互
↓
点赞: TemplateSocialController.like({ templateId })
收藏: TemplateSocialController.favorite({ templateId })
评论: TemplateSocialController.createComment({ templateId, content })
代码示例
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<boolean> {
const socialCtrl = root.get(TemplateSocialController)
if (isCurrentlyLiked) {
await socialCtrl.unlike({ templateId })
} else {
await socialCtrl.like({ templateId })
}
return !isCurrentlyLiked
}
// 获取评论列表(含回复)
async function getCommentsWithReplies(templateId: string): Promise<GetCommentsResponse> {
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<TemplateComment> {
const socialCtrl = root.get(TemplateSocialController)
const comment = await socialCtrl.createComment({
templateId,
content,
parentId // 如果是回复,传入父评论ID
})
return comment
}
3. 项目管理与标签流程
场景:用户创建项目,使用标签分类管理
涉及控制器:
ProjectControllerProjectTagController
流程图
创建用户标签
↓
ProjectTagController.create({ name, color })
↓
创建项目
↓
ProjectController.create({ title, content })
↓
给项目添加标签
↓
ProjectTagController.addToProject({ projectId, tagId })
↓
按标签筛选项目
↓
ProjectController.list({ tagId })
代码示例
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<UserTag[]> {
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<Project> {
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<Array<UserTag & { projectCount: number }>> {
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<TransferProjectResult> {
const projectCtrl = root.get(ProjectController)
const result = await projectCtrl.transfer({
projectId,
targetUserId,
mode: 'copy' // 'transfer' 会移动所有权,'copy' 会复制
})
return result
}
4. 文件上传与处理流程
场景:用户上传文件,进行格式转换和处理
涉及控制器:
FileControllerFFmpegController(视频合成)
流程图
用户选择文件
↓
FileController.uploadS3(formData)
↓ 返回文件URL
选择处理方式
↓
├─ 压缩视频: FileController.compressVideo({ videoUrl, quality })
├─ 转WebP: FileController.convertToWebp({ videoUrl, ... })
├─ 转ANI: FileController.convertToAni({ videoUrl })
├─ 加水印: FileController.convertToWatermark({ videoUrl, watermarkUrl })
└─ 视频合成: FFmpegController.concat({ videoUrls })
代码示例
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<string> {
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<string> {
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<string> {
const fileCtrl = root.get(FileController)
const formData = new FormData()
formData.append('file', file)
// 使用组合接口,一步完成上传和转换
const result = await fileCtrl.uploadAndConvertToAni(formData)
return result.data
}
5. 分类标签管理流程
场景:管理员管理模板分类和标签体系
涉及控制器:
CategoryControllerTagController
流程图
创建分类
↓
CategoryController.create({ name, nameEn })
↓
创建标签
↓
TagController.create({ name, nameEn })
↓
关联标签到分类
↓
TagController.updateCategoryTag({ tagId, categoryId, sortOrder })
↓
调整排序
↓
CategoryController.batchUpdateSortOrder({ items })
CategoryController.batchUpdateTagSortOrder({ categoryId, items })
代码示例
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<Category[]> {
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<void> {
const categoryCtrl = root.get(CategoryController)
await categoryCtrl.batchUpdateSortOrder({ items })
}
6. 消息通知处理流程
场景:用户查看和管理消息通知
涉及控制器:
MessageControllerAnnouncementController
流程图
获取未读数量
↓
MessageController.getUnreadCount()
AnnouncementController.getUnreadCount()
↓
获取消息列表
↓
MessageController.list({ type, isRead })
↓
标记已读
↓
MessageController.markRead({ id })
MessageController.batchMarkRead({ ids })
代码示例
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<ListMessagesResult> {
const messageCtrl = root.get(MessageController)
const { messages, total } = await messageCtrl.list({
type,
page: 1,
limit: 50
})
return { messages, total }
}
// 一键已读所有消息
async function markAllAsRead(): Promise<void> {
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. 用户收藏夹管理流程
场景:用户管理收藏的模板和喜欢的内容
涉及控制器:
TemplateSocialControllerTemplateController
代码示例
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<GetUserLikesResponse> {
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<boolean> {
const socialCtrl = root.get(TemplateSocialController)
if (isCurrentlyFavorited) {
await socialCtrl.unfavorite({ templateId })
} else {
await socialCtrl.favorite({ templateId })
}
return !isCurrentlyFavorited
}
8. AI 内容生成流程
场景:直接使用 AI 模型生成图片或视频
涉及控制器:
AigcControllerChatController
代码示例
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<Record<string, AigcModel[]>> {
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<string, AigcModel[]>)
return groupedModels
}
// 生成图片
async function generateImage(prompt: string, modelName: string, options?: {
aspectRatio?: string;
watermark?: boolean;
}): Promise<string | undefined> {
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<string> {
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<string | undefined> {
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. 权限角色管理流程
场景:管理员配置系统权限和角色
涉及控制器:
PermissionControllerRoleController
代码示例
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<RoleWithPermissions[]> {
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 | 权限分配给角色 |