material.go 16 KB

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