odf_new/odf-uniapp/services/cos.js
zpc 88f86efd7a
All checks were successful
continuous-integration/drone/push Build is passing
21
2026-04-06 13:43:39 +08:00

109 lines
3.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { post } from './api'
/**
* 从后端获取 COS 预签名上传 URL
* @param {number} count - 文件数量
* @param {string} ext - 文件扩展名
* @returns {Promise<Array<{cosKey, presignUrl, accessUrl}>>}
*/
export async function getPresignUrls(count, ext = '.jpg') {
const res = await post('/business/CosUpload/presignUrl', { count, ext }, { timeout: 120000 })
if (res.code !== 200) {
throw new Error(res.msg || '获取上传地址失败')
}
return res.data
}
/**
* 通过预签名 URL 直传文件到 COS
* @param {string} presignUrl - PUT 预签名 URL
* @param {string} filePath - 本地文件路径
* @returns {Promise<void>}
*/
export function uploadToCos(presignUrl, filePath) {
return new Promise((resolve, reject) => {
// #ifdef H5
_uploadH5(presignUrl, filePath).then(resolve).catch(reject)
// #endif
// #ifdef APP-PLUS
_uploadApp(presignUrl, filePath).then(resolve).catch(reject)
// #endif
})
}
// #ifdef H5
async function _uploadH5(presignUrl, filePath) {
// H5 端 filePath 可能是 base64 或 blob URL
let blob
if (filePath.startsWith('data:')) {
const resp = await fetch(filePath)
blob = await resp.blob()
} else {
const resp = await fetch(filePath)
blob = await resp.blob()
}
const res = await fetch(presignUrl, {
method: 'PUT',
headers: { 'Content-Type': 'image/jpeg' },
body: blob
})
if (!res.ok) {
throw new Error(`COS上传失败: ${res.status}`)
}
}
// #endif
// #ifdef APP-PLUS
function _uploadApp(presignUrl, filePath) {
return new Promise((resolve, reject) => {
console.log('[COS] APP端开始读取文件:', filePath)
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
entry.file((file) => {
console.log('[COS] 文件大小:', file.size, 'bytes')
const reader = new plus.io.FileReader()
reader.onloadend = (e) => {
const base64Data = e.target.result
const pure = base64Data.split(',')[1]
const binary = atob(pure)
const len = binary.length
const bytes = new Uint8Array(len)
for (let i = 0; i < len; i++) {
bytes[i] = binary.charCodeAt(i)
}
console.log('[COS] 文件读取完成, 准备PUT上传, 数据大小:', len, 'bytes')
// 使用 uni.request 发送 PUTAPP端走原生网络支持 ArrayBuffer
uni.request({
url: presignUrl,
method: 'PUT',
header: { 'Content-Type': 'image/jpeg' },
data: bytes.buffer,
timeout: 120000,
success(res) {
console.log('[COS] PUT响应, statusCode:', res.statusCode)
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve()
} else {
reject(new Error(`COS上传失败: ${res.statusCode}`))
}
},
fail(err) {
console.error('[COS] PUT请求失败:', JSON.stringify(err))
reject(new Error('COS上传网络错误: ' + (err.errMsg || '')))
}
})
}
reader.onerror = () => {
console.error('[COS] 文件读取失败')
reject(new Error('读取文件失败'))
}
reader.readAsDataURL(file)
})
}, (err) => {
console.error('[COS] 解析文件路径失败:', JSON.stringify(err))
reject(new Error('解析文件路径失败: ' + JSON.stringify(err)))
})
})
}
// #endif