Codex Assistant
4 天以前 915d80766dd8e0157e9b9510b3634ed758eb5c5a
web/src/api/media.js
@@ -38,50 +38,12 @@
`;
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);
  }
  const result = await graphqlRequest(MEDIAS_BY_TARGET_QUERY, { targetType, targetId });
  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);
  }
  const result = await graphqlRequest(SAVE_MEDIA_MUTATION, { input });
  return result.data.saveMedia;
};
@@ -101,8 +63,8 @@
  }
};
// 上传文件到服务器
export const uploadFile = async (file) => {
// 上传文件到服务器(带重试机制)
export const uploadFile = async (file, maxRetries = 3) => {
  const formData = new FormData();
  formData.append('file', file);
  
@@ -114,18 +76,56 @@
    headers['Authorization'] = `Bearer ${token}`;
  }
  
  const response = await fetch('http://localhost:8080/api/upload/image', {
    method: 'POST',
    headers: headers,
    body: formData
  });
  let lastError;
  
  const result = await response.json();
  if (!result.success) {
    throw new Error(result.error || '上传失败');
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch('http://localhost:8080/api/upload/image', {
        method: 'POST',
        headers: headers,
        body: formData,
        // 添加超时设置
        signal: AbortSignal.timeout(30000) // 30秒超时
      });
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      const result = await response.json();
      if (!result.success) {
        throw new Error(result.error || '上传失败');
      }
      return result;
    } catch (error) {
      lastError = error;
      console.warn(`文件上传第${attempt}次尝试失败:`, error.message);
      // 如果是最后一次尝试,或者是非网络错误,直接抛出
      if (attempt === maxRetries ||
          (!error.message.includes('Failed to fetch') &&
           !error.message.includes('ERR_CONNECTION_RESET') &&
           !error.message.includes('ERR_NETWORK'))) {
        break;
      }
      // 等待一段时间后重试(指数退避)
      const delay = Math.min(1000 * Math.pow(2, attempt - 1), 5000);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
  
  return result;
  // 提供更友好的错误信息
  if (lastError.message.includes('Failed to fetch') ||
      lastError.message.includes('ERR_CONNECTION_RESET') ||
      lastError.message.includes('ERR_NETWORK')) {
    throw new Error('网络连接失败,请检查网络连接或稍后重试');
  } else if (lastError.message.includes('timeout')) {
    throw new Error('上传超时,请检查网络连接或稍后重试');
  } else {
    throw new Error(`上传失败: ${lastError.message}`);
  }
};
// 上传视频文件并自动生成缩略图
@@ -177,17 +177,6 @@
// 统一的 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);
  }
  const result = await graphqlRequest(SAVE_MEDIA_V2_MUTATION, { input });
  return result.data.saveMediaV2;
};