import { BaseApi } from './baseApi.js' import api from './index.js' const OPEN_DOCUMENT_EXTENSIONS = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'] const TEXT_PREVIEW_EXTENSIONS = ['txt', 'md', 'csv'] const MAX_TEXT_PREVIEW_SIZE = 256 * 1024 function parseResult(response) { let result = response && response.data if (typeof result === 'string') { try { result = JSON.parse(result) } catch (error) { throw new Error('上传失败,请重试') } } if (!response || response.statusCode !== 200 || !result || result.code !== 0) { throw new Error(result && result.msg ? result.msg : '上传失败,请重试') } return result.data } function unwrap(response) { const result = response && response.data if (!result || result.code !== 0) { throw new Error(result && result.msg ? result.msg : '请求失败,请重试') } return result.data } function getHeader(headers, name) { if (!headers || typeof headers !== 'object') return '' const expectedName = name.toLowerCase() for (const key of Object.keys(headers)) { if (key.toLowerCase() === expectedName) return String(headers[key] || '') } return '' } function isSafeAttachment(headers) { const contentType = getHeader(headers, 'content-type').split(';')[0].trim().toLowerCase() const disposition = getHeader(headers, 'content-disposition').trim() if (!contentType || !/^attachment(?:\s*;|$)/i.test(disposition)) return false if (contentType === 'application/json' || contentType === 'text/json' || contentType.endsWith('+json') || contentType === 'text/html' || contentType === 'application/xhtml+xml') return false return true } function getDownloadFileName(headers) { const disposition = getHeader(headers, 'content-disposition') const encodedMatch = disposition.match(/(?:^|;)\s*filename\*\s*=\s*UTF-8''([^;]*)/i) if (encodedMatch) { try { const decoded = decodeURIComponent(encodedMatch[1].trim()) if (decoded) return decoded } catch (error) { // Fall back to the compatible ASCII filename below. } } const fallbackMatch = disposition.match(/(?:^|;)\s*filename\s*=\s*(?:"([^"]*)"|([^;]*))/i) return fallbackMatch ? String(fallbackMatch[1] || fallbackMatch[2] || '').trim() : '' } function getFileExtension(fileName) { const extensionIndex = fileName.lastIndexOf('.') if (extensionIndex < 0 || extensionIndex === fileName.length - 1) return '' return fileName.slice(extensionIndex + 1).toLowerCase() } function readTextPreview(filePath, fileName) { return new Promise((resolve, reject) => { const fail = () => reject(new Error('文件读取失败,请重试')) let fileSystem try { fileSystem = typeof wx !== 'undefined' && typeof wx.getFileSystemManager === 'function' ? wx.getFileSystemManager() : null } catch (error) { fail() return } if (!fileSystem || typeof fileSystem.getFileInfo !== 'function' || typeof fileSystem.readFile !== 'function') { fail() return } try { fileSystem.getFileInfo({ filePath, success: info => { const size = Number(info && info.size) if (!Number.isFinite(size) || size < 0) { fail() return } if (size === 0) { resolve({ mode: 'text', fileName, content: '', truncated: false }) return } try { fileSystem.readFile({ filePath, encoding: 'utf8', position: 0, length: Math.min(size, MAX_TEXT_PREVIEW_SIZE), success: result => { if (!result || typeof result.data !== 'string') { fail() return } resolve({ mode: 'text', fileName, content: result.data, truncated: size > MAX_TEXT_PREVIEW_SIZE }) }, fail }) } catch (error) { fail() } }, fail }) } catch (error) { fail() } }) } export function uploadTeamBackgroundFile(teamId, filePath, onProgress = () => {}) { return new Promise((resolve, reject) => { const task = uni.uploadFile({ url: `${BaseApi}/core/user/team/${teamId}/background-files`, filePath, name: 'file', header: { token: uni.getStorageSync('token') }, success: response => { try { resolve(parseResult(response)) } catch (error) { reject(error) } }, fail: reject }) task.onProgressUpdate(progress => onProgress(progress.progress)) }) } export const listTeamBackgroundFiles = teamId => api .get(`/core/user/team/${teamId}/background-files`, {}, false) .then(unwrap) export const disableTeamBackgroundFile = (teamId, fileId) => api .del(`/core/user/team/${teamId}/background-files/${fileId}`, {}, false) .then(unwrap) export const createTeamBackgroundSession = teamId => api .post(`/core/user/team/${teamId}/background-upload-session`, {}, false) .then(unwrap) export function downloadTeamBackgroundFile(teamId, fileId) { return new Promise((resolve, reject) => { let responseHeaders const task = uni.downloadFile({ url: `${BaseApi}/core/user/team/${teamId}/background-files/${fileId}/download`, header: { token: uni.getStorageSync('token') }, success: result => { const resultHeaders = result && (result.header || result.headers) const headers = responseHeaders || resultHeaders if (!result || result.statusCode !== 200 || !isSafeAttachment(headers)) { reject(new Error('下载失败,请重试')) return } const fileName = getDownloadFileName(headers) const extension = getFileExtension(fileName) if (OPEN_DOCUMENT_EXTENSIONS.includes(extension)) { resolve({ mode: 'document', fileName, filePath: result.tempFilePath }) return } if (TEXT_PREVIEW_EXTENSIONS.includes(extension)) { readTextPreview(result.tempFilePath, fileName).then(resolve, reject) return } reject(new Error('文件类型不支持预览')) }, fail: reject }) if (task && typeof task.onHeadersReceived === 'function') { task.onHeadersReceived(result => { responseHeaders = result && (result.header || result.headers) }) } }) }