mirror of
https://github.com/doocs/md.git
synced 2024-11-28 21:46:25 +08:00
feat: support qiniu kudo
This commit is contained in:
parent
5ae6fd4b28
commit
de4417b954
@ -1,8 +1,11 @@
|
|||||||
import fetch from "./fetch";
|
import fetch from "./fetch";
|
||||||
|
import CryptoJS from "crypto-js";
|
||||||
import OSS from "ali-oss";
|
import OSS from "ali-oss";
|
||||||
import COS from "cos-js-sdk-v5";
|
import COS from "cos-js-sdk-v5";
|
||||||
import Buffer from "buffer-from";
|
import Buffer from "buffer-from";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import * as qiniu from "qiniu-js";
|
||||||
|
import { utf16to8, base64encode, safe64 } from "../assets/scripts/tokenTools";
|
||||||
|
|
||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
username: "filess",
|
username: "filess",
|
||||||
@ -28,6 +31,8 @@ function fileUpload(content, file) {
|
|||||||
return aliOSSFileUpload(content, file.name);
|
return aliOSSFileUpload(content, file.name);
|
||||||
case "txCOS":
|
case "txCOS":
|
||||||
return txCOSFileUpload(file);
|
return txCOSFileUpload(file);
|
||||||
|
case "qiniu":
|
||||||
|
return qiniuUpload(file);
|
||||||
case "github":
|
case "github":
|
||||||
default:
|
default:
|
||||||
return ghFileUpload(content, file.name);
|
return ghFileUpload(content, file.name);
|
||||||
@ -81,6 +86,14 @@ function getGitHubConfig() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
async function ghFileUpload(content, filename) {
|
async function ghFileUpload(content, filename) {
|
||||||
const isDefault = localStorage.getItem("imgHost") !== "github";
|
const isDefault = localStorage.getItem("imgHost") !== "github";
|
||||||
const config = isDefault ? getDefaultConfig() : getGitHubConfig();
|
const config = isDefault ? getDefaultConfig() : getGitHubConfig();
|
||||||
@ -166,6 +179,44 @@ async function txCOSFileUpload(file) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function qiniuUpload(file) {
|
||||||
|
const qiniuConfig = JSON.parse(localStorage.getItem("qiniuConfig"));
|
||||||
|
const putPolicy = {
|
||||||
|
scope: qiniuConfig.bucket,
|
||||||
|
deadline: Math.trunc(new Date().getTime() / 1000) + 3600,
|
||||||
|
};
|
||||||
|
const token = getQiniuToken(
|
||||||
|
qiniuConfig.accessKey,
|
||||||
|
qiniuConfig.secretKey,
|
||||||
|
putPolicy
|
||||||
|
);
|
||||||
|
const dir = qiniuConfig.path ? qiniuConfig.path + "/" : "";
|
||||||
|
const dateFilename =
|
||||||
|
dir +
|
||||||
|
new Date().getTime() +
|
||||||
|
"-" +
|
||||||
|
uuidv4() +
|
||||||
|
"." +
|
||||||
|
file.name.split(".")[1];
|
||||||
|
const config = {
|
||||||
|
region: qiniuConfig.region,
|
||||||
|
};
|
||||||
|
const observable = qiniu.upload(file, dateFilename, token, {}, config);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
observable.subscribe({
|
||||||
|
next: (result) => {
|
||||||
|
console.log(result);
|
||||||
|
},
|
||||||
|
error: (err) => {
|
||||||
|
reject(err.message);
|
||||||
|
},
|
||||||
|
complete: (result) => {
|
||||||
|
resolve(qiniuConfig.domain + "/" + result.key);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
fileUpload,
|
fileUpload,
|
||||||
};
|
};
|
||||||
|
155
src/assets/scripts/tokenTools.js
Normal file
155
src/assets/scripts/tokenTools.js
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/* utf.js - UTF-8 <=> UTF-16 convertion
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
|
||||||
|
* Version: 1.0
|
||||||
|
* LastModified: Dec 25 1999
|
||||||
|
* This library is free. You can redistribute it and/or modify it.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Interfaces:
|
||||||
|
* utf8 = utf16to8(utf16);
|
||||||
|
* utf16 = utf8to16(utf8);
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function utf16to8(str) {
|
||||||
|
var out, i, len, c;
|
||||||
|
out = "";
|
||||||
|
len = str.length;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
c = str.charCodeAt(i);
|
||||||
|
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||||
|
out += str.charAt(i);
|
||||||
|
} else if (c > 0x07FF) {
|
||||||
|
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
|
||||||
|
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
|
||||||
|
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
|
||||||
|
} else {
|
||||||
|
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
|
||||||
|
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function utf8to16(str) {
|
||||||
|
var out, i, len, c;
|
||||||
|
var char2, char3;
|
||||||
|
out = "";
|
||||||
|
len = str.length;
|
||||||
|
i = 0;
|
||||||
|
while (i < len) {
|
||||||
|
c = str.charCodeAt(i++);
|
||||||
|
switch (c >> 4) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
// 0xxxxxxx
|
||||||
|
out += str.charAt(i - 1);
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
// 110x xxxx 10xx xxxx
|
||||||
|
char2 = str.charCodeAt(i++);
|
||||||
|
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
// 1110 xxxx 10xx xxxx 10xx xxxx
|
||||||
|
char2 = str.charCodeAt(i++);
|
||||||
|
char3 = str.charCodeAt(i++);
|
||||||
|
out += String.fromCharCode(((c & 0x0F) << 12)
|
||||||
|
| ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
//========================================================
|
||||||
|
/*
|
||||||
|
* Interfaces:
|
||||||
|
* b64 = base64encode(data);
|
||||||
|
* data = base64decode(b64);
|
||||||
|
*/
|
||||||
|
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||||
|
var base64DecodeChars = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||||
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
|
||||||
|
export function base64encode(str) {
|
||||||
|
var out, i, len;
|
||||||
|
var c1, c2, c3;
|
||||||
|
len = str.length;
|
||||||
|
i = 0;
|
||||||
|
out = "";
|
||||||
|
while (i < len) {
|
||||||
|
c1 = str.charCodeAt(i++) & 0xff;
|
||||||
|
if (i == len) {
|
||||||
|
out += base64EncodeChars.charAt(c1 >> 2);
|
||||||
|
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
|
||||||
|
out += "==";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c2 = str.charCodeAt(i++);
|
||||||
|
if (i == len) {
|
||||||
|
out += base64EncodeChars.charAt(c1 >> 2);
|
||||||
|
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
|
||||||
|
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
|
||||||
|
out += "=";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c3 = str.charCodeAt(i++);
|
||||||
|
out += base64EncodeChars.charAt(c1 >> 2);
|
||||||
|
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
|
||||||
|
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
|
||||||
|
out += base64EncodeChars.charAt(c3 & 0x3F);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function base64decode(str) {
|
||||||
|
var c1, c2, c3, c4;
|
||||||
|
var i, len, out;
|
||||||
|
len = str.length;
|
||||||
|
i = 0;
|
||||||
|
out = "";
|
||||||
|
while (i < len) {
|
||||||
|
/* c1 */
|
||||||
|
do {
|
||||||
|
c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
|
||||||
|
} while (i < len && c1 == -1);
|
||||||
|
if (c1 == -1) break;
|
||||||
|
/* c2 */
|
||||||
|
do {
|
||||||
|
c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
|
||||||
|
} while (i < len && c2 == -1);
|
||||||
|
if (c2 == -1) break;
|
||||||
|
out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
|
||||||
|
/* c3 */
|
||||||
|
do {
|
||||||
|
c3 = str.charCodeAt(i++) & 0xff;
|
||||||
|
if (c3 == 61) return out;
|
||||||
|
c3 = base64DecodeChars[c3];
|
||||||
|
} while (i < len && c3 == -1);
|
||||||
|
if (c3 == -1) break;
|
||||||
|
out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
|
||||||
|
/* c4 */
|
||||||
|
do {
|
||||||
|
c4 = str.charCodeAt(i++) & 0xff;
|
||||||
|
if (c4 == 61) return out;
|
||||||
|
c4 = base64DecodeChars[c4];
|
||||||
|
} while (i < len && c4 == -1);
|
||||||
|
if (c4 == -1) break;
|
||||||
|
out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function safe64(base64) {
|
||||||
|
base64 = base64.replace(/\+/g, "-");
|
||||||
|
base64 = base64.replace(/\//g, "_");
|
||||||
|
return base64;
|
||||||
|
}
|
@ -201,6 +201,66 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane class="github-panel" label="七牛云 Kodo" name="qiniu">
|
||||||
|
<el-form
|
||||||
|
class="setting-form"
|
||||||
|
ref="form"
|
||||||
|
:model="formQiniu"
|
||||||
|
label-position="right"
|
||||||
|
label-width="140px"
|
||||||
|
>
|
||||||
|
<el-form-item label="AccessKey" :required="true">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="formQiniu.accessKey"
|
||||||
|
placeholder="如:6DD3VaLJ_SQgOdoocsyTV_YWaDmdnL2n8EGx7kG"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="SecretKey" :required="true">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="formQiniu.secretKey"
|
||||||
|
show-password
|
||||||
|
placeholder="如:qgZa5qrvDOOcsmdKStD1oCjZ9nB7MDvJUs_34SIm"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Bucket" :required="true">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="formQiniu.bucket"
|
||||||
|
placeholder="如:md"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Bucket 对应域名" :required="true">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="formQiniu.domain"
|
||||||
|
placeholder="如:http://images.123ylb.cn"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="存储区域" :required="true">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="formQiniu.region"
|
||||||
|
placeholder="如:z2"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="存储路径" :required="false">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="formQiniu.path"
|
||||||
|
placeholder="如:img,可不填,默认为根目录"
|
||||||
|
></el-input>
|
||||||
|
<el-link
|
||||||
|
type="primary"
|
||||||
|
href="https://cloud.tencent.com/document/product/436/38484"
|
||||||
|
target="_blank"
|
||||||
|
>如何使用七牛云 Kodo?</el-link
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="saveQiniuConfiguration"
|
||||||
|
>保存配置</el-button
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
@ -238,6 +298,13 @@ export default {
|
|||||||
path: "",
|
path: "",
|
||||||
cdnHost: "",
|
cdnHost: "",
|
||||||
},
|
},
|
||||||
|
formQiniu: {
|
||||||
|
accessKey: "",
|
||||||
|
secretKey: "",
|
||||||
|
bucket: "",
|
||||||
|
domain: "",
|
||||||
|
region: "",
|
||||||
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: "default",
|
value: "default",
|
||||||
@ -255,6 +322,10 @@ export default {
|
|||||||
value: "txCOS",
|
value: "txCOS",
|
||||||
label: "腾讯云",
|
label: "腾讯云",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: "qiniu",
|
||||||
|
label: "七牛云",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
imgHost: "default",
|
imgHost: "default",
|
||||||
uploadingImg: false,
|
uploadingImg: false,
|
||||||
@ -353,6 +424,30 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
saveQiniuConfiguration() {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
this.formQiniu.accessKey &&
|
||||||
|
this.formQiniu.secretKey &&
|
||||||
|
this.formQiniu.bucket &&
|
||||||
|
this.formQiniu.domain &&
|
||||||
|
this.formQiniu.region
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: `七牛云 Kodo 参数配置不全`,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localStorage.setItem("qiniuConfig", JSON.stringify(this.formQiniu));
|
||||||
|
this.$message({
|
||||||
|
message: "保存成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// 图片上传前的处理
|
// 图片上传前的处理
|
||||||
beforeUpload(file) {
|
beforeUpload(file) {
|
||||||
if (!this.validateConfig()) {
|
if (!this.validateConfig()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user