package handler import ( "bytes" "crypto/md5" "encoding/json" "errors" "fmt" "github.com/fsnotify/fsnotify" ipfs "github.com/ipfs/go-ipfs-api" "io/ioutil" "locking-kit-server/consts" "locking-kit-server/db" "locking-kit-server/env" "locking-kit-server/utils" "log" "net/http" "os" "path/filepath" "strconv" "strings" "time" ) //查询工作空间 func GetWorkSpace(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, utils.BuildSuccessData(env.WorkSpace)) } //设置工作空间 func SetWorkSpace(w http.ResponseWriter, r *http.Request) { //参数解析 defer r.Body.Close() data := r.URL.Query() workSpace := data.Get("path") if len(workSpace) == 0 { fmt.Fprintln(w, utils.BuildFail("path为必填参数")) return } oldWorkSpace :=env.WorkSpace err := env.SetWorkSpaceToRegistry(workSpace) if err != nil{ log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } //新目录添加监控 log.Printf("添加监控%v", fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone)) err = filepath.Walk(fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone),watchWalkfunc) if err != nil { log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败")) return } log.Printf("添加监控%v", fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone)) err = filepath.Walk(fmt.Sprintf("%v%v%v", oldWorkSpace, string(os.PathSeparator),env.CurrentUserPhone),removeWatchWalkfunc) if err != nil { log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败")) return } fmt.Fprintln(w, utils.BuildSuccess()) return } /** * @author yuanrh * @description http服务核心逻辑 * @date 2021/6/28 11:11 **/ //@title 同步文件夹至工作空间 //@param ids 项目id,逗号分隔 func Login(w http.ResponseWriter, r *http.Request) { //参数解析 defer r.Body.Close() data := r.URL.Query() userId := data.Get("userId") userPhone := data.Get("userPhone") api := data.Get("api") log.Println(api) if len(userId) == 0 { fmt.Fprintln(w, utils.BuildFail("userId为必填参数")) return } if len(userPhone) == 0 { fmt.Fprintln(w, utils.BuildFail("userPhone为必填参数")) return } //初始化ipfs路径 env.IpfsPath= os.Getenv(consts.IPFS_PATH)+"ipfs.exe" env.IpfsApi = api env.CurrentUserId = userId env.CurrentUserPhone= userPhone TaskToWebChanel = make(chan map[string] interface{}, 100000) TaskToDownloadOrUploadChanel = make(chan map[string] interface{}, 100000) MessageToWebChanel = make(chan map[string] interface{}, 100000) //工作目录监控 var err error env.GobalFileWatch, err = fsnotify.NewWatcher() if err != nil { log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败")) return } startFileWatchProcess() //添加监控 log.Printf("添加监控%v", fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone)) err = filepath.Walk(fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone),watchWalkfunc) if err != nil { log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败")) return } env.LoginStatus =1 remoteIpfsApi := ipfs.NewShell(env.IpfsApi) isUp := remoteIpfsApi.IsUp() if !isUp { log.Println("盒子节点网络连接不通!") fmt.Fprintln(w, utils.BuildSuccess()) return } //添加本地引导节点 ID,err :=remoteIpfsApi.ID() if err!=nil{ log.Println(err) } if len(ID.Addresses)>1{ var peers = []string{ID.Addresses[1]} localIpfsApi := ipfs.NewShell("localhost:5001") isUp := localIpfsApi.IsUp() if !isUp { log.Println("localhost ipfs节点网络连接不通!") fmt.Fprintln(w, utils.BuildSuccess()) return } _,err := localIpfsApi.BootstrapAdd(peers) if err!=nil{ log.Println(err) } } fmt.Fprintln(w, utils.BuildSuccess()) } //工作空间增加文件监听事件 func watchWalkfunc(filePath string, info os.FileInfo, err error) error { if info == nil{ return nil } if info.IsDir()==true{ //config.GobalWatch.Remove(filePath) err = env.GobalFileWatch.Add(filePath) if err != nil { log.Println(err) return err } } return nil } //工作空间增加文件监听事件 func removeWatchWalkfunc(filePath string, info os.FileInfo, err error) error { if info == nil{ return nil } if info.IsDir()==true{ //config.GobalWatch.Remove(filePath) err = env.GobalFileWatch.Remove(filePath) if err != nil { log.Println(err) return err } } return nil } func removeFileObjectTaskIsModify(filePath string){ key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath) err := db.DeleteWithPrefix(key) if err != nil{ log.Println() } } func updateFileObjectTaskIsModify(filePath string){ key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath) data,_ := db.QueryWithPrefix(key) if data == nil || len(data)==0{ return } var fileObj = make(map[string] interface{}) err :=json.Unmarshal([]byte(data[key]), &fileObj) if err !=nil{ log.Println(err) return } fileObj[consts.TASK_IS_MODIFY] = true taskByte,err := json.Marshal(fileObj) if err !=nil{ log.Println(err) return } err = db.ReplaceInto(key, string(taskByte)) if err !=nil{ log.Println(err) } } func startFileWatchProcess(){ fmt.Println("开启文件监控进程") go func() { for { select { case ev := <-env.GobalFileWatch.Events: { //log.Println(ev.Op.String()+":"+ev.Name) if ev.Op&fsnotify.Create == fsnotify.Create { //fmt.Println("创建文件 : ", ev.Name); //这里获取新创建文件的信息,如果是目录,则加入监控中 fi, err := os.Stat(ev.Name); if err == nil && fi.IsDir() { env.GobalFileWatch.Add(ev.Name); fmt.Println("添加监控 : ", ev.Name); }else{ log.Println("chan-->"+("create"+";"+ev.Name)) //ch <- ("create"+";"+ev.Name) // 创建文件 不做任何动作 dir := filepath.Dir(ev.Name) env.GobalFileWatch.Add(dir); updateFileObjectTaskIsModify(ev.Name) } } if ev.Op&fsnotify.Write == fsnotify.Write { //fmt.Println("写入文件 : ", ev.Name); //判断文件,发送事件 fi, err := os.Stat(ev.Name); if err == nil && !fi.IsDir() { log.Println("chan-->"+("write"+";"+ev.Name)) //log.Println(ch) //ch <- ("write"+";"+ev.Name) updateFileObjectTaskIsModify(ev.Name) } } if ev.Op&fsnotify.Remove == fsnotify.Remove { //fmt.Println("删除文件 : ", ev.Name); //如果删除文件是目录,则移除监控 fi, err := os.Stat(ev.Name); if err == nil && fi.IsDir() { env.GobalFileWatch.Remove(ev.Name); //fmt.Println("删除监控 : ", ev.Name); }else{ // 删除文件 log.Println("chan-->"+("remove"+";"+ev.Name)) //ch <- ("remove"+";"+ev.Name) removeFileObjectTaskIsModify(ev.Name) } } if ev.Op&fsnotify.Rename == fsnotify.Rename { //fmt.Println("重命名文件 : ", ev.Name); //如果重命名文件是目录,则移除监控 //注意这里无法使用os.Stat来判断是否是目录了 //因为重命名后,go已经无法找到原文件来获取信息了 //所以这里就简单粗爆的直接remove好了 env.GobalFileWatch.Remove(ev.Name); } if ev.Op&fsnotify.Chmod == fsnotify.Chmod { //fmt.Println("修改权限 : ", ev.Name); } } case err := <-env.GobalFileWatch.Errors: { log.Printf("error : %v", err); return; } } } }(); } //注销 func Logout(w http.ResponseWriter, r *http.Request) { go func() { if TaskToDownloadOrUploadChanel!=nil{ close(TaskToDownloadOrUploadChanel) } if TaskToWebChanel!=nil{ close(TaskToWebChanel) } if MessageToWebChanel!=nil{ close(MessageToWebChanel) } }() env.LoginStatus =0 fmt.Fprintln(w, utils.BuildSuccess()) } //@title 同步文件夹至工作空间 //@param ids 项目id,逗号分隔 func SyncFolderToWorkSpace(w http.ResponseWriter, r *http.Request){ //参数解析 defer r.Body.Close() data := r.URL.Query() ids := strings.Split(data.Get("ids"),",") if len(ids) == 0{ fmt.Fprintln(w, utils.BuildFail("ids为必填参数")) return } //遍历文件夹 for _, id := range ids { //查询文件列表 task,err := postQueryArchiveListByProjectId(id) if err !=nil{ fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } if task==nil || len(task)==0{ continue } //本地化项目、文件夹id,仅现一个文件夹出现 for _, archive := range task { err = insertProjectFolderObject(archive.(map[string] interface{})) if err !=nil{ fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } } //添加同步任务 err = batchInsertTask(task, consts.TASK_TYPE_DOWNLOAD) if err !=nil{ fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } } fmt.Fprintln(w, utils.BuildSuccess()) } func insertProjectFolderObject(task map[string] interface{}) error{ key := fmt.Sprintf("/%v%v%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_PROJECT_FOLDER_OBJECT,task["ProjName"].(string),string(os.PathSeparator),task["NodeName"].(string)) var po struct{ProjId int64; FolderId int64} po.ProjId,_ = strconv.ParseInt(task["ProjId"].(string),10, 64) po.FolderId,_ = strconv.ParseInt(task["FolderId"].(string),10, 64) poByte,_ := json.Marshal(po) return db.ReplaceInto(key,string(poByte)) } //批量插入同步任务 func batchInsertTask(task []interface{},taskType string) error{ for _, archiveObj := range task { //key=userId:TASK_SYNC_STATUS_WAIT:taskId taskId := strconv.FormatInt(utils.GeneratorId(), 10) addAttribute(archiveObj.(map[string] interface{}), taskId, consts.TASK_SYNC_STATUS_WAIT, 0, taskType) var obj = archiveObj archiveByte,err := json.Marshal(obj) if err !=nil{ return err } // key -> /userid/TASK_SYNC/417367746536689664 key := fmt.Sprintf("/%v%v%v",env.CurrentUserPhone, consts.ETCD_DIRECTOR_TASK_SYNC,taskId) err = db.ReplaceInto(key,string(archiveByte)) if err !=nil{ return err } //推送到web TaskToWebChanel <- archiveObj.(map[string] interface{}) //添加到下载队列 TaskToDownloadOrUploadChanel <- archiveObj.(map[string] interface{}) //记录下载操作日志 var Obj = archiveObj.(map[string] interface{}) if Obj[consts.TASK_TYPE].(string) == consts.TASK_TYPE_DOWNLOAD{ err = addProjArchiveLog(Obj["ProjId"].(string), Obj["Id"].(string), Obj["ArchName"].(string), Obj["NodeName"].(string), Obj["IpfsCid"].(string), Obj["Extension"].(string), Obj["RelativePath"].(string), Obj["ModifyUserId"].(string), Obj[consts.TASK_TYPE].(string), int(Obj["Version"].(float64))) if err != nil{ log.Printf("下载操作日志记录失败", err) } } } return nil } func addAttribute(archiveObj map[string] interface{}, taskId string, taskSyncStatus string, progress float64, taskType string){ archiveObj[consts.TASK_ID] = taskId archiveObj[consts.TASK_SYNC_STATUS] = taskSyncStatus archiveObj[consts.TASK_SYNC_PROGRESS] = progress archiveObj[consts.TASK_TYPE] = taskType archiveObj[consts.TASK_CREATE_UNIX_TIME] = time.Now().Unix() } //@title 文件/文件夹下载 //@param fileObject 消息中的param对象字符串 func DownloadFileFromMsg(w http.ResponseWriter, r *http.Request) { //参数解析 defer r.Body.Close() data := r.URL.Query() fileObject := data.Get("fileObject") if len(fileObject) == 0 { fmt.Fprintln(w, utils.BuildFail("fileObject为必填参数")) return } var task []interface{} taskOne := make(map[string] interface{}) err := json.Unmarshal([]byte(fileObject), &taskOne) task = append(task, taskOne) //添加同步任务 err = batchInsertTask(task, consts.TASK_TYPE_DOWNLOAD) if err !=nil{ fmt.Fprintln(w, utils.BuildFail("下载失败!")) return } fmt.Fprintln(w, utils.BuildSuccess()) } //@title 文件/文件夹下载 //@param filePath 文件/文件夹路径 func DownloadFile(w http.ResponseWriter, r *http.Request){ log.Println("右键菜单下载至工作空间") //参数解析 defer r.Body.Close() data := r.URL.Query() filePath := data.Get("filePath") if len(filePath) == 0{ fmt.Fprintln(w, utils.BuildFail("filePath为必填参数")) return } var task []interface{} var err error _,err = os.Stat(filePath) if err != nil{ fmt.Fprintln(w, utils.BuildFail("filePath参数无效")) return } if strings.Index(filePath,env.WorkSpace)<0{ fmt.Fprintln(w, utils.BuildFail("请至工作空间目录进行操作")) return } absFilePath := strings.Replace(filePath, env.WorkSpace, "", 1) blocks := strings.Split(absFilePath, string(os.PathSeparator)) if len(blocks)<3{ fmt.Fprintln(w, utils.BuildFail("请至工作空间目录进行操作")) return } projectName := blocks[2] folderName := blocks[3] //if fileInfo.IsDir() { // relativePath := strings.Replace(absFilePath, blocks[0]+string(os.PathSeparator)+projectName+string(os.PathSeparator)+folderName, "", 1) // task, err = postQueryArchiveListByCondition(projectName, folderName, "", "", relativePath) //}else{ // extension := strings.Replace(filepath.Ext(filePath), ".", "", 1) // archName := strings.Replace(filepath.Base(filePath), filepath.Ext(filePath), "", 1) // relativePath := strings.Replace(absFilePath, env.CurrentUserPhone+string(os.PathSeparator)+projectName+string(os.PathSeparator)+folderName, "", 1) // relativePath = strings.Replace(relativePath, filepath.Base(filePath), "", 1) // if relativePath == string(os.PathSeparator){ // relativePath = "" // } // task, err = postQueryArchiveListByCondition(projectName, folderName, archName, extension,relativePath) //} key := fmt.Sprintf("/%v%v%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_PROJECT_FOLDER_OBJECT,projectName,string(os.PathSeparator),folderName) log.Println(key) mapString,err := db.QueryWithPrefix(key) if err != nil || mapString==nil{ log.Printf("文件列表查询失败,%v", err) fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } //获取第一个 var firstMapString string for _,v := range mapString { log.Println(firstMapString) firstMapString = v break } var po struct{ProjId int64; FolderId int64} err = json.Unmarshal([]byte(firstMapString), &po) if err != nil{ log.Printf("序列化失败,%v", err) fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } task, err = postQueryArchiveListByProjectId(strconv.FormatInt(po.ProjId,10)) if err != nil{ log.Printf("文件列表查询失败,%v", err) fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } if task==nil || len(task)==0{ fmt.Fprintln(w, utils.BuildSuccess()) return } var datas []interface{} //判断无更改文件 for _, t := range task { remoteObj := t.(map[string] interface{}) directory := fmt.Sprintf("%v%v%v%v%v%v%v%v%v",env.WorkSpace,string(os.PathSeparator),env.CurrentUserPhone,string(os.PathSeparator),remoteObj["ProjName"],string(os.PathSeparator),remoteObj["NodeName"],string(os.PathSeparator),remoteObj["RelativePath"]) filePath := filepath.Clean(fmt.Sprintf("%v%v%v.%v",directory,string(os.PathSeparator),remoteObj["ArchName"].(string),remoteObj["Extension"].(string))) key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath) taskMap,err := db.QueryWithPrefix(key) if err != nil{ fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } taskString := taskMap[key] localTask := make(map[string] interface{}) if len(taskString)>0{ err = json.Unmarshal([]byte(taskString),&localTask) if err != nil{ fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } if localTask["IpfsCid"].(string)!=remoteObj["IpfsCid"].(string) || localTask[consts.TASK_IS_MODIFY].(bool){ datas = append(datas, t) } }else{ datas = append(datas, t) } } //添加同步任务 err = batchInsertTask(datas, consts.TASK_TYPE_DOWNLOAD) if err !=nil{ fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } fmt.Fprintln(w, utils.BuildSuccess()) } //@title 文件上传 //@param filePath 文件路径 func UploadFile(w http.ResponseWriter, r *http.Request){ //参数解析 defer r.Body.Close() data := r.URL.Query() filePath := data.Get("filePath") if len(filePath) == 0{ fmt.Fprintln(w, utils.BuildFail("filePath为必填参数")) return } log.Printf("上传文件 %v",filePath) fileInfo,err := os.Stat(filePath) if err != nil{ fmt.Fprintln(w, utils.BuildFail("filePath参数无效")) return } //不支持文件夹上传 if fileInfo.IsDir(){ fmt.Fprintln(w, utils.BuildFail("filePath参数无效,不支持文件夹上传")) return } //判断本地数据库是否存在该对象,存在则取出,否转构建空对象 key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath) taskMap,err := db.QueryWithPrefix(key) if err != nil{ fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } taskString := taskMap[key] task := make(map[string] interface{}) if len(taskString)>0{ err = json.Unmarshal([]byte(taskString),&task) if err != nil{ fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } task["ModifyUserId"] = env.CurrentUserId }else{ //构建任务对象 absFilePath := strings.Replace(filePath, env.WorkSpace, "", 1) blocks := strings.Split(absFilePath, string(os.PathSeparator)) projectName := blocks[2] folderName := blocks[3] extension := strings.Replace(filepath.Ext(filePath), ".", "", 1) archName := strings.Replace(filepath.Base(filePath), filepath.Ext(filePath), "", 1) task["ArchName"] = archName task["Extension"] = extension task["NodeName"] = folderName task["ProjName"] = projectName task["ModifyUserId"] = env.CurrentUserId task["FileSize"] = fileInfo.Size() task["Version"] = 1 relativePath := strings.Replace(absFilePath, env.CurrentUserPhone+string(os.PathSeparator)+projectName+string(os.PathSeparator)+folderName, "", 1) relativePath = strings.Replace(relativePath, filepath.Base(filePath), "", 1) if relativePath == string(os.PathSeparator) || relativePath == "\\\\"{ relativePath = "" } task["RelativePath"] = relativePath //初始化projId,folderId key := fmt.Sprintf("/%v%v%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_PROJECT_FOLDER_OBJECT,task["ProjName"].(string),string(os.PathSeparator),task["NodeName"].(string)) ret,err := db.QueryWithPrefix(key) if err!=nil || ret[key]==""{ fmt.Fprintln(w, utils.BuildFail("操作失败!")) } var projFolderObj map[string] int64 err = json.Unmarshal([]byte(ret[key]),&projFolderObj) if err!=nil { fmt.Fprintln(w, utils.BuildFail("操作失败!")) } task["ProjId"] = strconv.FormatInt(projFolderObj["ProjId"],10) task["FolderId"] = strconv.FormatInt(projFolderObj["FolderId"],10) } task[consts.TASK_ABSOLUTE_PATH] = filepath.Clean(filePath) var tasks []interface{} tasks = append(tasks, task) //添加同步任务 err = batchInsertTask(tasks, consts.TASK_TYPE_UPLOAD) if err !=nil{ fmt.Fprintln(w, utils.BuildFail("同步失败!")) return } fmt.Fprintln(w, utils.BuildSuccess()) } //@title 重新执行任务 //@param taskIds 项目id,逗号分隔 func RestartTask(w http.ResponseWriter, r *http.Request){ //参数解析 defer r.Body.Close() data := r.URL.Query() ids := strings.Split(data.Get("taskIds"),",") if len(ids) == 0{ fmt.Fprintln(w, utils.BuildFail("taskIds为必填参数")) return } for _, id := range ids { //查询值 key := fmt.Sprintf("/%v%v%v",env.CurrentUserPhone, consts.ETCD_DIRECTOR_TASK_SYNC, id) taskMap,err := db.QueryWithPrefix(key) if err != nil{ log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } taskString := taskMap[key] var task map[string] interface{} err = json.Unmarshal([]byte(taskString),&task) if err != nil{ log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } //更新任务状态为 等待 task[consts.TASK_SYNC_STATUS] = consts.TASK_SYNC_STATUS_WAIT task[consts.TASK_SYNC_PROGRESS] = 0 v,err := json.Marshal(task) if err != nil{ log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } //重置任务对象 err = db.ReplaceInto(key, string(v)) if err != nil{ log.Println(err) fmt.Fprintln(w, utils.BuildFail("操作失败!")) return } //重新推送 TaskToWebChanel <- task //重新推送 TaskToDownloadOrUploadChanel <- task } fmt.Fprintln(w, utils.BuildSuccess()) } //根据项目Id查询所有文件列表 func GetLockingMsgListByFilter(userId,unixTime string)(data []interface{},err error){ url:=consts.SERVER_IP_PORT+"/api/pms/sdk/getLockingMsgListByFilter" var param struct{UserId, Status, UnixTime, Digest string} param.UserId = userId param.Status = "0" param.UnixTime = unixTime //摘要 text:=fmt.Sprintf("%v|%v|%v", param.UserId, param.Status, param.UnixTime) textByte := []byte(text) md5Byte := md5.Sum(textByte) digest := fmt.Sprintf("%x", md5Byte) param.Digest=digest jsonData,err :=json.Marshal(param) if err!=nil{ log.Printf("json序列化化错误!") return nil,err } resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData)) if err != nil { log.Printf("post failed, err:%v\n", err) return nil,err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { log.Printf("get resp failed,err:%v\n", err) return nil,err } returnValue := make(map[string] interface{}) err=json.Unmarshal(b,&returnValue) if err!=nil{ log.Printf("字符串%v反序列化出错", string(b[:])) } //成功 if returnValue["Code"].(float64)==0{ if returnValue["Data"]==nil{ return data,err } return returnValue["Data"].([] interface{}),nil } //失败 return nil,errors.New(returnValue["Msg"].(string)) } //根据项目Id查询所有文件列表 func postQueryArchiveListByProjectId(id string)(data []interface{},err error){ url:=consts.SERVER_IP_PORT+"/api/pms/sdk/queryArchiveListByProjectId" var param struct{Id string; Digest string} param.Id = id //摘要 text:=fmt.Sprintf("%v",param.Id) textByte := []byte(text) md5Byte := md5.Sum(textByte) digest := fmt.Sprintf("%x", md5Byte) param.Digest=digest jsonData,err :=json.Marshal(param) if err!=nil{ log.Printf("json序列化化错误!") return nil,err } resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData)) if err != nil { log.Printf("post failed, err:%v\n", err) return nil,err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { log.Printf("get resp failed,err:%v\n", err) return nil,err } returnValue := make(map[string] interface{}) err=json.Unmarshal(b,&returnValue) if err!=nil{ log.Printf("字符串%v反序列化出错", string(b[:])) } //成功 if returnValue["Code"].(float64)==0{ if returnValue["Data"] == nil { return data,nil } return returnValue["Data"].([] interface{}),nil } //失败 return nil,errors.New(returnValue["Msg"].(string)) } //根据条件查询所有文件列表 (过期) func postQueryArchiveListByCondition( projectName, folderName, archName, extension, relativePath string)(data []interface{},err error){ url:=consts.SERVER_IP_PORT+"/api/pms/sdk/queryArchiveListByCondition" var param struct{ ProjectName, FolderName, ArchName, Extension, RelativePath, Digest string} param.ProjectName = projectName param.FolderName = folderName param.ArchName = archName param.Extension = extension param.RelativePath = relativePath //摘要 text:=fmt.Sprintf("%v|%v|%v|%v|%v", param.ProjectName, param.FolderName, param.ArchName, param.Extension, param.RelativePath) textByte := []byte(text) md5Byte := md5.Sum(textByte) digest := fmt.Sprintf("%x", md5Byte) param.Digest=digest jsonData,err :=json.Marshal(param) if err!=nil{ log.Printf("json序列化化错误!") return nil,err } resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData)) if err != nil { log.Printf("post failed, err:%v\n", err) return nil,err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { log.Printf("get resp failed,err:%v\n", err) return nil,err } returnValue := make(map[string] interface{}) err=json.Unmarshal(b,&returnValue) if err!=nil{ log.Printf("字符串%v反序列化出错", string(b[:])) } //成功 if returnValue["Code"].(float64)==0{ return returnValue["Data"].([] interface{}),nil } //失败 return nil,errors.New(returnValue["Msg"].(string)) } //根据文件Id替换文件对象 func replaceIntoArchiveById( id, projId, folderId, archName, extension, ipfsCid, fileSize, relativePath, modifyUserId string, version int)(data map[string]interface {},err error){ url:=consts.SERVER_IP_PORT+"/api/pms/sdk/replaceIntoArchiveById" var param struct{ Id string; ProjId string; FolderId string; ArchName string; Extension string; IpfsCid string; FileSize string; Version int; RelativePath string; ModifyUserId string; Digest string } param.Id = id param.ProjId = projId param.FolderId = folderId param.ArchName = archName param.Extension =extension param.IpfsCid = ipfsCid param.FileSize = fileSize param.RelativePath = relativePath param.ModifyUserId = modifyUserId param.Version = version //摘要 text:=fmt.Sprintf("%v|%v|%v|%v|%v|%v|%v|%v|%v|%v",param.Id, param.ProjId, param.FolderId, param.ArchName, param.Extension, param.IpfsCid,param.FileSize, param.Version, param.RelativePath, param.ModifyUserId) textByte := []byte(text) md5Byte := md5.Sum(textByte) digest := fmt.Sprintf("%x", md5Byte) param.Digest=digest jsonData,err :=json.Marshal(param) if err!=nil{ log.Printf("json序列化化错误!") return nil,err } resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData)) if err != nil { log.Printf("post failed, err:%v\n", err) return nil,err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { log.Printf("get resp failed,err:%v\n", err) return nil,err } returnValue := make(map[string] interface{}) err=json.Unmarshal(b,&returnValue) if err!=nil{ log.Printf("字符串%v反序列化出错", string(b[:])) } //成功 if returnValue["Code"].(float64)==0 { if returnValue["Data"]==nil{ return data,nil } return returnValue["Data"].(map[string]interface {}),nil } //失败 return nil,errors.New(returnValue["Msg"].(string)) } //根据文件Id替换文件对象 func addProjArchiveLog(projId, archId, archName, folderName, ipfsCid, extension, relativePath, createUserId, actionType string, version int)(err error){ url:=consts.SERVER_IP_PORT+"/api/pms/sdk/addProjArchiveLog" var param struct{ Id string; ProjId string; ArchId string; ArchName string; FolderName string; RelativePath string; Extension string; IpfsCid string; Version int; ActionType string; CreateUserId string; Digest string } param.ProjId = projId param.ArchId = archId param.ArchName = archName param.FolderName = folderName param.Extension =extension param.IpfsCid = ipfsCid param.ActionType = actionType param.RelativePath = relativePath param.CreateUserId = createUserId param.Version = version //摘要 text:=fmt.Sprintf("%v|%v|%v|%v|%v|%v|%v|%v|%v|%v|%v",param.Id, param.ProjId,param.ArchId, param.ArchName, param.FolderName, param.RelativePath, param.Extension,param.IpfsCid, param.Version, param.ActionType, param.CreateUserId) textByte := []byte(text) md5Byte := md5.Sum(textByte) digest := fmt.Sprintf("%x", md5Byte) param.Digest=digest jsonData,err :=json.Marshal(param) if err!=nil{ log.Printf("json序列化化错误!") return err } resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData)) if err != nil { log.Printf("post failed, err:%v\n", err) return err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { log.Printf("get resp failed,err:%v\n", err) return err } returnValue := make(map[string] interface{}) err=json.Unmarshal(b,&returnValue) if err!=nil{ log.Printf("字符串%v反序列化出错", string(b[:])) } //成功 if returnValue["Code"].(float64)==0 { return err } //失败 return errors.New(returnValue["Msg"].(string)) } func CanShowRedOverlay(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() data := r.URL.Query() filePath := data.Get("filePath") key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath) //log.Printf("red %v", filePath) mapString,err := db.QueryWithPrefix(key) if err != nil{ log.Println(err) fmt.Fprintln(w, false) return } for _, v := range mapString { archiveObj := make(map[string] interface{}) err :=json.Unmarshal([]byte(v), &archiveObj) if err != nil{ log.Println(err) fmt.Fprintln(w, false) return } if archiveObj[consts.TASK_IS_MODIFY]==nil{ fmt.Fprintln(w, false) return } if archiveObj[consts.TASK_IS_MODIFY].(bool){ fmt.Fprintln(w, true) return } } fmt.Fprintln(w, false) } func CanShowBlueOverlay(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() data := r.URL.Query() filePath := data.Get("filePath") //log.Printf("blue %v", filePath) key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath) mapString,err := db.QueryWithPrefix(key) if err != nil{ log.Println(err) fmt.Fprintln(w, false) return } if len(mapString)==0{ fmt.Fprintln(w, false) return } for _, v := range mapString { archiveObj := make(map[string] interface{}) err :=json.Unmarshal([]byte(v), &archiveObj) if err != nil{ log.Println(err) fmt.Fprintln(w, false) return } if archiveObj[consts.TASK_IS_MODIFY]==nil{ fmt.Fprintln(w, false) return } if archiveObj[consts.TASK_IS_MODIFY].(bool){ fmt.Fprintln(w, false) return } } fmt.Fprintln(w, true) }