feat: init commit

This commit is contained in:
merlin
2025-10-16 15:54:37 +08:00
commit b2bcfdf1a9
52 changed files with 10777 additions and 0 deletions

37
src/store/Online.js Normal file
View File

@@ -0,0 +1,37 @@
import { defineStore } from 'pinia'
import { connectWebSocket, disconnectWebSocket, sendMessage, setIsManualClose } from '@/socket/onlineSocket'
import { messageStore } from './message'
const message = messageStore()
export const onlineSocketStore = defineStore('onlineSocket', {
state: () => ({
isConnected: false,
hasGotMessage: false,
u_id: ''
}),
actions: {
connect(u_id) {
this.u_id = u_id;
if (this.isConnected === true) return
connectWebSocket();
this.isConnected = true;
if (!this.hasGotMessage) {
message.loadMessagesHistory(this.u_id)
this.hasGotMessage = true
}
},
disconnect() {
setIsManualClose(true);
disconnectWebSocket();
this.isConnected = false;
if (this.hasGotMessage) {
message.saveMessagesHistory(this.u_id)
}
},
send(message) {
sendMessage(message);
}
}
})

50
src/store/Voice.js Normal file
View File

@@ -0,0 +1,50 @@
import { connectVoicesocket, disconnectVoicesocket, sendMessage, hangup } from "@/socket/voiceSocket";
import { defineStore } from "pinia";
export const voiceStore = defineStore("voice", {
state: () => ({
isConnected: false
}),
actions: {
connect() {
connectVoicesocket();
this.isConnected = true;
},
disconnect() {
disconnectVoicesocket();
this.isConnected = false;
},
startCall(from, from_name, from_avatar, to) {
if (this.isConnected) {
const message = {
type: "incomingcall",
from: from,
from_name: from_name,
from_avatar: from_avatar,
to: to
}
sendMessage(JSON.stringify(message))
} else {
console.log("voice socket is not connected")
}
},
pickup(from,to){
if (this.isConnected) {
const message ={
type: "pickup",
from: from,
to: to
}
sendMessage(JSON.stringify(message))
} else {
console.log("voice socket is not connected")
}
},
hangup(){
hangup()
}
}
}
)

93
src/store/VoiceTarget.js Normal file
View File

@@ -0,0 +1,93 @@
import { defineStore } from "pinia";
export const onCallStore = defineStore("onCall", {
state: () => ({
target: {
u_id: "",
name: "",
avatar: ""
},
panel: false,
calling: false,
from: false,
status: false,
localstream: {
audioStream: null,
audioElement: null
},
remotestream: {
audioStream: null,
audioElement: null
}
}),
actions: {
setTarget(u_id, u_name, u_avatar) {
this.target = {
u_id: u_id,
name: u_name,
avatar: u_avatar
}
},
panelOn() {
this.panel = true
},
panelOff() {
this.panel = false
},
callingOn() {
this.calling = true
},
callingOff() {
this.calling = false
},
fromOn() {
this.from = true
},
fromOff() {
this.from = false
},
statusOn() {
this.status = true
},
statusOff() {
this.status = false
},
setLocalStream(stream) {
this.localstream.audioStream = stream;
if (this.localstream.audioStream) {
this.localstream.audioElement.srcObject = stream;
}
},
setLocalElement(element) {
this.localstream.audioElement = element;
if (this.localstream.audioStream) {
this.localstream.audioElement.srcObject = this.localstream.audioStream;
}
},
setRemoteStream(stream) {
this.remotestream.audioStream = stream;
if (this.remotestream.audioStream) {
this.remotestream.audioElement.srcObject = stream;
}
},
setRemoteElement(element) {
this.remotestream.audioElement = element;
if (this.remotestream.audioStream) {
this.remotestream.audioElement.srcObject = this.remotestream.audioStream;
}
},
resetStream() {
// 停止本地媒体流
if (this.localstream.audioStream) {
this.localstream.audioStream.getTracks().forEach(track => track.stop());
this.localstream.audioStream = null;
}
// 停止远程媒体流
if (this.remotestream.videoStream) {
this.remotestream.videoStream.getTracks().forEach(track => track.stop());
this.remotestream.videoStream = null;
}
}
}
})

186
src/store/message.js Normal file
View File

