task-23: 拆分 image-video / brand / permission / digital-human 模块 API 至 types/modules/,旧文件转 re-export 存根

This commit is contained in:
2026-08-31 19:57:38 +08:00
parent 8f119198fd
commit 21c92afa7a
9 changed files with 853 additions and 618 deletions
+1 -108
View File
@@ -1,108 +1 @@
import { requestDeleteJson, requestGetJson, requestPostJson } from '@/shared/api/http'
function getCurrentUserId() {
const raw = typeof window === 'undefined' ? '' : window.localStorage.getItem('uid') || ''
const value = Number(raw)
if (!Number.isFinite(value) || value <= 0) {
throw new Error('未获取到用户ID')
}
return value
}
export interface BrandExpandFolderItem {
absolutePath: string
relativePath: string
}
export interface BrandExpandFolderResponse {
success: boolean
items?: BrandExpandFolderItem[]
error?: string
}
export interface BrandTaskResultPaths {
zip_url?: string
}
export interface BrandTaskItem {
id: number | string
status?: 'pending' | 'running' | 'success' | 'failed' | 'cancelled' | string
desc?: string
file_paths?: string[]
created_at?: string
progress_total?: number
progress_current?: number
result_paths?: BrandTaskResultPaths
}
export interface BrandTaskListResponse {
success: boolean
items?: BrandTaskItem[]
error?: string
}
export interface BrandTaskDetailResponse {
success: boolean
task?: BrandTaskItem
error?: string
}
export interface BrandTaskMutationResponse {
success: boolean
task_id?: string
error?: string
}
const API_PREFIX = ''
export function getBrandTaskEventsUrl(taskId: string | number) {
return `${API_PREFIX}/api/brand/tasks/${taskId}/events?user_id=${encodeURIComponent(String(getCurrentUserId()))}`
}
export function getBrandTaskDownloadUrl(taskId: string | number) {
return `${API_PREFIX}/api/brand/tasks/${taskId}/download?user_id=${encodeURIComponent(String(getCurrentUserId()))}`
}
export function getBrandTemplateXlsxUrl() {
return `${API_PREFIX}/static/品牌文档格式_模板.xlsx`
}
export function getBrandTemplateZipUrl() {
return `${API_PREFIX}/static/模板2-以文件夹方式上传.zip`
}
export function expandBrandFolder(folder: string) {
return requestPostJson<BrandExpandFolderResponse>(`${API_PREFIX}/api/brand/expand-folder`, { folder })
}
export function expandBrandFolderRecursive(folder: string) {
return requestPostJson<BrandExpandFolderResponse>(`${API_PREFIX}/api/brand/expand-folder-recursive`, { folder })
}
export function runBrandNow(paths: string[], strategy: string) {
return requestPostJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/run`, { paths, strategy })
}
export function createBrandTask(paths: string[], strategy: string) {
return requestPostJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/tasks?userId=${encodeURIComponent(String(getCurrentUserId()))}`, { paths, strategy })
}
export function getBrandTasks() {
return requestGetJson<BrandTaskListResponse>(`${API_PREFIX}/api/brand/tasks?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function getBrandTask(taskId: string | number) {
return requestGetJson<BrandTaskDetailResponse>(`${API_PREFIX}/api/brand/tasks/${taskId}?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function cancelBrandTask(taskId: string | number) {
return requestPostJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/tasks/${taskId}/cancel?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function deleteBrandTask(taskId: string | number) {
return requestDeleteJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/tasks/${taskId}?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function createBrandTaskEvents(taskId: string | number) {
return new EventSource(getBrandTaskEventsUrl(taskId))
}
export * from './types/modules/brand'
+1 -157
View File
@@ -1,157 +1 @@
import { get, post, del, type JavaApiResponse, unwrapJavaResponse } from '@/shared/api/http'
const JAVA_API_PREFIX = '/newApi/api/digital-human/versions'
/**
* 数字人版本信息
*/
export interface DigitalHumanVersion {
id: number
version: string
ossObjectKey: string
fileSize: number
md5: string
changelog: string | null
minClientVersion: string | null
isLatest: boolean
status: 'DRAFT' | 'RELEASED' | 'DEPRECATED'
createdBy: string | null
createdAt: string
releasedAt: string | null
downloadUrl?: string
}
/**
* 下载链接信息
*/
export interface DownloadUrlVo {
version: string
downloadUrl: string
expiresIn: number
}
/**
* 分页查询参数
*/
export interface VersionListParams {
page?: number
pageSize?: number
status?: 'DRAFT' | 'RELEASED' | 'DEPRECATED'
}
/**
* 分页结果
*/
export interface PageResult<T> {
records: T[]
total: number
size: number
current: number
pages: number
}
/**
* 上传新版本
*/
export function uploadDigitalHumanVersion(
file: File,
version: string,
changelog?: string,
minClientVersion?: string,
) {
const formData = new FormData()
formData.append('file', file)
formData.append('version', version)
if (changelog) formData.append('changelog', changelog)
if (minClientVersion) formData.append('minClientVersion', minClientVersion)
return unwrapJavaResponse(
post<JavaApiResponse<DigitalHumanVersion>>(
`${JAVA_API_PREFIX}/upload`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
),
)
}
/**
* 查询版本列表
*/
export function getDigitalHumanVersions(params?: VersionListParams) {
return unwrapJavaResponse(
get<JavaApiResponse<PageResult<DigitalHumanVersion>>>(
JAVA_API_PREFIX,
{ params },
),
)
}
/**
* 获取最新版本
*/
export function getLatestDigitalHumanVersion() {
return unwrapJavaResponse(
get<JavaApiResponse<DigitalHumanVersion>>(
`${JAVA_API_PREFIX}/latest`,
),
)
}
/**
* 获取指定版本详情
*/
export function getDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
get<JavaApiResponse<DigitalHumanVersion>>(
`${JAVA_API_PREFIX}/${version}`,
),
)
}
/**
* 发布版本
*/
export function releaseDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
post<JavaApiResponse<void>>(
`${JAVA_API_PREFIX}/${version}/release`,
),
)
}
/**
* 设为最新版本
*/
export function setLatestDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
post<JavaApiResponse<void>>(
`${JAVA_API_PREFIX}/${version}/set-latest`,
),
)
}
/**
* 删除版本
*/
export function deleteDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
del<JavaApiResponse<void>>(
`${JAVA_API_PREFIX}/${version}`,
),
)
}
/**
* 获取下载链接
*/
export function getDigitalHumanVersionDownloadUrl(version: string) {
return unwrapJavaResponse(
get<JavaApiResponse<DownloadUrlVo>>(
`${JAVA_API_PREFIX}/${version}/download-url`,
),
)
}
export * from './types/modules/digital-human'
+4 -268
View File
@@ -22,6 +22,10 @@ export * from "./types/modules/shop-match.ts";
export * from "./types/modules/query-asin.ts";
export * from "./types/modules/withdraw.ts";
export * from "./types/modules/collect-data.ts";
export * from "./types/modules/image-video.ts";
export * from "./types/modules/brand.ts";
export * from "./types/modules/permission.ts";
export * from "./types/modules/digital-human.ts";
import type {
ProductRiskCandidateVo,
ProductRiskDashboardVo,
@@ -166,274 +170,6 @@ export async function uploadTempFileToJava(
}
// ========== 视频复刻 / 图生视频 ==========
export interface ImageVideoDouyinCopyVo {
recognizedContent?: string;
scriptDraft?: string;
executeId?: string;
debugUrl?: string;
}
export interface ImageVideoDouyinCopyPayload {
url: string;
api_key?: string;
t8_key?: string;
duration?: number;
proc_info?: {
type: string;
name: string;
proc_image: string[];
properties: string;
};
}
export interface ImageVideoSecretStatusVo {
userId?: number;
configured?: boolean;
valid?: boolean;
expired?: boolean;
hasCopyApiKey?: boolean;
hasT8Key?: boolean;
hasT8VideoKey?: boolean;
hasVoiceApiKey?: boolean;
hasVoiceGroupId?: boolean;
copyApiKeyMasked?: string;
t8KeyMasked?: string;
t8VideoKeyMasked?: string;
voiceApiKeyMasked?: string;
voiceGroupIdMasked?: string;
expireDays?: number;
expiresAt?: string;
}
export interface ImageVideoSecretSavePayload {
copyApiKey?: string;
t8Key?: string;
t8VideoKey?: string;
voiceApiKey?: string;
voiceGroupId?: string;
expireDays: number;
}
export interface ImageVideoWorkflowParameters {
api_key_info: {
t8star_key: string;
t8_video_key: string;
ai_conductor_key: string;
};
bg_info: {
type: number;
prompt: string;
bg_image: string;
};
face_info: {
type: number;
model_figure: string;
model_image: string[];
};
proc_info: {
type: string;
name: string;
proc_image: string[];
properties: string;
};
text_info: {
type: number;
language: string;
text: string;
file_url: string;
};
audio_info: {
audio_url: string;
type: number;
bgm_url: string;
mode: number;
voice_name: string;
};
video_info: {
video_url: string;
share_url: string;
ref_video_mode: string;
mode: string;
draft: boolean;
model: string;
prompt: string;
ratio: string;
resolution: string;
duration: number;
};
}
export interface ImageVideoWorkflowResponse {
code?: number;
msg?: string;
data?: string;
execute_id?: string;
debug_url?: string;
[key: string]: unknown;
}
export type ImageVideoAsyncTaskStatus = 'PENDING' | 'RUNNING' | 'WAITING' | 'POLLING' | 'SUCCESS' | 'FAILED'
export interface ImageVideoAsyncTaskVo {
taskId: number;
taskType: string;
status: ImageVideoAsyncTaskStatus;
cozeExecuteId?: string;
cozeStatus?: string;
debugUrl?: string;
result?: unknown;
errorMessage?: string;
submittedAt?: string;
completedAt?: string;
}
export interface ImageVideoMediaUploadVo {
url: string;
objectKey: string;
originalFilename: string;
mediaType: "image" | "video" | "audio" | string;
}
export interface ImageVideoVoiceWorkflowResponse {
code?: number;
msg?: string;
data?: unknown;
execute_id?: string;
debug_url?: string;
[key: string]: unknown;
}
export interface ImageVideoWorkflowRunRequest {
userId: number;
parameters: ImageVideoWorkflowParameters;
}
export interface ImageVideoWorkflowResultRequest {
userId: number;
executeId: string;
}
export function getImageVideoSecretStatus() {
return unwrapJavaResponse(
get<JavaApiResponse<ImageVideoSecretStatusVo>>(
`${JAVA_API_PREFIX}/image-video/secrets`,
{ params: { user_id: getCurrentUserId() } },
),
);
}
export function saveImageVideoSecrets(payload: ImageVideoSecretSavePayload) {
return unwrapJavaResponse(
put<JavaApiResponse<ImageVideoSecretStatusVo>, ImageVideoSecretSavePayload & { userId: number }>(
`${JAVA_API_PREFIX}/image-video/secrets`,
{ ...payload, userId: getCurrentUserId() },
),
);
}
export function runImageVideoDouyinCopy(payload: ImageVideoDouyinCopyPayload) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, ImageVideoDouyinCopyPayload & { userId: number }>(
`${JAVA_API_PREFIX}/image-video/douyin-copy`,
{ userId: getCurrentUserId(), ...payload },
),
);
}
export function runImageVideoWorkflow(parameters: ImageVideoWorkflowParameters) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, ImageVideoWorkflowRunRequest>(
`${JAVA_API_PREFIX}/image-video/workflow/run`,
{ userId: getCurrentUserId(), parameters },
),
);
}
export function getImageVideoWorkflowResult(executeId: string) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, ImageVideoWorkflowResultRequest>(
`${JAVA_API_PREFIX}/image-video/workflow/result`,
{ userId: getCurrentUserId(), executeId },
),
);
}
export function getImageVideoAsyncTask(taskId: number) {
return unwrapJavaResponse(
get<JavaApiResponse<ImageVideoAsyncTaskVo>>(
`${JAVA_API_PREFIX}/image-video/tasks/${taskId}`,
{ params: { user_id: getCurrentUserId() } },
),
);
}
export async function uploadImageVideoMedia(file: File) {
const response = await uploadTempFileToJava(file, {
uploadToOss: true,
moduleType: "IMAGE_VIDEO",
});
if (!response.success) {
throw new Error(response.message || "请求失败");
}
const data = response.data;
if (!data?.url || !data.objectKey) {
throw new Error("OSS 上传未返回有效 URL");
}
return {
url: data.url,
objectKey: data.objectKey,
originalFilename: data.originalFilename || file.name,
mediaType: data.mediaType || resolveImageVideoMediaType(file),
} as ImageVideoMediaUploadVo;
}
function resolveImageVideoMediaType(file: File) {
const type = (file.type || "").toLowerCase();
const name = (file.name || "").toLowerCase();
if (type.startsWith("image/") || /\.(png|jpe?g|webp|gif|bmp|svg)$/.test(name)) return "image";
if (type.startsWith("video/") || /\.(mp4|mov|webm|m4v|ogg|avi|mkv)$/.test(name)) return "video";
if (type.startsWith("audio/") || /\.(mp3|wav|m4a|aac|flac)$/.test(name)) return "audio";
return "file";
}
export function listImageVideoVoices(name = "") {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; name: string }>(
`${JAVA_API_PREFIX}/image-video/voice/list`,
{ userId: getCurrentUserId(), name },
),
);
}
export function deleteImageVideoVoice(voiceId: string) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; voiceId: string }>(
`${JAVA_API_PREFIX}/image-video/voice/delete`,
{ userId: getCurrentUserId(), voiceId },
),
);
}
export function cloneImageVideoVoice(payload: { name?: string; audioUrl?: string; videoUrl?: string }) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; name?: string; audioUrl?: string; videoUrl?: string }>(
`${JAVA_API_PREFIX}/image-video/voice/clone`,
{ userId: getCurrentUserId(), ...payload },
),
);
}
export function synthesizeImageVideoVoice(payload: { text: string; voiceId: string }) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; text: string; voiceId: string }>(
`${JAVA_API_PREFIX}/image-video/voice/synthesis`,
{ userId: getCurrentUserId(), ...payload },
),
);
}
export function getJavaDownloadUrl(path: string) {
let raw =
path.startsWith("http://") || path.startsWith("https://")
+1 -85
View File
@@ -1,85 +1 @@
import { requestGetJson } from '@/shared/api/http'
export interface PermissionMenuItem {
id: number | string
name?: string
column_key?: string
columnKey?: string
route_path?: string
routePath?: string
menu_type?: string
parent_id?: number | string | null
parentId?: number | string | null
root_column_key?: string
rootColumnKey?: string
sort_order?: number
created_at?: string
}
interface PermissionMenuResponse {
success: boolean
data?: PermissionMenuItem[]
items?: PermissionMenuItem[]
error?: string
message?: string
}
function getCurrentUserId() {
const raw = typeof window === 'undefined' ? '' : window.localStorage.getItem('uid') || ''
const value = Number(raw)
if (!Number.isFinite(value) || value <= 0) {
throw new Error('未获取到用户ID')
}
return value
}
function getAppPermissionCacheKey(uid: number) {
return `app_column_permissions:${String(uid)}`
}
function getAuthToken() {
return typeof window === 'undefined' ? '' : window.localStorage.getItem('aiimage_auth_token') || ''
}
function normalizeColumnKeys(items: PermissionMenuItem[] | undefined) {
const keys = new Set<string>()
for (const item of items || []) {
for (const value of [item.column_key, item.columnKey, item.route_path, item.routePath]) {
const key = String(value || '').trim().toLowerCase()
if (key) {
keys.add(key)
}
}
}
return Array.from(keys)
}
export async function getCurrentUserAppColumnKeys() {
const uid = getCurrentUserId()
const cacheKey = getAppPermissionCacheKey(uid)
const headers: Record<string, string> = {}
const token = getAuthToken()
if (token) {
headers.Authorization = `Bearer ${token}`
}
const res = await requestGetJson<PermissionMenuResponse>(
`/newApi/api/admin/permission-users/${encodeURIComponent(String(uid))}/column-permissions`,
{
params: { menuType: 'app' },
headers,
},
)
if (!res.success) {
throw new Error(res.error || res.message || '获取菜单权限失败')
}
const items = res.data || res.items || []
try {
window.localStorage.setItem(cacheKey, JSON.stringify(items))
} catch (_error) {}
return normalizeColumnKeys(items)
}
export * from './types/modules/permission'
@@ -0,0 +1,108 @@
import { requestDeleteJson, requestGetJson, requestPostJson } from '../../http.ts'
function getCurrentUserId() {
const raw = typeof window === 'undefined' ? '' : window.localStorage.getItem('uid') || ''
const value = Number(raw)
if (!Number.isFinite(value) || value <= 0) {
throw new Error('未获取到用户ID')
}
return value
}
export interface BrandExpandFolderItem {
absolutePath: string
relativePath: string
}
export interface BrandExpandFolderResponse {
success: boolean
items?: BrandExpandFolderItem[]
error?: string
}
export interface BrandTaskResultPaths {
zip_url?: string
}
export interface BrandTaskItem {
id: number | string
status?: 'pending' | 'running' | 'success' | 'failed' | 'cancelled' | string
desc?: string
file_paths?: string[]
created_at?: string
progress_total?: number
progress_current?: number
result_paths?: BrandTaskResultPaths
}
export interface BrandTaskListResponse {
success: boolean
items?: BrandTaskItem[]
error?: string
}
export interface BrandTaskDetailResponse {
success: boolean
task?: BrandTaskItem
error?: string
}
export interface BrandTaskMutationResponse {
success: boolean
task_id?: string
error?: string
}
const API_PREFIX = ''
export function getBrandTaskEventsUrl(taskId: string | number) {
return `${API_PREFIX}/api/brand/tasks/${taskId}/events?user_id=${encodeURIComponent(String(getCurrentUserId()))}`
}
export function getBrandTaskDownloadUrl(taskId: string | number) {
return `${API_PREFIX}/api/brand/tasks/${taskId}/download?user_id=${encodeURIComponent(String(getCurrentUserId()))}`
}
export function getBrandTemplateXlsxUrl() {
return `${API_PREFIX}/static/品牌文档格式_模板.xlsx`
}
export function getBrandTemplateZipUrl() {
return `${API_PREFIX}/static/模板2-以文件夹方式上传.zip`
}
export function expandBrandFolder(folder: string) {
return requestPostJson<BrandExpandFolderResponse>(`${API_PREFIX}/api/brand/expand-folder`, { folder })
}
export function expandBrandFolderRecursive(folder: string) {
return requestPostJson<BrandExpandFolderResponse>(`${API_PREFIX}/api/brand/expand-folder-recursive`, { folder })
}
export function runBrandNow(paths: string[], strategy: string) {
return requestPostJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/run`, { paths, strategy })
}
export function createBrandTask(paths: string[], strategy: string) {
return requestPostJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/tasks?userId=${encodeURIComponent(String(getCurrentUserId()))}`, { paths, strategy })
}
export function getBrandTasks() {
return requestGetJson<BrandTaskListResponse>(`${API_PREFIX}/api/brand/tasks?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function getBrandTask(taskId: string | number) {
return requestGetJson<BrandTaskDetailResponse>(`${API_PREFIX}/api/brand/tasks/${taskId}?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function cancelBrandTask(taskId: string | number) {
return requestPostJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/tasks/${taskId}/cancel?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function deleteBrandTask(taskId: string | number) {
return requestDeleteJson<BrandTaskMutationResponse>(`${API_PREFIX}/api/brand/tasks/${taskId}?userId=${encodeURIComponent(String(getCurrentUserId()))}`)
}
export function createBrandTaskEvents(taskId: string | number) {
return new EventSource(getBrandTaskEventsUrl(taskId))
}
@@ -0,0 +1,157 @@
import { get, post, del, type JavaApiResponse, unwrapJavaResponse } from '../../http.ts'
const JAVA_API_PREFIX = '/newApi/api/digital-human/versions'
/**
* 数字人版本信息
*/
export interface DigitalHumanVersion {
id: number
version: string
ossObjectKey: string
fileSize: number
md5: string
changelog: string | null
minClientVersion: string | null
isLatest: boolean
status: 'DRAFT' | 'RELEASED' | 'DEPRECATED'
createdBy: string | null
createdAt: string
releasedAt: string | null
downloadUrl?: string
}
/**
* 下载链接信息
*/
export interface DownloadUrlVo {
version: string
downloadUrl: string
expiresIn: number
}
/**
* 分页查询参数
*/
export interface VersionListParams {
page?: number
pageSize?: number
status?: 'DRAFT' | 'RELEASED' | 'DEPRECATED'
}
/**
* 分页结果
*/
export interface PageResult<T> {
records: T[]
total: number
size: number
current: number
pages: number
}
/**
* 上传新版本
*/
export function uploadDigitalHumanVersion(
file: File,
version: string,
changelog?: string,
minClientVersion?: string,
) {
const formData = new FormData()
formData.append('file', file)
formData.append('version', version)
if (changelog) formData.append('changelog', changelog)
if (minClientVersion) formData.append('minClientVersion', minClientVersion)
return unwrapJavaResponse(
post<JavaApiResponse<DigitalHumanVersion>>(
`${JAVA_API_PREFIX}/upload`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
),
)
}
/**
* 查询版本列表
*/
export function getDigitalHumanVersions(params?: VersionListParams) {
return unwrapJavaResponse(
get<JavaApiResponse<PageResult<DigitalHumanVersion>>>(
JAVA_API_PREFIX,
{ params },
),
)
}
/**
* 获取最新版本
*/
export function getLatestDigitalHumanVersion() {
return unwrapJavaResponse(
get<JavaApiResponse<DigitalHumanVersion>>(
`${JAVA_API_PREFIX}/latest`,
),
)
}
/**
* 获取指定版本详情
*/
export function getDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
get<JavaApiResponse<DigitalHumanVersion>>(
`${JAVA_API_PREFIX}/${version}`,
),
)
}
/**
* 发布版本
*/
export function releaseDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
post<JavaApiResponse<void>>(
`${JAVA_API_PREFIX}/${version}/release`,
),
)
}
/**
* 设为最新版本
*/
export function setLatestDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
post<JavaApiResponse<void>>(
`${JAVA_API_PREFIX}/${version}/set-latest`,
),
)
}
/**
* 删除版本
*/
export function deleteDigitalHumanVersion(version: string) {
return unwrapJavaResponse(
del<JavaApiResponse<void>>(
`${JAVA_API_PREFIX}/${version}`,
),
)
}
/**
* 获取下载链接
*/
export function getDigitalHumanVersionDownloadUrl(version: string) {
return unwrapJavaResponse(
get<JavaApiResponse<DownloadUrlVo>>(
`${JAVA_API_PREFIX}/${version}/download-url`,
),
)
}
@@ -0,0 +1,279 @@
import { get, post, put, type JavaApiResponse, unwrapJavaResponse } from '../../http.ts'
import { buildJavaUrl, JAVA_API_PREFIX } from '../../url.ts'
import { getCurrentUserId } from '../../user.ts'
export interface ImageVideoDouyinCopyVo {
recognizedContent?: string;
scriptDraft?: string;
executeId?: string;
debugUrl?: string;
}
export interface ImageVideoDouyinCopyPayload {
url: string;
api_key?: string;
t8_key?: string;
duration?: number;
proc_info?: {
type: string;
name: string;
proc_image: string[];
properties: string;
};
}
export interface ImageVideoSecretStatusVo {
userId?: number;
configured?: boolean;
valid?: boolean;
expired?: boolean;
hasCopyApiKey?: boolean;
hasT8Key?: boolean;
hasT8VideoKey?: boolean;
hasVoiceApiKey?: boolean;
hasVoiceGroupId?: boolean;
copyApiKeyMasked?: string;
t8KeyMasked?: string;
t8VideoKeyMasked?: string;
voiceApiKeyMasked?: string;
voiceGroupIdMasked?: string;
expireDays?: number;
expiresAt?: string;
}
export interface ImageVideoSecretSavePayload {
copyApiKey?: string;
t8Key?: string;
t8VideoKey?: string;
voiceApiKey?: string;
voiceGroupId?: string;
expireDays: number;
}
export interface ImageVideoWorkflowParameters {
api_key_info: {
t8star_key: string;
t8_video_key: string;
ai_conductor_key: string;
};
bg_info: {
type: number;
prompt: string;
bg_image: string;
};
face_info: {
type: number;
model_figure: string;
model_image: string[];
};
proc_info: {
type: string;
name: string;
proc_image: string[];
properties: string;
};
text_info: {
type: number;
language: string;
text: string;
file_url: string;
};
audio_info: {
audio_url: string;
type: number;
bgm_url: string;
mode: number;
voice_name: string;
};
video_info: {
video_url: string;
share_url: string;
ref_video_mode: string;
mode: string;
draft: boolean;
model: string;
prompt: string;
ratio: string;
resolution: string;
duration: number;
};
}
export interface ImageVideoWorkflowResponse {
code?: number;
msg?: string;
data?: string;
execute_id?: string;
debug_url?: string;
[key: string]: unknown;
}
export type ImageVideoAsyncTaskStatus = 'PENDING' | 'RUNNING' | 'WAITING' | 'POLLING' | 'SUCCESS' | 'FAILED'
export interface ImageVideoAsyncTaskVo {
taskId: number;
taskType: string;
status: ImageVideoAsyncTaskStatus;
cozeExecuteId?: string;
cozeStatus?: string;
debugUrl?: string;
result?: unknown;
errorMessage?: string;
submittedAt?: string;
completedAt?: string;
}
export interface ImageVideoMediaUploadVo {
url: string;
objectKey: string;
originalFilename: string;
mediaType: "image" | "video" | "audio" | string;
}
export interface ImageVideoVoiceWorkflowResponse {
code?: number;
msg?: string;
data?: unknown;
execute_id?: string;
debug_url?: string;
[key: string]: unknown;
}
export interface ImageVideoWorkflowRunRequest {
userId: number;
parameters: ImageVideoWorkflowParameters;
}
export interface ImageVideoWorkflowResultRequest {
userId: number;
executeId: string;
}
export function getImageVideoSecretStatus() {
return unwrapJavaResponse(
get<JavaApiResponse<ImageVideoSecretStatusVo>>(
`${JAVA_API_PREFIX}/image-video/secrets`,
{ params: { user_id: getCurrentUserId() } },
),
);
}
export function saveImageVideoSecrets(payload: ImageVideoSecretSavePayload) {
return unwrapJavaResponse(
put<JavaApiResponse<ImageVideoSecretStatusVo>, ImageVideoSecretSavePayload & { userId: number }>(
`${JAVA_API_PREFIX}/image-video/secrets`,
{ ...payload, userId: getCurrentUserId() },
),
);
}
export function runImageVideoDouyinCopy(payload: ImageVideoDouyinCopyPayload) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, ImageVideoDouyinCopyPayload & { userId: number }>(
`${JAVA_API_PREFIX}/image-video/douyin-copy`,
{ userId: getCurrentUserId(), ...payload },
),
);
}
export function runImageVideoWorkflow(parameters: ImageVideoWorkflowParameters) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, ImageVideoWorkflowRunRequest>(
`${JAVA_API_PREFIX}/image-video/workflow/run`,
{ userId: getCurrentUserId(), parameters },
),
);
}
export function getImageVideoWorkflowResult(executeId: string) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, ImageVideoWorkflowResultRequest>(
`${JAVA_API_PREFIX}/image-video/workflow/result`,
{ userId: getCurrentUserId(), executeId },
),
);
}
export function getImageVideoAsyncTask(taskId: number) {
return unwrapJavaResponse(
get<JavaApiResponse<ImageVideoAsyncTaskVo>>(
`${JAVA_API_PREFIX}/image-video/tasks/${taskId}`,
{ params: { user_id: getCurrentUserId() } },
),
);
}
function resolveImageVideoMediaType(file: File) {
const type = (file.type || "").toLowerCase();
const name = (file.name || "").toLowerCase();
if (type.startsWith("image/") || /\.(png|jpe?g|webp|gif|bmp|svg)$/.test(name)) return "image";
if (type.startsWith("video/") || /\.(mp4|mov|webm|m4v|ogg|avi|mkv)$/.test(name)) return "video";
if (type.startsWith("audio/") || /\.(mp3|wav|m4a|aac|flac)$/.test(name)) return "audio";
return "file";
}
export async function uploadImageVideoMedia(file: File) {
const formData = new FormData();
formData.append("file", file);
formData.append("uploadToOss", "true");
formData.append("moduleType", "IMAGE_VIDEO");
const response = await post<JavaApiResponse<{ url?: string; objectKey?: string; originalFilename?: string; mediaType?: string }>>(
`${JAVA_API_PREFIX}/files/upload`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
},
timeout: 120000,
},
);
if (!response.success) {
throw new Error(response.message || "请求失败");
}
const data = response.data;
if (!data?.url || !data.objectKey) {
throw new Error("OSS 上传未返回有效 URL");
}
return {
url: data.url,
objectKey: data.objectKey,
originalFilename: data.originalFilename || file.name,
mediaType: data.mediaType || resolveImageVideoMediaType(file),
} as ImageVideoMediaUploadVo;
}
export function listImageVideoVoices(name = "") {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; name: string }>(
`${JAVA_API_PREFIX}/image-video/voice/list`,
{ userId: getCurrentUserId(), name },
),
);
}
export function deleteImageVideoVoice(voiceId: string) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; voiceId: string }>(
`${JAVA_API_PREFIX}/image-video/voice/delete`,
{ userId: getCurrentUserId(), voiceId },
),
);
}
export function cloneImageVideoVoice(payload: { name?: string; audioUrl?: string; videoUrl?: string }) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; name?: string; audioUrl?: string; videoUrl?: string }>(
`${JAVA_API_PREFIX}/image-video/voice/clone`,
{ userId: getCurrentUserId(), ...payload },
),
);
}
export function synthesizeImageVideoVoice(payload: { text: string; voiceId: string }) {
return unwrapJavaResponse(
post<JavaApiResponse<ImageVideoAsyncTaskVo>, { userId: number; text: string; voiceId: string }>(
`${JAVA_API_PREFIX}/image-video/voice/synthesis`,
{ userId: getCurrentUserId(), ...payload },
),
);
}
@@ -0,0 +1,85 @@
import { requestGetJson } from '../../http.ts'
export interface PermissionMenuItem {
id: number | string
name?: string
column_key?: string
columnKey?: string
route_path?: string
routePath?: string
menu_type?: string
parent_id?: number | string | null
parentId?: number | string | null
root_column_key?: string
rootColumnKey?: string
sort_order?: number
created_at?: string
}
interface PermissionMenuResponse {
success: boolean
data?: PermissionMenuItem[]
items?: PermissionMenuItem[]
error?: string
message?: string
}
function getCurrentUserId() {
const raw = typeof window === 'undefined' ? '' : window.localStorage.getItem('uid') || ''
const value = Number(raw)
if (!Number.isFinite(value) || value <= 0) {
throw new Error('未获取到用户ID')
}
return value
}
function getAppPermissionCacheKey(uid: number) {
return `app_column_permissions:${String(uid)}`
}
function getAuthToken() {
return typeof window === 'undefined' ? '' : window.localStorage.getItem('aiimage_auth_token') || ''
}
function normalizeColumnKeys(items: PermissionMenuItem[] | undefined) {
const keys = new Set<string>()
for (const item of items || []) {
for (const value of [item.column_key, item.columnKey, item.route_path, item.routePath]) {
const key = String(value || '').trim().toLowerCase()
if (key) {
keys.add(key)
}
}
}
return Array.from(keys)
}
export async function getCurrentUserAppColumnKeys() {
const uid = getCurrentUserId()
const cacheKey = getAppPermissionCacheKey(uid)
const headers: Record<string, string> = {}
const token = getAuthToken()
if (token) {
headers.Authorization = `Bearer ${token}`
}
const res = await requestGetJson<PermissionMenuResponse>(
`/newApi/api/admin/permission-users/${encodeURIComponent(String(uid))}/column-permissions`,
{
params: { menuType: 'app' },
headers,
},
)
if (!res.success) {
throw new Error(res.error || res.message || '获取菜单权限失败')
}
const items = res.data || res.items || []
try {
window.localStorage.setItem(cacheKey, JSON.stringify(items))
} catch (_error) {}
return normalizeColumnKeys(items)
}