mirror of https://gitee.com/godoos/godoos.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.2 KiB
134 lines
3.2 KiB
package files
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"godo/libs"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// 定义结构体来匹配 JSON 数据结构
|
|
type CallbackData struct {
|
|
Key string `json:"key"`
|
|
Status int `json:"status"`
|
|
URL string `json:"url"`
|
|
ChangesURL string `json:"changesurl"`
|
|
History struct {
|
|
ServerVersion string `json:"serverVersion"`
|
|
Changes []struct {
|
|
DocumentSHA256 string `json:"documentSha256"`
|
|
Created string `json:"created"`
|
|
User struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
} `json:"user"`
|
|
} `json:"changes"`
|
|
} `json:"history"`
|
|
Users []string `json:"users"`
|
|
Actions []struct {
|
|
Type int `json:"type"`
|
|
UserID string `json:"userid"`
|
|
} `json:"actions"`
|
|
LastSave string `json:"lastsave"`
|
|
NotModified bool `json:"notmodified"`
|
|
FileType string `json:"filetype"`
|
|
}
|
|
|
|
// 定义 OnlyOffice 预期的响应结构
|
|
type OnlyOfficeResponse struct {
|
|
Error int `json:"error"`
|
|
}
|
|
|
|
// OnlyOffice 回调处理函数
|
|
func OnlyOfficeCallbackHandler(w http.ResponseWriter, r *http.Request) {
|
|
// 读取请求体
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
http.Error(w, "Failed to read request body", http.StatusBadRequest)
|
|
return
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
// 打印原始请求体
|
|
//fmt.Printf("Received raw data: %s\n", body)
|
|
|
|
// 解析 JSON 数据
|
|
var callbackData CallbackData
|
|
err = json.Unmarshal(body, &callbackData)
|
|
if err != nil {
|
|
http.Error(w, "Failed to decode request body", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// 打印解析后的回调数据
|
|
//fmt.Printf("Received callback: %+v\n", callbackData)
|
|
|
|
// 使用 key 查找对应的 path
|
|
mapOnlyOfficeMutex.Lock()
|
|
path, exists := OnlyOfficekeyPathMap[callbackData.Key]
|
|
if exists {
|
|
delete(OnlyOfficekeyPathMap, callbackData.Key) // 删除已使用的 key
|
|
if callbackData.Status == 2 {
|
|
err := downloadFile(path, callbackData.URL)
|
|
log.Printf("Download file error: %v", err)
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to download file: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
mapOnlyOfficeMutex.Unlock()
|
|
// 构造响应
|
|
response := OnlyOfficeResponse{
|
|
Error: 0,
|
|
}
|
|
|
|
// 设置响应头为 JSON 格式
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
// 返回 JSON 响应
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// 下载文件
|
|
func downloadFile(filePath string, url string) error {
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
basePath, err := libs.GetOsDir()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fullFilePath := filepath.Join(basePath, filePath)
|
|
// 使用 os.OpenFile 创建或截断文件
|
|
out, err := os.OpenFile(fullFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer out.Close()
|
|
// 获取文件密钥
|
|
fileSecret := libs.GetConfigString("filePwd")
|
|
if fileSecret != "" {
|
|
// 读取文件内容到内存中
|
|
fileBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
encryData, err := libs.EncodeFile(fileSecret, string(fileBytes))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = out.Write([]byte(encryData))
|
|
return err
|
|
} else {
|
|
_, err = io.Copy(out, resp.Body)
|
|
return err
|
|
}
|
|
|
|
}
|
|
|