易云轻量版服务端
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

http_handler.go 30 KiB

3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  1. package handler
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "github.com/fsnotify/fsnotify"
  9. ipfs "github.com/ipfs/go-ipfs-api"
  10. "io/ioutil"
  11. "locking-kit-server/consts"
  12. "locking-kit-server/db"
  13. "locking-kit-server/env"
  14. "locking-kit-server/utils"
  15. "log"
  16. "net/http"
  17. "os"
  18. "path/filepath"
  19. "strconv"
  20. "strings"
  21. "time"
  22. )
  23. //查询工作空间
  24. func GetWorkSpace(w http.ResponseWriter, r *http.Request) {
  25. fmt.Fprintln(w, utils.BuildSuccessData(env.WorkSpace))
  26. }
  27. //设置工作空间
  28. func SetWorkSpace(w http.ResponseWriter, r *http.Request) {
  29. //参数解析
  30. defer r.Body.Close()
  31. data := r.URL.Query()
  32. workSpace := data.Get("path")
  33. if len(workSpace) == 0 {
  34. fmt.Fprintln(w, utils.BuildFail("path为必填参数"))
  35. return
  36. }
  37. oldWorkSpace :=env.WorkSpace
  38. err := env.SetWorkSpaceToRegistry(workSpace)
  39. if err != nil{
  40. log.Println(err)
  41. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  42. return
  43. }
  44. //新目录添加监控
  45. log.Printf("添加监控%v", fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone))
  46. err = filepath.Walk(fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone),watchWalkfunc)
  47. if err != nil {
  48. log.Println(err)
  49. fmt.Fprintln(w, utils.BuildFail("操作失败"))
  50. return
  51. }
  52. log.Printf("添加监控%v", fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone))
  53. err = filepath.Walk(fmt.Sprintf("%v%v%v", oldWorkSpace, string(os.PathSeparator),env.CurrentUserPhone),removeWatchWalkfunc)
  54. if err != nil {
  55. log.Println(err)
  56. fmt.Fprintln(w, utils.BuildFail("操作失败"))
  57. return
  58. }
  59. fmt.Fprintln(w, utils.BuildSuccess())
  60. return
  61. }
  62. /**
  63. * @author yuanrh
  64. * @description http服务核心逻辑
  65. * @date 2021/6/28 11:11
  66. **/
  67. //@title 同步文件夹至工作空间
  68. //@param ids 项目id,逗号分隔
  69. func Login(w http.ResponseWriter, r *http.Request) {
  70. //参数解析
  71. defer r.Body.Close()
  72. data := r.URL.Query()
  73. userId := data.Get("userId")
  74. userPhone := data.Get("userPhone")
  75. api := data.Get("api")
  76. log.Println(api)
  77. if len(userId) == 0 {
  78. fmt.Fprintln(w, utils.BuildFail("userId为必填参数"))
  79. return
  80. }
  81. if len(userPhone) == 0 {
  82. fmt.Fprintln(w, utils.BuildFail("userPhone为必填参数"))
  83. return
  84. }
  85. //初始化ipfs路径
  86. env.IpfsPath= os.Getenv(consts.IPFS_PATH)+"ipfs.exe"
  87. env.IpfsApi = api
  88. env.CurrentUserId = userId
  89. env.CurrentUserPhone= userPhone
  90. TaskToWebChanel = make(chan map[string] interface{}, 100000)
  91. TaskToDownloadOrUploadChanel = make(chan map[string] interface{}, 100000)
  92. MessageToWebChanel = make(chan map[string] interface{}, 100000)
  93. //工作目录监控
  94. var err error
  95. env.GobalFileWatch, err = fsnotify.NewWatcher()
  96. if err != nil {
  97. log.Println(err)
  98. fmt.Fprintln(w, utils.BuildFail("操作失败"))
  99. return
  100. }
  101. startFileWatchProcess()
  102. //添加监控
  103. log.Printf("添加监控%v", fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone))
  104. err = filepath.Walk(fmt.Sprintf("%v%v%v", env.WorkSpace, string(os.PathSeparator),env.CurrentUserPhone),watchWalkfunc)
  105. if err != nil {
  106. log.Println(err)
  107. fmt.Fprintln(w, utils.BuildFail("操作失败"))
  108. return
  109. }
  110. env.LoginStatus =1
  111. remoteIpfsApi := ipfs.NewShell(env.IpfsApi)
  112. isUp := remoteIpfsApi.IsUp()
  113. if !isUp {
  114. log.Println("盒子节点网络连接不通!")
  115. fmt.Fprintln(w, utils.BuildSuccess())
  116. return
  117. }
  118. //添加本地引导节点
  119. ID,err :=remoteIpfsApi.ID()
  120. if err!=nil{
  121. log.Println(err)
  122. }
  123. if len(ID.Addresses)>1{
  124. var peers = []string{ID.Addresses[1]}
  125. localIpfsApi := ipfs.NewShell("localhost:5001")
  126. isUp := localIpfsApi.IsUp()
  127. if !isUp {
  128. log.Println("localhost ipfs节点网络连接不通!")
  129. fmt.Fprintln(w, utils.BuildSuccess())
  130. return
  131. }
  132. _,err := localIpfsApi.BootstrapAdd(peers)
  133. if err!=nil{
  134. log.Println(err)
  135. }
  136. }
  137. fmt.Fprintln(w, utils.BuildSuccess())
  138. }
  139. //工作空间增加文件监听事件
  140. func watchWalkfunc(filePath string, info os.FileInfo, err error) error {
  141. if info == nil{
  142. return nil
  143. }
  144. if info.IsDir()==true{
  145. //config.GobalWatch.Remove(filePath)
  146. err = env.GobalFileWatch.Add(filePath)
  147. if err != nil {
  148. log.Println(err)
  149. return err
  150. }
  151. }
  152. return nil
  153. }
  154. //工作空间增加文件监听事件
  155. func removeWatchWalkfunc(filePath string, info os.FileInfo, err error) error {
  156. if info == nil{
  157. return nil
  158. }
  159. if info.IsDir()==true{
  160. //config.GobalWatch.Remove(filePath)
  161. err = env.GobalFileWatch.Remove(filePath)
  162. if err != nil {
  163. log.Println(err)
  164. return err
  165. }
  166. }
  167. return nil
  168. }
  169. func removeFileObjectTaskIsModify(filePath string){
  170. key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath)
  171. err := db.DeleteWithPrefix(key)
  172. if err != nil{
  173. log.Println()
  174. }
  175. }
  176. func updateFileObjectTaskIsModify(filePath string){
  177. key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath)
  178. data,_ := db.QueryWithPrefix(key)
  179. if data == nil || len(data)==0{
  180. return
  181. }
  182. var fileObj = make(map[string] interface{})
  183. err :=json.Unmarshal([]byte(data[key]), &fileObj)
  184. if err !=nil{
  185. log.Println(err)
  186. return
  187. }
  188. fileObj[consts.TASK_IS_MODIFY] = true
  189. taskByte,err := json.Marshal(fileObj)
  190. if err !=nil{
  191. log.Println(err)
  192. return
  193. }
  194. err = db.ReplaceInto(key, string(taskByte))
  195. if err !=nil{
  196. log.Println(err)
  197. }
  198. }
  199. func startFileWatchProcess(){
  200. fmt.Println("开启文件监控进程")
  201. go func() {
  202. for {
  203. select {
  204. case ev := <-env.GobalFileWatch.Events:
  205. {
  206. //log.Println(ev.Op.String()+":"+ev.Name)
  207. if ev.Op&fsnotify.Create == fsnotify.Create {
  208. //fmt.Println("创建文件 : ", ev.Name);
  209. //这里获取新创建文件的信息,如果是目录,则加入监控中
  210. fi, err := os.Stat(ev.Name);
  211. if err == nil && fi.IsDir() {
  212. env.GobalFileWatch.Add(ev.Name);
  213. fmt.Println("添加监控 : ", ev.Name);
  214. }else{
  215. log.Println("chan-->"+("create"+";"+ev.Name))
  216. //ch <- ("create"+";"+ev.Name)
  217. // 创建文件 不做任何动作
  218. dir := filepath.Dir(ev.Name)
  219. env.GobalFileWatch.Add(dir);
  220. updateFileObjectTaskIsModify(ev.Name)
  221. }
  222. }
  223. if ev.Op&fsnotify.Write == fsnotify.Write {
  224. //fmt.Println("写入文件 : ", ev.Name);
  225. //判断文件,发送事件
  226. fi, err := os.Stat(ev.Name);
  227. if err == nil && !fi.IsDir() {
  228. log.Println("chan-->"+("write"+";"+ev.Name))
  229. //log.Println(ch)
  230. //ch <- ("write"+";"+ev.Name)
  231. updateFileObjectTaskIsModify(ev.Name)
  232. }
  233. }
  234. if ev.Op&fsnotify.Remove == fsnotify.Remove {
  235. //fmt.Println("删除文件 : ", ev.Name);
  236. //如果删除文件是目录,则移除监控
  237. fi, err := os.Stat(ev.Name);
  238. if err == nil && fi.IsDir() {
  239. env.GobalFileWatch.Remove(ev.Name);
  240. //fmt.Println("删除监控 : ", ev.Name);
  241. }else{
  242. // 删除文件
  243. log.Println("chan-->"+("remove"+";"+ev.Name))
  244. //ch <- ("remove"+";"+ev.Name)
  245. removeFileObjectTaskIsModify(ev.Name)
  246. }
  247. }
  248. if ev.Op&fsnotify.Rename == fsnotify.Rename {
  249. //fmt.Println("重命名文件 : ", ev.Name);
  250. //如果重命名文件是目录,则移除监控
  251. //注意这里无法使用os.Stat来判断是否是目录了
  252. //因为重命名后,go已经无法找到原文件来获取信息了
  253. //所以这里就简单粗爆的直接remove好了
  254. env.GobalFileWatch.Remove(ev.Name);
  255. }
  256. if ev.Op&fsnotify.Chmod == fsnotify.Chmod {
  257. //fmt.Println("修改权限 : ", ev.Name);
  258. }
  259. }
  260. case err := <-env.GobalFileWatch.Errors:
  261. {
  262. log.Printf("error : %v", err);
  263. return;
  264. }
  265. }
  266. }
  267. }();
  268. }
  269. //注销
  270. func Logout(w http.ResponseWriter, r *http.Request) {
  271. go func() {
  272. if TaskToDownloadOrUploadChanel!=nil{
  273. close(TaskToDownloadOrUploadChanel)
  274. }
  275. if TaskToWebChanel!=nil{
  276. close(TaskToWebChanel)
  277. }
  278. if MessageToWebChanel!=nil{
  279. close(MessageToWebChanel)
  280. }
  281. }()
  282. env.LoginStatus =0
  283. fmt.Fprintln(w, utils.BuildSuccess())
  284. }
  285. //@title 同步文件夹至工作空间
  286. //@param ids 项目id,逗号分隔
  287. func SyncFolderToWorkSpace(w http.ResponseWriter, r *http.Request){
  288. //参数解析
  289. defer r.Body.Close()
  290. data := r.URL.Query()
  291. ids := strings.Split(data.Get("ids"),",")
  292. if len(ids) == 0{
  293. fmt.Fprintln(w, utils.BuildFail("ids为必填参数"))
  294. return
  295. }
  296. //遍历文件夹
  297. for _, id := range ids {
  298. //查询文件列表
  299. task,err := postQueryArchiveListByProjectId(id)
  300. if err !=nil{
  301. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  302. return
  303. }
  304. if task==nil || len(task)==0{
  305. continue
  306. }
  307. //本地化项目、文件夹id,仅现一个文件夹出现
  308. for _, archive := range task {
  309. err = insertProjectFolderObject(archive.(map[string] interface{}))
  310. if err !=nil{
  311. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  312. return
  313. }
  314. }
  315. //添加同步任务
  316. err = batchInsertTask(task, consts.TASK_TYPE_DOWNLOAD)
  317. if err !=nil{
  318. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  319. return
  320. }
  321. }
  322. fmt.Fprintln(w, utils.BuildSuccess())
  323. }
  324. func insertProjectFolderObject(task map[string] interface{}) error{
  325. 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))
  326. var po struct{ProjId int64; FolderId int64}
  327. po.ProjId,_ = strconv.ParseInt(task["ProjId"].(string),10, 64)
  328. po.FolderId,_ = strconv.ParseInt(task["FolderId"].(string),10, 64)
  329. poByte,_ := json.Marshal(po)
  330. return db.ReplaceInto(key,string(poByte))
  331. }
  332. //批量插入同步任务
  333. func batchInsertTask(task []interface{},taskType string) error{
  334. for _, archiveObj := range task {
  335. //key=userId:TASK_SYNC_STATUS_WAIT:taskId
  336. taskId := strconv.FormatInt(utils.GeneratorId(), 10)
  337. addAttribute(archiveObj.(map[string] interface{}), taskId, consts.TASK_SYNC_STATUS_WAIT, 0, taskType)
  338. var obj = archiveObj
  339. archiveByte,err := json.Marshal(obj)
  340. if err !=nil{
  341. return err
  342. }
  343. // key -> /userid/TASK_SYNC/417367746536689664
  344. key := fmt.Sprintf("/%v%v%v",env.CurrentUserPhone, consts.ETCD_DIRECTOR_TASK_SYNC,taskId)
  345. err = db.ReplaceInto(key,string(archiveByte))
  346. if err !=nil{
  347. return err
  348. }
  349. //推送到web
  350. TaskToWebChanel <- archiveObj.(map[string] interface{})
  351. //添加到下载队列
  352. TaskToDownloadOrUploadChanel <- archiveObj.(map[string] interface{})
  353. //记录下载操作日志
  354. var Obj = archiveObj.(map[string] interface{})
  355. if Obj[consts.TASK_TYPE].(string) == consts.TASK_TYPE_DOWNLOAD{
  356. 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)))
  357. if err != nil{
  358. log.Printf("下载操作日志记录失败", err)
  359. }
  360. }
  361. }
  362. return nil
  363. }
  364. func addAttribute(archiveObj map[string] interface{}, taskId string, taskSyncStatus string, progress float64, taskType string){
  365. archiveObj[consts.TASK_ID] = taskId
  366. archiveObj[consts.TASK_SYNC_STATUS] = taskSyncStatus
  367. archiveObj[consts.TASK_SYNC_PROGRESS] = progress
  368. archiveObj[consts.TASK_TYPE] = taskType
  369. archiveObj[consts.TASK_CREATE_UNIX_TIME] = time.Now().Unix()
  370. }
  371. //@title 文件/文件夹下载
  372. //@param fileObject 消息中的param对象字符串
  373. func DownloadFileFromMsg(w http.ResponseWriter, r *http.Request) {
  374. //参数解析
  375. defer r.Body.Close()
  376. data := r.URL.Query()
  377. fileObject := data.Get("fileObject")
  378. if len(fileObject) == 0 {
  379. fmt.Fprintln(w, utils.BuildFail("fileObject为必填参数"))
  380. return
  381. }
  382. var task []interface{}
  383. taskOne := make(map[string] interface{})
  384. err := json.Unmarshal([]byte(fileObject), &taskOne)
  385. task = append(task, taskOne)
  386. //添加同步任务
  387. err = batchInsertTask(task, consts.TASK_TYPE_DOWNLOAD)
  388. if err !=nil{
  389. fmt.Fprintln(w, utils.BuildFail("下载失败!"))
  390. return
  391. }
  392. fmt.Fprintln(w, utils.BuildSuccess())
  393. }
  394. //@title 文件/文件夹下载
  395. //@param filePath 文件/文件夹路径
  396. func DownloadFile(w http.ResponseWriter, r *http.Request){
  397. log.Println("右键菜单下载至工作空间")
  398. //参数解析
  399. defer r.Body.Close()
  400. data := r.URL.Query()
  401. filePath := data.Get("filePath")
  402. if len(filePath) == 0{
  403. fmt.Fprintln(w, utils.BuildFail("filePath为必填参数"))
  404. return
  405. }
  406. var task []interface{}
  407. var err error
  408. _,err = os.Stat(filePath)
  409. if err != nil{
  410. fmt.Fprintln(w, utils.BuildFail("filePath参数无效"))
  411. return
  412. }
  413. if strings.Index(filePath,env.WorkSpace)<0{
  414. fmt.Fprintln(w, utils.BuildFail("请至工作空间目录进行操作"))
  415. return
  416. }
  417. absFilePath := strings.Replace(filePath, env.WorkSpace, "", 1)
  418. blocks := strings.Split(absFilePath, string(os.PathSeparator))
  419. if len(blocks)<3{
  420. fmt.Fprintln(w, utils.BuildFail("请至工作空间目录进行操作"))
  421. return
  422. }
  423. projectName := blocks[2]
  424. folderName := blocks[3]
  425. //if fileInfo.IsDir() {
  426. // relativePath := strings.Replace(absFilePath, blocks[0]+string(os.PathSeparator)+projectName+string(os.PathSeparator)+folderName, "", 1)
  427. // task, err = postQueryArchiveListByCondition(projectName, folderName, "", "", relativePath)
  428. //}else{
  429. // extension := strings.Replace(filepath.Ext(filePath), ".", "", 1)
  430. // archName := strings.Replace(filepath.Base(filePath), filepath.Ext(filePath), "", 1)
  431. // relativePath := strings.Replace(absFilePath, env.CurrentUserPhone+string(os.PathSeparator)+projectName+string(os.PathSeparator)+folderName, "", 1)
  432. // relativePath = strings.Replace(relativePath, filepath.Base(filePath), "", 1)
  433. // if relativePath == string(os.PathSeparator){
  434. // relativePath = ""
  435. // }
  436. // task, err = postQueryArchiveListByCondition(projectName, folderName, archName, extension,relativePath)
  437. //}
  438. key := fmt.Sprintf("/%v%v%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_PROJECT_FOLDER_OBJECT,projectName,string(os.PathSeparator),folderName)
  439. log.Println(key)
  440. mapString,err := db.QueryWithPrefix(key)
  441. if err != nil || mapString==nil{
  442. log.Printf("文件列表查询失败,%v", err)
  443. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  444. return
  445. }
  446. //获取第一个
  447. var firstMapString string
  448. for _,v := range mapString {
  449. log.Println(firstMapString)
  450. firstMapString = v
  451. break
  452. }
  453. var po struct{ProjId int64; FolderId int64}
  454. err = json.Unmarshal([]byte(firstMapString), &po)
  455. if err != nil{
  456. log.Printf("序列化失败,%v", err)
  457. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  458. return
  459. }
  460. task, err = postQueryArchiveListByProjectId(strconv.FormatInt(po.ProjId,10))
  461. if err != nil{
  462. log.Printf("文件列表查询失败,%v", err)
  463. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  464. return
  465. }
  466. if task==nil || len(task)==0{
  467. fmt.Fprintln(w, utils.BuildSuccess())
  468. return
  469. }
  470. var datas []interface{}
  471. //判断无更改文件
  472. for _, t := range task {
  473. remoteObj := t.(map[string] interface{})
  474. 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"])
  475. filePath := filepath.Clean(fmt.Sprintf("%v%v%v.%v",directory,string(os.PathSeparator),remoteObj["ArchName"].(string),remoteObj["Extension"].(string)))
  476. key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath)
  477. taskMap,err := db.QueryWithPrefix(key)
  478. if err != nil{
  479. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  480. return
  481. }
  482. taskString := taskMap[key]
  483. localTask := make(map[string] interface{})
  484. if len(taskString)>0{
  485. err = json.Unmarshal([]byte(taskString),&localTask)
  486. if err != nil{
  487. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  488. return
  489. }
  490. if localTask["IpfsCid"].(string)!=remoteObj["IpfsCid"].(string) || localTask[consts.TASK_IS_MODIFY].(bool){
  491. datas = append(datas, t)
  492. }
  493. }else{
  494. datas = append(datas, t)
  495. }
  496. }
  497. //添加同步任务
  498. err = batchInsertTask(datas, consts.TASK_TYPE_DOWNLOAD)
  499. if err !=nil{
  500. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  501. return
  502. }
  503. fmt.Fprintln(w, utils.BuildSuccess())
  504. }
  505. //@title 文件上传
  506. //@param filePath 文件路径
  507. func UploadFile(w http.ResponseWriter, r *http.Request){
  508. //参数解析
  509. defer r.Body.Close()
  510. data := r.URL.Query()
  511. filePath := data.Get("filePath")
  512. if len(filePath) == 0{
  513. fmt.Fprintln(w, utils.BuildFail("filePath为必填参数"))
  514. return
  515. }
  516. log.Printf("上传文件 %v",filePath)
  517. fileInfo,err := os.Stat(filePath)
  518. if err != nil{
  519. fmt.Fprintln(w, utils.BuildFail("filePath参数无效"))
  520. return
  521. }
  522. //不支持文件夹上传
  523. if fileInfo.IsDir(){
  524. fmt.Fprintln(w, utils.BuildFail("filePath参数无效,不支持文件夹上传"))
  525. return
  526. }
  527. //判断本地数据库是否存在该对象,存在则取出,否转构建空对象
  528. key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath)
  529. taskMap,err := db.QueryWithPrefix(key)
  530. if err != nil{
  531. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  532. return
  533. }
  534. taskString := taskMap[key]
  535. task := make(map[string] interface{})
  536. if len(taskString)>0{
  537. err = json.Unmarshal([]byte(taskString),&task)
  538. if err != nil{
  539. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  540. return
  541. }
  542. task["ModifyUserId"] = env.CurrentUserId
  543. }else{
  544. //构建任务对象
  545. absFilePath := strings.Replace(filePath, env.WorkSpace, "", 1)
  546. blocks := strings.Split(absFilePath, string(os.PathSeparator))
  547. projectName := blocks[2]
  548. folderName := blocks[3]
  549. extension := strings.Replace(filepath.Ext(filePath), ".", "", 1)
  550. archName := strings.Replace(filepath.Base(filePath), filepath.Ext(filePath), "", 1)
  551. task["ArchName"] = archName
  552. task["Extension"] = extension
  553. task["NodeName"] = folderName
  554. task["ProjName"] = projectName
  555. task["ModifyUserId"] = env.CurrentUserId
  556. task["FileSize"] = fileInfo.Size()
  557. task["Version"] = 1
  558. relativePath := strings.Replace(absFilePath, env.CurrentUserPhone+string(os.PathSeparator)+projectName+string(os.PathSeparator)+folderName, "", 1)
  559. relativePath = strings.Replace(relativePath, filepath.Base(filePath), "", 1)
  560. if relativePath == string(os.PathSeparator) || relativePath == "\\\\"{
  561. relativePath = ""
  562. }
  563. task["RelativePath"] = relativePath
  564. //初始化projId,folderId
  565. 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))
  566. ret,err := db.QueryWithPrefix(key)
  567. if err!=nil || ret[key]==""{
  568. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  569. }
  570. var projFolderObj map[string] int64
  571. err = json.Unmarshal([]byte(ret[key]),&projFolderObj)
  572. if err!=nil {
  573. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  574. }
  575. task["ProjId"] = strconv.FormatInt(projFolderObj["ProjId"],10)
  576. task["FolderId"] = strconv.FormatInt(projFolderObj["FolderId"],10)
  577. }
  578. task[consts.TASK_ABSOLUTE_PATH] = filepath.Clean(filePath)
  579. var tasks []interface{}
  580. tasks = append(tasks, task)
  581. //添加同步任务
  582. err = batchInsertTask(tasks, consts.TASK_TYPE_UPLOAD)
  583. if err !=nil{
  584. fmt.Fprintln(w, utils.BuildFail("同步失败!"))
  585. return
  586. }
  587. fmt.Fprintln(w, utils.BuildSuccess())
  588. }
  589. //@title 重新执行任务
  590. //@param taskIds 项目id,逗号分隔
  591. func RestartTask(w http.ResponseWriter, r *http.Request){
  592. //参数解析
  593. defer r.Body.Close()
  594. data := r.URL.Query()
  595. ids := strings.Split(data.Get("taskIds"),",")
  596. if len(ids) == 0{
  597. fmt.Fprintln(w, utils.BuildFail("taskIds为必填参数"))
  598. return
  599. }
  600. for _, id := range ids {
  601. //查询值
  602. key := fmt.Sprintf("/%v%v%v",env.CurrentUserPhone, consts.ETCD_DIRECTOR_TASK_SYNC, id)
  603. taskMap,err := db.QueryWithPrefix(key)
  604. if err != nil{
  605. log.Println(err)
  606. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  607. return
  608. }
  609. taskString := taskMap[key]
  610. var task map[string] interface{}
  611. err = json.Unmarshal([]byte(taskString),&task)
  612. if err != nil{
  613. log.Println(err)
  614. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  615. return
  616. }
  617. //更新任务状态为 等待
  618. task[consts.TASK_SYNC_STATUS] = consts.TASK_SYNC_STATUS_WAIT
  619. task[consts.TASK_SYNC_PROGRESS] = 0
  620. v,err := json.Marshal(task)
  621. if err != nil{
  622. log.Println(err)
  623. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  624. return
  625. }
  626. //重置任务对象
  627. err = db.ReplaceInto(key, string(v))
  628. if err != nil{
  629. log.Println(err)
  630. fmt.Fprintln(w, utils.BuildFail("操作失败!"))
  631. return
  632. }
  633. //重新推送
  634. TaskToWebChanel <- task
  635. //重新推送
  636. TaskToDownloadOrUploadChanel <- task
  637. }
  638. fmt.Fprintln(w, utils.BuildSuccess())
  639. }
  640. //根据项目Id查询所有文件列表
  641. func GetLockingMsgListByFilter(userId,unixTime string)(data []interface{},err error){
  642. url:=consts.SERVER_IP_PORT+"/api/pms/sdk/getLockingMsgListByFilter"
  643. var param struct{UserId, Status, UnixTime, Digest string}
  644. param.UserId = userId
  645. param.Status = "0"
  646. param.UnixTime = unixTime
  647. //摘要
  648. text:=fmt.Sprintf("%v|%v|%v", param.UserId, param.Status, param.UnixTime)
  649. textByte := []byte(text)
  650. md5Byte := md5.Sum(textByte)
  651. digest := fmt.Sprintf("%x", md5Byte)
  652. param.Digest=digest
  653. jsonData,err :=json.Marshal(param)
  654. if err!=nil{
  655. log.Printf("json序列化化错误!")
  656. return nil,err
  657. }
  658. resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData))
  659. if err != nil {
  660. log.Printf("post failed, err:%v\n", err)
  661. return nil,err
  662. }
  663. defer resp.Body.Close()
  664. b, err := ioutil.ReadAll(resp.Body)
  665. if err != nil {
  666. log.Printf("get resp failed,err:%v\n", err)
  667. return nil,err
  668. }
  669. returnValue := make(map[string] interface{})
  670. err=json.Unmarshal(b,&returnValue)
  671. if err!=nil{
  672. log.Printf("字符串%v反序列化出错", string(b[:]))
  673. }
  674. //成功
  675. if returnValue["Code"].(float64)==0{
  676. if returnValue["Data"]==nil{
  677. return data,err
  678. }
  679. return returnValue["Data"].([] interface{}),nil
  680. }
  681. //失败
  682. return nil,errors.New(returnValue["Msg"].(string))
  683. }
  684. //根据项目Id查询所有文件列表
  685. func postQueryArchiveListByProjectId(id string)(data []interface{},err error){
  686. url:=consts.SERVER_IP_PORT+"/api/pms/sdk/queryArchiveListByProjectId"
  687. var param struct{Id string; Digest string}
  688. param.Id = id
  689. //摘要
  690. text:=fmt.Sprintf("%v",param.Id)
  691. textByte := []byte(text)
  692. md5Byte := md5.Sum(textByte)
  693. digest := fmt.Sprintf("%x", md5Byte)
  694. param.Digest=digest
  695. jsonData,err :=json.Marshal(param)
  696. if err!=nil{
  697. log.Printf("json序列化化错误!")
  698. return nil,err
  699. }
  700. resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData))
  701. if err != nil {
  702. log.Printf("post failed, err:%v\n", err)
  703. return nil,err
  704. }
  705. defer resp.Body.Close()
  706. b, err := ioutil.ReadAll(resp.Body)
  707. if err != nil {
  708. log.Printf("get resp failed,err:%v\n", err)
  709. return nil,err
  710. }
  711. returnValue := make(map[string] interface{})
  712. err=json.Unmarshal(b,&returnValue)
  713. if err!=nil{
  714. log.Printf("字符串%v反序列化出错", string(b[:]))
  715. }
  716. //成功
  717. if returnValue["Code"].(float64)==0{
  718. if returnValue["Data"] == nil {
  719. return data,nil
  720. }
  721. return returnValue["Data"].([] interface{}),nil
  722. }
  723. //失败
  724. return nil,errors.New(returnValue["Msg"].(string))
  725. }
  726. //根据条件查询所有文件列表 (过期)
  727. func postQueryArchiveListByCondition( projectName, folderName, archName, extension, relativePath string)(data []interface{},err error){
  728. url:=consts.SERVER_IP_PORT+"/api/pms/sdk/queryArchiveListByCondition"
  729. var param struct{ ProjectName, FolderName, ArchName, Extension, RelativePath, Digest string}
  730. param.ProjectName = projectName
  731. param.FolderName = folderName
  732. param.ArchName = archName
  733. param.Extension = extension
  734. param.RelativePath = relativePath
  735. //摘要
  736. text:=fmt.Sprintf("%v|%v|%v|%v|%v", param.ProjectName, param.FolderName, param.ArchName, param.Extension, param.RelativePath)
  737. textByte := []byte(text)
  738. md5Byte := md5.Sum(textByte)
  739. digest := fmt.Sprintf("%x", md5Byte)
  740. param.Digest=digest
  741. jsonData,err :=json.Marshal(param)
  742. if err!=nil{
  743. log.Printf("json序列化化错误!")
  744. return nil,err
  745. }
  746. resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData))
  747. if err != nil {
  748. log.Printf("post failed, err:%v\n", err)
  749. return nil,err
  750. }
  751. defer resp.Body.Close()
  752. b, err := ioutil.ReadAll(resp.Body)
  753. if err != nil {
  754. log.Printf("get resp failed,err:%v\n", err)
  755. return nil,err
  756. }
  757. returnValue := make(map[string] interface{})
  758. err=json.Unmarshal(b,&returnValue)
  759. if err!=nil{
  760. log.Printf("字符串%v反序列化出错", string(b[:]))
  761. }
  762. //成功
  763. if returnValue["Code"].(float64)==0{
  764. return returnValue["Data"].([] interface{}),nil
  765. }
  766. //失败
  767. return nil,errors.New(returnValue["Msg"].(string))
  768. }
  769. //根据文件Id替换文件对象
  770. func replaceIntoArchiveById( id, projId, folderId, archName, extension, ipfsCid, fileSize, relativePath, modifyUserId string, version int)(data map[string]interface {},err error){
  771. url:=consts.SERVER_IP_PORT+"/api/pms/sdk/replaceIntoArchiveById"
  772. var param struct{
  773. Id string;
  774. ProjId string;
  775. FolderId string;
  776. ArchName string;
  777. Extension string;
  778. IpfsCid string;
  779. FileSize string;
  780. Version int;
  781. RelativePath string;
  782. ModifyUserId string;
  783. Digest string
  784. }
  785. param.Id = id
  786. param.ProjId = projId
  787. param.FolderId = folderId
  788. param.ArchName = archName
  789. param.Extension =extension
  790. param.IpfsCid = ipfsCid
  791. param.FileSize = fileSize
  792. param.RelativePath = relativePath
  793. param.ModifyUserId = modifyUserId
  794. param.Version = version
  795. //摘要
  796. 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)
  797. textByte := []byte(text)
  798. md5Byte := md5.Sum(textByte)
  799. digest := fmt.Sprintf("%x", md5Byte)
  800. param.Digest=digest
  801. jsonData,err :=json.Marshal(param)
  802. if err!=nil{
  803. log.Printf("json序列化化错误!")
  804. return nil,err
  805. }
  806. resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData))
  807. if err != nil {
  808. log.Printf("post failed, err:%v\n", err)
  809. return nil,err
  810. }
  811. defer resp.Body.Close()
  812. b, err := ioutil.ReadAll(resp.Body)
  813. if err != nil {
  814. log.Printf("get resp failed,err:%v\n", err)
  815. return nil,err
  816. }
  817. returnValue := make(map[string] interface{})
  818. err=json.Unmarshal(b,&returnValue)
  819. if err!=nil{
  820. log.Printf("字符串%v反序列化出错", string(b[:]))
  821. }
  822. //成功
  823. if returnValue["Code"].(float64)==0 {
  824. if returnValue["Data"]==nil{
  825. return data,nil
  826. }
  827. return returnValue["Data"].(map[string]interface {}),nil
  828. }
  829. //失败
  830. return nil,errors.New(returnValue["Msg"].(string))
  831. }
  832. //根据文件Id替换文件对象
  833. func addProjArchiveLog(projId, archId, archName, folderName, ipfsCid, extension, relativePath, createUserId, actionType string, version int)(err error){
  834. url:=consts.SERVER_IP_PORT+"/api/pms/sdk/addProjArchiveLog"
  835. var param struct{
  836. Id string;
  837. ProjId string;
  838. ArchId string;
  839. ArchName string;
  840. FolderName string;
  841. RelativePath string;
  842. Extension string;
  843. IpfsCid string;
  844. Version int;
  845. ActionType string;
  846. CreateUserId string;
  847. Digest string
  848. }
  849. param.ProjId = projId
  850. param.ArchId = archId
  851. param.ArchName = archName
  852. param.FolderName = folderName
  853. param.Extension =extension
  854. param.IpfsCid = ipfsCid
  855. param.ActionType = actionType
  856. param.RelativePath = relativePath
  857. param.CreateUserId = createUserId
  858. param.Version = version
  859. //摘要
  860. 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)
  861. textByte := []byte(text)
  862. md5Byte := md5.Sum(textByte)
  863. digest := fmt.Sprintf("%x", md5Byte)
  864. param.Digest=digest
  865. jsonData,err :=json.Marshal(param)
  866. if err!=nil{
  867. log.Printf("json序列化化错误!")
  868. return err
  869. }
  870. resp, err := http.Post(url, consts.CONTENT_TYPE, bytes.NewReader(jsonData))
  871. if err != nil {
  872. log.Printf("post failed, err:%v\n", err)
  873. return err
  874. }
  875. defer resp.Body.Close()
  876. b, err := ioutil.ReadAll(resp.Body)
  877. if err != nil {
  878. log.Printf("get resp failed,err:%v\n", err)
  879. return err
  880. }
  881. returnValue := make(map[string] interface{})
  882. err=json.Unmarshal(b,&returnValue)
  883. if err!=nil{
  884. log.Printf("字符串%v反序列化出错", string(b[:]))
  885. }
  886. //成功
  887. if returnValue["Code"].(float64)==0 {
  888. return err
  889. }
  890. //失败
  891. return errors.New(returnValue["Msg"].(string))
  892. }
  893. func CanShowRedOverlay(w http.ResponseWriter, r *http.Request) {
  894. defer r.Body.Close()
  895. data := r.URL.Query()
  896. filePath := data.Get("filePath")
  897. key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath)
  898. //log.Printf("red %v", filePath)
  899. mapString,err := db.QueryWithPrefix(key)
  900. if err != nil{
  901. log.Println(err)
  902. fmt.Fprintln(w, false)
  903. return
  904. }
  905. for _, v := range mapString {
  906. archiveObj := make(map[string] interface{})
  907. err :=json.Unmarshal([]byte(v), &archiveObj)
  908. if err != nil{
  909. log.Println(err)
  910. fmt.Fprintln(w, false)
  911. return
  912. }
  913. if archiveObj[consts.TASK_IS_MODIFY]==nil{
  914. fmt.Fprintln(w, false)
  915. return
  916. }
  917. if archiveObj[consts.TASK_IS_MODIFY].(bool){
  918. fmt.Fprintln(w, true)
  919. return
  920. }
  921. }
  922. fmt.Fprintln(w, false)
  923. }
  924. func CanShowBlueOverlay(w http.ResponseWriter, r *http.Request) {
  925. defer r.Body.Close()
  926. data := r.URL.Query()
  927. filePath := data.Get("filePath")
  928. //log.Printf("blue %v", filePath)
  929. key := fmt.Sprintf("/%v%v%v", env.CurrentUserPhone, consts.ETCD_DIRECTOR_WORKSPACE_FILE_OBJECT,filePath)
  930. mapString,err := db.QueryWithPrefix(key)
  931. if err != nil{
  932. log.Println(err)
  933. fmt.Fprintln(w, false)
  934. return
  935. }
  936. if len(mapString)==0{
  937. fmt.Fprintln(w, false)
  938. return
  939. }
  940. for _, v := range mapString {
  941. archiveObj := make(map[string] interface{})
  942. err :=json.Unmarshal([]byte(v), &archiveObj)
  943. if err != nil{
  944. log.Println(err)
  945. fmt.Fprintln(w, false)
  946. return
  947. }
  948. if archiveObj[consts.TASK_IS_MODIFY]==nil{
  949. fmt.Fprintln(w, false)
  950. return
  951. }
  952. if archiveObj[consts.TASK_IS_MODIFY].(bool){
  953. fmt.Fprintln(w, false)
  954. return
  955. }
  956. }
  957. fmt.Fprintln(w, true)
  958. }