u
This commit is contained in:
1 parent
ce466130c0
commit
9c026f00ad
36 files changed
+2230
-1036
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { toast } from 'sard-uniapp'
|
||||
import { getaliyunkeyApi } from '@/request/api'
|
||||
import { getOssKey } from './oss'
|
||||
import { isApp, isH5, isMpWeixin } from './platform'
|
||||
|
||||
const aliyunBucket = import.meta.env.VITE_ALIYUN_BUCKET
|
||||
@@ -115,70 +115,12 @@ export function formatFileSize(size: number): string {
|
||||
else return `${(size / (1024 * 1024 * 1024)).toFixed(2)} GB`
|
||||
}
|
||||
|
||||
export interface AliyunUploadResult {
|
||||
url: string // 上传后的完整 URL
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到阿里云 OSS
|
||||
* @param filePath 本地文件路径
|
||||
* @param fileName 文件名
|
||||
* @param fileType 文件类型,可选:image/video/file
|
||||
* @returns Promise<AliyunUploadResult>
|
||||
* 上传文件到阿里云 OSS(优化版)
|
||||
*/
|
||||
export async function uploadFileToAliyun(
|
||||
filePath: string,
|
||||
fileName: string,
|
||||
fileType: any,
|
||||
): Promise<AliyunUploadResult> {
|
||||
// 获取 OSS 临时上传凭证
|
||||
const keyRes = await getaliyunkeyApi({
|
||||
bucketName: aliyunBucket,
|
||||
})
|
||||
const { accessid, callback, dir, host, policy, signature } = keyRes.data
|
||||
|
||||
// 构建文件在 OSS 的存储路径
|
||||
const fileExtension = fileName.split('.').pop()?.toLowerCase() || 'tmp'
|
||||
const timestamp = Date.now()
|
||||
const random = Math.floor(Math.random() * 1000)
|
||||
const key = `${dir}${timestamp + random}.${fileExtension}`
|
||||
|
||||
const formData: Record<string, any> = {
|
||||
key,
|
||||
OSSAccessKeyId: accessid,
|
||||
policy,
|
||||
signature,
|
||||
success_action_status: '200',
|
||||
name: fileName,
|
||||
}
|
||||
if (callback)
|
||||
formData.callback = callback
|
||||
|
||||
// 使用 Promise 包裹 uni.uploadFile
|
||||
return new Promise<AliyunUploadResult>((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: host,
|
||||
filePath,
|
||||
name: 'file',
|
||||
fileName,
|
||||
fileType,
|
||||
formData,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
resolve({
|
||||
url: `${host}/${key}`,
|
||||
})
|
||||
}
|
||||
else {
|
||||
reject(new Error(`上传失败,状态码: ${res.statusCode}`))
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err)
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
/** =================== 工具函数 =================== */
|
||||
|
||||
/** 获取文件名:从 URL 提取最后一段 */
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// utils/ossManager.ts
|
||||
import { getAliyunkeyApi } from '@/request/api'
|
||||
|
||||
const aliyunBucket = import.meta.env.VITE_ALIYUN_BUCKET
|
||||
|
||||
interface OssKey {
|
||||
accessid: string
|
||||
callback?: string
|
||||
dir: string
|
||||
host: string
|
||||
policy: string
|
||||
signature: string
|
||||
expire: number
|
||||
}
|
||||
|
||||
interface OssUpdateResult {
|
||||
url: string // 上传后的完整 URL
|
||||
}
|
||||
|
||||
// ✅ 模块级缓存(天然单例)
|
||||
let ossKeyCache: OssKey | null = null
|
||||
let ossKeyPromise: Promise<OssKey> | null = null
|
||||
|
||||
/**
|
||||
* 获取 OSS Key(缓存 + 并发锁)
|
||||
*/
|
||||
export async function getOssKey(): Promise<OssKey> {
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const SAFE_GAP = 10 // 提前10秒过期
|
||||
|
||||
// ✅ 命中缓存
|
||||
if (ossKeyCache && ossKeyCache.expire - SAFE_GAP > now) {
|
||||
console.log('===命中缓存===')
|
||||
return ossKeyCache
|
||||
}
|
||||
|
||||
// ✅ 并发锁
|
||||
if (ossKeyPromise) {
|
||||
return ossKeyPromise
|
||||
}
|
||||
|
||||
// ✅ 请求
|
||||
ossKeyPromise = getAliyunkeyApi({
|
||||
bucketName: aliyunBucket,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log('===重新请求===')
|
||||
|
||||
const data = res.data
|
||||
|
||||
ossKeyCache = {
|
||||
accessid: data.accessid,
|
||||
callback: data.callback,
|
||||
dir: data.dir,
|
||||
host: data.host,
|
||||
policy: data.policy,
|
||||
signature: data.signature,
|
||||
expire: Number(data.expire),
|
||||
}
|
||||
|
||||
return ossKeyCache
|
||||
})
|
||||
.finally(() => {
|
||||
ossKeyPromise = null
|
||||
})
|
||||
|
||||
return ossKeyPromise
|
||||
}
|
||||
|
||||
export async function uploadToOss(
|
||||
filePath: string,
|
||||
fileName: string,
|
||||
fileType?: 'image' | 'video' | 'file',
|
||||
): Promise<OssUpdateResult> {
|
||||
// ✅ 使用缓存后的 key
|
||||
const { accessid, callback, dir, host, policy, signature } = await getOssKey()
|
||||
|
||||
// 生成文件路径
|
||||
const ext = fileName.split('.').pop()?.toLowerCase() || 'tmp'
|
||||
const key = `${dir}${Date.now()}_${Math.floor(Math.random() * 1000)}.${ext}`
|
||||
|
||||
const formData: Record<string, any> = {
|
||||
key,
|
||||
OSSAccessKeyId: accessid,
|
||||
policy,
|
||||
signature,
|
||||
success_action_status: '200',
|
||||
name: fileName,
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
formData.callback = callback
|
||||
}
|
||||
|
||||
return new Promise<OssUpdateResult>((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: host,
|
||||
filePath,
|
||||
name: 'file',
|
||||
fileName,
|
||||
fileType: 'image',
|
||||
formData,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
resolve({
|
||||
url: `${host}/${key}`,
|
||||
})
|
||||
}
|
||||
else {
|
||||
reject(new Error(`上传失败,状态码: ${res.statusCode}`))
|
||||
}
|
||||
},
|
||||
fail: reject,
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,9 +1,3 @@
|
||||
/*
|
||||
* @Author: 菲鸽
|
||||
* @Date: 2024-03-28 19:13:55
|
||||
* @Last Modified by: 菲鸽
|
||||
* @Last Modified time: 2024-03-28 19:24:55
|
||||
*/
|
||||
export const platform = __UNI_PLATFORM__
|
||||
export const isH5 = __UNI_PLATFORM__ === 'h5'
|
||||
export const isApp = __UNI_PLATFORM__ === 'app'
|
||||
@@ -13,6 +7,11 @@ export const isMpAplipay = __UNI_PLATFORM__.startsWith('mp-alipay')
|
||||
export const isMpToutiao = __UNI_PLATFORM__.startsWith('mp-toutiao')
|
||||
export const isHarmony = __UNI_PLATFORM__.startsWith('app-harmony')
|
||||
|
||||
function isInWeChat() {
|
||||
const ua = navigator.userAgent.toLowerCase()
|
||||
return ua.includes('micromessenger')
|
||||
}
|
||||
|
||||
const PLATFORM = {
|
||||
platform,
|
||||
isH5,
|
||||
@@ -22,5 +21,6 @@ const PLATFORM = {
|
||||
isMpAplipay,
|
||||
isMpToutiao,
|
||||
isHarmony,
|
||||
isInWeChat
|
||||
}
|
||||
export default PLATFORM
|
||||
Reference in new issue
Block a user