| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- 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)
- })
- }
- })
- }
|