添加登录功能

This commit is contained in:
539943419 committed 2024-03-27 22:05:00 +08:00
1 parent 20e9f4940e
commit 530e54a596
17 files changed
+632 -160

No files matched your search

+117 -71
View File
@@ -1,15 +1,17 @@
<template>
<n-flex style="padding-top: 10px;padding-bottom: 10px;">
<n-input v-model:value="groupCode" type="text" placeholder="输入进群码" style="flex:1">
<n-input v-model:value="groupCode" type="text" placeholder="输入邀请码" style="flex:1">
<template #suffix>
<n-icon :component="CopyOutline" style="cursor: pointer;" @click='toClipboard(groupCode)' />
</template>
</n-input>
<n-flex>
<n-button @click="createGroup" :disabled="groupCode !== ''" :type="groupCode !== ''?'default':'primary'" ghost >
<n-button @click="createGroup" :disabled="groupCode !== ''" :type="groupCode !== '' ? 'default' : 'primary'"
ghost>
创建群组
</n-button>
<n-button @click="joinGroup(groupCode)" :disabled="groupCode === ''" :type="groupCode === ''?'default':'primary'" ghost>
<n-button @click="joinGroup(groupCode)" :disabled="groupCode === ''"
:type="groupCode === '' ? 'default' : 'primary'" ghost>
加入群组
</n-button>
</n-flex>
@@ -23,54 +25,65 @@
<n-button @click="joinGroup(codeInput)">
joinTest
</n-button> -->
<n-input
v-model:value="msg"
type="textarea"
placeholder="测试发送信息"
:autosize="{
minRows: 3,
maxRows: 3
}"
/>
<n-input v-model:value="msg" type="textarea" placeholder="测试发送信息" :autosize="{
minRows: 3,
maxRows: 3
}" />
<n-flex style="padding-top: 10px;padding-bottom: 10px;">
<n-select v-model:value="activeGID" :options="joinedGroup.map(gid=>{return {label:gid,value:gid}})" placeholder="选择当前查看群组"
style="flex:1"/>
<n-button @click="sendMsg(activeGID,msg)" :disabled="msg === '' || activeGID === null" :type="msg === '' || activeGID === null?'default':'primary'">
<n-select v-model:value="activeGID" :options="joinedGroup.map(gid => { return { label: gid, value: gid } })"
placeholder="选择当前查看群组" style="flex:1" />
<n-button @click="sendMsg(activeGID, msg)" :disabled="msg === '' || activeGID === null"
:type="msg === '' || activeGID === null ? 'default' : 'primary'">
发送消息
</n-button>
<n-button @click="shareWithQR()" :disabled="activeGID === null"
:type="activeGID === null ? 'default' : 'primary'">
分享群组
</n-button>
</n-flex>
<!-- <n-button @click="dataTest.length = 0">
clearMsg
</n-button> -->
<n-data-table
:columns="columns"
:data="activeGID?Messages[activeGID].map(v=>{v.timestampString = new Date(v.timestamp).toLocaleString();return v}):[]"
:row-props="null"
<n-data-table :columns="columns"
:data="activeGID ? Messages[activeGID].map(v => { v.timestampString = new Date(v.timestamp).toLocaleString(); return v }).reverse() : []"
:row-props="null" :bordered="false" :single-line="false" :max-height="400" />
<n-modal v-model:show="showModal">
<n-card
style="width: fit-content;"
title=""
:bordered="false"
:single-line="false"
:max-height="400"
/>
size="huge"
role="dialog"
aria-modal="true"
>
<n-qr-code :value="QRCodeData" style="padding: 0;" :size="256" error-correction-level="Q" :v-if="showModal" :icon-src='QRIconUrl' :icon-size="128"/>
</n-card>
</n-modal>
</template>
<script setup>
import {ref} from 'vue'
import { useNotification } from "naive-ui";
import { ref,onMounted } from 'vue'
// import { useModal } from "naive-ui";
import useClipboard from "vue-clipboard3";
import {NIcon,NFlex,NDataTable,NButton,NInput,NSelect} from 'naive-ui'
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 } from '@/func/upload';
import { decryptString } from '@/func/download';
import WebsocketHeartbeatJs from 'websocket-heartbeat-js';
import {CopyOutline} from '@vicons/ionicons5'
import { CopyOutline } from '@vicons/ionicons5'
import getQueryString from '@/func/getQuery'
const notification = useNotification();
// const modal = useModal();
const { toClipboard } = useClipboard();
const setting = useSettingStore();
const serverPort = setting.serverPort;
const baseUrl = 'ws' + "://" + location.hostname + ":" + serverPort;
const QRIconUrl = ref(location.protocol + "//" + location.hostname + ":" + serverPort + "/favicon.ico")
const columns = [
{
@@ -110,6 +123,15 @@ const columnsTest = [
},
];
// 用于二维码分享
const showModal = ref(false)
const QRCodeData = ref('')
function shareWithQR(){
let code = activeGID.value+gID2key[activeGID.value].key
QRCodeData.value = location.protocol + "//" + location.hostname + ":" + serverPort + `/?aP=chat&cG=${code}`
showModal.value = true
}
// 凭此code进入群组
const groupCode = ref('')
@@ -136,10 +158,10 @@ const gID2key = {}
const options = {
url: baseUrl,
pingTimeout: 20000,
pongTimeout: 10000,
pingTimeout: 20000,
pongTimeout: 10000,
reconnectTimeout: 3000,
pingMsg: JSON.stringify({type:'heartbeat'})
pingMsg: JSON.stringify({ type: 'heartbeat' })
}
let socket = new WebsocketHeartbeatJs(options);
@@ -150,64 +172,64 @@ let socket = new WebsocketHeartbeatJs(options);
// setInterval(()=>console.log(activeGID.value),1000)
socket.onmessage= (event) => {
socket.onmessage = (event) => {
const msg = JSON.parse(event.data)
dataTest.value.push({from:'server',msg:event.data})
if(msg.type){
dataTest.value.push({ from: 'server', msg: event.data })
if (msg.type) {
let type = msg.type
if(type === 'sMsg'){
if (type === 'sMsg') {
let type1 = msg.type1
if(type1 === 'create'){
gID.value=msg.gID
if (type1 === 'create') {
gID.value = msg.gID
groupCode.value = msg.gID + key.value
joinGroup(groupCode.value)
}else if(type1 === 'joinVerify'){
} else if (type1 === 'joinVerify') {
let gID = msg.gID
let key = gID2key[gID].key
let res = decryptString(key,msg.verify)
console.log(res,key,msg.verify)
let res = decryptString(key, msg.verify)
// console.log(res, key, msg.verify)
// 验证成功,正式加入群组
if(res === 'miaoSpring'){
socket.send(JSON.stringify({type:'join',type1:'success',gID}))
if (res === 'miaoSpring') {
socket.send(JSON.stringify({ type: 'join', type1: 'success', gID }))
joinedGroup.value.push(msg.gID)
Messages.value[msg.gID] = []
if(activeGID.value === null){
activeGID.value = msg.gID
}
// if(activeGID.value === null){
activeGID.value = msg.gID
// }
}
}else if(type1 === 'history'){
} else if (type1 === 'history') {
let gID = msg.gID
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})
dataTest.value.push({from:'decrypt',msg:decryptString(key,m.msg)})
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 })
dataTest.value.push({ from: 'decrypt', msg: decryptString(key, m.msg) })
}
}else if(type1 === 'uuid'){
} else if (type1 === 'uuid') {
uuid.value = msg.uuid
}
}else if(type === 'gMsg'){
} else if (type === 'gMsg') {
let gID = msg.gID
let key = gID2key[gID].key
Messages.value[msg.gID].push({type:msg.type,msg:decryptString(key,msg.msg),from:msg.from,timestamp:msg.timestamp})
Messages.value[msg.gID].push({ type: msg.type, 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)})
dataTest.value.push({ from: 'decrypt', msg: decryptString(key, msg.msg) })
}
}
};
socket.onopen = ()=>{
if(uuid.value){
socket.send(JSON.stringify({type:'uuid',type1:'set',uuid:uuid.value}))
}else{
socket.send(JSON.stringify({type:'uuid',type1:'get'}))
socket.onopen = () => {
if (uuid.value) {
socket.send(JSON.stringify({ type: 'uuid', type1: 'set', uuid: uuid.value }))
} else {
socket.send(JSON.stringify({ type: 'uuid', type1: 'get' }))
}
// console.log(joinedGroup)
let toJoin = [...joinedGroup.value]
joinedGroup.value.length = 0
for(let gID of toJoin){
let code = gID+gID2key[gID].key
for (let gID of toJoin) {
let code = gID + gID2key[gID].key
console.log(code)
joinGroup(code)
}
@@ -217,16 +239,16 @@ socket.onreconnect = (e) => {
console.log('reconnecting...');
}
function createGroup(){
function createGroup() {
let keyt = generateKey(setting)
key.value = keyt
socket.send(JSON.stringify({type:'create',verify:encryptString(keyt,'miaoSpring',setting)}))
socket.send(JSON.stringify({ type: 'create', verify: encryptString(keyt, 'miaoSpring', setting) }))
}
function joinGroup(code){
function joinGroup(code) {
var gID = code.substring(0, 8);
var key = code.substring(8);
if(joinedGroup.value.includes(gID)){
if (joinedGroup.value.includes(gID)) {
return
}
gID2key[gID] = {}
@@ -234,18 +256,42 @@ function joinGroup(code){
joinGroup_Verify(gID)
}
function joinGroup_Verify(gID){
socket.send(JSON.stringify({type:'join',type1:'verify',gID}))
function joinGroup_Verify(gID) {
socket.send(JSON.stringify({ type: 'join', type1: 'verify', gID }))
}
function sendMsg(gID,msg){
function sendMsg(gID, msg) {
let key = gID2key[gID].key
msg = encryptString(key,msg,setting)
socket.send(JSON.stringify({type:'message',msg,gID}))
msg = encryptString(key, msg, setting)
socket.send(JSON.stringify({ type: 'message', 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;
// }
onMounted(()=>{
let aP = getQueryString('aP')
let cG = getQueryString('cG')
if(aP === 'chat' && cG){
groupCode.value = cG
var st = setInterval(()=>{
if(joinedGroup.value.includes(cG.substring(0,8))){
clearInterval(st)
return
}
joinGroup(cG)
},2000)
}
})
</script>
<style>
</style>
<style></style>