Files
video-gen/video-gen-app/src/api/index.ts
T
2026-07-01 13:44:19 +08:00

766 lines
33 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* API abstraction layer.
* Switches between mock data and real backend based on VITE_USE_MOCK env var.
*/
import { api, setToken, clearToken } from './client';
import * as mock from './mock';
import type {
User, CreditRecord, Project, GenerationRecord, OptimizeParams, GenerateParams, OptimizeResult,
Industry, IndustryConfig, AdminUser, AdminStats, ModelConfig, SystemConfig, AdminNotification,
} from '../types';
const USE_MOCK = import.meta.env.VITE_USE_MOCK === 'true';
// ── Auth ──────────────────────────────────────────────────
export async function login(username: string, password: string, captchaToken?: string, rememberMe?: boolean): Promise<User> {
if (USE_MOCK) return mock.mockLogin({ username, password });
const res = await api.post<{ accessToken: string; user: User }>('/auth/login', { username, password, captcha_token: captchaToken, remember_me: rememberMe || false }, false, true);
setToken(res.accessToken);
return res.user;
}
export async function phonelogin(phone: string, code: string): Promise<User> {
// if (USE_MOCK) return mock.mockLogin({ username, password });
const res = await api.post<{ accessToken: string; user: User }>('/auth/sms-login', { phone, code }, false, true);
setToken(res.accessToken);
return res.user;
}
export async function register(phone: string, code: string, password: string): Promise<User> {
const res = await api.post<{ accessToken: string; user: User }>('/auth/register', { phone, code, password }, false);
setToken(res.accessToken);
return res.user;
}
export async function logout(): Promise<void> {
if (USE_MOCK) return mock.mockLogout();
await api.post('/auth/logout');
clearToken();
}
export async function getUser(): Promise<User | null> {
if (USE_MOCK) return mock.mockGetUser();
try {
return await api.get<User>('/auth/me');
} catch {
return null;
}
}
export async function changePassword(oldPwd: string, newPwd: string): Promise<void> {
if (USE_MOCK) return;
await api.post('/auth/change-password', { old_password: oldPwd, new_password: newPwd });
}
// ── Projects ──────────────────────────────────────────────
export async function getProjects(): Promise<Project[]> {
if (USE_MOCK) return mock.mockGetProjects();
return api.get<Project[]>('/projects');
}
export async function createProject(name: string, industry: Industry): Promise<Project> {
if (USE_MOCK) return mock.mockCreateProject(name, industry);
return api.post<Project>('/projects', { name, industry });
}
export async function deleteProject(id: string): Promise<void> {
if (USE_MOCK) return mock.mockDeleteProject(id);
await api.delete(`/projects/${id}`);
}
// ── Generation ────────────────────────────────────────────
export interface GenerationRecordPageListOut {
page: number;
pageSize: number;
total: number;
items: GenerationRecord[];
}
export interface GetRecordsPageParams {
projectId?: string;
status?: string;
page?: number;
pageSize?: number;
signal?: AbortSignal;
}
export async function getRecordsPage(params: GetRecordsPageParams = {}): Promise<GenerationRecordPageListOut> {
const page = params.page && params.page > 0 ? params.page : 1;
const pageSize = params.pageSize && params.pageSize > 0 ? params.pageSize : 10;
if (USE_MOCK) {
const mockRecords = await mock.mockGetGenerationRecords(params.projectId);
const filtered = params.status
? mockRecords.filter((record) => record.status === params.status)
: mockRecords;
const start = (page - 1) * pageSize;
return {
page,
pageSize,
total: filtered.length,
items: filtered.slice(start, start + pageSize),
};
}
const query = new URLSearchParams();
if (params.projectId) query.set('project_id', params.projectId);
if (params.status) query.set('status', params.status);
query.set('page', String(page));
query.set('page_size', String(pageSize));
return api.get<GenerationRecordPageListOut>(`/generation-records?${query.toString()}`, { signal: params.signal });
}
export async function optimizePrompt(
projectId: string, params: OptimizeParams
): Promise<OptimizeResult> {
if (USE_MOCK) return mock.mockOptimizePrompt(projectId, params as any);
return api.post('/generation-records/optimize', {
project_id: projectId,//项目id
gen_type:params.genType,//生成类型
prompt: params.prompt,
duration: params.duration,
references: params.references || null,
idempotency_key: params.idempotencyKey || null,
image_size: params.image_size || null,
image_proportion: params.image_proportion || null,
image_px: params.image_px || null,
});
}
export async function uploadImage(file: File): Promise<{ url: string; filename: string }> {
const form = new FormData();
form.append('file', file);
const token = localStorage.getItem('auth_token');
const res = await fetch(`${import.meta.env.VITE_API_BASE || 'http://localhost:8000'}/api/generation-records/upload-image`, {
method: 'POST',
headers: token ? { Authorization: `Bearer ${token}` } : {},
body: form,
});
if (!res.ok) throw new Error('图片上传失败');
const data = await res.json();
return { url: data.url, filename: data.filename };
}
export async function uploadVideo(file: File): Promise<{ url: string; filename: string }> {
const form = new FormData();
form.append('file', file);
const token = localStorage.getItem('auth_token');
const res = await fetch(`${import.meta.env.VITE_API_BASE || 'http://localhost:8000'}/api/generation-records/upload-video`, {
method: 'POST',
headers: token ? { Authorization: `Bearer ${token}` } : {},
body: form,
});
if (!res.ok) throw new Error('视频上传失败');
const data = await res.json();
return { url: data.url, filename: data.filename };
}
export async function deleteUpload(url: string): Promise<void> {
await api.post(`/generation-records/delete-file?url=${encodeURIComponent(url)}`);
}
export async function updateRecordPrompt(recordId: string, optimizedPrompt: string): Promise<void> {
await api.put(`/generation-records/${recordId}/prompt`, { optimized_prompt: optimizedPrompt });
}
export async function generateVideo(recordId: string, params: GenerateParams): Promise<GenerationRecord> {
if (USE_MOCK) return mock.mockGenerateVideo(recordId);
return api.post<GenerationRecord>(`/generation-records/${recordId}/generate`, {
aspect_ratio: params.aspectRatio,
resolution: params.resolution,
});
}
// ── Credits ───────────────────────────────────────────────
export async function getCredits(page = 1, pageSize = 20): Promise<{ credits: number; records: CreditRecord[]; total: number }> {
if (USE_MOCK) {
const data = await mock.mockGetCredits();
return data;
}
const params = new URLSearchParams();
params.set('page', String(page));
params.set('page_size', String(pageSize));
return api.get(`/credits?${params.toString()}`);
}
// ── Captcha ───────────────────────────────────────────────
export async function getSliderCaptcha(): Promise<{ captcha_id: string; bg_image: string; slider_image: string }> {
if (USE_MOCK) return { captcha_id: 'mock', bg_image: '', slider_image: '' };
return api.get('/captcha/slider', false);
}
export async function verifyCaptcha(captchaId: string, x: number): Promise<string> {
if (USE_MOCK) return 'mock-token';
const res = await api.post<{ token: string }>('/captcha/verify', { captcha_id: captchaId, x_offset: x }, false);
return res.token;
}
// ── Site Info ─────────────────────────────────────────────
export async function getSiteInfo(): Promise<{ siteName: string; siteLogo: string; userAgreementPrivacyUrl: string; siteCopyright: string }> {
if (USE_MOCK) return { siteName: 'VideoGen.AI', siteLogo: '', userAgreementPrivacyUrl: '', siteCopyright: '© 2024 民众智创 版权所有' };
return api.get('/auth/site-info', false);
}
// ── Video Engines ─────────────────────────────────────────
export async function getVideoEngines(): Promise<{ items: { id: string; name: string; provider: string; supportedRatios: string[]; supportedResolutions: string[]; supportedDurations: number[] }[] }> {
if (USE_MOCK) return { items: [{ id: 'mock', name: 'Seedance', provider: 'seedance', supportedRatios: ['16:9', '9:16', '1:1', '4:3', '3:4', '21:9'], supportedResolutions: ['480p', '720p', '1080p'], supportedDurations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] }] };
return api.get('/video-engines');
}
// 参数选择(图片)Parameters
export async function getParameters(): Promise<any[]> {
return api.get('/image-engines');
}
// ── SMS ───────────────────────────────────────────────────
export async function sendSms(phone: string, scene: string): Promise<void> {
if (USE_MOCK) return;
await api.post('/sms/send', { phone, scene: scene }, false);
}
export async function verifySms(phone: string, code: string): Promise<{ token: string }> {
if (USE_MOCK) return { token: 'mock-sms-token' };
return api.post('/sms/verify', { phone, code }, false);
}
// ── Notifications ─────────────────────────────────────────
export async function getNotifications(page = 1, pageSize = 20, isRead?: boolean): Promise<{ items: AdminNotification[], total: number, credits?: { balance: number } }> {
if (USE_MOCK) {
const items = await mock.mockGetAdminNotifications();
return { items, total: items.length };
}
const params = new URLSearchParams();
params.set('page', String(page));
params.set('page_size', String(pageSize));
if (isRead !== undefined) {
params.set('is_read', String(isRead));
}
return api.get(`/notifications?${params.toString()}`);
}
export async function getUnreadCount(): Promise<number> {
if (USE_MOCK) return mock.mockGetAdminNotifications().then(n => n.filter(x => !x.isRead).length);
const res = await api.get<{ count: number }>('/notifications/unread-count');
return res.count;
}
export async function markNotificationRead(id: string): Promise<void> {
if (USE_MOCK) return;
await api.put(`/notifications/${id}/read`);
}
// ── Admin ─────────────────────────────────────────────────
export async function getAdminStats(): Promise<AdminStats> {
if (USE_MOCK) return mock.mockGetAdminStats();
return api.get('/admin/stats');
}
export async function getAdminUsers(search?: string): Promise<AdminUser[]> {
if (USE_MOCK) return mock.mockGetAdminUsers(search);
const q = search ? `?search=${encodeURIComponent(search)}` : '';
return api.get(`/admin/users${q}`);
}
export async function adjustCredits(userId: string, amount: number, description: string): Promise<void> {
if (USE_MOCK) return mock.mockAdjustCredits(userId, amount, description);
await api.post(`/admin/users/${userId}/credits`, { amount, description });
}
export async function toggleUserStatus(userId: string, isActive: boolean): Promise<void> {
if (USE_MOCK) return mock.mockToggleUserStatus(userId, isActive);
await api.put(`/admin/users/${userId}/status`, { is_active: isActive });
}
export async function getModelConfigs(): Promise<ModelConfig[]> {
if (USE_MOCK) return mock.mockGetModelConfigs();
return api.get('/admin/model-configs');
}
export async function saveModelConfig(config: Partial<ModelConfig> & { id?: string }): Promise<ModelConfig> {
if (USE_MOCK) return mock.mockSaveModelConfig(config as any);
if (config.id) return api.put(`/admin/model-configs/${config.id}`, config);
return api.post('/admin/model-configs', config);
}
export async function deleteModelConfig(id: string): Promise<void> {
if (USE_MOCK) return mock.mockDeleteModelConfig(id);
await api.delete(`/admin/model-configs/${id}`);
}
export async function getSystemConfigs(): Promise<SystemConfig[]> {
if (USE_MOCK) return mock.mockGetSystemConfigs();
return api.get('/admin/system-configs');
}
export async function updateSystemConfig(id: string, value: string): Promise<void> {
if (USE_MOCK) return mock.mockUpdateSystemConfig(id, value);
await api.put(`/admin/system-configs/${id}`, { value });
}
// ── Industries ─────────────────────────────────────────────
export async function getIndustries(): Promise<IndustryConfig[]> {
const data = await api.get<any[]>('/industries');
return data.map((item: any) => {
const skills = Array.isArray(item.skills) ? item.skills : [];
const optionGroups = skills
.filter((s: any) => s && s.type === 'option_group' && s.name && Array.isArray(s.options))
.map((s: any) => ({ name: s.name, options: s.options }));
return { ...item, optionGroups };
});
}
// ── Menu Config ────────────────────────────────────────────
export async function getMenuConfigs(): Promise<any[]> {
return api.get('/menu-configs');
}
// ── Recharge Packages ──────────────────────────────────────
export async function getRechargePackages(): Promise<any[]> {
return api.get('/recharge-packages');
}
export async function getPaymentMethods(): Promise<{ alipay: boolean; wechat: boolean }> {
return api.get('/payments/methods');
}
export async function createRechargeOrder(planId: string, method: string = 'wechat'): Promise<any> {
return api.post('/payments/recharge', { plan: planId, method });
}
export async function getPaymentOrders(page = 1, pageSize = 20): Promise<{ items: any[]; total: number }> {
const params = new URLSearchParams();
params.set('page', String(page));
params.set('page_size', String(pageSize));
return api.get(`/payments/orders?${params.toString()}`);
}
export async function getPaymentOrder(orderNo: string): Promise<any> {
return api.get(`/payments/orders/${orderNo}`);
}
export async function cancelPaymentOrder(orderNo: string): Promise<void> {
return api.post(`/payments/orders/${orderNo}/cancel`);
}
export async function getCreditRatios(): Promise<any[]> {
return api.get('/credits/ratios');
}
// 引擎配置
export async function getEngine(): Promise<any> {
if (USE_MOCK) return {
engine: {
image: [
{
id: "0019e3dac0b795b925b",
name: "Seedream 5.0",
provider: "ark",
model_name: "doubao-seedream-5-0-260128",
supported_models: ["doubao-seedream-5-0-260128"],
supported_sizes: {
"2K": {
"1:1": "2048×2048",
"4:3": "2304×1728",
"3:4": "1728×2304",
"16:9": "2560×1440",
"9:16": "1600×2848",
"3:2": "2496×1664",
"2:3": "1664×2496",
"21:9": "3024×1296"
},
"4K": {
"1:1": "4096×4096",
"4:3": "4608×3456",
"3:4": "3520×4704",
"16:9": "5404×3040",
"9:16": "3040×5504",
"3:2": "4992×3328",
"2:3": "3328×4992",
"21:9": "6197×2656"
}
},
default_size: "2K",
priority: 10,
maxImageCount: 4,
maxVideoCount: 0
}
],
video: [
{ id: '0019e1697667d0eff39', name: 'Seedance 2.0', provider: 'ark', model_name: 'seedance-2-0', supportedRatios: ['16:9', '9:16', '1:1', '4:3', '3:4', '21:9'], supportedResolutions: ['480p', '720p', '1080p'], supportedDurations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], maxImageCount: 4, maxVideoCount: 1 },
{ id: '0019e1697667d0eff38', name: 'Seedance 2.0 fast', provider: 'ark', model_name: 'seedance-2-0-fast', supportedRatios: ['16:9', '9:16', '1:1'], supportedResolutions: ['720p', '1080p'], supportedDurations: [5, 8, 10], maxImageCount: 2, maxVideoCount: 1 },
{ id: '0019f1b89b545d8e4b1', name: 'Seedance 2.0 mini', provider: 'ark', model_name: 'seedance-2-0-mini', supportedRatios: ['16:9', '9:16', '1:1'], supportedResolutions: ['480p', '720p'], supportedDurations: [4, 5, 6], maxImageCount: 1, maxVideoCount: 1 }
]
}
};
return api.get('/generation-ai/engines');
}
// ── Generation AI Tasks ────────────────────────────────────
// 创建ai生成任务
export async function createGenerationTask(params: any): Promise<any> {
return api.post('/generation-ai/tasks', params);
}
// 获取ai生成任务列表
export async function getgen_list(Pagebreak: any): Promise<any[]> {
return api.get('/generation-ai/tasks?page='+Pagebreak.page+'&page_size='+Pagebreak.pageSize);
}
// 获取生成任务历史记录
export async function gethistory(Pagebreak: any): Promise<any[]> {
return api.get('/generation-ai/history'+Pagebreak);
}
// 获取生成任务历史记录子项
export async function gethistoryItems(Pagebreak: any): Promise<any[]> {
return api.get('/generation-ai/history/'+Pagebreak);
}
// 删除ai对话历史记录
export async function deleteHistory(id: string): Promise<void> {
await api.delete(`/generation-ai/tasks/${id}`);
}
export async function calculateCredits(): Promise<any[]> {
return api.get('/credits/credit-ratios');
}
// 获取验证码
export async function getSendcode(phone: string): Promise<any> {
return api.post('/sms/send', { phone });
}
export interface OAuthAppParam {
page: number;
pageSize: number;
open_type?: string;
status?: string;
app_id?: string;
}
export interface OAuthAppList {
page: number;
pageSize: number;
total: number;
data: any[];
}
// 获取用户列表
export async function getAuthorizationList(params: OAuthAppParam): Promise<OAuthAppList> {
const query = new URLSearchParams();
query.set('page', String(params.page));
query.set('page_size', String(params.pageSize));
if (params.open_type) query.set('open_type', params.open_type);
if (params.status) query.set('status', params.status);
if (params.app_id) query.set('app_id', params.app_id);
return api.get<OAuthAppList>(`/admin/user-oauth-apps/list?${query.toString()}`);
}
// 爆款开头复刻
export async function generateReplication(params: any): Promise<any> {
return api.post('/hot-opening-replications/tasks', params);
}
// 获取爆款开头复刻任务列表
export async function getReplicationList(page: number, page_size: number, keyword?: string): Promise<any[]> {
let url = `/hot-opening-replications/tasks?page=${page}&page_size=${page_size}`;
if (keyword) {
url += `&keyword=${encodeURIComponent(keyword)}`;
}
return api.get(url);
}
// 获取爆款开头复刻任务详情
export async function getReplicationDetail(id: string): Promise<any> {
return api.get(`/hot-opening-replications/tasks/${id}`);
}
// 第一步,生成提示词
export async function getone(projectId: string, stepId: string): Promise<any> {
return api.post(`/hot-opening-replications/tasks/${projectId}/steps/${stepId}/generate-image-prompt`);
}
// 修改图片生成提示词
export async function updateImagePrompt(projectId: string, stepId: string, params: any): Promise<any> {
return api.put(`/hot-opening-replications/tasks/${projectId}/steps/${stepId}/image-prompt`, params);
}
// 第二步,生成图片
export async function gettwo(projectId: string, stepId: string ,params: any): Promise<any> {
return api.post(`/hot-opening-replications/tasks/${projectId}/steps/${stepId}/generate-image`, params);
}
// 第三步,生成视频提示词
export async function getthree(projectId: string, stepId: string ,params: any): Promise<any> {
return api.post(`/hot-opening-replications/tasks/${projectId}/steps/${stepId}/generate-video-prompt`, params);
}
// 第四步,生成视频
export async function getfour(projectId: string, stepId: string ,params: any): Promise<any> {
return api.post(`/hot-opening-replications/tasks/${projectId}/steps/${stepId}/generate-video`, params);
}
// 获取授权链接
export interface RequestOAuthParams {
open_type: number;
}
export async function requestOAuth(params: RequestOAuthParams): Promise<any> {
return api.post(`/user-oauth/request_oauth`, params);
}
// 巨量授权回调
export interface JuliangCallbackParams {
auth_code: string;
state: string;
app_id?: string;
material_auth_status?: string;
scope?: string;
uid?: string;
}
export async function juliang_callback(params: JuliangCallbackParams): Promise<any> {
const query = new URLSearchParams();
query.set('auth_code', params.auth_code);
query.set('state', params.state);
if (params.app_id) query.set('app_id', params.app_id);
if (params.material_auth_status) query.set('material_auth_status', params.material_auth_status);
if (params.scope) query.set('scope', params.scope);
if (params.uid) query.set('uid', params.uid);
return api.get(`/user-oauth/juliang_callback?${query.toString()}`);
}
// 授权列表
export interface OAuthListParams {
account_userid?: string;
open_type?: number;
account_id?: string;
page?: number;
page_size?: number;
}
export async function getOAuthList(params: OAuthListParams): Promise<any> {
const query = new URLSearchParams();
if (params.account_userid) query.set('account_userid', params.account_userid);
if (params.open_type !== undefined) query.set('open_type', String(params.open_type));
if (params.account_id) query.set('account_id', params.account_id);
if (params.page !== undefined) query.set('page', String(params.page));
if (params.page_size !== undefined) query.set('page_size', String(params.page_size));
return api.get(`/user-oauth/oauth_list?${query.toString()}`);
}
// 前测模板列表
export interface PreTestListParams {
platform?: string;
page?: number;
pageSize?: number;
}
export async function getPreTestList(params?: PreTestListParams): Promise<any> {
const query = new URLSearchParams();
if (params.platform) query.set('platform', params.platform);
if (params.page !== undefined) query.set('page', String(params.page));
if (params.pageSize !== undefined) query.set('page_size', String(params.pageSize));
return api.get(`/pre-test-template/list?${query.toString()}`);
}
// 获取前测字段列表
export async function getPreTestFields(): Promise<any> {
return api.get(`/pre-test-template/fields`);
}
// 创建前测模板
export async function createPreTest(params: any): Promise<any> {
return api.post(`/pre-test-template/create`, params);
}
// 前测模板详情
export async function getPreTestDetail(templateId: string): Promise<any> {
return api.get(`/pre-test-template/select/${templateId}`);
}
// 更新前测模板
export async function updatePreTest(templateId: string, params: any): Promise<any> {
return api.post(`/pre-test-template/update/${templateId}`, params);
}
// 删除前测模板
export async function deletePreTest(templateId: string): Promise<any> {
return api.get(`/pre-test-template/delete/${templateId}`);
}
// 获取默认前测模板
export async function getDefaultPreTest(): Promise<any> {
return api.get(`/pre-test-template/default`);
}
// 修改第四步视频 AI 提词 JSON schema
export async function updateHotOpeningVideoPromptSchema(projectId: string, stepId: string, params: { prompt_schema: Record<string, any> }): Promise<any> {
return api.put(`/hot-opening-replications/tasks/${projectId}/steps/${stepId}/video-prompt-schema`, params);
}
// 镜头复刻
export async function createShotReplication(params: any): Promise<any> {
return api.post('/shot-replications/task-sets', params);
}
// 获取镜头复刻任务列表
export async function getShotReplicationList(page: number, page_size: number, keyword?: string): Promise<any> {
const url = keyword
? `/shot-replications/task-sets?page=${page}&page_size=${page_size}&keyword=${encodeURIComponent(keyword)}`
: `/shot-replications/task-sets?page=${page}&page_size=${page_size}`;
return api.get(url);
}
// 获取镜头复刻任务详情
export async function getShotReplicationDetail(taskSetId: string): Promise<any> {
return api.get(`/shot-replications/task-sets/${taskSetId}`);
}
// ai拆镜
export async function createRemoveLens(taskSetId: string, params: any): Promise<any> {
return api.post(`/shot-replications/task-sets/${taskSetId}/split-by-ai`, params);
}
// 手动分割
export async function splitCustom(taskSetId: string, params: any): Promise<any> {
return api.post(`/shot-replications/task-sets/${taskSetId}/split-custom`, params);
}
// 拆镜列表
export async function Removelist(taskSetId: string): Promise<any> {
return api.get(`/shot-replications/task-sets/${taskSetId}/segments`);
}
// 生成视频
export async function removeCreate(recordId: string, params: any): Promise<any> {
return api.post(`/shot-replications/segments/${recordId}/replication-projects`, params);
}
// 获取爆款开头复刻任务详情
export async function removeDetail(id: string): Promise<any> {
return api.get(`/shot-replications/projects/${id}`);
}
// 第一步,生成提示词
export async function removeone(projectId: string, stepId: string): Promise<any> {
return api.post(`/shot-replications/projects/${projectId}/steps/${stepId}/generate-image-prompt`);
}
// 修改图片提示词
export async function updateShotImagePrompt(projectId: string, stepId: string, params: any): Promise<any> {
return api.put(`/shot-replications/projects/${projectId}/steps/${stepId}/image-prompt`, params);
}
// 修改视频提示词
export async function updateShotVideoPromptSchema(projectId: string, stepId: string, params: any): Promise<any> {
return api.put(`/shot-replications/projects/${projectId}/steps/${stepId}/video-prompt-schema`, params);
}
// 第二步,生成图片
export async function removetwo(projectId: string, stepId: string ,params: any): Promise<any> {
return api.post(`/shot-replications/projects/${projectId}/steps/${stepId}/generate-image`, params);
}
// 第三步,生成视频提示词
export async function removethree(projectId: string, stepId: string ,params: any): Promise<any> {
return api.post(`/shot-replications/projects/${projectId}/steps/${stepId}/generate-video-prompt`, params);
}
// 第四步,生成视频
export async function removefour(projectId: string, stepId: string ,params: any): Promise<any> {
return api.post(`/shot-replications/projects/${projectId}/steps/${stepId}/generate-video`, params);
}
// 获取地区信息
export interface GetAreaParams {
level?: string;
parent_code?: string;
}
export async function getArea(params?: GetAreaParams): Promise<any> {
const query = new URLSearchParams();
if (params?.level) query.set('level', params.level);
if (params?.parent_code) query.set('parent_code', params.parent_code);
return api.get(`/pre-test-template/getArea?${query.toString()}`);
}
// ── Upload Material ───────────────────────────────────────
export interface AsyncBatchUploadTask {
advertiser_ids: string[];
resource_ids: string[];
oauth_id: string;
is_pre_test: string;
pre_test_template: string;
source_model: string;
}
export interface AsyncBatchUploadParams {
tasks: AsyncBatchUploadTask[];
}
export async function asyncBatchUploadMaterial(params: AsyncBatchUploadParams): Promise<any> {
return api.post('/upload-material/async-batch-upload', params);
}
// 获取上传历史
// /api/upload-material/upload-history
export interface UploadHistoryParams {
status?: string;
page?: number;
pageSize?: number;
}
export async function getUploadHistory(params: UploadHistoryParams): Promise<any> {
const searchParams = new URLSearchParams();
if (params.status) searchParams.set('status', params.status);
if (params.page) searchParams.set('page', String(params.page));
if (params.pageSize) searchParams.set('page_size', String(params.pageSize));
const query = searchParams.toString();
return api.get(`/upload-material/upload-history${query ? `?${query}` : ''}`);
}
export interface UploadFilenames {
source_id: string;
file_name: string;
}
export interface UpdateFilenameParams {
filenames: UploadFilenames[];
}
// 上传文件名
export async function updateFilename(params: UpdateFilenameParams): Promise<any> {
return api.post('/upload-material/batch-update-filename', params);
}
// 查询素材消耗列表
export interface MaterialConsumpListParams {
advertiser_id?: string;
consume_date?: [string, string];
page?: number;
page_size?: number;
}
export async function getMaterialConsumpList(params: MaterialConsumpListParams): Promise<any> {
const query = new URLSearchParams();
if (params.advertiser_id) query.set('advertiser_id', params.advertiser_id);
if (params.consume_date !== undefined) query.set('consume_date', params.consume_date[0] + ',' + params.consume_date[1]);
if (params.page !== undefined) query.set('page', String(params.page));
if (params.page_size !== undefined) query.set('page_size', String(params.page_size));
return api.get(`/material-consumption/list?${query.toString()}`);
}
// 拉取消耗
export async function syncMaterialConsumption(params: { date: string; advertiser_id?: string }): Promise<any> {
const query = new URLSearchParams();
if (params.advertiser_id) query.set('advertiser_id', params.advertiser_id);
if (params.date) query.set('date', params.date);
return api.get(`/material-consumption/sync?${query.toString()}`);
}
// 获取消耗字段列表
export async function getMaterialConsumptionFields(): Promise<any> {
return api.get('/material-consumption/fields');
}
// ── Contact ────────────────────────────────────────────────
export interface ContactRequestParams {
phone: string;
company_name: string;
industry: string;
name: string;
message?: string;
}
export async function createContactRequest(params: ContactRequestParams): Promise<any> {
return api.post('/contact/request', params);
}
// 查询上传素材列表
export interface ResourcesMaterialListParams {
advertiser_id?: string;
material_id?: string;
upload_id?: string;
file_name?: string;
resource_type?: string; // image或者video
page?: number;
page_size?: number;
}
export async function getResourcesMaterialList(params: ResourcesMaterialListParams): Promise<any> {
const query = new URLSearchParams();
if (params.advertiser_id) query.set('advertiser_id', params.advertiser_id);
if (params.material_id) query.set('material_id', params.material_id);
if (params.upload_id) query.set('upload_id', params.upload_id);
if (params.file_name) query.set('file_name', params.file_name);
if (params.resource_type) query.set('resource_type', params.resource_type);
if (params.page !== undefined) query.set('page', String(params.page));
if (params.page_size !== undefined) query.set('page_size', String(params.page_size));
return api.get(`/resources-material/list?${query.toString()}`);
}
// home 获取各模块媒体
export async function getmedit(limit:number): Promise<any> {
return api.get(`/recent-generations?limit=${limit}&modules=project&modules=chat_ai&modules=hot_opening_replicate&modules=shot_replicate`);
}
export interface OpenTypeItem {
id: string;
openType: number;
typeName: string;
description: string;
thumb?: string;
}
export async function getOpenTypeAll(): Promise<{ data: OpenTypeItem[] }> {
return api.get('/open-type/open_type_all');
}
// 获取授权账户列表,支持按广告主ID、授权ID、广告账户名称筛选
export interface OAuthAccountParams {
advertiser_id: string;
oauth_id: string;
advertiser_name: string;
page?: number;
page_size?: number;
}
export async function getOAuthAccountList(params: OAuthAccountParams): Promise<any> {
const query = new URLSearchParams();
if (params.advertiser_id) query.set('advertiser_id', params.advertiser_id);
if (params.oauth_id) query.set('oauth_id', params.oauth_id);
if (params.advertiser_name) query.set('advertiser_name', params.advertiser_name);
if (params.page !== undefined) query.set('page', String(params.page));
if (params.page_size !== undefined) query.set('page_size', String(params.page_size));
return api.get(`/oauth-account/list?${query.toString()}`);
}
// 软删除授权账户
export interface DeleteOAuthAccountParams {
id: string;
}
export async function deleteOAuthAccount(params: DeleteOAuthAccountParams): Promise<any> {
const query = new URLSearchParams();
if (params.id) query.set('id', params.id);
return api.get(`/oauth-account/delete?${query.toString()}`);
}
// 获取用户全部授权账户列表
export async function getAllOAuthAccountList(): Promise<any> {
return api.post(`/upload-material/oauth_account_list`);
}
// 首页素材案例头
export async function getHomeCaseHeader(): Promise<any> {
return api.get(`/home-materials/categories`);
}
// 首页素材按钮资源
export async function getHomeCaseButton(id: string,limit:number=8): Promise<any> {
return api.get(`/home-materials?category_id=${id}&limit_per_category=${limit}&include_empty_categories=false&response_mode=grouped&page=1&page_size=20`);
}