cloud_disk.go 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. package controllers
  2. import (
  3. "archive/zip"
  4. "encoding/json"
  5. "eta/eta_api/models"
  6. "eta/eta_api/services"
  7. "eta/eta_api/services/alarm_msg"
  8. "eta/eta_api/utils"
  9. "fmt"
  10. "github.com/h2non/filetype"
  11. "github.com/rdlucklib/rdluck_tools/http"
  12. "io/ioutil"
  13. "os"
  14. "path"
  15. "strconv"
  16. "strings"
  17. "time"
  18. )
  19. // CloudDiskController 共享云盘
  20. type CloudDiskController struct {
  21. BaseAuthController
  22. }
  23. // MenuCreate 创建文件夹
  24. // @Title 创建文件夹
  25. // @Description 创建文件夹
  26. // @Param request body models.CloudDiskMenuCreateReq true "type json string"
  27. // @Success 200 Ret=200 操作成功
  28. // @router /menu/create [post]
  29. func (this *CloudDiskController) MenuCreate() {
  30. br := new(models.BaseResponse).Init()
  31. defer func() {
  32. this.Data["json"] = br
  33. this.ServeJSON()
  34. }()
  35. var req models.CloudDiskMenuCreateReq
  36. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  37. br.Msg = "参数解析异常!"
  38. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  39. return
  40. }
  41. req.MenuName = strings.TrimSpace(req.MenuName)
  42. if req.MenuName == "" {
  43. br.Msg = "文件夹名称不可为空"
  44. return
  45. }
  46. // 权限校验
  47. ok, e := services.CheckCloudDiskManagerAuth(this.SysUser.RoleTypeCode)
  48. if e != nil {
  49. br.Msg = "操作失败"
  50. br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
  51. return
  52. }
  53. if !ok {
  54. br.Msg = "无权操作"
  55. return
  56. }
  57. // 重名校验
  58. existItem := new(models.CloudDiskMenu)
  59. existCond := ` AND menu_name = ? AND parent_id = ? `
  60. existPars := make([]interface{}, 0)
  61. existPars = append(existPars, req.MenuName, req.ParentId)
  62. if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
  63. br.Msg = "操作失败"
  64. br.ErrMsg = "获取重名目录失败, Err: " + e.Error()
  65. return
  66. }
  67. if existItem != nil && existItem.MenuId > 0 {
  68. br.Msg = "该文件夹已存在"
  69. return
  70. }
  71. nowTime := time.Now().Local()
  72. newMenu := &models.CloudDiskMenu{
  73. MenuName: req.MenuName,
  74. ParentId: req.ParentId,
  75. AdminId: this.SysUser.AdminId,
  76. AdminName: this.SysUser.RealName,
  77. CreateTime: nowTime,
  78. ModifyTime: nowTime,
  79. }
  80. if e := newMenu.Create(); e != nil {
  81. br.Msg = "操作失败"
  82. br.ErrMsg = "新增目录失败, Err: " + e.Error()
  83. return
  84. }
  85. br.Ret = 200
  86. br.Success = true
  87. br.Msg = "操作成功"
  88. }
  89. // MenuRename 重命名文件夹
  90. // @Title 重命名文件夹
  91. // @Description 重命名文件夹
  92. // @Param request body models.CloudDiskMenuRenameReq true "type json string"
  93. // @Success 200 Ret=200 操作成功
  94. // @router /menu/rename [post]
  95. func (this *CloudDiskController) MenuRename() {
  96. br := new(models.BaseResponse).Init()
  97. defer func() {
  98. this.Data["json"] = br
  99. this.ServeJSON()
  100. }()
  101. var req models.CloudDiskMenuRenameReq
  102. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  103. br.Msg = "参数解析异常!"
  104. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  105. return
  106. }
  107. if req.MenuId <= 0 {
  108. br.Msg = "参数有误"
  109. return
  110. }
  111. req.MenuName = strings.TrimSpace(req.MenuName)
  112. if req.MenuName == "" {
  113. br.Msg = "文件夹名称不可为空"
  114. return
  115. }
  116. // 权限校验
  117. ok, e := services.CheckCloudDiskManagerAuth(this.SysUser.RoleTypeCode)
  118. if e != nil {
  119. br.Msg = "操作失败"
  120. br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
  121. return
  122. }
  123. if !ok {
  124. br.Msg = "无权操作"
  125. return
  126. }
  127. // 重名校验
  128. menuItem := new(models.CloudDiskMenu)
  129. if e := menuItem.GetItemById(req.MenuId); e != nil {
  130. br.Msg = "操作失败"
  131. br.ErrMsg = "获取目录信息失败, Err: " + e.Error()
  132. return
  133. }
  134. existItem := new(models.CloudDiskMenu)
  135. existCond := ` AND menu_name = ? AND parent_id = ? AND menu_id <> ? `
  136. existPars := make([]interface{}, 0)
  137. existPars = append(existPars, req.MenuName, menuItem.ParentId, menuItem.MenuId)
  138. if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
  139. br.Msg = "操作失败"
  140. br.ErrMsg = "获取重名目录失败, Err: " + e.Error()
  141. return
  142. }
  143. if existItem != nil && existItem.MenuId > 0 {
  144. br.Msg = "该文件夹已存在"
  145. return
  146. }
  147. menuItem.MenuName = req.MenuName
  148. menuItem.ModifyTime = time.Now().Local()
  149. if e := menuItem.Update([]string{"MenuName", "ModifyTime"}); e != nil {
  150. br.Msg = "操作失败"
  151. br.ErrMsg = "目录重命名失败, Err: " + e.Error()
  152. return
  153. }
  154. br.Ret = 200
  155. br.Success = true
  156. br.Msg = "操作成功"
  157. }
  158. // MenuDelete 删除文件夹
  159. // @Title 删除文件夹
  160. // @Description 删除文件夹
  161. // @Param request body models.CloudDiskMenuDeleteReq true "type json string"
  162. // @Success 200 Ret=200 操作成功
  163. // @router /menu/delete [post]
  164. func (this *CloudDiskController) MenuDelete() {
  165. br := new(models.BaseResponse).Init()
  166. defer func() {
  167. this.Data["json"] = br
  168. this.ServeJSON()
  169. }()
  170. var req models.CloudDiskMenuDeleteReq
  171. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  172. br.Msg = "参数解析异常!"
  173. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  174. return
  175. }
  176. if req.MenuId <= 0 {
  177. br.Msg = "参数有误"
  178. return
  179. }
  180. // 权限校验
  181. ok, e := services.CheckCloudDiskManagerAuth(this.SysUser.RoleTypeCode)
  182. if e != nil {
  183. br.Msg = "操作失败"
  184. br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
  185. return
  186. }
  187. if !ok {
  188. br.Msg = "无权操作"
  189. return
  190. }
  191. // 获取文件夹子目录IDs
  192. menuIds := make([]int, 0)
  193. menuIds = append(menuIds, req.MenuId)
  194. childIds, e := services.GetCloudDiskMenuIdsByParentId(req.MenuId)
  195. if e != nil {
  196. br.Msg = "操作失败"
  197. br.ErrMsg = "获取子目录IDs失败, ErrMsg: " + e.Error()
  198. return
  199. }
  200. menuIds = append(menuIds, childIds...)
  201. // 删除目录及目录下所有文件
  202. if e = models.DeleteCloudDiskMenuAndResourcesByMenuIds(menuIds); e != nil {
  203. br.Msg = "操作失败"
  204. br.ErrMsg = "删除目录及文件失败, Err: " + e.Error()
  205. return
  206. }
  207. br.Ret = 200
  208. br.Success = true
  209. br.Msg = "操作成功"
  210. }
  211. // MenuTree 目录分类树
  212. // @Title 目录分类树
  213. // @Description 目录分类树
  214. // @Success 200 Ret=200 获取成功
  215. // @router /menu/tree [get]
  216. func (this *CloudDiskController) MenuTree() {
  217. br := new(models.BaseResponse).Init()
  218. defer func() {
  219. this.Data["json"] = br
  220. this.ServeJSON()
  221. }()
  222. treeData, e := services.GetCloudDiskMenuTree()
  223. if e != nil {
  224. br.Msg = "获取失败"
  225. br.ErrMsg = "获取目录分类树失败, Err: " + e.Error()
  226. return
  227. }
  228. br.Ret = 200
  229. br.Success = true
  230. br.Msg = "获取成功"
  231. br.Data = treeData
  232. }
  233. // MenuResources 目录文件
  234. // @Title 目录文件
  235. // @Description 获取目录下所有文件
  236. // @Param MenuId query int true "目录ID"
  237. // @Success 200 Ret=200 获取成功
  238. // @router /menu/resources [get]
  239. func (this *CloudDiskController) MenuResources() {
  240. br := new(models.BaseResponse).Init()
  241. defer func() {
  242. this.Data["json"] = br
  243. this.ServeJSON()
  244. }()
  245. menuId, _ := this.GetInt("MenuId", 0)
  246. if menuId <= 0 {
  247. br.Msg = "参数有误"
  248. return
  249. }
  250. menuItem := new(models.CloudDiskMenu)
  251. if e := menuItem.GetItemById(menuId); e != nil {
  252. br.Msg = "目录已被删除, 请刷新页面"
  253. br.ErrMsg = "获取目录信息失败, Err: " + e.Error()
  254. return
  255. }
  256. // 获取该目录子目录IDs
  257. menuIds := make([]int, 0)
  258. menuIds = append(menuIds, menuId)
  259. childIds, e := services.GetCloudDiskMenuIdsByParentId(menuId)
  260. if e != nil {
  261. br.Msg = "操作失败"
  262. br.ErrMsg = "获取子目录IDs失败, ErrMsg: " + e.Error()
  263. return
  264. }
  265. menuIds = append(menuIds, childIds...)
  266. // 获取目录下所有文件
  267. resourceOB := new(models.CloudDiskResource)
  268. resourceCond := ` AND menu_id IN (` + utils.GetOrmInReplace(len(menuIds)) + `) `
  269. resourcePars := make([]interface{}, 0)
  270. resourcePars = append(resourcePars, menuIds)
  271. resourceFieldArr := []string{"resource_id", "resource_name", "resource_suffix", "resource_url", "menu_id"}
  272. resourceList, e := resourceOB.GetItemsByCondition(resourceCond, resourcePars, resourceFieldArr, "create_time ASC")
  273. if e != nil {
  274. br.Msg = "操作失败"
  275. br.ErrMsg = "获取目录下所有文件失败, Err: " + e.Error()
  276. return
  277. }
  278. // 获取目录列表, 取出parentMap
  279. listCond := ``
  280. listPars := make([]interface{}, 0)
  281. menuList, e := menuItem.GetItemsByCondition(listCond, listPars, []string{}, "")
  282. if e != nil {
  283. br.Msg = "操作失败"
  284. br.ErrMsg = "获取目录列表失败, Err: " + e.Error()
  285. return
  286. }
  287. menuMap := make(map[int]*models.CloudDiskMenu)
  288. for i := range menuList {
  289. menuMap[menuList[i].MenuId] = menuList[i]
  290. }
  291. type MenuResource struct {
  292. ResourceId int
  293. ResourceName string
  294. ResourceSuffix string
  295. ResourceUrl string
  296. OriginName string
  297. }
  298. respList := make([]*MenuResource, 0)
  299. for i := range resourceList {
  300. n := resourceList[i].ResourceName + resourceList[i].ResourceSuffix
  301. p := services.FillMenuPath2File(resourceList[i].MenuId, resourceList[i].MenuId, n, menuMap) // 完整的文件路径
  302. respList = append(respList, &MenuResource{
  303. ResourceId: resourceList[i].ResourceId,
  304. ResourceName: p,
  305. ResourceSuffix: resourceList[i].ResourceSuffix,
  306. ResourceUrl: resourceList[i].ResourceUrl,
  307. OriginName: n,
  308. })
  309. }
  310. br.Ret = 200
  311. br.Success = true
  312. br.Msg = "获取成功"
  313. br.Data = respList
  314. }
  315. // MenuDownload 目录文件打包下载
  316. // @Title 目录文件打包下载
  317. // @Description 目录文件打包下载
  318. // @Param MenuId query int true "目录ID"
  319. // @Success 200 Ret=200 操作成功
  320. // @router /menu/download [get]
  321. func (this *CloudDiskController) MenuDownload() {
  322. br := new(models.BaseResponse).Init()
  323. defer func() {
  324. this.Data["json"] = br
  325. this.ServeJSON()
  326. }()
  327. menuId, _ := this.GetInt("MenuId", 0)
  328. if menuId <= 0 {
  329. br.Msg = "参数有误"
  330. return
  331. }
  332. menuItem := new(models.CloudDiskMenu)
  333. if e := menuItem.GetItemById(menuId); e != nil {
  334. br.Msg = "目录已被删除, 请刷新页面"
  335. br.ErrMsg = "获取目录信息失败, Err: " + e.Error()
  336. return
  337. }
  338. // 获取该目录子目录IDs
  339. menuIds := make([]int, 0)
  340. menuIds = append(menuIds, menuId)
  341. childIds, e := services.GetCloudDiskMenuIdsByParentId(menuId)
  342. if e != nil {
  343. br.Msg = "操作失败"
  344. br.ErrMsg = "获取子目录IDs失败, ErrMsg: " + e.Error()
  345. return
  346. }
  347. menuIds = append(menuIds, childIds...)
  348. // 获取目录下所有文件
  349. resourceOB := new(models.CloudDiskResource)
  350. resourceCond := ` AND menu_id IN (` + utils.GetOrmInReplace(len(menuIds)) + `) `
  351. resourcePars := make([]interface{}, 0)
  352. resourcePars = append(resourcePars, menuIds)
  353. resourceFieldArr := []string{"resource_id", "resource_name", "resource_suffix", "resource_url"}
  354. resourceList, e := resourceOB.GetItemsByCondition(resourceCond, resourcePars, resourceFieldArr, "create_time ASC")
  355. if e != nil {
  356. br.Msg = "操作失败"
  357. br.ErrMsg = "获取目录下所有文件失败, Err: " + e.Error()
  358. return
  359. }
  360. if len(resourceList) == 0 {
  361. br.Msg = "无文件可下载"
  362. return
  363. }
  364. // 创建zip
  365. zipName := time.Now().Format(utils.FormatDateTimeUnSpace) + utils.GetRandString(5) + ".zip"
  366. savePath := zipName
  367. zipFile, err := os.Create(zipName)
  368. if err != nil {
  369. br.Msg = "操作失败"
  370. br.ErrMsg = "生成压缩文件失败, Err: " + e.Error()
  371. return
  372. }
  373. zipWriter := zip.NewWriter(zipFile)
  374. // 生成zip过程中报错关闭
  375. defer func() {
  376. if err != nil {
  377. _ = zipWriter.Close()
  378. _ = zipFile.Close()
  379. }
  380. _ = os.Remove(savePath)
  381. }()
  382. // 获取资源, 写入zip
  383. for i := range resourceList {
  384. if resourceList[i].ResourceName == "" || resourceList[i].ResourceSuffix == "" || resourceList[i].ResourceUrl == "" {
  385. continue
  386. }
  387. fmt.Printf("开始压缩第%d个文件\n", i+1)
  388. ioWriter, err := zipWriter.Create(fmt.Sprintf("%s.%s", resourceList[i].ResourceName, resourceList[i].ResourceSuffix))
  389. if err != nil {
  390. if os.IsPermission(err) {
  391. br.Msg = "操作失败"
  392. br.ErrMsg = "打包权限不足, Err: " + err.Error()
  393. return
  394. }
  395. br.Msg = "操作失败"
  396. br.ErrMsg = "压缩出错, Err: " + err.Error()
  397. return
  398. }
  399. var content []byte
  400. content, err = http.Get(resourceList[i].ResourceUrl)
  401. if err != nil {
  402. br.Msg = "操作失败"
  403. br.ErrMsg = "资源获取失败, Err: " + err.Error()
  404. return
  405. }
  406. _, err = ioWriter.Write(content)
  407. if err != nil {
  408. br.Msg = "操作失败"
  409. br.ErrMsg = "压缩文件写入失败, Err: " + err.Error()
  410. return
  411. }
  412. fmt.Printf("第%d个文件写入成功\n", i+1)
  413. }
  414. // 生成zip后关闭,否则下载文件会损坏
  415. _ = zipWriter.Close()
  416. _ = zipFile.Close()
  417. this.Ctx.Output.Download(savePath, fmt.Sprintf("%s.zip", menuItem.MenuName))
  418. br.Ret = 200
  419. br.Msg = "下载成功"
  420. br.Success = true
  421. }
  422. // CheckResourceRepeat 校验目录下文件重名
  423. // @Title 校验目录下文件重名
  424. // @Description 校验目录下文件重名
  425. // @Param request body models.CloudDiskCheckResourceRepeatReq true "type json string"
  426. // @Success 200 Ret=200 操作成功
  427. // @router /resource/check_repeat [post]
  428. func (this *CloudDiskController) CheckResourceRepeat() {
  429. br := new(models.BaseResponse).Init()
  430. defer func() {
  431. this.Data["json"] = br
  432. this.ServeJSON()
  433. }()
  434. var req models.CloudDiskCheckResourceRepeatReq
  435. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  436. br.Msg = "参数解析异常!"
  437. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  438. return
  439. }
  440. // 检测接口允许menuId为0, 上传不允许
  441. if len(req.FileNames) == 0 {
  442. br.Msg = "请选择文件"
  443. return
  444. }
  445. // 获取该级目录下的文件
  446. resourceOB := new(models.CloudDiskResource)
  447. resourceCond := ` AND menu_id = ? `
  448. resourcePars := make([]interface{}, 0)
  449. resourcePars = append(resourcePars, req.MenuId)
  450. resourceFieldArr := []string{"resource_id", "resource_name", "resource_suffix"}
  451. resourceList, e := resourceOB.GetItemsByCondition(resourceCond, resourcePars, resourceFieldArr, "create_time ASC")
  452. if e != nil {
  453. br.Msg = "操作失败"
  454. br.ErrMsg = "获取目录下文件失败, Err: " + e.Error()
  455. return
  456. }
  457. resourceLen := len(resourceList)
  458. respList := make([]*models.CloudDiskCheckResourceRepeatResp, 0)
  459. for i := range req.FileNames {
  460. v := new(models.CloudDiskCheckResourceRepeatResp)
  461. v.OriginName = req.FileNames[i]
  462. r := false
  463. a := v.OriginName
  464. if resourceLen > 0 {
  465. r, a = services.CheckFileNameFormFiles(v.OriginName, "", resourceList, 0)
  466. }
  467. v.IsRepeat = r
  468. v.AvailableName = a
  469. respList = append(respList, v)
  470. }
  471. br.Ret = 200
  472. br.Success = true
  473. br.Msg = "操作成功"
  474. br.Data = respList
  475. }
  476. // ResourceUpload 上传文件
  477. // @Title 上传文件
  478. // @Description 上传文件
  479. // @Param MenuId query int true "目录ID"
  480. // @Param File query file true "文件"
  481. // @Success 200 Ret=200 操作成功
  482. // @router /resource/upload [post]
  483. func (this *CloudDiskController) ResourceUpload() {
  484. br := new(models.BaseResponse).Init()
  485. defer func() {
  486. if br.ErrMsg == "" {
  487. br.IsSendEmail = false
  488. }
  489. this.Data["json"] = br
  490. this.ServeJSON()
  491. }()
  492. sysUser := this.SysUser
  493. if sysUser == nil {
  494. br.Msg = "请登录"
  495. br.ErrMsg = "请登录,SysUser Is Empty"
  496. br.Ret = 408
  497. return
  498. }
  499. menuId, _ := this.GetInt("MenuId", 0)
  500. if menuId <= 0 {
  501. br.Msg = "不允许上传文件至根目录"
  502. return
  503. }
  504. originName := this.GetString("OriginName", "")
  505. if originName == "" {
  506. br.Msg = "请上传文件名"
  507. return
  508. }
  509. if !strings.Contains(originName, ".") {
  510. br.Msg = "文件名有误"
  511. return
  512. }
  513. f, h, e := this.GetFile("file")
  514. if e != nil {
  515. br.Msg = "获取资源信息失败"
  516. br.ErrMsg = "获取资源信息失败, Err:" + e.Error()
  517. return
  518. }
  519. defer func() {
  520. _ = f.Close()
  521. }()
  522. extIndex := strings.LastIndex(originName, ".")
  523. fileName := originName[:extIndex]
  524. // 不依赖于文件扩展名检查文件格式
  525. fileData, e := ioutil.ReadAll(f)
  526. if e != nil {
  527. br.Msg = "上传失败"
  528. br.ErrMsg = "读取文件失败, Err: " + e.Error()
  529. return
  530. }
  531. // 允许上传图片/音视频/文档/压缩包
  532. if !filetype.IsImage(fileData) && !filetype.IsVideo(fileData) && !filetype.IsAudio(fileData) && !filetype.IsDocument(fileData) && !filetype.IsArchive(fileData) {
  533. br.Msg = "不允许上传该格式文件"
  534. br.ErrMsg = "文件格式有误"
  535. return
  536. }
  537. // 重名校验
  538. existItem := new(models.CloudDiskResource)
  539. existCond := ` AND resource_name = ? AND menu_id = ? `
  540. existPars := make([]interface{}, 0)
  541. existPars = append(existPars, fileName, menuId)
  542. if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
  543. br.Msg = "操作失败"
  544. br.ErrMsg = "获取重名文件失败, Err: " + e.Error()
  545. return
  546. }
  547. if existItem != nil && existItem.MenuId > 0 {
  548. br.Msg = fmt.Sprintf("文件名%s已存在", fileName)
  549. return
  550. }
  551. uploadDir := utils.STATIC_DIR + "hongze/" + time.Now().Format("20060102")
  552. if e = os.MkdirAll(uploadDir, utils.DIR_MOD); e != nil {
  553. br.Msg = "存储目录创建失败"
  554. br.ErrMsg = "存储目录创建失败, Err:" + e.Error()
  555. return
  556. }
  557. ext := path.Ext(h.Filename)
  558. ossFileName := utils.GetRandStringNoSpecialChar(28) + ext
  559. filePath := uploadDir + "/" + ossFileName
  560. if e = this.SaveToFile("file", filePath); e != nil {
  561. br.Msg = "文件保存失败"
  562. br.ErrMsg = "文件保存失败, Err:" + e.Error()
  563. return
  564. }
  565. defer func() {
  566. _ = os.Remove(filePath)
  567. }()
  568. // 上传到阿里云
  569. ossDir := utils.RESOURCE_DIR + "cloud_disk/"
  570. resourceUrl := ``
  571. //上传到阿里云 和 minio
  572. //if utils.ObjectStorageClient == "minio" {
  573. // resourceUrl, e = services.UploadMinIoToDir(ossFileName, filePath, ossDir, "")
  574. // if e != nil {
  575. // br.Msg = "文件上传失败"
  576. // br.ErrMsg = "文件上传失败, Err:" + e.Error()
  577. // return
  578. // }
  579. //} else {
  580. // resourceUrl, e = services.UploadAliyunToDir(ossFileName, filePath, ossDir, "")
  581. // if e != nil {
  582. // br.Msg = "文件上传失败"
  583. // br.ErrMsg = "文件上传失败, Err:" + e.Error()
  584. // return
  585. // }
  586. //}
  587. savePath := ossDir + time.Now().Format("200601/20060102/") + ossFileName
  588. ossClient := services.NewOssClient()
  589. if ossClient == nil {
  590. br.Msg = "上传失败"
  591. br.ErrMsg = "初始化OSS服务失败"
  592. return
  593. }
  594. resourceUrl, e = ossClient.UploadFile(ossFileName, filePath, savePath)
  595. if e != nil {
  596. br.Msg = "文件上传失败"
  597. br.ErrMsg = "文件上传失败,Err:" + e.Error()
  598. return
  599. }
  600. // 新增云盘资源
  601. extMap := services.GetCloudDiskResourceFileTypeExtMap()
  602. resourceIcon := extMap[ext]
  603. if resourceIcon == "" {
  604. resourceIcon = models.CloudDiskResourceFileTypeIconUnknown
  605. }
  606. resourceItem := &models.CloudDiskResource{
  607. MenuId: menuId,
  608. ResourceName: fileName,
  609. ResourceSuffix: ext,
  610. ResourceUrl: resourceUrl,
  611. ResourceIcon: resourceIcon,
  612. AdminId: this.SysUser.AdminId,
  613. AdminName: this.SysUser.RealName,
  614. Size: h.Size,
  615. CreateTime: time.Now().Local(),
  616. ModifyTime: time.Now().Local(),
  617. }
  618. if e = resourceItem.Create(); e != nil {
  619. br.Msg = "上传失败"
  620. br.ErrMsg = "新增云盘资源失败, Err: " + e.Error()
  621. return
  622. }
  623. // 更新目录大小
  624. go func() {
  625. if e = services.UpdateCloudDiskMenuSize(menuId); e != nil {
  626. alarm_msg.SendAlarmMsg("更新云盘目录大小失败, Err: "+e.Error(), 3)
  627. }
  628. }()
  629. br.Msg = "上传成功"
  630. br.Ret = 200
  631. br.Success = true
  632. br.Data = resourceItem
  633. }
  634. // ResourceRename 重命名文件
  635. // @Title 重命名文件
  636. // @Description 重命名文件
  637. // @Param request body models.CloudDiskResourceRenameReq true "type json string"
  638. // @Success 200 Ret=200 操作成功
  639. // @router /resource/rename [post]
  640. func (this *CloudDiskController) ResourceRename() {
  641. br := new(models.BaseResponse).Init()
  642. defer func() {
  643. this.Data["json"] = br
  644. this.ServeJSON()
  645. }()
  646. var req models.CloudDiskResourceRenameReq
  647. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  648. br.Msg = "参数解析异常!"
  649. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  650. return
  651. }
  652. if req.ResourceId <= 0 {
  653. br.Msg = "参数有误"
  654. return
  655. }
  656. req.ResourceName = strings.TrimSpace(req.ResourceName)
  657. if req.ResourceName == "" {
  658. br.Msg = "文件名称不可为空"
  659. return
  660. }
  661. // 权限校验-仅上传人或管理员可操作
  662. resourceItem := new(models.CloudDiskResource)
  663. if e := resourceItem.GetItemById(req.ResourceId); e != nil {
  664. br.Msg = "操作失败"
  665. br.ErrMsg = "获取文件信息失败, Err: " + e.Error()
  666. return
  667. }
  668. if resourceItem.AdminId != this.SysUser.AdminId {
  669. ok, e := services.CheckCloudDiskManagerAuth(this.SysUser.RoleTypeCode)
  670. if e != nil {
  671. br.Msg = "操作失败"
  672. br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
  673. return
  674. }
  675. if !ok {
  676. br.Msg = "无权操作"
  677. return
  678. }
  679. }
  680. // 重名校验
  681. existItem := new(models.CloudDiskResource)
  682. existCond := ` AND resource_name = ? AND menu_id = ? AND resource_id <> ? `
  683. existPars := make([]interface{}, 0)
  684. existPars = append(existPars, req.ResourceName, resourceItem.MenuId, resourceItem.ResourceId)
  685. if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
  686. br.Msg = "操作失败"
  687. br.ErrMsg = "获取重名文件失败, Err: " + e.Error()
  688. return
  689. }
  690. if existItem != nil && existItem.MenuId > 0 {
  691. br.Msg = "该文件名已存在"
  692. return
  693. }
  694. resourceItem.ResourceName = req.ResourceName
  695. resourceItem.ModifyTime = time.Now().Local()
  696. if e := resourceItem.Update([]string{"ResourceName", "ModifyTime"}); e != nil {
  697. br.Msg = "操作失败"
  698. br.ErrMsg = "文件重命名失败, Err: " + e.Error()
  699. return
  700. }
  701. br.Ret = 200
  702. br.Success = true
  703. br.Msg = "操作成功"
  704. }
  705. // ResourceDelete 删除文件
  706. // @Title 删除文件
  707. // @Description 删除文件
  708. // @Param request body models.CloudDiskResourceDeleteReq true "type json string"
  709. // @Success 200 Ret=200 操作成功
  710. // @router /resource/delete [post]
  711. func (this *CloudDiskController) ResourceDelete() {
  712. br := new(models.BaseResponse).Init()
  713. defer func() {
  714. this.Data["json"] = br
  715. this.ServeJSON()
  716. }()
  717. var req models.CloudDiskResourceDeleteReq
  718. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  719. br.Msg = "参数解析异常!"
  720. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  721. return
  722. }
  723. if req.ResourceId <= 0 {
  724. br.Msg = "参数有误"
  725. return
  726. }
  727. // 权限校验-仅上传人或管理员可操作
  728. resourceItem := new(models.CloudDiskResource)
  729. if e := resourceItem.GetItemById(req.ResourceId); e != nil {
  730. br.Msg = "操作失败"
  731. br.ErrMsg = "获取文件信息失败, Err: " + e.Error()
  732. return
  733. }
  734. if resourceItem.AdminId != this.SysUser.AdminId {
  735. ok, e := services.CheckCloudDiskManagerAuth(this.SysUser.RoleTypeCode)
  736. if e != nil {
  737. br.Msg = "操作失败"
  738. br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
  739. return
  740. }
  741. if !ok {
  742. br.Msg = "无权操作"
  743. return
  744. }
  745. }
  746. if e := resourceItem.Delete(); e != nil {
  747. br.Msg = "操作失败"
  748. br.ErrMsg = "删除文件失败, Err: " + e.Error()
  749. return
  750. }
  751. // 更新目录大小
  752. go func() {
  753. if e := services.UpdateCloudDiskMenuSize(resourceItem.MenuId); e != nil {
  754. alarm_msg.SendAlarmMsg("更新云盘目录大小失败, Err: "+e.Error(), 3)
  755. }
  756. }()
  757. br.Ret = 200
  758. br.Success = true
  759. br.Msg = "操作成功"
  760. }
  761. // List 云盘列表
  762. // @Title 云盘列表
  763. // @Description 云盘列表
  764. // @Param MenuId query int false "目录ID"
  765. // @Param Keyword query string false "关键词"
  766. // @Param SortType query int false "排序方式: 0-默认; 1-创建时间倒序; 2-创建时间正序"
  767. // @Success 200 Ret=200 获取成功
  768. // @router /list [get]
  769. func (this *CloudDiskController) List() {
  770. br := new(models.BaseResponse).Init()
  771. defer func() {
  772. this.Data["json"] = br
  773. this.ServeJSON()
  774. }()
  775. menuId, _ := this.GetInt("MenuId", 0)
  776. keyword := this.GetString("Keyword", "")
  777. sortType, _ := this.GetInt("SortType", 0)
  778. menuCond := ``
  779. menuPars := make([]interface{}, 0)
  780. resourceCond := ``
  781. resourcePars := make([]interface{}, 0)
  782. if keyword != "" {
  783. // 有关键词时全局搜索
  784. menuCond += ` AND menu_name LIKE ? `
  785. menuPars = append(menuPars, utils.GetLikeKeyword(keyword))
  786. resourceCond += ` AND resource_name LIKE ? `
  787. resourcePars = append(resourcePars, utils.GetLikeKeyword(keyword))
  788. } else {
  789. menuCond += ` AND parent_id = ? `
  790. menuPars = append(menuPars, menuId)
  791. resourceCond += ` AND menu_id = ? `
  792. resourcePars = append(resourcePars, menuId)
  793. }
  794. orderRule := `create_time DESC`
  795. if sortType == 2 {
  796. orderRule = `create_time ASC`
  797. }
  798. // 父级目录
  799. parentItem := new(models.CloudDiskMenu)
  800. parentCond := ``
  801. parentPars := make([]interface{}, 0)
  802. parentList, e := parentItem.GetItemsByCondition(parentCond, parentPars, []string{}, "")
  803. if e != nil {
  804. br.Msg = "获取失败"
  805. br.ErrMsg = "获取父级目录列表失败, Err: " + e.Error()
  806. return
  807. }
  808. parentNameMap := make(map[int]string)
  809. menuMap := make(map[int]*models.CloudDiskMenu)
  810. for i := range parentList {
  811. parentNameMap[parentList[i].MenuId] = parentList[i].MenuName
  812. menuMap[parentList[i].MenuId] = parentList[i]
  813. }
  814. list, e := models.GetCloudDiskMenuAndResourceList(menuCond, resourceCond, menuPars, resourcePars, orderRule)
  815. if e != nil {
  816. br.Msg = "获取失败"
  817. br.ErrMsg = "获取云盘列表数据失败, Err: " + e.Error()
  818. return
  819. }
  820. // 管理员权限
  821. ok, e := services.CheckCloudDiskManagerAuth(this.SysUser.RoleTypeCode)
  822. if e != nil {
  823. br.Msg = "操作失败"
  824. br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
  825. return
  826. }
  827. listResp := new(models.CloudDiskListResp)
  828. listResp.UploadResourceAuth = true
  829. if ok {
  830. listResp.CreateMenuAuth = true
  831. listResp.BatchDelAuth = true
  832. }
  833. menuCount := 0
  834. for i := range list {
  835. list[i].ParentName = parentNameMap[list[i].ParentId]
  836. if list[i].ItemType == 1 {
  837. menuCount += 1
  838. list[i].ItemIcon = models.CloudDiskResourceFileTypeIconMenu
  839. }
  840. list[i].SizeName = utils.FormatFileSize(list[i].Size)
  841. // 按钮权限
  842. au := new(models.CloudDiskListButton)
  843. if ok || (list[i].AdminId == this.SysUser.AdminId) {
  844. au.RenameAuth = true
  845. au.DelAuth = true
  846. }
  847. list[i].ButtonAuth = au
  848. }
  849. // 根目录无子目录时, 关闭上传文件按钮
  850. if menuId == 0 && menuCount == 0 {
  851. listResp.UploadResourceAuth = false
  852. }
  853. // 面包屑
  854. pathArr := make([]*models.CloudDiskMenuResourcePath, 0)
  855. pathArr = services.GetCloudDiskMenuOrResourcePath(menuId, 0, menuMap, menuMap[menuId], pathArr)
  856. listResp.ListPath = pathArr
  857. listResp.List = list
  858. br.Ret = 200
  859. br.Success = true
  860. br.Msg = "获取成功"
  861. br.Data = listResp
  862. }
  863. // BatchDelete 批量删除
  864. // @Title 批量删除
  865. // @Description 批量删除
  866. // @Param request body models.CloudDiskBatchDeleteReq true "type json string"
  867. // @Success 200 Ret=200 操作成功
  868. // @router /batch_delete [post]
  869. func (this *CloudDiskController) BatchDelete() {
  870. br := new(models.BaseResponse).Init()
  871. defer func() {
  872. this.Data["json"] = br
  873. this.ServeJSON()
  874. }()
  875. var req models.CloudDiskBatchDeleteReq
  876. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  877. br.Msg = "参数解析异常!"
  878. br.ErrMsg = "参数解析失败,Err:" + e.Error()
  879. return
  880. }
  881. if req.MenuIds == "" && req.ResourceIds == "" {
  882. br.Msg = "请选择目录或文件"
  883. return
  884. }
  885. menuIds := make([]int, 0)
  886. resourceIds := make([]int, 0)
  887. if req.MenuIds != "" {
  888. menuIdArr := strings.Split(req.MenuIds, ",")
  889. for i := range menuIdArr {
  890. n, e := strconv.Atoi(menuIdArr[i])
  891. if e != nil {
  892. br.Msg = "参数有误"
  893. br.ErrMsg = "参数有误, Err:" + e.Error()
  894. return
  895. }
  896. menuIds = append(menuIds, n)
  897. }
  898. }
  899. if req.ResourceIds != "" {
  900. resourceIdArr := strings.Split(req.ResourceIds, ",")
  901. for i := range resourceIdArr {
  902. n, e := strconv.Atoi(resourceIdArr[i])
  903. if e != nil {
  904. br.Msg = "参数有误"
  905. br.ErrMsg = "参数有误, Err:" + e.Error()
  906. return
  907. }
  908. resourceIds = append(resourceIds, n)
  909. }
  910. }
  911. // 权限校验-仅管理员可操作
  912. ok, e := services.CheckCloudDiskManagerAuth(this.SysUser.RoleTypeCode)
  913. if e != nil {
  914. br.Msg = "操作失败"
  915. br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
  916. return
  917. }
  918. if !ok {
  919. br.Msg = "无权操作"
  920. return
  921. }
  922. if e = models.BatchDeleteCloudDiskMenuAndResource(menuIds, resourceIds); e != nil {
  923. br.Msg = "操作失败"
  924. br.ErrMsg = "批量删除目录及文件失败, Err:" + e.Error()
  925. return
  926. }
  927. // 更新目录大小
  928. if req.MenuId > 0 {
  929. go func() {
  930. if e := services.UpdateCloudDiskMenuSize(req.MenuId); e != nil {
  931. alarm_msg.SendAlarmMsg("更新云盘目录大小失败, Err: "+e.Error(), 3)
  932. }
  933. }()
  934. }
  935. br.Ret = 200
  936. br.Success = true
  937. br.Msg = "操作成功"
  938. }