md/src/utils/file.js

342 lines
10 KiB
JavaScript
Raw Normal View History

import CryptoJS from 'crypto-js'
import OSS from 'ali-oss'
import * as Minio from 'minio'
import COS from 'cos-js-sdk-v5'
import Buffer from 'buffer-from'
import { v4 as uuidv4 } from 'uuid'
import * as qiniu from 'qiniu-js'
2024-08-18 19:49:16 +08:00
import fetch from '@/utils/fetch'
import { base64encode, safe64, utf16to8 } from '@/utils/tokenTools'
import * as tokenTools from '@/utils/tokenTools'
import { giteeConfig, githubConfig } from '@/config'
2020-08-31 20:48:22 +08:00
2020-12-01 14:55:46 +08:00
function getConfig(useDefault, platform) {
if (useDefault) {
// load default config file
const config = platform === `github` ? githubConfig : giteeConfig
const { username, repoList, branch, accessTokenList } = config
// choose random token from access_token list
const tokenIndex = Math.floor(Math.random() * accessTokenList.length)
const accessToken = accessTokenList[tokenIndex].replace(`doocsmd`, ``)
// choose random repo from repo list
const repoIndex = Math.floor(Math.random() * repoList.length)
const repo = repoList[repoIndex]
return { username, repo, branch, accessToken }
}
// load configuration from localStorage
const customConfig = JSON.parse(localStorage.getItem(`${platform}Config`))
// split username/repo
const repoUrl = customConfig.repo
.replace(`https://${platform}.com/`, ``)
.replace(`http://${platform}.com/`, ``)
.replace(`${platform}.com/`, ``)
.split(`/`)
return {
username: repoUrl[0],
repo: repoUrl[1],
branch: customConfig.branch || `master`,
accessToken: customConfig.accessToken,
}
2020-09-13 21:24:27 +08:00
}
/**
* 获取 `年/月/日` 形式的目录
* @returns string
*/
2020-12-01 15:35:08 +08:00
function getDir() {
const date = new Date()
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, `0`)
const day = date.getDate().toString().padStart(2, `0`)
return `${year}/${month}/${day}`
2020-12-01 15:35:08 +08:00
}
/**
* 根据文件名获取它以 `时间戳+uuid` 的形式
* @param {string} filename 文件名
2024-08-18 19:49:16 +08:00
* @returns {string} `时间戳+uuid`
*/
2020-12-01 15:35:08 +08:00
function getDateFilename(filename) {
const currentTimestamp = new Date().getTime()
const fileSuffix = filename.split(`.`)[1]
return `${currentTimestamp}-${uuidv4()}.${fileSuffix}`
2020-12-01 15:35:08 +08:00
}
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-12-01 14:55:46 +08:00
// GitHub File Upload
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-12-01 14:55:46 +08:00
async function ghFileUpload(content, filename) {
const useDefault = localStorage.getItem(`imgHost`) === `default`
const { username, repo, branch, accessToken } = getConfig(
useDefault,
2024-08-18 19:49:16 +08:00
`github`,
)
const dir = getDir()
const url = `https://api.github.com/repos/${username}/${repo}/contents/${dir}/`
const dateFilename = getDateFilename(filename)
const res = await fetch({
url: url + dateFilename,
method: `put`,
headers: {
Authorization: `token ${accessToken}`,
},
data: {
content,
branch,
message: `Upload by ${window.location.href}`,
},
})
const githubResourceUrl = `raw.githubusercontent.com/${username}/${repo}/${branch}/`
2022-05-23 22:33:28 +08:00
const cdnResourceUrl = `fastly.jsdelivr.net/gh/${username}/${repo}@${branch}/`
res.content = res.data?.content || res.content
return useDefault
2021-11-25 22:08:58 +08:00
? res.content.download_url.replace(githubResourceUrl, cdnResourceUrl)
: res.content.download_url
2020-05-01 21:30:25 +08:00
}
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
// Gitee File Upload
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
2020-11-12 09:47:06 +08:00
async function giteeUpload(content, filename) {
const useDefault = localStorage.getItem(`imgHost`) === `default`
const { username, repo, branch, accessToken } = getConfig(useDefault, `gitee`)
const dir = getDir()
const dateFilename = getDateFilename(filename)
const url = `https://gitee.com/api/v5/repos/${username}/${repo}/contents/${dir}/${dateFilename}`
const res = await fetch({
url,
method: `POST`,
data: {
content,
branch,
access_token: accessToken,
message: `Upload by ${window.location.href}`,
},
})
res.content = res.data?.content || res.content
return encodeURI(res.content.download_url)
2020-11-12 09:47:06 +08:00
}
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
// Qiniu File Upload
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
function getQiniuToken(accessKey, secretKey, putPolicy) {
const policy = JSON.stringify(putPolicy)
const encoded = base64encode(utf16to8(policy))
const hash = CryptoJS.HmacSHA1(encoded, secretKey)
const encodedSigned = hash.toString(CryptoJS.enc.Base64)
return `${accessKey}:${safe64(encodedSigned)}:${encoded}`
2020-11-30 23:48:22 +08:00
}
async function qiniuUpload(file) {
const { accessKey, secretKey, bucket, region, path, domain } = JSON.parse(
2024-08-18 19:49:16 +08:00
localStorage.getItem(`qiniuConfig`),
)
const token = getQiniuToken(accessKey, secretKey, {
scope: bucket,
deadline: Math.trunc(new Date().getTime() / 1000) + 3600,
})
const dir = path ? `${path}/` : ``
const dateFilename = dir + getDateFilename(file.name)
const observable = qiniu.upload(file, dateFilename, token, {}, { region })
return new Promise((resolve, reject) => {
observable.subscribe({
next: (result) => {
console.log(result)
},
error: (err) => {
reject(err.message)
},
complete: (result) => {
resolve(`${domain}/${result.key}`)
},
})
})
2020-11-30 23:48:22 +08:00
}
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
// AliOSS File Upload
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
async function aliOSSFileUpload(content, filename) {
const dateFilename = getDateFilename(filename)
2024-08-18 19:49:16 +08:00
const { region, bucket, accessKeyId, accessKeySecret, cdnHost, path }
= JSON.parse(localStorage.getItem(`aliOSSConfig`))
const buffer = Buffer(content, `base64`)
const dir = `${path}/${dateFilename}`
const client = new OSS({
region,
bucket,
accessKeyId,
accessKeySecret,
})
try {
const res = await client.put(dir, buffer)
2024-08-18 19:49:16 +08:00
if (cdnHost === ``)
return res.url
return `${cdnHost}/${path === `` ? dateFilename : dir}`
2024-08-18 19:49:16 +08:00
}
catch (e) {
return Promise.reject(e)
}
2020-09-12 16:53:52 +08:00
}
2020-05-01 21:30:25 +08:00
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
// TxCOS File Upload
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2020-11-30 23:48:22 +08:00
async function txCOSFileUpload(file) {
const dateFilename = getDateFilename(file.name)
const { secretId, secretKey, bucket, region, path, cdnHost } = JSON.parse(
2024-08-18 19:49:16 +08:00
localStorage.getItem(`txCOSConfig`),
)
const cos = new COS({
SecretId: secretId,
SecretKey: secretKey,
})
return new Promise((resolve, reject) => {
cos.putObject(
{
Bucket: bucket,
Region: region,
Key: `${path}/${dateFilename}`,
Body: file,
},
2024-08-18 19:49:16 +08:00
(err, data) => {
if (err) {
reject(err)
2024-08-18 19:49:16 +08:00
}
else if (cdnHost) {
resolve(
2024-08-18 19:49:16 +08:00
path === ``
? `${cdnHost}/${dateFilename}`
2024-08-18 19:49:16 +08:00
: `${cdnHost}/${path}/${dateFilename}`,
)
2024-08-18 19:49:16 +08:00
}
else {
resolve(`https://${data.Location}`)
}
2024-08-18 19:49:16 +08:00
},
)
})
2020-09-15 21:49:30 +08:00
}
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2022-02-14 00:12:07 +08:00
// Minio File Upload
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
2022-02-14 00:12:07 +08:00
async function minioFileUpload(content, filename) {
const dateFilename = getDateFilename(filename)
2022-02-14 00:12:07 +08:00
const { endpoint, port, useSSL, bucket, accessKey, secretKey } = JSON.parse(
2024-08-18 19:49:16 +08:00
localStorage.getItem(`minioConfig`),
)
const buffer = Buffer(content, `base64`)
2022-02-14 00:12:07 +08:00
const conf = {
endPoint: endpoint,
2024-08-18 19:49:16 +08:00
useSSL,
accessKey,
secretKey,
}
const p = Number(port || 0)
const isCustomPort = p > 0 && p !== 80 && p !== 443
2022-02-14 00:12:07 +08:00
if (isCustomPort) {
conf.port = p
2022-02-14 00:12:07 +08:00
}
return new Promise((resolve, reject) => {
const minioClient = new Minio.Client(conf)
2022-02-14 00:12:07 +08:00
try {
2024-08-18 19:49:16 +08:00
minioClient.putObject(bucket, dateFilename, buffer, (e) => {
2022-02-14 00:12:07 +08:00
if (e) {
reject(e)
2022-02-14 00:12:07 +08:00
}
const host = `${useSSL ? `https://` : `http://`}${endpoint}${
2024-08-18 19:49:16 +08:00
isCustomPort ? `:${port}` : ``
}`
const url = `${host}/${bucket}/${dateFilename}`
2022-02-14 00:12:07 +08:00
// console.log("文件上传成功: ", url)
resolve(url)
2022-02-14 00:12:07 +08:00
// return `${endpoint}/${bucket}/${dateFilename}`;
})
2024-08-18 19:49:16 +08:00
}
catch (e) {
reject(e)
2022-02-14 00:12:07 +08:00
}
})
2022-02-14 00:12:07 +08:00
}
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
// formCustom File Upload
2024-08-18 19:49:16 +08:00
// -----------------------------------------------------------------------
async function formCustomUpload(content, file) {
const str = `
async (CUSTOM_ARG) => {
${localStorage.getItem(`formCustomConfig`)}
}
`
return new Promise((resolve, reject) => {
const exportObj = {
content, // 待上传图片的 base64
file, // 待上传图片的 file 对象
util: {
axios: fetch, // axios 实例
CryptoJS, // 加密库
OSS, // ali-oss
COS, // cos-js-sdk-v5
Buffer, // buffer-from
uuidv4, // uuid
qiniu, // qiniu-js
tokenTools, // 一些编码转换函数
getDir, // 获取 年/月/日 形式的目录
getDateFilename, // 根据文件名获取它以 时间戳+uuid 的形式
},
okCb: resolve, // 重要: 上传成功后给此回调传 url 即可
errCb: reject, // 上传失败调用的函数
}
2024-08-18 19:49:16 +08:00
// eslint-disable-next-line no-eval
2021-11-25 22:08:58 +08:00
eval(str)(exportObj).catch((err) => {
console.error(err)
reject(err)
})
})
}
2020-12-01 11:12:18 +08:00
function fileUpload(content, file) {
const imgHost = localStorage.getItem(`imgHost`)
!imgHost && localStorage.setItem(`imgHost`, `default`)
switch (imgHost) {
case `aliOSS`:
return aliOSSFileUpload(content, file.name)
case `minio`:
return minioFileUpload(content, file.name)
case `txCOS`:
return txCOSFileUpload(file)
case `qiniu`:
return qiniuUpload(file)
case `gitee`:
return giteeUpload(content, file.name)
case `github`:
return ghFileUpload(content, file.name)
case `formCustom`:
return formCustomUpload(content, file)
default:
// return file.size / 1024 < 1024
// ? giteeUpload(content, file.name)
// : ghFileUpload(content, file.name);
return ghFileUpload(content, file.name)
}
2020-12-01 11:12:18 +08:00
}
2020-12-01 14:55:46 +08:00
export default {
fileUpload,
}