易云轻量版服务端
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.

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. }