@@ -0,0 +1,186 @@
import { defineStore } from "pinia";
import {
saveMessages,
loadMessages,
deleteMessages,
} from "@/functions/historyMessages";
import {
saveGroupMessages,
loadGroupMessages,
deleteGroupMessages,
} from "@/functions/groupHistoryMessage";
import { toRaw } from "vue";
export const messageStore = defineStore("messageStore", {
// 定义一个响应式数组来存储聊天消息
state: () => ({
historymessages: [],
messages: [],
sender: "", //选择的聊天用户id
target: "", //用户自己的id
corresponding: [],
}),
// 定义操作消息的函数
actions: {
// 添加消息到数组
addMessage(message) {
this.messages.push(message);
},
// 清空所有消息
clearMessages() {
this.messages = [];
},
setCorresponding() {
// 过滤出当前聊天中的消息
this.corresponding = this.messages.filter(
(msg) =>
(msg.sender === this.sender && msg.target === this.target) ||
(msg.sender === this.target && msg.target === this.sender)
);
const historymessages = this.historymessages.filter(
(msg) =>
(msg.sender === this.sender && msg.target === this.target) ||
(msg.sender === this.target && msg.target === this.sender)
);
this.corresponding = [...historymessages, ...this.corresponding];
},
// 清楚当前登录的聊天数据,保存到本地
async saveMessagesHistory(u_id) {
const messages = toRaw(this.messages);
await saveMessages(u_id, messages);
},
// 加载本地聊天数据
async loadMessagesHistory(u_id) {
try {
this.historymessages = await loadMessages(u_id);
// 确保历史消息是数组类型
if (!Array.isArray(this.historymessages)) {
console.error("历史消息数据无效:", this.historymessages);
this.historymessages = []; // 如果数据无效,设置为空数组
}
} catch (error) {
console.log("加载历史消息时出错" + error);
}
},
async deleteMessagesHistory(u_id, f_id) {
this.historymessages = this.historymessages.filter(
(msg) =>
!(
(msg.sender === f_id && msg.target === u_id) ||
(msg.sender === u_id && msg.target === f_id)
)
);
this.messages = this.messages.filter(
(msg) =>
!(
(msg.sender === f_id && msg.target === u_id) ||
(msg.sender === u_id && msg.target === f_id)
)
);
if (f_id === this.sender) {
console.log("清除对应聊天数据展示栈");
this.corresponding = [];
}
const messages = JSON.parse(JSON.stringify(toRaw(this.historymessages)));
try {
await deleteMessages(u_id, messages);
} catch (error) {
console.log("删除历史消息时出错" + error);
}
},
},
// 定义计算属性(可选)
getters: {
// 获取消息数量
messageCount: (state) => state.messages.length,
},
});
export const messageSignStore = defineStore("messageSignStore", {
state: () => ({
sign: [],
}),
actions: {
addSign(sign) {
// 检查是否已经存在相同的值
const exists = this.sign.some(
(item) =>
item.sender === sign.sender && item.sender_name === sign.sender_name
);
if (!exists) {
this.sign.push(sign);
} else {
console.warn(`Sign "${sign}" already exists and will not be added.`);
}
},
clearSign() {
this.sign = [];
},
removeSign(sign) {
// 找到相同值的索引
const index = this.sign.indexOf(sign);
if (index !== -1) {
// 如果存在,删除该值
this.sign.splice(index, 1);
} else {
console.warn(`Sign "${sign}" not found.`);
}
},
},
});
export const groupMessageStore = defineStore("groupMessageStore", {
state: () => ({
g_id: "",
historymessages: [],
messages: [],
corresponding: [],
}),
actions: {
addMessage(message) {
this.messages.push(message);
},
clearMessages() {
this.messages = [];
},
async initMessages() {
this.historymessages = [...this.historymessages, ...this.messages];
this.messages = [];
},
async getHistoryMessages(u_id, g_id) {
this.g_id = g_id;
const key = `${u_id}-${g_id}`;
try {
this.historymessages = await loadGroupMessages(key);
console.log("缓存到历史消息:");
console.log(this.historymessages);
// 确保历史消息是数组类型
if (!Array.isArray(this.historymessages)) {
console.error("历史消息数据无效:", this.historymessages);
this.historymessages = []; // 如果数据无效,设置为空数组
}
} catch (error) {
console.log("加载历史消息时出错" + error);
}
},
async saveMessagesHistory(u_id, g_id) {
const key = `${u_id}-${g_id}`;
console.log(key);
const messages = toRaw(this.messages);
this.messages = [];
this.historymessages = [];
await saveGroupMessages(key, messages);
},
async deleteMessagesHistory(u_id, g_id) {
const key = `${u_id}-${g_id}`;
this.historymessages = [];
this.messages = [];
await deleteGroupMessages(key, []);
},
},
});

15
src/store/room.js Normal file
View File

@@ -0,0 +1,15 @@
import { ref } from "vue";
import { defineStore } from "pinia";
export const roomStore = defineStore("room",{
state: () => ({
r_id: '',
r_name: '',
r_avatar: '',
inroomTag: '',
currentURL: '',
}),
actions:{
}
})

50
src/store/store.js Normal file
View File

@@ -0,0 +1,50 @@
import { ref, reactive } from "vue";
import { defineStore } from "pinia";
export const userInfoStore = defineStore(
"userInfo",
() => {
const token = ref(null);
const user = reactive({
u_id: "",
u_name: "",
u_avatar: "@/assets/defaultavatar.jpg",
u_account: "",
u_introduction: "",
});
const clearUserInfo = () => {
// 清除 token
token.value = null;
// 清除 user 对象中的所有属性
user.u_id = "";
user.u_name = "";
user.u_avatar = "@/assets/defaultavatar.jpg"; // 重置为默认头像路径
user.u_account = "";
user.u_introduction = "";
};
return {
token,
user,
clearUserInfo,
};
},
{
persist: {
key: "userInfo",
storage: localStorage,
paths: ["token", "user"],
},
}
);
export const messagePointStore = defineStore("hasNewMessage", () => {
const hasNewMessage = ref(false);
return {
hasNewMessage,
};
});