material.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. package materialService
  2. import (
  3. "eta/eta_api/models"
  4. "eta/eta_api/models/data_manage"
  5. "eta/eta_api/models/data_manage/excel"
  6. "eta/eta_api/models/material"
  7. "eta/eta_api/models/sandbox"
  8. "eta/eta_api/models/system"
  9. "eta/eta_api/services"
  10. _interface "eta/eta_api/services/interface"
  11. "eta/eta_api/utils"
  12. "fmt"
  13. "github.com/rdlucklib/rdluck_tools/http"
  14. "os"
  15. "path"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. func materialClassifyHaveChild(allNode []*material.MaterialClassifyItems, node *material.MaterialClassifyItems) (childs []*material.MaterialClassifyItems, yes bool) {
  21. for _, v := range allNode {
  22. if v.ParentId == node.ClassifyId {
  23. childs = append(childs, v)
  24. }
  25. }
  26. if len(childs) > 0 {
  27. yes = true
  28. }
  29. return
  30. }
  31. func MaterialClassifyItemsMakeTree(sysUser *system.Admin, allNode []*material.MaterialClassifyItems, node *material.MaterialClassifyItems) {
  32. childs, _ := materialClassifyHaveChild(allNode, node) //判断节点是否有子节点并返回
  33. if len(childs) > 0 {
  34. node.Children = append(node.Children, childs[0:]...) //添加子节点
  35. for _, v := range childs { //查询子节点的子节点,并添加到子节点
  36. _, has := materialClassifyHaveChild(allNode, v)
  37. if has {
  38. MaterialClassifyItemsMakeTree(sysUser, allNode, v) //递归添加节点
  39. } else {
  40. childrenArr := make([]*material.MaterialClassifyItems, 0)
  41. v.Children = childrenArr
  42. }
  43. }
  44. } else {
  45. childrenArr := make([]*material.MaterialClassifyItems, 0)
  46. node.Children = childrenArr
  47. }
  48. }
  49. // GetMaterialClassifyListForMe 获取我创建的素材
  50. func GetMaterialClassifyListForMe(adminInfo system.Admin, resp *material.MaterialClassifyListResp, classifyId int) (errMsg string, err error) {
  51. classifyAll, err := material.GetMaterialClassifyByParentId(classifyId)
  52. if err != nil && err.Error() != utils.ErrNoRow() {
  53. errMsg = "获取失败"
  54. return
  55. }
  56. nodeAll := make([]*material.MaterialClassifyItems, 0)
  57. for k := range classifyAll {
  58. rootNode := classifyAll[k]
  59. MaterialClassifyItemsMakeTree(&adminInfo, classifyAll, rootNode)
  60. nodeAll = append(nodeAll, rootNode)
  61. }
  62. resp.AllNodes = nodeAll
  63. return
  64. }
  65. func BatchAddMaterial(materialList []material.BatchAddMaterialItem, classifyId, opUserId int, opUserName string) (err error) {
  66. addList := make([]*material.Material, 0)
  67. sort, err := material.GetMaterialMaxSort()
  68. if err != nil {
  69. return
  70. }
  71. for _, v := range materialList {
  72. sort = sort + 1
  73. addList = append(addList, &material.Material{
  74. MaterialName: v.MaterialName,
  75. MaterialNameEn: v.MaterialName,
  76. ImgUrl: v.ImgUrl,
  77. SysUserId: opUserId,
  78. SysUserRealName: opUserName,
  79. ModifyTime: time.Now(),
  80. CreateTime: time.Now(),
  81. ClassifyId: classifyId,
  82. Sort: sort,
  83. })
  84. }
  85. if len(addList) > 0 {
  86. err = material.AddMultiMaterial(addList)
  87. }
  88. return
  89. }
  90. // AddToMaterial 将图库等封面上传至素材库
  91. func AddToMaterial(req material.SaveAsMaterialReq, opUserId int, opUserName string) (err error, errMsg string) {
  92. // 判断出对应的类型,得倒最终的资源地址
  93. oldRsourceUrl := ""
  94. switch req.ObjectType {
  95. case "chart":
  96. // 获取图表封面地址
  97. chartInfo, e := data_manage.GetChartInfoById(req.ObjectId)
  98. if e != nil {
  99. if e.Error() == utils.ErrNoRow() {
  100. errMsg = "图表不存在"
  101. err = fmt.Errorf("图表不存在")
  102. return
  103. }
  104. errMsg = "获取图表信息失败"
  105. err = e
  106. return
  107. }
  108. if chartInfo.ChartImage == "" {
  109. errMsg = "图表封面为空"
  110. err = fmt.Errorf("图表封面为空")
  111. return
  112. }
  113. oldRsourceUrl = chartInfo.ChartImage
  114. case "sandbox":
  115. // 获取逻辑图
  116. sandboxInfo, e := sandbox.GetSandboxById(req.ObjectId)
  117. if e != nil {
  118. if e.Error() == utils.ErrNoRow() {
  119. errMsg = "逻辑图不存在"
  120. err = fmt.Errorf("逻辑图不存在")
  121. return
  122. }
  123. errMsg = "获取逻辑图信息失败"
  124. err = e
  125. return
  126. }
  127. if sandboxInfo.PicUrl == "" { // 获取逻辑图封面地址
  128. errMsg = "逻辑图封面为空"
  129. err = fmt.Errorf("逻辑图封面为空")
  130. return
  131. }
  132. oldRsourceUrl = sandboxInfo.PicUrl
  133. case "excel":
  134. // 获取表格封面地址
  135. excelInfo, e := excel.GetExcelViewInfoByExcelInfoId(req.ObjectId)
  136. if e != nil {
  137. if e.Error() == utils.ErrNoRow() {
  138. errMsg = "表格不存在"
  139. err = fmt.Errorf("表格不存在")
  140. return
  141. }
  142. errMsg = "获取表格信息失败"
  143. err = e
  144. return
  145. }
  146. if excelInfo.ExcelImage == "" {
  147. errMsg = "表格封面为空"
  148. err = fmt.Errorf("表格封面为空")
  149. return
  150. }
  151. oldRsourceUrl = excelInfo.ExcelImage
  152. default:
  153. errMsg = "不支持的类型"
  154. err = fmt.Errorf("不支持的类型")
  155. return
  156. }
  157. resourceUrl, err, errMsg := uploadToMaterial(oldRsourceUrl)
  158. if err != nil {
  159. return
  160. }
  161. // 新增素材库
  162. sort, err := material.GetMaterialMaxSort()
  163. if err != nil {
  164. return
  165. }
  166. //素材主表信息
  167. materialInfo := &material.Material{
  168. MaterialName: utils.TrimStr(req.MaterialName),
  169. MaterialNameEn: utils.TrimStr(req.MaterialName),
  170. ImgUrl: utils.TrimStr(resourceUrl),
  171. SysUserId: opUserId,
  172. SysUserRealName: opUserName,
  173. ModifyTime: time.Now(),
  174. CreateTime: time.Now(),
  175. ClassifyId: req.ClassifyId,
  176. Sort: sort + 1,
  177. }
  178. //新增素材
  179. id, err := material.AddMaterial(materialInfo)
  180. if err != nil {
  181. return
  182. }
  183. materialInfo.MaterialId = int(id)
  184. return
  185. }
  186. // MyChartAddToMaterial 将我的
  187. func MyChartAddToMaterial(req material.MyChartSaveAsMaterialReq, opUserId int, opUserName string) (err error, errMsg string) {
  188. // 判断出对应的类型,得倒最终的资源地址
  189. // 获取图表ID
  190. chartInfoIds := make([]int, 0)
  191. for _, v := range req.MaterialList {
  192. chartInfoIds = append(chartInfoIds, v.ChartInfoId)
  193. }
  194. // 获取图表信息
  195. if len(chartInfoIds) <= 0 {
  196. return
  197. }
  198. chartInfoList, e := data_manage.GetChartInfoByIdList(chartInfoIds)
  199. if e != nil {
  200. if e.Error() == utils.ErrNoRow() {
  201. errMsg = "图表不存在"
  202. err = fmt.Errorf("图表不存在")
  203. return
  204. }
  205. errMsg = "获取图表信息失败"
  206. err = e
  207. return
  208. }
  209. chartInfoMap := make(map[int]string)
  210. for _, v := range chartInfoList {
  211. if v.ChartImage == "" {
  212. errMsg = "图表封面为空"
  213. err = fmt.Errorf("图表封面为空")
  214. return
  215. }
  216. chartInfoMap[v.ChartInfoId] = v.ChartImage
  217. }
  218. addList := make([]*material.Material, 0)
  219. sort, err := material.GetMaterialMaxSort()
  220. if err != nil {
  221. return
  222. }
  223. for _, v := range req.MaterialList {
  224. sort = sort + 1
  225. oldResourceUrl, ok := chartInfoMap[v.ChartInfoId]
  226. if !ok {
  227. return
  228. }
  229. resourceUrl := ""
  230. resourceUrl, err, errMsg = uploadToMaterial(oldResourceUrl)
  231. if err != nil {
  232. return
  233. }
  234. // 新增素材库
  235. //素材主表信息
  236. materialInfo := &material.Material{
  237. MaterialName: utils.TrimStr(v.MaterialName),
  238. MaterialNameEn: utils.TrimStr(v.MaterialName),
  239. ImgUrl: utils.TrimStr(resourceUrl),
  240. SysUserId: opUserId,
  241. SysUserRealName: opUserName,
  242. ModifyTime: time.Now(),
  243. CreateTime: time.Now(),
  244. ClassifyId: v.ClassifyId,
  245. Sort: sort,
  246. }
  247. addList = append(addList, materialInfo)
  248. }
  249. if len(addList) > 0 {
  250. err = material.AddMultiMaterial(addList)
  251. }
  252. return
  253. }
  254. func uploadToMaterial(oldRsourceUrl string) (resourceUrl string, err error, errMsg string) {
  255. // 下载资源地址内容,并上传至存储空间得倒最终的素材地址
  256. urlFileName := path.Base(oldRsourceUrl)
  257. uploadDir := utils.STATIC_DIR + "hongze/" + time.Now().Format("20060102")
  258. if e := os.MkdirAll(uploadDir, utils.DIR_MOD); e != nil {
  259. errMsg = "存储目录创建失败"
  260. err = fmt.Errorf("存储目录创建失败, Err:" + e.Error())
  261. return
  262. }
  263. var content []byte
  264. content, err = http.Get(oldRsourceUrl)
  265. if err != nil {
  266. errMsg = "操作失败"
  267. err = fmt.Errorf("资源获取失败, Err: " + err.Error())
  268. return
  269. }
  270. filePath := uploadDir + "/" + urlFileName
  271. ioWriter, err := os.Create(filePath)
  272. if err != nil {
  273. errMsg = "操作失败"
  274. err = fmt.Errorf("文件创建失败, Err: " + err.Error())
  275. return
  276. }
  277. n, err := ioWriter.Write(content)
  278. fmt.Println("n", n)
  279. if err != nil {
  280. errMsg = "操作失败"
  281. err = fmt.Errorf("压缩文件写入失败, Err: " + err.Error())
  282. return
  283. }
  284. ext := path.Ext(urlFileName)
  285. randStr := utils.GetRandStringNoSpecialChar(28)
  286. newFileName := randStr + ext
  287. // 上传到阿里云
  288. ossDir := utils.RESOURCE_DIR + "material_dir/"
  289. savePath := ossDir + time.Now().Format("200601/20060102/") + newFileName
  290. // 上传文件
  291. ossClient := services.NewOssClient()
  292. if ossClient == nil {
  293. err = fmt.Errorf("初始化OSS服务失败")
  294. return
  295. }
  296. resourceUrl, err = ossClient.UploadFile(newFileName, filePath, savePath)
  297. if err != nil {
  298. err = fmt.Errorf("文件上传失败, Err: %s", err.Error())
  299. return
  300. }
  301. defer func() {
  302. os.Remove(filePath)
  303. }()
  304. return
  305. }
  306. func MaterialItemsMakeTree(allNode []*material.MaterialClassifyItems, sandListMap map[int][]*material.MaterialClassifyItems, classifyId int) (nodeAll []*material.MaterialClassifyItems) {
  307. for k := range allNode {
  308. if len(allNode[k].Children) > 0 {
  309. MaterialItemsMakeTree(allNode[k].Children, sandListMap, classifyId)
  310. allNode = append(allNode, sandListMap[allNode[k].ParentId]...)
  311. nodeAll = allNode
  312. } else if k == len(allNode)-1 {
  313. allNode = append(allNode, sandListMap[allNode[k].ParentId]...)
  314. nodeAll = allNode
  315. }
  316. }
  317. if len(allNode) == 0 {
  318. nodeAll = append(nodeAll, sandListMap[classifyId]...)
  319. }
  320. return
  321. }
  322. func MaterialClassifyHaveChild(allNode []*material.MaterialClassifyItems, node *material.MaterialClassifyItems) (childs []*material.MaterialClassifyItems, yes bool) {
  323. for _, v := range allNode {
  324. if v.ParentId == node.ClassifyId {
  325. childs = append(childs, v)
  326. }
  327. }
  328. if len(childs) > 0 {
  329. yes = true
  330. }
  331. return
  332. }
  333. func MaterialClassifyItemsMakeTreeV2(sysUser *system.Admin, allNode []*material.MaterialClassifyItems, node *material.MaterialClassifyItems) {
  334. childs, _ := materialClassifyHaveChildV2(allNode, node) //判断节点是否有子节点并返回
  335. if len(childs) > 0 {
  336. node.Children = append(node.Children, childs[0:]...) //添加子节点
  337. for _, v := range childs { //查询子节点的子节点,并添加到子节点
  338. _, has := materialClassifyHaveChildV2(allNode, v)
  339. if has {
  340. MaterialClassifyItemsMakeTreeV2(sysUser, allNode, v) //递归添加节点
  341. }
  342. }
  343. }
  344. }
  345. func materialClassifyHaveChildV2(allNode []*material.MaterialClassifyItems, node *material.MaterialClassifyItems) (childs []*material.MaterialClassifyItems, yes bool) {
  346. for _, v := range allNode {
  347. if v.ParentId == node.ClassifyId && node.ClassifyId == 0 {
  348. childs = append(childs, v)
  349. }
  350. }
  351. if len(childs) > 0 {
  352. yes = true
  353. }
  354. return
  355. }
  356. func MoveMaterialClassify(classifyInfo *material.MaterialClassify, req *material.MoveMaterialClassifyReq) (err error, errMsg string) {
  357. nodeMove := models.SingleMoveNodeReq{}
  358. nodeMove.NodeId = req.ClassifyId
  359. nodeMove.ParentNodeId = req.ParentClassifyId
  360. nodeMove.PrevNodeId = req.PrevClassifyId
  361. nodeMove.NextNodeId = req.NextClassifyId
  362. materialClassifyMove := new(ClassifyMove)
  363. nodeInfo, updateCol, err, errMsg := _interface.MoveSingleNode(materialClassifyMove, nodeMove)
  364. if err != nil {
  365. return
  366. }
  367. oldParentId := classifyInfo.ParentId
  368. oldLevelPath := classifyInfo.LevelPath
  369. if len(updateCol) > 0 {
  370. classifyInfo.Sort = nodeInfo.Sort
  371. classifyInfo.ModifyTime = nodeInfo.ModifyTime
  372. classifyInfo.ParentId = nodeInfo.ParentId
  373. levelPath := classifyInfo.LevelPath
  374. if classifyInfo.ParentId != oldParentId {
  375. //查找父级分类
  376. parentClassify, e := material.GetMaterialClassifyById(classifyInfo.ParentId)
  377. if e != nil {
  378. errMsg = "获取父级分类失败"
  379. err = fmt.Errorf("获取父级分类失败,Err:" + e.Error())
  380. return
  381. }
  382. levelPath = fmt.Sprintf("%s,%d", parentClassify.LevelPath, classifyInfo.ClassifyId)
  383. classifyInfo.LevelPath = levelPath
  384. updateCol = append(updateCol, "LevelPath")
  385. }
  386. err = classifyInfo.Update(updateCol)
  387. if err != nil {
  388. err = fmt.Errorf("修改失败,Err:" + err.Error())
  389. return
  390. }
  391. if classifyInfo.ParentId != oldParentId {
  392. tmpList, e := material.GetMaterialClassifyByLevelPath(oldLevelPath)
  393. if e != nil {
  394. err = fmt.Errorf("保存分类失败,Err:" + e.Error())
  395. return
  396. }
  397. // 把原先的父级levePath,替换成最新的父级序列
  398. for _, tmp := range tmpList {
  399. //获取字符串前缀的位置
  400. after, _ := strings.CutPrefix(tmp.LevelPath, oldLevelPath)
  401. fmt.Println("after", after)
  402. // 拼接字符串
  403. if after != "" {
  404. tmp.LevelPath = levelPath + after
  405. tmp.ModifyTime = time.Now()
  406. e = tmp.Update([]string{"LevelPath", "ModifyTime"})
  407. if e != nil {
  408. err = fmt.Errorf("修改子分类,Err:" + e.Error())
  409. return
  410. }
  411. }
  412. }
  413. }
  414. }
  415. return
  416. }
  417. type ClassifyMove struct{}
  418. func (m *ClassifyMove) GetNodeInfoById(nodeId int) (nodeInfo *models.NodeInfo, err error) {
  419. classifyInfo, err := material.GetMaterialClassifyById(nodeId)
  420. if err != nil {
  421. return
  422. }
  423. nodeInfo = &models.NodeInfo{
  424. NodeId: classifyInfo.ClassifyId,
  425. NodeName: classifyInfo.ClassifyName,
  426. ParentId: classifyInfo.ParentId,
  427. Level: classifyInfo.Level,
  428. Sort: classifyInfo.Sort,
  429. ModifyTime: classifyInfo.ModifyTime,
  430. }
  431. return
  432. }
  433. func (m *ClassifyMove) UpdateNodeInfoSortByParentIdAndSource(parentNodeId, nodeId, prevNodeSort int, updateSortStr string, nodeType int) (err error) {
  434. err = material.UpdateMaterialClassifySortByParentId(parentNodeId, nodeId, prevNodeSort, updateSortStr)
  435. return
  436. }
  437. func (m *ClassifyMove) GetNodeMaxSort(parentId, nodeType int) (maxSort int, err error) {
  438. maxSort, err = material.GetMaterialClassifyMaxSort(parentId)
  439. return
  440. }
  441. func (m *ClassifyMove) GetFirstNodeInfoByParentId(parentId int) (nodeInfo *models.NodeInfo, err error) {
  442. classifyInfo, err := material.GetFirstMaterialClassifyByParentId(parentId)
  443. if err != nil {
  444. return
  445. }
  446. nodeInfo = &models.NodeInfo{
  447. NodeId: classifyInfo.ClassifyId,
  448. NodeName: classifyInfo.ClassifyName,
  449. ParentId: classifyInfo.ParentId,
  450. Level: classifyInfo.Level,
  451. Sort: classifyInfo.Sort,
  452. ModifyTime: classifyInfo.ModifyTime,
  453. }
  454. return
  455. }
  456. func GetBatchSelectedMaterialList(classifyId int, keyword string, isShowMe bool, sysUser *system.Admin, lang string) (list []*material.MaterialListItems, err error, errMsg string) {
  457. var condition string
  458. var pars []interface{}
  459. if classifyId <= 0 {
  460. errMsg = "请选择分类"
  461. err = fmt.Errorf(errMsg)
  462. return
  463. }
  464. // 查询当前的分类
  465. classifyInfo, e := material.GetMaterialClassifyById(classifyId)
  466. if e != nil {
  467. errMsg = "分类不存在"
  468. err = fmt.Errorf("获取分类信息失败,Err:" + e.Error())
  469. return
  470. }
  471. // 获取所有子分类
  472. childList, e := material.GetMaterialClassifyByLevelPath(classifyInfo.LevelPath)
  473. if e != nil {
  474. errMsg = "获取分类失败"
  475. err = fmt.Errorf("获取子分类失败,Err:" + e.Error())
  476. return
  477. }
  478. // 把原先的父级levePath,替换成最新的父级序列
  479. classifyIdMap := make(map[string]struct{})
  480. classifyIds := make([]string, 0)
  481. childClassifyMap := make(map[int]*material.MaterialClassify)
  482. for _, tmp := range childList {
  483. childClassifyMap[tmp.ClassifyId] = tmp
  484. //获取字符串前缀的位置
  485. after, _ := strings.CutPrefix(tmp.LevelPath, classifyInfo.LevelPath)
  486. fmt.Println("after", after)
  487. // 拼接字符串
  488. if after != "" {
  489. ids := strings.Split(after, ",")
  490. for _, v := range ids {
  491. if _, ok := classifyIdMap[v]; !ok {
  492. classifyIds = append(classifyIds, v)
  493. classifyIdMap[v] = struct{}{}
  494. }
  495. }
  496. }
  497. }
  498. classifyIds = append(classifyIds, strconv.Itoa(classifyId))
  499. if len(classifyIds) > 0 {
  500. condition += " AND classify_id IN(" + utils.GetOrmInReplace(len(classifyIds)) + ") "
  501. pars = append(pars, classifyIds)
  502. }
  503. if keyword != "" {
  504. switch lang {
  505. case utils.LANG_EN:
  506. condition += ` AND ( material_name_en LIKE '%` + keyword + `%' )`
  507. default:
  508. condition += ` AND ( material_name LIKE '%` + keyword + `%' )`
  509. }
  510. }
  511. //只看我的
  512. if isShowMe {
  513. condition += ` AND sys_user_id = ? `
  514. pars = append(pars, sysUser.AdminId)
  515. }
  516. //获取图表信息
  517. list, err = material.GetMaterialListByCondition(condition, pars)
  518. if err != nil && err.Error() != utils.ErrNoRow() {
  519. errMsg = "获取素材库信息失败"
  520. err = fmt.Errorf("获取素材库信息失败,Err:" + err.Error())
  521. return
  522. }
  523. return
  524. }