// 媒体查询 API import { graphqlRequest, API_CONFIG } from '../config/api.ts'; const GRAPHQL_ENDPOINT = API_CONFIG.GRAPHQL_ENDPOINT; const MEDIAS_BY_TARGET_QUERY = ` query MediasByTarget($targetType: Int!, $targetId: ID!) { mediasByTarget(targetType: $targetType, targetId: $targetId) { id name path fileExt mediaType fullUrl } } `; const SAVE_MEDIA_MUTATION = ` mutation SaveMedia($input: MediaInput!) { saveMedia(input: $input) { id name path fileExt mediaType fullUrl targetType targetId } } `; const DELETE_MEDIA_MUTATION = ` mutation DeleteMedia($id: ID!) { deleteMedia(id: $id) } `; export const getMediasByTarget = async (targetType, targetId) => { // 获取JWT token const { getToken } = await import('@/utils/auth'); const token = getToken(); const headers = { 'Content-Type': 'application/json' }; if (token) { headers['Authorization'] = `Bearer ${token}`; } const res = await fetch(GRAPHQL_ENDPOINT, { method: 'POST', headers: headers, body: JSON.stringify({ query: MEDIAS_BY_TARGET_QUERY, variables: { targetType, targetId } }) }); const result = await res.json(); if (result.errors) { throw new Error(result.errors[0].message); } return result.data.mediasByTarget || []; }; export const saveMedia = async (input) => { // 获取JWT token const { getToken } = await import('@/utils/auth'); const token = getToken(); const headers = { 'Content-Type': 'application/json' }; if (token) { headers['Authorization'] = `Bearer ${token}`; } const res = await fetch(GRAPHQL_ENDPOINT, { method: 'POST', headers: headers, body: JSON.stringify({ query: SAVE_MEDIA_MUTATION, variables: { input } }) }); const result = await res.json(); if (result.errors) { throw new Error(result.errors[0].message); } return result.data.saveMedia; }; export const deleteMedia = async (id) => { try { const variables = { id: parseInt(id) }; // 发送GraphQL请求 const result = await graphqlRequest(DELETE_MEDIA_MUTATION, variables); // 检查返回结果 const deleteResult = result.data?.deleteMedia; return deleteResult; } catch (error) { throw new Error(`删除媒体失败: ${error.message}`); } }; // 上传文件到服务器 export const uploadFile = async (file) => { const formData = new FormData(); formData.append('file', file); // 获取JWT token const { getToken } = await import('@/utils/auth'); const token = getToken(); const headers = {}; if (token) { headers['Authorization'] = `Bearer ${token}`; } const response = await fetch('http://localhost:8080/api/upload/image', { method: 'POST', headers: headers, body: formData }); const result = await response.json(); if (!result.success) { throw new Error(result.error || '上传失败'); } return result; }; // 上传视频文件并自动生成缩略图 export const uploadVideoWithThumbnail = async (videoFile) => { const { extractVideoFrame, generateThumbnailFileName } = await import('@/utils/video.js'); try { // 1. 上传视频文件 const videoUploadResult = await uploadFile(videoFile); // 2. 提取视频第一帧 const thumbnailBlob = await extractVideoFrame(videoFile); // 3. 创建缩略图文件对象 const thumbnailFileName = generateThumbnailFileName(videoFile.name); const thumbnailFile = new File([thumbnailBlob], thumbnailFileName, { type: 'image/jpeg' }); // 4. 上传缩略图 const thumbnailUploadResult = await uploadFile(thumbnailFile); // 5. 返回包含视频和缩略图信息的结果 return { video: videoUploadResult, thumbnail: thumbnailUploadResult, success: true }; } catch (error) { console.error('视频处理失败:', error); throw new Error(`视频处理失败: ${error.message}`); } }; // 新版保存媒体(SaveMediaV2):使用字符串 targetType 与 MediaSaveInput // 注意:目前后端仅支持 targetType: "player"(学员头像 -> 6)与 "activity_player"(报名资料 -> 5)。 // 字段命名与旧版不同:fileName 替代 name;可选 thumbPath;mediaType: 1图片、2视频、3音频、4文档。 const SAVE_MEDIA_V2_MUTATION = ` mutation SaveMediaV2($input: MediaSaveInput!) { saveMediaV2(input: $input) { success message mediaId } } `; // 统一的 V2 保存接口(返回 { success, message, mediaId }),示例: // await saveMediaV2({ targetType: 'player', targetId: 123, path: 'avatar/xxx.jpg', fileName: 'avatar.jpg', fileExt: 'jpg', fileSize: 2048, mediaType: 1 }) export const saveMediaV2 = async (input) => { const res = await fetch(GRAPHQL_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: SAVE_MEDIA_V2_MUTATION, variables: { input } }) }); const result = await res.json(); if (result.errors) { throw new Error(result.errors[0].message); } return result.data.saveMediaV2; };