| | |
| | | // 媒体查询 API |
| | | const GRAPHQL_ENDPOINT = 'http://localhost:8080/api/graphql'; |
| | | 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!) { |
| | |
| | | `; |
| | | |
| | | 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: { 'Content-Type': 'application/json' }, |
| | | headers: headers, |
| | | body: JSON.stringify({ |
| | | query: MEDIAS_BY_TARGET_QUERY, |
| | | variables: { targetType, targetId } |
| | |
| | | }; |
| | | |
| | | 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: { 'Content-Type': 'application/json' }, |
| | | headers: headers, |
| | | body: JSON.stringify({ |
| | | query: SAVE_MEDIA_MUTATION, |
| | | variables: { input } |
| | |
| | | console.log('要删除的媒体ID:', id); |
| | | console.log('GraphQL查询:', DELETE_MEDIA_MUTATION); |
| | | |
| | | // 获取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: { 'Content-Type': 'application/json' }, |
| | | headers: headers, |
| | | body: JSON.stringify({ |
| | | query: DELETE_MEDIA_MUTATION, |
| | | variables: { id: id.toString() } |
| | |
| | | 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 |
| | | }); |
| | | |
| | |
| | | } |
| | | |
| | | return result; |
| | | }; |
| | | |
| | | // 上传视频文件并自动生成缩略图 |
| | | export const uploadVideoWithThumbnail = async (videoFile) => { |
| | | const { extractVideoFrame, generateThumbnailFileName } = await import('@/utils/video.js'); |
| | | |
| | | try { |
| | | console.log('开始处理视频文件:', videoFile.name); |
| | | |
| | | // 1. 上传原视频文件 |
| | | console.log('上传视频文件...'); |
| | | const videoUploadResult = await uploadFile(videoFile); |
| | | console.log('视频上传成功:', videoUploadResult); |
| | | |
| | | // 2. 提取视频第一帧 |
| | | console.log('提取视频第一帧...'); |
| | | const thumbnailBlob = await extractVideoFrame(videoFile); |
| | | console.log('视频帧提取成功,大小:', thumbnailBlob.size); |
| | | |
| | | // 3. 创建缩略图文件对象 |
| | | const thumbnailFileName = generateThumbnailFileName(videoFile.name); |
| | | const thumbnailFile = new File([thumbnailBlob], thumbnailFileName, { |
| | | type: 'image/jpeg' |
| | | }); |
| | | |
| | | // 4. 上传缩略图 |
| | | console.log('上传缩略图...'); |
| | | const thumbnailUploadResult = await uploadFile(thumbnailFile); |
| | | console.log('缩略图上传成功:', thumbnailUploadResult); |
| | | |
| | | // 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; |
| | | }; |