269 lines
8.8 KiB
Vue
269 lines
8.8 KiB
Vue
<template>
|
||
<div>
|
||
<n-upload
|
||
ref="uploadRef"
|
||
:default-upload="false"
|
||
multiple
|
||
:custom-request="customRequest"
|
||
@before-upload="beforeUpload"
|
||
>
|
||
<n-upload-dragger>
|
||
<!-- <div style="margin-bottom: 12px">
|
||
<n-icon size="48" :depth="3"></n-icon>
|
||
</div>-->
|
||
<n-text style="font-size: 16px;user-select: none;">点击此处或者拖动文件到该区域来上传</n-text>
|
||
<n-p depth="3" style="margin: 8px 0 0 0;user-select: none;">
|
||
最大支持200MB大小文件,其实只是懒得做分片上传而已
|
||
<!-- <br />虽然理论上没有人有能力审查你上传的东西 -->
|
||
<br />反正没人用写这么多干什么。。。
|
||
</n-p>
|
||
</n-upload-dragger>
|
||
</n-upload>
|
||
|
||
<n-flex justify="end" style="margin: 10px 0;position:relative">
|
||
<n-input-number v-model:value="downloadCredit" placeholder="可下载次数,默认无限" clearable :min="1" :max="2147483647" style="width:max-content"/>
|
||
<n-button type="primary" @click="clickUpload">开始上传</n-button>
|
||
</n-flex>
|
||
<n-data-table
|
||
:columns="columns"
|
||
:data="file_Code_Map"
|
||
:row-props="rowProps"
|
||
:max-height="250"
|
||
:bordered="false"
|
||
:single-line="false"
|
||
style="user-select: none;"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted,computed } from "vue";
|
||
// import aesjs from "aes-js";
|
||
// import { Base64 } from "js-base64";
|
||
import { useMessage, useNotification } from "naive-ui";
|
||
import useClipboard from "vue-clipboard3";
|
||
import { useSettingStore } from "@/pinia/store";
|
||
// import { sm4 } from 'sm-crypto'
|
||
import {NUpload,NUploadDragger,NText,NP,NFlex,NDataTable,NButton,NInputNumber} from 'naive-ui'
|
||
import {encrypt,encryptString,generateKey} from '../func/upload'
|
||
|
||
const setting = useSettingStore();
|
||
const { toClipboard } = useClipboard();
|
||
const message = useMessage();
|
||
const notification = useNotification();
|
||
|
||
|
||
// 服务端端口
|
||
const serverPort = setting.serverPort;
|
||
|
||
// console.log(activeFuction,activeKeyButtons)
|
||
// var charMap = ""
|
||
// for(let i of setting.activeKeyMap){
|
||
// if(i === 'A-Z'){
|
||
// charMap = charMap + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||
// }else if(i === "a-z"){
|
||
// charMap = charMap + 'abcdefghijklmnopqrstuvwxyz'
|
||
// }else if(i === '0-9'){
|
||
// charMap = charMap + '0123456789'
|
||
// }
|
||
// }
|
||
// // 生成密钥
|
||
// const generateKey = function() {
|
||
// if(setting.activeFuction === "不加密"){
|
||
// return ''
|
||
// }
|
||
// var returnStr = "",
|
||
// length = setting.activeFuction === "AES128" ? 16 : 32
|
||
// // charMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||
|
||
// for (var i = 0; i < length; i++) {
|
||
// var index = Math.round(Math.random() * charMap.length);
|
||
// returnStr += charMap.substring(index, index + 1);
|
||
// }
|
||
// return returnStr;
|
||
// };
|
||
|
||
// 上传文件用
|
||
const uploadRef = ref(null);
|
||
|
||
// 分享码可用次数
|
||
const downloadCredit = ref(null);
|
||
|
||
var file_Code_Map = ref([]);
|
||
|
||
var uploadProcess = ref(0);
|
||
|
||
|
||
// const baseUrl = location.protocol + "//" + location.hostname + ":" + serverPort + "/";
|
||
const baseUrl = setting.baseUrl
|
||
console.log(baseUrl)
|
||
|
||
|
||
// const blob2Uint8Array = function(blob) {
|
||
// return new Promise((resolve, reject) => {
|
||
// let reader = new FileReader();
|
||
// reader.readAsArrayBuffer(blob);
|
||
// reader.onload = function() {
|
||
// let buffer = reader.result;
|
||
// let uint8array = new Uint8Array(buffer);
|
||
// resolve(uint8array);
|
||
// };
|
||
// reader.onerror = function() {
|
||
// reject(reader.error);
|
||
// };
|
||
// });
|
||
// };
|
||
// // 包含AES128和AES256
|
||
// const AES = (key,data)=>{
|
||
// key = aesjs.utils.utf8.toBytes(key);
|
||
// var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
|
||
// var encryptedBytes = aesCtr.encrypt(data);
|
||
// return encryptedBytes;
|
||
// }
|
||
// const SM4 = (key,data)=>{
|
||
// // console.log(key)
|
||
// var encryptedBytes = sm4.encrypt(data,key,{padding: 'pkcs#7',output:'array'});
|
||
// // console.log(encryptedBytes, sm4.decrypt(encryptedBytes, key,{output:'array'}))
|
||
// return new Uint8Array(encryptedBytes);
|
||
// }
|
||
// const encrypt = (key, data, fileName) => {
|
||
// return blob2Uint8Array(data).then(data => {
|
||
// let encrypted_data = null
|
||
// if(setting.activeFuction === "不加密"){
|
||
// encrypted_data = data
|
||
// }else if(setting.activeFuction != "SM4"){
|
||
// message.info(`开始加密${fileName}`);
|
||
// encrypted_data = AES(key,data)
|
||
// message.info(`${fileName}加密完成`);
|
||
// }else{
|
||
// message.info(`开始加密${fileName}`);
|
||
// encrypted_data = SM4(key,data)
|
||
// message.info(`${fileName}加密完成`);
|
||
// }
|
||
// return encrypted_data
|
||
// });
|
||
// };
|
||
// const encryptString = (key, str) => {
|
||
// // console.log(key)
|
||
// if(setting.activeFuction === "不加密"){
|
||
// return sm4.encrypt(str, 'miaospringmiaospringmiaospringao')
|
||
// }else if(setting.activeFuction !== "SM4"){
|
||
// key = aesjs.utils.utf8.toBytes(key);
|
||
// var data = aesjs.utils.utf8.toBytes(str);
|
||
// var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
|
||
// var encryptedBytes = aesCtr.encrypt(data);
|
||
// return Base64.encode(encryptedBytes);
|
||
// }else{
|
||
// return sm4.encrypt(str, key)
|
||
// }
|
||
// };
|
||
|
||
const clickUpload = function(){
|
||
// for(let i of uploadRef.value)console.log(i)
|
||
// console.log(uploadRef.value)
|
||
uploadRef.value.submit();
|
||
}
|
||
|
||
const beforeUpload = async function(data) {
|
||
// console.log(data.file.file.size)
|
||
if (data.file.file.size > 200 * 1024 * 1024) {
|
||
message.error(`${data.file.file.name}的大小超过限制,无法上传`);
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
const customRequest = ({
|
||
file,
|
||
data,
|
||
headers,
|
||
withCredentials,
|
||
action,
|
||
onFinish,
|
||
onError,
|
||
onProgress
|
||
}) => {
|
||
file = file.file;
|
||
var fileName = file.name;
|
||
const key = generateKey(setting);
|
||
const encryptedFileName = encryptString(key, fileName, setting);
|
||
var f = new Blob([file]);
|
||
encrypt(key, f, fileName, setting, message).then(data => {
|
||
message.info(`开始上传${fileName}`);
|
||
const params = {
|
||
fileName: encryptedFileName,
|
||
downloadCredit:downloadCredit.value == null ? -1 : downloadCredit.value
|
||
};
|
||
const xhr = new XMLHttpRequest();
|
||
xhr.upload.addEventListener("progress", function(event) {
|
||
const percent = (event.loaded / event.total) * 100;
|
||
uploadProcess.value = percent.toFixed(2);
|
||
onProgress({ percent: Math.ceil(percent) });
|
||
});
|
||
onProgress({ percent: 1 });
|
||
xhr.open(
|
||
"POST",
|
||
baseUrl + "file/upload?" + new URLSearchParams(params)
|
||
);
|
||
console.log(setting.token)
|
||
xhr.setRequestHeader('Authorization', `Bearer ${setting.token}`);
|
||
xhr.send(data);
|
||
xhr.onreadystatechange = () => {
|
||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||
let id = xhr.responseText;
|
||
let code = id + key
|
||
// if(setting.activeFuction === "SM4"){
|
||
// code = id + 'SM4' + key
|
||
// }
|
||
file_Code_Map.value.push({
|
||
code: code,
|
||
fileName: fileName
|
||
});
|
||
notification["success"]({
|
||
content: "上传完成",
|
||
meta: `${fileName} 已成功上传`,
|
||
duration: 2500,
|
||
keepAliveOnHover: true
|
||
});
|
||
onFinish();
|
||
} else {
|
||
console.error(xhr.statusText);
|
||
onError();
|
||
}
|
||
};
|
||
});
|
||
};
|
||
const columns = [
|
||
{
|
||
title: "文件名",
|
||
key: "fileName",
|
||
width: 150
|
||
},
|
||
{
|
||
title: "取件码(点击复制)",
|
||
key: "code"
|
||
}
|
||
];
|
||
|
||
// 记录是否复制过,第一次复制的时候提醒可以连续复制
|
||
var copyedArray = [];
|
||
const rowProps = row => {
|
||
return {
|
||
style: "cursor: pointer;",
|
||
onClick: () => {
|
||
toClipboard(`${copyedArray.join('\n')}\n${row.code}`.trim()).then(() => {
|
||
message.info(`已复制 ${row.fileName} 的取件码至剪切板`);
|
||
if (copyedArray.length == 0) {
|
||
message.info(
|
||
`可以试试点击其他取件码,也许这个玩意会自动处理剪切板内容`
|
||
);
|
||
}
|
||
copyedArray.push(row.code)
|
||
});
|
||
}
|
||
};
|
||
};
|
||
</script>
|
||
|
||
<style>
|
||
</style> |