|
@@ -0,0 +1,192 @@
|
|
|
+import axios from 'axios'
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取上传地址
|
|
|
+ * bucket 所在区域。ECN, SCN, NCN, NA, ASG,分别对应七牛云的:华东,华南,华北,北美,新加坡 5 个区域
|
|
|
+ */
|
|
|
+function uploadURLFromRegionCode (regionCode) {
|
|
|
+ switch (regionCode) {
|
|
|
+ case 'ECN':
|
|
|
+ return 'https://up.qiniup.com'
|
|
|
+ case 'NCN':
|
|
|
+ return 'https://up-z1.qiniup.com'
|
|
|
+ case 'SCN':
|
|
|
+ return 'https://up-z2.qiniup.com'
|
|
|
+ case 'NA':
|
|
|
+ return 'https://up-na0.qiniup.com'
|
|
|
+ case 'ASG':
|
|
|
+ return 'https://up-as0.qiniup.com'
|
|
|
+ default:
|
|
|
+ console.error('please make the region is with one of [ECN, SCN, NCN, NA, ASG]')
|
|
|
+ return ''
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取上传token
|
|
|
+ * @param bucket{string} 七牛云某个区域的空间名称
|
|
|
+ */
|
|
|
+function getToken (bucket = 'img') {
|
|
|
+ return new Promise(async resolve => {
|
|
|
+ const res = await axios({
|
|
|
+ url: `/zd-api/teacher-lib/utils/file/token/${bucket}`,
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ token: window.localStorage.getItem('token')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (res.data.status === 200) {
|
|
|
+ resolve(res.data)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function fileToBuffer (file) {
|
|
|
+ return new Promise(async resolve => {
|
|
|
+ const blob = file.slice(0)
|
|
|
+ const arraybuffer = await blob.arrayBuffer()
|
|
|
+ const buf = new Buffer(arraybuffer.byteLength)
|
|
|
+ const view = new Uint8Array(arraybuffer)
|
|
|
+ for (let i = 0; i < buf.length; ++i) {
|
|
|
+ buf[i] = view[i]
|
|
|
+ }
|
|
|
+ resolve(buf)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function getEtag (buffer, callback) {
|
|
|
+ var mode = 'buffer'
|
|
|
+
|
|
|
+ if (typeof buffer === 'string') {
|
|
|
+ buffer = require('fs').createReadStream(buffer)
|
|
|
+ mode = 'stream'
|
|
|
+ } else if (buffer instanceof require('stream')) {
|
|
|
+ mode = 'stream'
|
|
|
+ }
|
|
|
+ var sha1 = function (content) {
|
|
|
+ var crypto = require('crypto')
|
|
|
+ var sha1 = crypto.createHash('sha1')
|
|
|
+ sha1.update(content)
|
|
|
+ return sha1.digest()
|
|
|
+ }
|
|
|
+
|
|
|
+ var blockSize = 4 * 1024 * 1024
|
|
|
+ var sha1String = []
|
|
|
+ var prefix = 0x16
|
|
|
+ var blockCount = 0
|
|
|
+
|
|
|
+ switch (mode) {
|
|
|
+ case 'buffer':
|
|
|
+ var bufferSize = buffer.length
|
|
|
+ blockCount = Math.ceil(bufferSize / blockSize)
|
|
|
+ // console.log(blockCount, "blockCount");
|
|
|
+ for (var i = 0; i < blockCount; i++) {
|
|
|
+ sha1String.push(sha1(buffer.slice(i * blockSize, (i + 1) * blockSize)))
|
|
|
+ }
|
|
|
+ process.nextTick(function () {
|
|
|
+ callback(calcEtag())
|
|
|
+ })
|
|
|
+ break
|
|
|
+ case 'stream':
|
|
|
+ var stream = buffer
|
|
|
+ stream.on('readable', function () {
|
|
|
+ var chunk
|
|
|
+ while ((chunk = stream.read(blockSize))) {
|
|
|
+ sha1String.push(sha1(chunk))
|
|
|
+ blockCount++
|
|
|
+ }
|
|
|
+ })
|
|
|
+ stream.on('end', function () {
|
|
|
+ callback(calcEtag())
|
|
|
+ })
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ function calcEtag () {
|
|
|
+ if (!sha1String.length) {
|
|
|
+ return 'Fto5o-5ea0sNMlW_75VgGJCv2AcJ'
|
|
|
+ }
|
|
|
+ var sha1Buffer = Buffer.concat(sha1String, blockCount * 20)
|
|
|
+
|
|
|
+ if (blockCount > 1) {
|
|
|
+ prefix = 0x96
|
|
|
+ sha1Buffer = sha1(sha1Buffer)
|
|
|
+ }
|
|
|
+
|
|
|
+ sha1Buffer = Buffer.concat([new Buffer([prefix]), sha1Buffer], sha1Buffer.length + 1)
|
|
|
+
|
|
|
+ return sha1Buffer
|
|
|
+ .toString('base64')
|
|
|
+ .replace(/\//g, '_')
|
|
|
+ .replace(/\+/g, '-')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 七牛云直传
|
|
|
+ * @param file{File} 要上传的文件对象
|
|
|
+ * @param directory{string} 所在空间的目录名称 最后要以 / 结尾
|
|
|
+ * @param bucket{string} 所在空间的名称
|
|
|
+ * @param regionCode{string} 所在空间七牛云区域代码
|
|
|
+ * @param domainName{string} 所在空间的七牛云域名
|
|
|
+ */
|
|
|
+export function qiniuUploadRequest (
|
|
|
+ file,
|
|
|
+ directory = '',
|
|
|
+ bucket = 'img',
|
|
|
+ regionCode = 'SCN',
|
|
|
+ domainName = 'https://img.luojigou.vip/'
|
|
|
+) {
|
|
|
+ return new Promise(async resolve => {
|
|
|
+ const { data: token } = await getToken(bucket)
|
|
|
+
|
|
|
+ const formData = new FormData()
|
|
|
+ const buffer = await fileToBuffer(file)
|
|
|
+
|
|
|
+ // 获取文件唯一标识作为key,可以防止上传多次重复文件
|
|
|
+ getEtag(buffer, async val => {
|
|
|
+ // 默认
|
|
|
+ let type = file.type.split('/')[1]
|
|
|
+ // console.log(type, "type");
|
|
|
+
|
|
|
+ // 文件后缀需要特殊处理
|
|
|
+ if (file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
|
|
|
+ type = 'xlsx'
|
|
|
+ } else if (file.type.includes('audio')) {
|
|
|
+ type = 'mp3'
|
|
|
+ }
|
|
|
+ const key = directory + val + '.' + type
|
|
|
+ console.log(key, 'key')
|
|
|
+
|
|
|
+ formData.append('file', file)
|
|
|
+ formData.append('token', token)
|
|
|
+ formData.append('key', key)
|
|
|
+
|
|
|
+ const options = {
|
|
|
+ url: uploadURLFromRegionCode(regionCode),
|
|
|
+ data: formData,
|
|
|
+ method: 'POST'
|
|
|
+ }
|
|
|
+
|
|
|
+ const { status } = await axios(options)
|
|
|
+ if (status === 200) {
|
|
|
+ const url = domainName + key
|
|
|
+ console.log(url, 'url')
|
|
|
+ resolve(url)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+export const BUCKET_LIST = [
|
|
|
+ {
|
|
|
+ bucket: 'img',
|
|
|
+ regionCode: 'SCN',
|
|
|
+ domainName: 'https://img.luojigou.vip/'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ bucket: 'luojigou-game',
|
|
|
+ regionCode: 'SCN',
|
|
|
+ domainName: 'https://res-game.luojigou.vip/'
|
|
|
+ }
|
|
|
+]
|