@ -2,60 +2,62 @@ import { defineStore } from 'pinia'
import emojiList from "@/assets/emoji.json"
import { ref , toRaw , inject } from "vue" ;
import { db } from './db'
import { System , dirname } from "@/system" ;
import { System , dirname } from "@/system" ;
import { getSystemConfig } from "@/system/config" ;
import { isBase64 , base64ToBuffer } from "@/util/file" ;
import { notifyError , notifySuccess } from "@/util/msg" ;
export const useLocalChatStore = defineStore ( 'localChatStore' , ( ) = > {
const config = getSystemConfig ( ) ;
const sys = inject < System > ( "system" ) ;
const userList :any = ref ( [ ] )
const msgList :any = ref ( [ ] )
const contentList :any = ref ( [ ] )
const hostInfo :any = ref ( { } )
const userList : any = ref ( [ ] )
const msgList : any = ref ( [ ] )
const contentList : any = ref ( [ ] )
const OutUserList : any = ref ( [ ] )
const hostInfo : any = ref ( { } )
const showChooseFile = ref ( false )
const currentPage = ref ( 1 )
const pageSize = ref ( 50 )
const navList = ref ( [
{ index : 1 , lable : "消息列表" , icon : "ChatDotRound" , type : "success" } ,
{ index : 1 , lable : "消息列表" , icon : "ChatDotRound" , type : "success" } ,
{ index : 2 , lable : "用户列表" , icon : "UserFilled" , type : "info" } ,
] )
const navId = ref ( 1 )
const sendInfo = ref ( "" )
const chatTargetId = ref ( 0 )
const chatTargetIp = ref ( "" )
const showAddUser = ref ( false )
const handleSelect = ( key : number ) = > {
navId . value = key ;
} ;
const setChatId = async ( ip : string ) = > {
const setChatId = async ( ip : string ) = > {
//console.log(ip)
//chatTargetId.value = id
chatTargetIp . value = ip
const data = await db . get ( "chatuser" , { ip : ip } )
if ( ! data ) return ;
const data = await db . get ( "chatuser" , { ip : ip } )
if ( ! data ) return ;
chatTargetId . value = data . id
clearContentList ( data . id )
currentPage . value = 1
await getMsgList ( )
}
const initContentList = async ( ) = > {
const list :any = { }
const list : any = { }
const msgAll = await db . getAll ( 'chatmsg' )
msgAll . forEach ( ( d : any ) = > {
if ( ! d . isMe ) {
if ( ! list [ d . targetIp ] ) {
msgAll . forEach ( ( d : any ) = > {
if ( ! d . isMe ) {
if ( ! list [ d . targetIp ] ) {
list [ d . targetIp ] = [ ]
}
list [ d . targetIp ] . push ( d )
}
} )
const res = [ ]
for ( const p in list ) {
for ( const p in list ) {
const chatArr = list [ p ]
let readNum = 0
chatArr . forEach ( ( d :any ) = > {
if ( ! d . isRead ) {
chatArr . forEach ( ( d : any ) = > {
if ( ! d . isRead ) {
readNum ++
}
} )
@ -65,23 +67,23 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
}
contentList . value = res . sort ( ( a , b ) = > b . createdAt - a . createdAt ) ;
}
const clearContentList = ( targetId :number ) = > {
contentList . value . forEach ( ( d : any ) = > {
if ( d . targetId === targetId ) {
const clearContentList = ( targetId : number ) = > {
contentList . value . forEach ( ( d : any ) = > {
if ( d . targetId === targetId ) {
d . readNum = 0
}
} )
}
const clearMsg = async ( ) = > {
if ( chatTargetIp . value === '' ) return
await db . deleteByField ( 'chatmsg' , 'targetIp' , chatTargetIp . value )
await db . deleteByField ( 'chatmsg' , 'targetIp' , chatTargetIp . value )
msgList . value = [ ]
}
const updateContentList = async ( msg :any ) = > {
if ( msg . isMe ) return ;
const has = contentList . value . find ( ( d :any ) = > d . targetIp === msg . targetIp )
if ( has ) {
const updateContentList = async ( msg : any ) = > {
if ( msg . isMe ) return ;
const has = contentList . value . find ( ( d : any ) = > d . targetIp === msg . targetIp )
if ( has ) {
contentList . value . forEach ( ( d : any , index : number ) = > {
if ( d . targetIp === msg . targetIp ) {
if ( ! msg . isRead ) {
@ -94,10 +96,10 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
}
} ) ;
//console.log(contentList.value)
} else {
if ( msg . isRead ) {
} else {
if ( msg . isRead ) {
msg . readNum = 0
} else {
} else {
msg . readNum = 1
}
contentList . value . unshift ( msg )
@ -105,14 +107,14 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
}
contentList . value = contentList . value . sort ( ( a : any , b : any ) = > b . createdAt - a . createdAt )
}
const init = async ( ) = > {
const init = async ( ) = > {
await getUserList ( )
await initUserList ( )
await initContentList ( )
}
const initUserList = async ( ) = > {
if ( userList . value . length > 0 ) {
const updates : any = [ ]
const initUserList = async ( ) = > {
if ( userList . value . length > 0 ) {
const updates : any = [ ]
userList . value . forEach ( ( d : any ) = > {
if ( d . isOnline ) {
updates . push ( {
@ -131,9 +133,7 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
userList . value = [ ]
}
const getMsgList = async ( ) = > {
if ( chatTargetId . value < 1 ) return ;
//msgList.value = await db.getByField('chatmsg', 'targetId', chatTargetId.value)
//msgList.value = await db.pageSearch('chatmsg', currentPage.value, pageSize.value, { targetId: chatTargetId.value })
if ( chatTargetId . value < 1 ) return ;
const offset = ( currentPage . value - 1 ) * pageSize . value
const list = await db . table ( 'chatmsg' )
. where ( { targetIp : chatTargetIp.value } )
@ -141,10 +141,10 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
. offset ( offset )
. limit ( pageSize . value )
. toArray ( ) ;
list . sort ( ( a :any , b :any ) = > a . id > b . id )
list . sort ( ( a : any , b : any ) = > a . id > b . id )
msgList . value = list ;
}
const moreMsgList = async ( ) = > {
const moreMsgList = async ( ) = > {
if ( chatTargetId . value < 1 ) return ;
//const list = await db.pageSearch('chatmsg', currentPage.value + 1, pageSize.value, { targetId: chatTargetId.value })
const offset = currentPage . value * pageSize . value
@ -154,73 +154,77 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
. offset ( offset )
. limit ( pageSize . value )
. toArray ( ) ;
if ( list && list . length > 0 ) {
if ( list && list . length > 0 ) {
list . sort ( ( a : any , b : any ) = > a . id > b . id )
currentPage . value = currentPage . value + 1
msgList . value = [ . . . list , . . . msgList . value ] ;
}
}
const getUserList = async ( ) = > {
const list = await db . getAll ( 'chatuser' )
list . sort ( ( a : any , b : any ) = > a . updatedAt > b . updatedAt )
userList . value = list
const listAll = await db . getAll ( 'chatuser' )
const list = [ . . . listAll , . . . OutUserList . value ]
let uniqueIpMap = new Map < string , any > ( ) ;
// 遍历 list 并添加 IP 地址到 Map 中
list . forEach ( ( item : any ) = > {
uniqueIpMap . set ( item . ip , item ) ;
} ) ;
// 将 Map 转换回数组
const uniqueIpList : any = Array . from ( uniqueIpMap . values ( ) ) ;
uniqueIpList . sort ( ( a : any , b : any ) = > a . updatedAt > b . updatedAt )
userList . value = uniqueIpList
}
const setUserList = async ( data :any ) = > {
const setUserList = async ( data : any ) = > {
//console.log(data)
if ( data . length < 1 ) {
if ( data . length < 1 ) {
return
}
hostInfo . value = data [ 0 ]
data . shift ( )
const ips :any = [ ]
userList . value . forEach ( ( d : any ) = > {
ips . push ( d . ip )
} ) ;
const has :any = [ ]
const nothas :any = [ ]
data . forEach ( ( d :any ) = > {
if ( ips . includes ( d . ip ) ) {
has . push ( d . ip )
} else {
nothas . push ( d )
const existingIps = new Set ( userList . value . map ( ( d : any ) = > d . ip ) ) ;
const updates : any [ ] = [ ] ;
const newEntries : any [ ] = [ ] ;
data . forEach ( ( d : any ) = > {
if ( existingIps . has ( d . ip ) ) {
updates . push ( {
key : d.id ,
changes : {
isOnline : true ,
updatedAt : Date.now ( )
}
} ) ;
} else {
newEntries . push ( {
ip : d.ip ,
isOnline : true ,
username : d.hostname ,
createdAt : Date.now ( ) ,
updatedAt : Date.now ( )
} ) ;
}
} )
if ( has . length > 0 ) {
const updates :any = [ ]
userList . value . forEach ( ( d : any ) = > {
if ( has . includes ( d . ip ) ) {
updates . push ( {
key : d.id ,
changes : {
isOnline : true ,
updatedAt :Date.now ( )
}
} )
}
} ) ;
await db . table ( 'chatuser' ) . bulkUpdate ( updates )
} ) ;
if ( updates . length > 0 ) {
await db . table ( 'chatuser' ) . bulkUpdate ( updates ) ;
}
if ( nothas . length > 0 ) {
nothas . forEach ( ( d :any ) = > {
d . isOnline = true
d . username = data . hostname
d . createdAt = Date . now ( )
d . updatedAt = Date . now ( )
} )
await db . table ( 'chatuser' ) . bulkAdd ( nothas )
if ( newEntries . length > 0 ) {
await db . table ( 'chatuser' ) . bulkAdd ( newEntries ) ;
}
await getUserList ( )
}
const addFile = async ( data :any ) = > {
const targetUser :any = await getTargetUser ( data )
const files :any = [ ]
data . fileList . forEach ( ( d :any ) = > {
const addFile = async ( data : any ) = > {
const targetUser : any = await getTargetUser ( data )
const files : any = [ ]
data . fileList . forEach ( ( d : any ) = > {
d . save_path = d . save_path . replace ( /\\/g , "/" ) ;
files . push ( {
name : d.name ,
path : d.save_path ,
ext : d.save_path.split ( '.' ) . pop ( ) ,
name : d.name ,
path : d.save_path ,
ext : d.save_path.split ( '.' ) . pop ( ) ,
content : d.content
} )
} )
@ -240,23 +244,23 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
saveMsg . isRead = true
msgList . value . push ( saveMsg )
}
console . log ( saveMsg )
//console.log(saveMsg)
await db . addOne ( 'chatmsg' , saveMsg )
//await getMsgList()
await updateContentList ( saveMsg )
if ( config . storeType === 'browser' ) {
await storeFile ( files )
}
handleSelect ( 1 )
}
const storeFile = async ( fileList : any ) = > {
const storeFile = async ( fileList : any ) = > {
if ( fileList . length < 1 ) return ;
console . log ( fileList )
for ( let i = 0 ; i < fileList . length ; i ++ ) {
let content = fileList [ i ] . content
if ( typeof content === 'string' ) {
if ( isBase64 ( content ) ) {
if ( typeof content === 'string' ) {
if ( isBase64 ( content ) ) {
content = base64ToBuffer ( content ) ;
}
const path = dirname ( fileList [ i ] . path )
@ -266,26 +270,26 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
}
}
}
const getTargetUser = async ( data :any ) = > {
let targetUser :any = userList . value . find ( ( d : any ) = > d . ip === data . senderInfo . ip )
if ( ! targetUser ) {
const getTargetUser = async ( data : any ) = > {
let targetUser : any = userList . value . find ( ( d : any ) = > d . ip === data . senderInfo . ip )
if ( ! targetUser ) {
targetUser = {
isOnline : true ,
ip :data.senderInfo.ip ,
isOnline : true ,
ip : data.senderInfo.ip ,
hostname : data.senderInfo.hostname ,
username : data.senderInfo.hostname ,
createdAt : Date.now ( ) ,
updatedAt : Date.now ( )
username : data.senderInfo.hostname ,
createdAt : Date.now ( ) ,
updatedAt : Date.now ( )
}
targetUser . id = await db . addOne ( "chatuser" , targetUser )
targetUser . id = await db . addOne ( "chatuser" , targetUser )
userList . value . unshift ( targetUser )
}
return targetUser
}
const addText = async ( data :any ) = > {
const targetUser :any = await getTargetUser ( data )
const addText = async ( data : any ) = > {
const targetUser : any = await getTargetUser ( data )
const saveMsg :any = {
const saveMsg : any = {
type : 'text' ,
targetId : targetUser.id ,
targetIp : targetUser.ip ,
@ -296,7 +300,7 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
isRead : false ,
status : 'reciped'
}
if ( targetUser . id === chatTargetId . value ) {
if ( targetUser . id === chatTargetId . value ) {
saveMsg . readAt = Date . now ( )
saveMsg . isRead = true
msgList . value . push ( saveMsg )
@ -304,24 +308,24 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
//console.log(saveMsg)
await db . addOne ( 'chatmsg' , saveMsg )
//await getMsgList()
await updateContentList ( saveMsg )
handleSelect ( 1 )
}
const sendMsg = async ( ) = > {
if ( chatTargetId . value < 1 ) {
if ( chatTargetId . value < 1 ) {
return
}
const saveMsg :any = {
type : 'text' ,
targetId : chatTargetId.value ,
const saveMsg : any = {
type : 'text' ,
targetId : chatTargetId.value ,
targetIp : chatTargetIp.value ,
content : sendInfo.value.trim ( ) ,
senderInfo : toRaw ( hostInfo . value ) ,
createdAt :Date.now ( ) ,
isMe :true ,
isRead :false ,
status : 'sending'
createdAt : Date.now ( ) ,
isMe : true ,
isRead : false ,
status : 'sending'
}
//console.log(saveMsg)
const msgId = await db . addOne ( 'chatmsg' , saveMsg )
@ -329,7 +333,7 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
msgList . value . push ( saveMsg )
const targetUser = userList . value . find ( ( d : any ) = > d . id === chatTargetId . value )
//console.log(targetUser)
if ( targetUser . isOnline ) {
if ( targetUser . isOnline ) {
const postUrl = ` http:// ${ targetUser . ip } :56780/localchat/message `
const completion = await fetch ( postUrl , {
method : "POST" ,
@ -337,7 +341,7 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
} )
if ( ! completion . ok ) {
console . log ( completion )
} else {
} else {
saveMsg . isRead = true
saveMsg . status = 'sended'
saveMsg . readAt = Date . now ( )
@ -347,10 +351,10 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
}
sendInfo . value = ""
await updateContentList ( saveMsg )
}
//上传文件资源
async function uploadFile ( paths :any ) {
async function uploadFile ( paths : any ) {
if ( chatTargetId . value < 1 ) {
return
}
@ -365,12 +369,12 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
}
//console.log(paths)
const formData = new FormData ( ) ;
const errstr :any = [ ]
const files :any = [ ]
const errstr : any = [ ]
const files : any = [ ]
for ( let i = 0 ; i < paths . length ; i ++ ) {
const content = await sys ? . fs . readFile ( paths [ i ] ) ;
let blobContent ;
if ( ! content || content == '' ) {
if ( ! content || content == '' ) {
errstr . push ( paths [ i ] + " is empty" )
continue
}
@ -393,13 +397,13 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
files . push ( {
name : fileName ,
path : paths [ i ] ,
ext : fileName.split ( "." ) . pop ( ) ,
ext : fileName.split ( "." ) . pop ( ) ,
} )
//files.push(blobContent);
formData . append ( ` files ` , blobContent , fileName ) ;
}
if ( errstr . length > 0 ) {
errstr . forEach ( ( d :any ) = > {
if ( errstr . length > 0 ) {
errstr . forEach ( ( d : any ) = > {
notifyError ( d ) ;
} )
return
@ -429,17 +433,52 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
isRead : true ,
status : 'reciped'
}
console . log ( saveMsg )
//console.log(saveMsg)
await db . addOne ( 'chatmsg' , saveMsg )
msgList . value . push ( saveMsg )
notifySuccess ( "upload success!" ) ;
}
return {
userList ,
navList ,
function isValidIP ( ip : string ) : boolean {
// 正则表达式用于匹配 IPv4 地址
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ ;
// 正则表达式用于匹配 IPv6 地址
const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4})$/ ;
// 验证 IP 地址
return ipv4Regex . test ( ip ) || ipv6Regex . test ( ip ) ;
}
async function addUser ( ip : string ) {
if ( ! isValidIP ( ip ) ) {
notifyError ( "请输入正确的IP地址" ) ;
return
}
const postUrl = ` http:// ${ ip } :56780/localchat/check `
const completion = await fetch ( postUrl )
if ( ! completion . ok ) {
notifyError ( '用户不在线' )
} else {
const res = await completion . json ( )
const data = res . data
data . createdAt = Date . now ( )
data . updatedAt = Date . now ( )
data . isOnline = true
data . username = data . hostname
if ( ! OutUserList . value . some ( ( item : any ) = > item . ip === data . ip ) ) {
OutUserList . value . push ( data ) ;
await getUserList ( )
}
}
}
return {
userList ,
navList ,
sendInfo ,
navId ,
navId ,
chatTargetId ,
chatTargetIp ,
msgList ,
@ -448,6 +487,8 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
emojiList ,
showChooseFile ,
pageSize ,
showAddUser ,
OutUserList ,
init ,
setUserList ,
getUserList ,
@ -459,6 +500,19 @@ export const useLocalChatStore = defineStore('localChatStore', () => {
uploadFile ,
moreMsgList ,
refreshUserList ,
clearMsg
}
clearMsg ,
addUser
}
} , {
persist : {
enabled : true ,
strategies : [
{
storage : localStorage ,
paths : [
"OutUserList"
]
} , // name 字段用localstorage存储
] ,
}
} )