chat中添加上传文件功能
This commit is contained in:
1 parent
709cac04f6
commit
dd56403d93
7 files changed
+427
-43
No files matched your search
+85
-26
@@ -38,12 +38,14 @@
|
||||
<chatui style="margin-bottom: 10px; height: 65vh"
|
||||
:messages="activeGID ? Messages[activeGID].map(v => { v.timestampString = new Date(v.timestamp).toLocaleString(); return v }).reverse() : []"/>
|
||||
|
||||
<n-input v-model:value="msg" type="textarea" placeholder="发送信息" :autosize="{
|
||||
<n-input v-model:value="msgInput" type="textarea" placeholder="发送信息" :autosize="{
|
||||
minRows: 1,
|
||||
maxRows: 2
|
||||
}" @keydown="handleKeyDown">
|
||||
}" @keydown="handleKeyDown" style="margin-top: 0px;">
|
||||
<template #suffix>
|
||||
<n-icon :component="SendOutline" style="cursor: pointer;" @click='sendMsg(activeGID, msg)'/>
|
||||
<n-icon :component="DocumentsOutline" style="cursor: pointer;margin-right: 5px;" @click='filePicker({fn:sendFiles,multiple:true})'/>
|
||||
<n-icon :component="ImagesOutline" style="cursor: pointer;margin-right: 5px;" @click='filePicker({fn:sendImages,accept:"image/*",multiple:true})'/>
|
||||
<n-icon :component="SendOutline" style="cursor: pointer;" @click='sendMsg(activeGID, msgInput)'/>
|
||||
</template>
|
||||
</n-input>
|
||||
|
||||
@@ -53,6 +55,8 @@
|
||||
</n-button> -->
|
||||
</div>
|
||||
</n-flex>
|
||||
<!-- {{ dataTest }} -->
|
||||
<!-- {{ Messages }} -->
|
||||
|
||||
|
||||
<n-modal v-model:show="showModal">
|
||||
@@ -77,21 +81,27 @@ import { ref,onMounted } from 'vue'
|
||||
import useClipboard from "vue-clipboard3";
|
||||
import { NIcon, NFlex, NDataTable, NButton, NInput, NSelect,NModal,NCard , NQrCode} from 'naive-ui'
|
||||
import { useSettingStore } from "@/pinia/store";
|
||||
import { generateKey, encryptString } from '@/func/upload';
|
||||
import { generateKey, encryptString, encrypt } from '@/func/upload';
|
||||
import { decryptString } from '@/func/download';
|
||||
import WebsocketHeartbeatJs from 'websocket-heartbeat-js';
|
||||
import { CopyOutline,SendOutline } from '@vicons/ionicons5'
|
||||
import { CopyOutline,SendOutline,ImagesOutline,DocumentsOutline } from '@vicons/ionicons5'
|
||||
import getQueryString from '@/func/getQuery'
|
||||
import chatui from "@/components/chatui.vue"
|
||||
import { Base64 } from 'js-base64';
|
||||
import { useMessage, useNotification } from "naive-ui";
|
||||
import filePicker from "@/func/filePicker"
|
||||
|
||||
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
// const modal = useModal();
|
||||
const { toClipboard } = useClipboard();
|
||||
|
||||
const setting = useSettingStore();
|
||||
const serverPort = setting.serverPort;
|
||||
const baseUrl = 'ws' + "://" + location.hostname + ":" + serverPort;
|
||||
const wsBaseUrl = 'ws' + "://" + location.hostname + ":" + serverPort;
|
||||
const baseUrl = location.protocol + "//" + location.hostname + ":" + serverPort + "/";
|
||||
const QRIconUrl = ref(location.protocol + "//" + location.hostname + ":" + serverPort + "/favicon.ico")
|
||||
|
||||
const columns = [
|
||||
@@ -160,7 +170,7 @@ const Messages = ref({})
|
||||
const dataTest = ref([])
|
||||
const gID = ref('')
|
||||
// const codeInput = ref('')
|
||||
const msg = ref('')
|
||||
const msgInput = ref('')
|
||||
|
||||
const joinedGroup = ref([])
|
||||
// 由server随机分配uuid
|
||||
@@ -170,7 +180,7 @@ const uuid = ref('')
|
||||
const gID2key = {}
|
||||
|
||||
const options = {
|
||||
url: baseUrl,
|
||||
url: wsBaseUrl,
|
||||
pingTimeout: 20000,
|
||||
pongTimeout: 10000,
|
||||
reconnectTimeout: 3000,
|
||||
@@ -216,7 +226,7 @@ socket.onmessage = (event) => {
|
||||
let key = gID2key[gID].key
|
||||
Messages.value[msg.gID].length = 0
|
||||
for (let m of JSON.parse(msg.history)) {
|
||||
Messages.value[msg.gID].push({ type: m.type, msg: decryptString(key, m.msg), from: m.from, timestamp: m.timestamp })
|
||||
Messages.value[msg.gID].push({ type: m.type,type1:m.type1, msg: decryptString(key, m.msg), from: m.from, timestamp: m.timestamp })
|
||||
dataTest.value.push({ from: 'decrypt', msg: decryptString(key, m.msg) })
|
||||
}
|
||||
} else if (type1 === 'uuid') {
|
||||
@@ -226,7 +236,6 @@ socket.onmessage = (event) => {
|
||||
let gID = msg.gID
|
||||
let key = gID2key[gID].key
|
||||
Messages.value[msg.gID].push({ type: msg.type,type1:msg.type1, msg: decryptString(key, msg.msg), from: msg.from, timestamp: msg.timestamp })
|
||||
// console.log(Messages.value)
|
||||
dataTest.value.push({ from: 'decrypt', msg: decryptString(key, msg.msg) })
|
||||
}
|
||||
}
|
||||
@@ -278,25 +287,75 @@ function sendMsg(gID, msg) {
|
||||
let key = gID2key[gID].key
|
||||
msg = encryptString(key, msg, setting)
|
||||
socket.send(JSON.stringify({ type: 'message',type1:'text', msg, gID }))
|
||||
msgInput.value = null
|
||||
}
|
||||
|
||||
function sendImg(gID,code){
|
||||
if(msg === '' || activeGID.value === null)return
|
||||
let key = gID2key[gID].key
|
||||
msg = encryptString(key, msg, setting)
|
||||
socket.send(JSON.stringify({ type: 'message',type1:'img', msg, gID }))
|
||||
}
|
||||
|
||||
|
||||
// 通过地址传参并加入传入的群组
|
||||
// function getQueryString(key) {
|
||||
// var reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)', 'i');
|
||||
// var r = window.location.search.substring(1).match(reg);
|
||||
// if (r != null) {
|
||||
// return unescape(r[2]);
|
||||
// }
|
||||
// return null;
|
||||
// async function encryptImg(file){
|
||||
// var f = new Blob([file]);
|
||||
// let key = gID2key[gID].key
|
||||
// let eU8A = await encrypt(key, f, fileName, setting)
|
||||
// let eb = Base64.fromUint8Array(eU8A)
|
||||
// return eb
|
||||
// }
|
||||
|
||||
async function uploadFile(file){
|
||||
if(activeGID.value === null)return
|
||||
var fileName = file.name;
|
||||
let key = gID2key[activeGID.value].key
|
||||
const encryptedFileName = encryptString(key, fileName, setting);
|
||||
var f = new Blob([file]);
|
||||
let data = await encrypt(key, f, fileName, setting)
|
||||
const params = {
|
||||
fileName: encryptedFileName,
|
||||
downloadCredit:-1
|
||||
};
|
||||
message.info(`开始上传${fileName}`)
|
||||
const xhr = new XMLHttpRequest();
|
||||
// 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);
|
||||
const code = await new Promise((resolve,reject)=>{
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
let id = xhr.responseText;
|
||||
let code = id + key
|
||||
message.success(`上传${fileName}成功`)
|
||||
resolve(code)
|
||||
} else {
|
||||
if(xhr.statusText !== 'OK'){
|
||||
console.error(xhr.statusText);
|
||||
message.error(`上传${fileName}失败`)
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
console.log(code)
|
||||
return code
|
||||
}
|
||||
|
||||
async function sendImages(files){
|
||||
if(activeGID.value === null || files.length === 0)return
|
||||
for(let file of files){
|
||||
const code = await uploadFile(file)
|
||||
let key = gID2key[activeGID.value].key
|
||||
socket.send(JSON.stringify({ type: 'message',type1:'img', msg: encryptString(key, code), gID:activeGID.value }))
|
||||
};
|
||||
}
|
||||
|
||||
async function sendFiles(files){
|
||||
if(activeGID.value === null || files.length === 0)return
|
||||
for(let file of files){
|
||||
let fileName = file.name;
|
||||
const code = await uploadFile(file)
|
||||
let key = gID2key[activeGID.value].key
|
||||
socket.send(JSON.stringify({ type: 'message',type1:'file', msg: encryptString(key, code), gID:activeGID.value }))
|
||||
};
|
||||
}
|
||||
onMounted(()=>{
|
||||
let aP = getQueryString('aP')
|
||||
let cG = getQueryString('cG')
|
||||
|
||||
Reference in new issue
Block a user