feat: 审核体系全面改造 — 多维度评分 + 卖点优先级 + AI 语义匹配 + 品牌方 AI 状态通知
后端: - 审核结果拆分为 4 个独立维度 (法规合规/平台规则/品牌安全/Brief匹配度) - 卖点优先级从 required:bool 改为三级 (core/recommended/reference) - AI 语义匹配卖点覆盖 + AI 整体 Brief 匹配度分析 - BriefMatchDetail 评分详情 (覆盖率+亮点+问题点) - min_selling_points 代理商可配置最少卖点数 + Alembic 迁移 - AI 语境复核过滤误报 - Brief AI 解析 + 规则 AI 解析 - AI 未配置/异常时通知品牌方 - 种子数据更新 (新格式审核结果+brief_match_detail) 前端: - 三端审核页面展示四维度评分卡片 - 卖点编辑改为三级优先级选择器 - BriefMatchDetail 展示 (覆盖率进度条+亮点+问题) - min_selling_points 配置 UI - AI 配置页未配置时静默处理 - 文件预览/下载/签名 URL 优化 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
0c59797d5b
commit
0ef7650c09
+72
-4
@@ -473,14 +473,44 @@ class ApiClient {
|
||||
/**
|
||||
* 获取私有桶文件的预签名访问 URL
|
||||
*/
|
||||
async getSignedUrl(url: string, expire: number = 3600, download: boolean = false): Promise<string> {
|
||||
async getSignedUrl(url: string): Promise<string> {
|
||||
const response = await this.client.get<{ signed_url: string; expire_seconds: number }>(
|
||||
'/upload/sign-url',
|
||||
{ params: { url, expire, download } }
|
||||
{ params: { url } }
|
||||
)
|
||||
return response.data.signed_url
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过后端代理获取文件预览 Blob URL(用于 iframe/img src)
|
||||
*/
|
||||
async getPreviewUrl(fileUrl: string): Promise<string> {
|
||||
const response = await this.client.get('/upload/preview', {
|
||||
params: { url: fileUrl },
|
||||
responseType: 'blob',
|
||||
})
|
||||
return URL.createObjectURL(response.data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过后端代理下载文件(避免 TOS CORS 问题)
|
||||
*/
|
||||
async downloadFile(fileUrl: string, filename: string): Promise<void> {
|
||||
const response = await this.client.get('/upload/download', {
|
||||
params: { url: fileUrl },
|
||||
responseType: 'blob',
|
||||
})
|
||||
const blob = new Blob([response.data])
|
||||
const blobUrl = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = blobUrl
|
||||
a.download = filename
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
}
|
||||
|
||||
// ==================== 视频审核 ====================
|
||||
|
||||
/**
|
||||
@@ -524,9 +554,9 @@ class ApiClient {
|
||||
/**
|
||||
* 查询任务列表
|
||||
*/
|
||||
async listTasks(page: number = 1, pageSize: number = 20, stage?: TaskStage): Promise<TaskListResponse> {
|
||||
async listTasks(page: number = 1, pageSize: number = 20, stage?: TaskStage, projectId?: string): Promise<TaskListResponse> {
|
||||
const response = await this.client.get<TaskListResponse>('/tasks', {
|
||||
params: { page, page_size: pageSize, stage },
|
||||
params: { page, page_size: pageSize, stage, project_id: projectId },
|
||||
})
|
||||
return response.data
|
||||
}
|
||||
@@ -677,6 +707,37 @@ class ApiClient {
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 代理商更新 Brief(agency_attachments + selling_points + blacklist_words)
|
||||
*/
|
||||
async updateBriefByAgency(projectId: string, data: {
|
||||
agency_attachments?: Array<{ id?: string; name: string; url: string; size?: string }>
|
||||
selling_points?: Array<{ content: string; required: boolean }>
|
||||
blacklist_words?: Array<{ word: string; reason: string }>
|
||||
brand_tone?: string
|
||||
other_requirements?: string
|
||||
min_selling_points?: number | null
|
||||
}): Promise<BriefResponse> {
|
||||
const response = await this.client.patch<BriefResponse>(`/projects/${projectId}/brief/agency-attachments`, data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* AI 解析 Brief 文档
|
||||
*/
|
||||
async parseBrief(projectId: string): Promise<{
|
||||
product_name: string
|
||||
target_audience: string
|
||||
content_requirements: string
|
||||
selling_points: Array<{ content: string; required: boolean }>
|
||||
blacklist_words: Array<{ word: string; reason: string }>
|
||||
}> {
|
||||
const response = await this.client.post(`/projects/${projectId}/brief/parse`, null, {
|
||||
timeout: 180000, // 3 分钟,文档下载 + AI 解析较慢
|
||||
})
|
||||
return response.data
|
||||
}
|
||||
|
||||
// ==================== 组织关系 ====================
|
||||
|
||||
/**
|
||||
@@ -841,6 +902,13 @@ class ApiClient {
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除白名单
|
||||
*/
|
||||
async deleteWhitelistItem(id: string): Promise<void> {
|
||||
await this.client.delete(`/rules/whitelist/${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询竞品列表
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user