Commit a57411e8 by lijiabin

【线上优化】 perf: 修改分片上传的地址,加入获取相关token逻辑

parent 6fefc62d
import axios, { type AxiosRequestConfig } from 'axios' import axios, { type AxiosRequestConfig } from 'axios'
import CryptoJS from 'crypto-js' import CryptoJS from 'crypto-js'
import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
type UploadFileResponseItem = { import type { UploadFileResponseItem, ChunkCheckResponse } from './types'
createTime: string
createUser: number
fileBucket: string
fileId: string
fileName: string
filePath: string
fileSizeKb: number
fileSuffix: string
finalName: string
realPath: string
updateTime: string
updateUser: string
}
type ChunkCheckResponse = {
status: number
fileUrl?: string
chunkNumbers?: number[]
}
const OA_UPLOAD_BASE_URL = 'http://47.112.96.71:8082' const OA_UPLOAD_CHUNK_BASE_URL = 'https://oa.yswg.com.cn:8085'
const OA_UPLOAD_COMMON_BASE_URL = 'http://47.112.96.71:8082'
const CHUNK_UPLOAD_THRESHOLD = 10 * 1024 * 1024 const CHUNK_UPLOAD_THRESHOLD = 10 * 1024 * 1024
const CHUNK_SIZE = 5 * 1024 * 1024 const CHUNK_SIZE = 5 * 1024 * 1024
const MAX_CONCURRENT_UPLOADS = 3 const MAX_CONCURRENT_UPLOADS = 3
const CHUNK_API_AUTH_SECRET = '4821-7395-1642-8053-2971-5604-9182-4307'
function hashBufferMD5(buffer: ArrayBuffer): string { function hashBufferMD5(buffer: ArrayBuffer): string {
const wordArray = CryptoJS.lib.WordArray.create(new Uint8Array(buffer)) const wordArray = CryptoJS.lib.WordArray.create(new Uint8Array(buffer))
...@@ -113,19 +98,21 @@ async function uploadFileByChunks( ...@@ -113,19 +98,21 @@ async function uploadFileByChunks(
}, },
signal: AbortSignal, signal: AbortSignal,
): Promise<UploadFileResponseItem> { ): Promise<UploadFileResponseItem> {
const userStore = useUserStore()
const { chunkApiAuthToken } = storeToRefs(userStore)
const { onProgress } = options const { onProgress } = options
const fileHash = await fileHashHeadTailMiddle(file) const fileHash = await fileHashHeadTailMiddle(file)
const fileSuffix = file.name.includes('.') ? file.name.slice(file.name.lastIndexOf('.')) : '' const fileSuffix = file.name.includes('.') ? file.name.slice(file.name.lastIndexOf('.')) : ''
const checkResponse = await axios.post<{ data: ChunkCheckResponse }>( const checkResponse = await axios.post<{ data: ChunkCheckResponse }>(
`${OA_UPLOAD_BASE_URL}/mobiles/file-upload/check`, `${OA_UPLOAD_CHUNK_BASE_URL}/mobiles/file-upload/check`,
{ {
hash: fileHash, hash: fileHash,
fileName: file.name, fileName: file.name,
fileSize: file.size, fileSize: file.size,
fileSuffx: fileSuffix, fileSuffx: fileSuffix,
}, },
{ signal }, { signal, headers: { authorization: chunkApiAuthToken.value } },
) )
// 秒传服务检查文件是否存在 // 秒传服务检查文件是否存在
...@@ -167,10 +154,11 @@ async function uploadFileByChunks( ...@@ -167,10 +154,11 @@ async function uploadFileByChunks(
formData.append('filePart', chunk, file.name) formData.append('filePart', chunk, file.name)
formData.append('chunkNumber', String(index)) formData.append('chunkNumber', String(index))
await axios.post(`${OA_UPLOAD_BASE_URL}/mobiles/file-upload/chunk`, formData, { await axios.post(`${OA_UPLOAD_CHUNK_BASE_URL}/mobiles/file-upload/chunk`, formData, {
signal, signal,
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
authorization: chunkApiAuthToken.value,
}, },
}) })
...@@ -206,12 +194,13 @@ async function uploadFileByChunks( ...@@ -206,12 +194,13 @@ async function uploadFileByChunks(
// 上传完成 通知后端文件上传完成 // 上传完成 通知后端文件上传完成
const finishResponse = await axios.post<{ data: { fileUrl: string } }>( const finishResponse = await axios.post<{ data: { fileUrl: string } }>(
`${OA_UPLOAD_BASE_URL}/mobiles/file-upload/finish`, `${OA_UPLOAD_CHUNK_BASE_URL}/mobiles/file-upload/finish`,
finishFormData, finishFormData,
{ {
signal, signal,
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
authorization: chunkApiAuthToken.value,
}, },
}, },
) )
...@@ -261,7 +250,7 @@ export const uploadFile = ( ...@@ -261,7 +250,7 @@ export const uploadFile = (
} }
return axios return axios
.post(`${OA_UPLOAD_BASE_URL}/mobiles/uploadFile`, formData, axiosOptions) .post(`${OA_UPLOAD_COMMON_BASE_URL}/mobiles/uploadFile`, formData, axiosOptions)
.then((data) => data.data.data[0] as UploadFileResponseItem) .then((data) => data.data.data[0] as UploadFileResponseItem)
})() })()
...@@ -272,3 +261,24 @@ export const uploadFile = ( ...@@ -272,3 +261,24 @@ export const uploadFile = (
promise, promise,
} }
} }
export const getTimestamp = async () => {
const {
data: { data: timestamp },
} = await axios.get(`${OA_UPLOAD_CHUNK_BASE_URL}/api/auth/getTime`)
return timestamp
}
export const getChunkApiAuthToken = async (weChatId: string) => {
const timestamp = await getTimestamp()
const rawStr = CHUNK_API_AUTH_SECRET + timestamp
const {
data: { data },
} = await axios.post(`${OA_UPLOAD_CHUNK_BASE_URL}/api/auth/getToken`, {
timestamp,
weChatId,
secret: CryptoJS.MD5(rawStr).toString(),
})
return data.token as string
}
...@@ -6,3 +6,24 @@ export interface FielItemDto { ...@@ -6,3 +6,24 @@ export interface FielItemDto {
msg: string msg: string
status: number status: number
} }
export interface UploadFileResponseItem {
createTime: string
createUser: number
fileBucket: string
fileId: string
fileName: string
filePath: string
fileSizeKb: number
fileSuffix: string
finalName: string
realPath: string
updateTime: string
updateUser: string
}
export interface ChunkCheckResponse {
status: number
fileUrl?: string
chunkNumbers?: number[]
}
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { loginByCode, loginByEmail, refreshTokenApi } from '@/api/login' import { loginByCode, loginByEmail, refreshTokenApi, getChunkApiAuthToken } from '@/api'
import type { LoginResponseDto } from '@/api/login/types' import type { LoginResponseDto } from '@/api/login/types'
import { useStorage } from '@vueuse/core'
/** /**
* 关于用户的store * 关于用户的store
*/ */
export const useUserStore = defineStore('user', () => { export const useUserStore = defineStore('user', () => {
const userInfo = ref(JSON.parse(localStorage.getItem('userInfo') || '{}') as LoginResponseDto) const userInfo = useStorage<LoginResponseDto>('userInfo', {} as LoginResponseDto)
const token = ref(localStorage.getItem('token') || '') const token = useStorage<string>('token', '')
const refreshToken = ref(localStorage.getItem('refreshToken') || '') const refreshToken = useStorage<string>('refreshToken', '')
const chunkApiAuthToken = useStorage<string>('chunkApiAuthToken', '')
// 获取用户信息 // 获取用户信息
const fetchUserInfo = async () => { const fetchUserInfo = async () => {
// { // {
...@@ -42,6 +44,10 @@ export const useUserStore = defineStore('user', () => { ...@@ -42,6 +44,10 @@ export const useUserStore = defineStore('user', () => {
const { data } = await loginByCode({ code, isCodeLogin, cutEmail }) const { data } = await loginByCode({ code, isCodeLogin, cutEmail })
console.log(data) console.log(data)
setUserInfoAndToken(data) setUserInfoAndToken(data)
// 同时获取关于分片的token
const token = await getChunkApiAuthToken(data.account)
setChunkApiAuthToken(token)
} }
const getNewToken = async () => { const getNewToken = async () => {
const { data } = await refreshTokenApi(refreshToken.value) const { data } = await refreshTokenApi(refreshToken.value)
...@@ -72,6 +78,10 @@ export const useUserStore = defineStore('user', () => { ...@@ -72,6 +78,10 @@ export const useUserStore = defineStore('user', () => {
// session存一份 // session存一份
localStorage.setItem('token', str) localStorage.setItem('token', str)
} }
const setChunkApiAuthToken = (str: string) => {
chunkApiAuthToken.value = str
localStorage.setItem('chunkApiAuthToken', str)
}
const setRefreshToken = (str: string) => { const setRefreshToken = (str: string) => {
refreshToken.value = str refreshToken.value = str
localStorage.setItem('refreshToken', str) localStorage.setItem('refreshToken', str)
...@@ -83,10 +93,12 @@ export const useUserStore = defineStore('user', () => { ...@@ -83,10 +93,12 @@ export const useUserStore = defineStore('user', () => {
return { return {
userInfo, userInfo,
token, token,
chunkApiAuthToken,
fetchUserInfo, fetchUserInfo,
setUserInfo, setUserInfo,
setToken, setToken,
getUserInfoByCode, getUserInfoByCode,
setChunkApiAuthToken,
refreshToken, refreshToken,
getNewToken, getNewToken,
clearAllUserInfo, clearAllUserInfo,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment