refactor: 清理无用模块、修复前后端对齐、添加注册页面

- 删除后端 risk_exceptions 模块(API/Model/Schema/迁移/测试)
- 删除后端 metrics 模块(API/测试)
- 删除后端 ManualTask 模型和相关 Schema
- 修复搜索接口响应缺少 total 字段的问题
- 统一 Platform 枚举(前端去掉后端不支持的 weibo/wechat)
- 新增前端注册页面 /register,登录页添加注册链接

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-02-09 14:51:17 +08:00
co-authored by Claude Opus 4.6
parent a32102f583
commit 4a3c7e7923
22 changed files with 725 additions and 1298 deletions
+176 -9
View File
@@ -8,6 +8,8 @@ import type {
VideoReviewResponse,
ReviewProgressResponse,
ReviewResultResponse,
ScriptReviewRequest,
ScriptReviewResponse,
} from '@/types/review'
import type {
TaskResponse,
@@ -40,6 +42,29 @@ import type {
AgencyDashboard,
BrandDashboard,
} from '@/types/dashboard'
import type {
ForbiddenWordCreate,
ForbiddenWordResponse,
ForbiddenWordListResponse,
WhitelistCreate,
WhitelistResponse,
WhitelistListResponse,
CompetitorCreate,
CompetitorResponse,
CompetitorListResponse,
PlatformRuleResponse,
PlatformListResponse,
RuleValidateRequest,
RuleValidateResponse,
} from '@/types/rules'
import type {
AIConfigUpdate,
AIConfigResponse,
GetModelsRequest,
ModelsListResponse,
TestConnectionRequest,
ConnectionTestResponse,
} from '@/types/ai-config'
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000'
const STORAGE_KEY_ACCESS = 'miaosi_access_token'
@@ -67,7 +92,8 @@ export interface User {
export interface LoginRequest {
email?: string
phone?: string
password: string
password?: string
sms_code?: string
}
export interface RegisterRequest {
@@ -102,6 +128,14 @@ export interface UploadPolicyResponse {
max_size_mb: number
}
export interface FileUploadedResponse {
url: string
file_key: string
file_name: string
file_size: number
file_type: string
}
// ==================== Token 管理 ====================
function getAccessToken(): string | null {
@@ -283,8 +317,8 @@ class ApiClient {
/**
* 文件上传完成回调
*/
async fileUploaded(fileKey: string, fileName: string, fileSize: number, fileType: string): Promise<{ url: string }> {
const response = await this.client.post<{ url: string }>('/upload/complete', {
async fileUploaded(fileKey: string, fileName: string, fileSize: number, fileType: string): Promise<FileUploadedResponse> {
const response = await this.client.post<FileUploadedResponse>('/upload/complete', {
file_key: fileKey,
file_name: fileName,
file_size: fileSize,
@@ -299,12 +333,7 @@ class ApiClient {
* 提交视频审核
*/
async submitVideoReview(data: VideoReviewRequest): Promise<VideoReviewResponse> {
const response = await this.client.post<VideoReviewResponse>('/videos/review', {
video_url: data.videoUrl,
platform: data.platform,
brand_id: data.brandId,
creator_id: data.creatorId,
})
const response = await this.client.post<VideoReviewResponse>('/videos/review', data)
return response.data
}
@@ -603,6 +632,144 @@ class ApiClient {
return response.data
}
// ==================== 脚本预审 ====================
/**
* 脚本预审(AI 审核)
*/
async reviewScriptContent(data: ScriptReviewRequest): Promise<ScriptReviewResponse> {
const response = await this.client.post<ScriptReviewResponse>('/scripts/review', data)
return response.data
}
// ==================== 规则管理 ====================
/**
* 查询违禁词列表
*/
async listForbiddenWords(category?: string): Promise<ForbiddenWordListResponse> {
const response = await this.client.get<ForbiddenWordListResponse>('/rules/forbidden-words', {
params: category ? { category } : undefined,
})
return response.data
}
/**
* 添加违禁词
*/
async addForbiddenWord(data: ForbiddenWordCreate): Promise<ForbiddenWordResponse> {
const response = await this.client.post<ForbiddenWordResponse>('/rules/forbidden-words', data)
return response.data
}
/**
* 删除违禁词
*/
async deleteForbiddenWord(wordId: string): Promise<void> {
await this.client.delete(`/rules/forbidden-words/${wordId}`)
}
/**
* 查询白名单
*/
async listWhitelist(brandId?: string): Promise<WhitelistListResponse> {
const response = await this.client.get<WhitelistListResponse>('/rules/whitelist', {
params: brandId ? { brand_id: brandId } : undefined,
})
return response.data
}
/**
* 添加白名单
*/
async addToWhitelist(data: WhitelistCreate): Promise<WhitelistResponse> {
const response = await this.client.post<WhitelistResponse>('/rules/whitelist', data)
return response.data
}
/**
* 查询竞品列表
*/
async listCompetitors(brandId?: string): Promise<CompetitorListResponse> {
const response = await this.client.get<CompetitorListResponse>('/rules/competitors', {
params: brandId ? { brand_id: brandId } : undefined,
})
return response.data
}
/**
* 添加竞品
*/
async addCompetitor(data: CompetitorCreate): Promise<CompetitorResponse> {
const response = await this.client.post<CompetitorResponse>('/rules/competitors', data)
return response.data
}
/**
* 删除竞品
*/
async deleteCompetitor(competitorId: string): Promise<void> {
await this.client.delete(`/rules/competitors/${competitorId}`)
}
/**
* 查询所有平台规则
*/
async listPlatformRules(): Promise<PlatformListResponse> {
const response = await this.client.get<PlatformListResponse>('/rules/platforms')
return response.data
}
/**
* 查询指定平台规则
*/
async getPlatformRules(platform: string): Promise<PlatformRuleResponse> {
const response = await this.client.get<PlatformRuleResponse>(`/rules/platforms/${platform}`)
return response.data
}
/**
* 规则冲突检测
*/
async validateRules(data: RuleValidateRequest): Promise<RuleValidateResponse> {
const response = await this.client.post<RuleValidateResponse>('/rules/validate', data)
return response.data
}
// ==================== AI 配置 ====================
/**
* 获取 AI 配置
*/
async getAIConfig(): Promise<AIConfigResponse> {
const response = await this.client.get<AIConfigResponse>('/ai-config')
return response.data
}
/**
* 更新 AI 配置
*/
async updateAIConfig(data: AIConfigUpdate): Promise<AIConfigResponse> {
const response = await this.client.put<AIConfigResponse>('/ai-config', data)
return response.data
}
/**
* 获取可用模型列表
*/
async getAIModels(data: GetModelsRequest): Promise<ModelsListResponse> {
const response = await this.client.post<ModelsListResponse>('/ai-config/models', data)
return response.data
}
/**
* 测试 AI 连接
*/
async testAIConnection(data: TestConnectionRequest): Promise<ConnectionTestResponse> {
const response = await this.client.post<ConnectionTestResponse>('/ai-config/test', data)
return response.data
}
// ==================== 健康检查 ====================
/**
-2
View File
@@ -4,8 +4,6 @@ export const platformOptions = [
{ id: 'xiaohongshu', name: '小红书', icon: '📕', bgColor: 'bg-[#fe2c55]/15', textColor: 'text-[#fe2c55]', borderColor: 'border-[#fe2c55]/30' },
{ id: 'bilibili', name: 'B站', icon: '📺', bgColor: 'bg-[#00a1d6]/15', textColor: 'text-[#00a1d6]', borderColor: 'border-[#00a1d6]/30' },
{ id: 'kuaishou', name: '快手', icon: '⚡', bgColor: 'bg-[#ff4906]/15', textColor: 'text-[#ff4906]', borderColor: 'border-[#ff4906]/30' },
{ id: 'weibo', name: '微博', icon: '🔴', bgColor: 'bg-[#e6162d]/15', textColor: 'text-[#e6162d]', borderColor: 'border-[#e6162d]/30' },
{ id: 'wechat', name: '微信视频号', icon: '💬', bgColor: 'bg-[#07c160]/15', textColor: 'text-[#07c160]', borderColor: 'border-[#07c160]/30' },
]
export type PlatformId = typeof platformOptions[number]['id']