From 7d9e9165e786fe1758a1a58ea6a6f33079f3c2f0 Mon Sep 17 00:00:00 2001 From: godo Date: Tue, 10 Sep 2024 13:50:50 +0800 Subject: [PATCH] change files --- .../src/components/localchat/ChatContent.vue | 8 +- frontend/src/stores/localchat.ts | 73 ++-- godo/localchat/file.go | 389 +++++++++--------- godo/localchat/server.go | 8 +- 4 files changed, 230 insertions(+), 248 deletions(-) diff --git a/frontend/src/components/localchat/ChatContent.vue b/frontend/src/components/localchat/ChatContent.vue index 168aafb..97cd7eb 100644 --- a/frontend/src/components/localchat/ChatContent.vue +++ b/frontend/src/components/localchat/ChatContent.vue @@ -111,7 +111,7 @@ async function scroll({ scrollTop }: { scrollTop: number }) { 接收中 - + 已接收 @@ -129,10 +129,10 @@ async function scroll({ scrollTop }: { scrollTop: number }) { diff --git a/frontend/src/stores/localchat.ts b/frontend/src/stores/localchat.ts index aa55ba1..3424429 100644 --- a/frontend/src/stores/localchat.ts +++ b/frontend/src/stores/localchat.ts @@ -57,7 +57,7 @@ export const useLocalChatStore = defineStore('localChatStore', () => { else if (msg.type === "fileSending"){ addText(msg) } - else if( msg.type === "fileCannel") { + else if( msg.type === "fileCannel" || msg.type === "fileAccessed") { changeMsg(msg) } }) @@ -261,42 +261,6 @@ export const useLocalChatStore = defineStore('localChatStore', () => { } await getUserList() } - 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(), - content: d.content - }) - }) - const saveMsg: any = { - type: 'file', - targetId: targetUser.id, - targetIp: targetUser.ip, - content: files, - reciperInfo: data.senderInfo, - createdAt: Date.now(), - isMe: false, - isRead: false, - status: 'reciped' - } - if (targetUser.id === chatTargetId.value) { - saveMsg.readAt = Date.now() - saveMsg.isRead = true - msgList.value.push(saveMsg) - } - //console.log(saveMsg) - await db.addOne('chatmsg', saveMsg) - //await getMsgList() - - await updateContentList(saveMsg) - - handleSelect(1) - } const getTargetUser = async (data: any) => { let targetUser: any = userList.value.find((d: any) => d.ip === data.ip) @@ -432,21 +396,42 @@ export const useLocalChatStore = defineStore('localChatStore', () => { notifyError("确认失败!") } else { item.content.status = 'cannel' - await db.update('chatmsg', item.id, item) + console.log(item) + await db.update('chatmsg', item.id, toRaw(item)) await updateContentList(item) notifySuccess("确认成功!") } } async function changeMsg(msg:any){ - console.log(msg) + //console.log(msg) const msgId = msg.message const item = await db.getOne('chatmsg', msgId) - item.content.status = 'cannel' + //console.log(item) + item.content.status = msg.type await db.update('chatmsg', item.id, item) - await updateContentList(item) + await getMsgList() } async function accessFile(item:any){ - + const messages = { + type: 'accessFile', + message: item.content, + ip: item.targetIp + } + const postUrl = `${config.apiUrl}/localchat/accessfile` + const coms = await fetch(postUrl, { + method: "POST", + body: JSON.stringify(messages), + }) + if (!coms.ok) { + //console.log(coms) + notifyError("确认失败!") + } else { + item.content.status = 'accessing' + //console.log(item) + await db.update('chatmsg', item.id, toRaw(item)) + await getMsgList() + //notifySuccess("确认成功!") + } } return { @@ -463,7 +448,6 @@ export const useLocalChatStore = defineStore('localChatStore', () => { showChooseFile, pageSize, showAddUser, - //OutUserList, init, setUserList, getUserList, @@ -471,12 +455,9 @@ export const useLocalChatStore = defineStore('localChatStore', () => { setChatId, sendMsg, addText, - addFile, - //uploadFile, moreMsgList, refreshUserList, clearMsg, - //addUser, handlerMessage, cannelFile, accessFile diff --git a/godo/localchat/file.go b/godo/localchat/file.go index fcabf96..ad9b4e8 100644 --- a/godo/localchat/file.go +++ b/godo/localchat/file.go @@ -24,19 +24,10 @@ package localchat import ( - "encoding/binary" "encoding/json" - "fmt" "godo/libs" - "io" - "log" - "net" "net/http" "os" - "path/filepath" - "strconv" - "strings" - "sync" "time" ) @@ -108,213 +99,223 @@ func HandlerAccessFile(w http.ResponseWriter, r *http.Request) { msg.Time = time.Now() msg.Type = "fileAccessed" SendToIP(msg) - libs.SuccessMsg(w, nil, "请求文件发送成功") -} -func HandlerSendFile(msg UdpMessage) { - toIp := msg.IP - hostname, err := os.Hostname() + err = downloadFiles(msg) if err != nil { - log.Printf("HandleMessage error: %v", err) - return - } - msg.Hostname = hostname - msg.Time = time.Now() - msg.Type = "file" - basePath, err := libs.GetOsDir() - if err != nil { - log.Printf("GetOsDir error: %v", err) - return - } - paths, ok := msg.Message.([]string) - if !ok { - log.Printf("invalid message type") + libs.ErrorMsg(w, "HandleMessage error") return } - for _, p := range paths { - filePath := filepath.Join(basePath, p) - // 处理单个文件或整个文件夹 - if fileInfo, err := os.Stat(filePath); err == nil { - if fileInfo.IsDir() { - handleDirectory(filePath, toIp, msg) - } else { - handleFile(filePath, toIp, msg) - } - } else { - continue - } - } - msg.Type = "fileSended" - msg.Message = "" - msg.Time = time.Now() - SendToIP(msg) + libs.SuccessMsg(w, msg.Message, "接收文件中") } +func downloadFiles(msg UdpMessage) error { -func handleFile(filePath string, toIp string, message UdpMessage) { - // 打开文件 - file, err := os.Open(filePath) - if err != nil { - log.Fatalf("Failed to open file: %v", err) - } - defer file.Close() + return nil +} - // 获取文件大小 - fileInfo, err := file.Stat() - if err != nil { - log.Fatalf("Failed to get file info: %v", err) - } - fileSize := fileInfo.Size() +// func HandlerSendFile(msg UdpMessage) { +// toIp := msg.IP +// hostname, err := os.Hostname() +// if err != nil { +// log.Printf("HandleMessage error: %v", err) +// return +// } +// msg.Hostname = hostname +// msg.Time = time.Now() +// msg.Type = "file" +// basePath, err := libs.GetOsDir() +// if err != nil { +// log.Printf("GetOsDir error: %v", err) +// return +// } +// paths, ok := msg.Message.([]string) +// if !ok { +// log.Printf("invalid message type") +// return +// } +// for _, p := range paths { +// filePath := filepath.Join(basePath, p) +// // 处理单个文件或整个文件夹 +// if fileInfo, err := os.Stat(filePath); err == nil { +// if fileInfo.IsDir() { +// handleDirectory(filePath, toIp, msg) +// } else { +// handleFile(filePath, toIp, msg) +// } +// } else { +// continue +// } +// } +// msg.Type = "fileSended" +// msg.Message = "" +// msg.Time = time.Now() +// SendToIP(msg) +// } - // 计算需要发送的数据包数量 - numChunks := fileSize / GlobalfileSize - if fileSize%GlobalfileSize != 0 { - numChunks++ - } - // 发送文件 - SendFile(file, int(numChunks), toIp, fileSize, message) -} +// func handleFile(filePath string, toIp string, message UdpMessage) { +// // 打开文件 +// file, err := os.Open(filePath) +// if err != nil { +// log.Fatalf("Failed to open file: %v", err) +// } +// defer file.Close() -func handleDirectory(dirPath string, toIp string, message UdpMessage) { - err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if !info.IsDir() { - handleFile(path, toIp, message) - } - return nil - }) - if err != nil { - log.Fatalf("Failed to walk directory: %v", err) - } -} -func SendFile(file *os.File, numChunks int, toIp string, fSize int64, message UdpMessage) { - var wg sync.WaitGroup +// // 获取文件大小 +// fileInfo, err := file.Stat() +// if err != nil { +// log.Fatalf("Failed to get file info: %v", err) +// } +// fileSize := fileInfo.Size() - // 逐块读取文件并发送 - for i := 0; i < numChunks; i++ { - wg.Add(1) - go func(index int) { - defer wg.Done() - idStr := message.Type + "@" + message.Hostname + "@" + filepath.Base(file.Name()) + "@" + fmt.Sprintf("%d", fSize) + "@" - chunkData := make([]byte, GlobalfileSize) - n, err := file.Read(chunkData[:]) - if err != nil && err != io.EOF { - log.Fatalf("Failed to read file chunk: %v", err) - } - sendBinaryData(idStr, chunkData[:n], toIp) - fmt.Printf("发送文件块 %d 到 %s 成功\n", index, toIp) - }(i) - } +// // 计算需要发送的数据包数量 +// numChunks := fileSize / GlobalfileSize +// if fileSize%GlobalfileSize != 0 { +// numChunks++ +// } +// // 发送文件 +// SendFile(file, int(numChunks), toIp, fileSize, message) +// } - wg.Wait() -} -func sendBinaryData(idStr string, data []byte, toIp string) { - port := "56780" - addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%s", toIp, port)) - if err != nil { - log.Fatalf("Failed to resolve UDP address: %v", err) - } +// func handleDirectory(dirPath string, toIp string, message UdpMessage) { +// err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { +// if err != nil { +// return err +// } +// if !info.IsDir() { +// handleFile(path, toIp, message) +// } +// return nil +// }) +// if err != nil { +// log.Fatalf("Failed to walk directory: %v", err) +// } +// } +// func SendFile(file *os.File, numChunks int, toIp string, fSize int64, message UdpMessage) { +// var wg sync.WaitGroup - conn, err := net.DialUDP("udp4", nil, addr) - if err != nil { - log.Fatalf("Failed to dial UDP address: %v", err) - } - defer conn.Close() +// // 逐块读取文件并发送 +// for i := 0; i < numChunks; i++ { +// wg.Add(1) +// go func(index int) { +// defer wg.Done() +// idStr := message.Type + "@" + message.Hostname + "@" + filepath.Base(file.Name()) + "@" + fmt.Sprintf("%d", fSize) + "@" +// chunkData := make([]byte, GlobalfileSize) +// n, err := file.Read(chunkData[:]) +// if err != nil && err != io.EOF { +// log.Fatalf("Failed to read file chunk: %v", err) +// } +// sendBinaryData(idStr, chunkData[:n], toIp) +// fmt.Printf("发送文件块 %d 到 %s 成功\n", index, toIp) +// }(i) +// } - // 添加长度前缀 - identifier := []byte(idStr) - lengthPrefix := make([]byte, 4) - binary.BigEndian.PutUint32(lengthPrefix, uint32(len(data))) +// wg.Wait() +// } +// func sendBinaryData(idStr string, data []byte, toIp string) { +// port := "56780" +// addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%s", toIp, port)) +// if err != nil { +// log.Fatalf("Failed to resolve UDP address: %v", err) +// } - // 发送长度前缀和数据 - _, err = conn.Write(append(append(identifier, lengthPrefix...), data...)) - if err != nil { - log.Printf("Failed to write data: %v", err) - } -} +// conn, err := net.DialUDP("udp4", nil, addr) +// if err != nil { +// log.Fatalf("Failed to dial UDP address: %v", err) +// } +// defer conn.Close() -var fileLocks = make(map[string]*sync.Mutex) +// // 添加长度前缀 +// identifier := []byte(idStr) +// lengthPrefix := make([]byte, 4) +// binary.BigEndian.PutUint32(lengthPrefix, uint32(len(data))) -func ReceiveFiles(parts []string) (string, error) { - fileName := parts[2] - fileSize, err := strconv.ParseInt(parts[3], 10, 64) - if err != nil { - return "", fmt.Errorf("failed to parse file size: %v", err) - } +// // 发送长度前缀和数据 +// _, err = conn.Write(append(append(identifier, lengthPrefix...), data...)) +// if err != nil { +// log.Printf("Failed to write data: %v", err) +// } +// } - // 创建接收文件的目录 - baseDir, err := libs.GetOsDir() - if err != nil { - log.Printf("Failed to get OS directory: %v", err) - return "", fmt.Errorf("failed to get OS directory") - } +// var fileLocks = make(map[string]*sync.Mutex) - resPath := filepath.Join("C", "Users", "Reciv", time.Now().Format("2006-01-02")) - receiveDir := filepath.Join(baseDir, resPath) - if !libs.PathExists(receiveDir) { - err := os.MkdirAll(receiveDir, 0755) - if err != nil { - log.Printf("Failed to create receive directory: %v", err) - return "", fmt.Errorf("failed to create receive directory") - } - } +// func ReceiveFiles(parts []string) (string, error) { +// fileName := parts[2] +// fileSize, err := strconv.ParseInt(parts[3], 10, 64) +// if err != nil { +// return "", fmt.Errorf("failed to parse file size: %v", err) +// } - // 确定文件路径 - filePath := filepath.Join(receiveDir, fileName) +// // 创建接收文件的目录 +// baseDir, err := libs.GetOsDir() +// if err != nil { +// log.Printf("Failed to get OS directory: %v", err) +// return "", fmt.Errorf("failed to get OS directory") +// } - // 如果文件不存在,则创建新文件 - if _, err := os.Stat(filePath); os.IsNotExist(err) { - file, err := os.Create(filePath) - if err != nil { - log.Printf("Failed to create file: %v", err) - return "", fmt.Errorf("failed to create file") - } - defer file.Close() - } +// resPath := filepath.Join("C", "Users", "Reciv", time.Now().Format("2006-01-02")) +// receiveDir := filepath.Join(baseDir, resPath) +// if !libs.PathExists(receiveDir) { +// err := os.MkdirAll(receiveDir, 0755) +// if err != nil { +// log.Printf("Failed to create receive directory: %v", err) +// return "", fmt.Errorf("failed to create receive directory") +// } +// } - // 锁定文件 - lock, ok := fileLocks[fileName] - if !ok { - lock = &sync.Mutex{} - fileLocks[fileName] = lock - } - lock.Lock() - defer lock.Unlock() +// // 确定文件路径 +// filePath := filepath.Join(receiveDir, fileName) - file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Printf("Failed to open file: %v", err) - return "", fmt.Errorf("failed to open file") - } - defer file.Close() +// // 如果文件不存在,则创建新文件 +// if _, err := os.Stat(filePath); os.IsNotExist(err) { +// file, err := os.Create(filePath) +// if err != nil { +// log.Printf("Failed to create file: %v", err) +// return "", fmt.Errorf("failed to create file") +// } +// defer file.Close() +// } - // 提取实际数据 - data := strings.Join(parts[4:], "") - if len(data) < 1 { - return "", fmt.Errorf("empty data") - } +// // 锁定文件 +// lock, ok := fileLocks[fileName] +// if !ok { +// lock = &sync.Mutex{} +// fileLocks[fileName] = lock +// } +// lock.Lock() +// defer lock.Unlock() - n, err := file.Write([]byte(data)) - if err != nil { - log.Printf("Failed to write data to file: %v", err) - return "", fmt.Errorf("failed to write data to file") - } - if n != len(data) { - log.Printf("Incomplete write: wrote %d bytes, expected %d bytes", n, len(data)) - return "", fmt.Errorf("incomplete write") - } +// file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +// if err != nil { +// log.Printf("Failed to open file: %v", err) +// return "", fmt.Errorf("failed to open file") +// } +// defer file.Close() - fileInfo, err := os.Stat(filePath) - if err != nil { - log.Printf("Failed to stat file: %v", err) - return "", fmt.Errorf("failed to stat file") - } +// // 提取实际数据 +// data := strings.Join(parts[4:], "") +// if len(data) < 1 { +// return "", fmt.Errorf("empty data") +// } - if fileInfo.Size() == fileSize { - fmt.Println("文件接收完成且大小一致") - return filePath, nil - } else { - fmt.Printf("文件大小不一致,发送大小为%d,接收大小为%d\n", fileSize, fileInfo.Size()) - return "", fmt.Errorf("file size mismatch") - } -} +// n, err := file.Write([]byte(data)) +// if err != nil { +// log.Printf("Failed to write data to file: %v", err) +// return "", fmt.Errorf("failed to write data to file") +// } +// if n != len(data) { +// log.Printf("Incomplete write: wrote %d bytes, expected %d bytes", n, len(data)) +// return "", fmt.Errorf("incomplete write") +// } + +// fileInfo, err := os.Stat(filePath) +// if err != nil { +// log.Printf("Failed to stat file: %v", err) +// return "", fmt.Errorf("failed to stat file") +// } + +// if fileInfo.Size() == fileSize { +// fmt.Println("文件接收完成且大小一致") +// return filePath, nil +// } else { +// fmt.Printf("文件大小不一致,发送大小为%d,接收大小为%d\n", fileSize, fileInfo.Size()) +// return "", fmt.Errorf("file size mismatch") +// } +// } diff --git a/godo/localchat/server.go b/godo/localchat/server.go index 3c24abd..d65a69a 100644 --- a/godo/localchat/server.go +++ b/godo/localchat/server.go @@ -117,10 +117,10 @@ func UdpServer() { // ReceiveFile(udpMsg) // continue // } - if udpMsg.Type == "fileAccessed" { - HandlerSendFile(udpMsg) - continue - } + // if udpMsg.Type == "fileAccessed" { + // HandlerSendFile(udpMsg) + // continue + // } if udpMsg.Type == "image" { filePath, err := ReceiveImg(udpMsg) if err != nil {