ppt.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. package services
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta_gn/eta_api/models"
  6. "eta_gn/eta_api/models/system"
  7. "eta_gn/eta_api/services/alarm_msg"
  8. "eta_gn/eta_api/services/ppt2img"
  9. "eta_gn/eta_api/utils"
  10. "fmt"
  11. "sort"
  12. "time"
  13. )
  14. const (
  15. ElementsTypeText = "text"
  16. ElementsTypeImage = "image"
  17. ElementsTypeChart = "chart"
  18. ElementsTypeSheet = "sheet"
  19. )
  20. type PPTContent struct {
  21. Key int `json:"key"`
  22. ModelId int `json:"modelId"`
  23. Title string `json:"title"`
  24. Elements []PPTContentElements `json:"elements"`
  25. }
  26. type PPTContentElements struct {
  27. Type string `json:"type"`
  28. Position int `json:"position"`
  29. Content string `json:"content"`
  30. RichContent string `json:"richContent"`
  31. ChartId string `json:"chartId"`
  32. SheetId string `json:"sheetId"`
  33. SheetHeight string `json:"sheetHeight"`
  34. Src string `json:"src"`
  35. }
  36. func SavePPTReport(pptId, classifyId int, title string, adminInfo *system.Admin) (reportId int, reportCode, errMsg string, err error) {
  37. defer func() {
  38. if err != nil {
  39. utils.FileLog.Info("%s", err.Error())
  40. go alarm_msg.SendAlarmMsg("PPT转报告失败, SavePPTReport Msg: "+errMsg+", Err: "+err.Error(), 3)
  41. }
  42. }()
  43. if pptId == 0 {
  44. errMsg = "参数有误"
  45. err = errors.New("参数有误")
  46. return
  47. }
  48. item, e := models.GetPptV2ById(pptId)
  49. if e != nil {
  50. errMsg = "获取PPT失败"
  51. err = errors.New("获取PPT失败, Err: " + e.Error())
  52. return
  53. }
  54. htm, e := pptContent2Html(item.Content, false)
  55. if e != nil {
  56. errMsg = "转换失败"
  57. err = e
  58. return
  59. }
  60. if classifyId == 0 {
  61. errMsg = "请选择报告类型"
  62. err = errors.New("请选择报告类型")
  63. return
  64. }
  65. if title == "" {
  66. errMsg = "标题不能为空"
  67. err = errors.New("标题不能为空")
  68. return
  69. }
  70. classifyList, e := models.GetAllClassify()
  71. if e != nil {
  72. errMsg = "转换失败"
  73. err = errors.New("获取分类列表失败, Err: " + e.Error())
  74. return
  75. }
  76. classifyMap := make(map[int]*models.Classify, 0)
  77. for _, v := range classifyList {
  78. classifyMap[v.Id] = v
  79. }
  80. classifyIdFirst := 0
  81. classifyIdSecond := 0
  82. classifyIdThird := 0
  83. classifyNameFirst := ""
  84. classifyNameSecond := ""
  85. classifyNameThird := ""
  86. var baseClassify, twoClassify, threeClassify *models.Classify
  87. var hasTwo, hasThird bool
  88. baseClassify, ok := classifyMap[classifyId]
  89. if !ok {
  90. errMsg = "分类异常"
  91. err = errors.New("获取分类失败 ")
  92. return
  93. }
  94. twoClassify, hasTwo = classifyMap[baseClassify.ParentId]
  95. if hasTwo {
  96. threeClassify, hasThird = classifyMap[twoClassify.ParentId]
  97. }
  98. if hasThird { // 如果确实是有三级分类
  99. classifyIdFirst = threeClassify.Id
  100. classifyNameFirst = threeClassify.ClassifyName
  101. classifyIdSecond = twoClassify.Id
  102. classifyNameSecond = twoClassify.ClassifyName
  103. classifyIdThird = baseClassify.Id
  104. classifyNameThird = baseClassify.ClassifyName
  105. } else if hasTwo {
  106. classifyIdFirst = twoClassify.Id
  107. classifyNameFirst = twoClassify.ClassifyName
  108. classifyIdSecond = baseClassify.Id
  109. classifyNameSecond = baseClassify.ClassifyName
  110. } else {
  111. classifyIdFirst = baseClassify.Id
  112. classifyNameFirst = baseClassify.ClassifyName
  113. }
  114. nowTime := time.Now().Local()
  115. reportReq := &models.AddReq{
  116. AddType: 1,
  117. ClassifyIdFirst: classifyIdFirst,
  118. ClassifyNameFirst: classifyNameFirst,
  119. ClassifyIdSecond: classifyIdSecond,
  120. ClassifyNameSecond: classifyNameSecond,
  121. ClassifyIdThird: classifyIdThird,
  122. ClassifyNameThird: classifyNameThird,
  123. Title: title,
  124. Abstract: "",
  125. Author: "",
  126. Frequency: utils.ReportFrequencyDefault,
  127. State: 1,
  128. Content: htm,
  129. CreateTime: nowTime.Format(utils.FormatDateTime),
  130. ReportVersion: 2,
  131. CollaborateType: 1, // 协作方式,1:个人,2:多人协作。默认:1
  132. ReportLayout: 1, // 报告布局,1:常规布局,2:智能布局。默认:1
  133. IsPublicPublish: 2, // 是否公开发布,1:是,2:否
  134. }
  135. if item.IsShare == 1 {
  136. reportReq.IsPublicPublish = 1
  137. }
  138. newReportId, newCode, _, e := CreateNewReport(*reportReq, adminInfo)
  139. if e != nil {
  140. errMsg = "转换失败"
  141. err = errors.New("新增报告失败, Err: " + e.Error())
  142. return
  143. }
  144. reportId = int(newReportId)
  145. reportCode = newCode
  146. go saveReportPptImg(pptId, reportId, item.PptxUrl)
  147. return
  148. }
  149. func pptContent2Html(content string, isEnglish bool) (htm string, err error) {
  150. contents := make([]PPTContent, 0)
  151. if e := json.Unmarshal([]byte(content), &contents); e != nil {
  152. err = errors.New("PPT内容转换失败")
  153. return
  154. }
  155. pageLen := len(contents)
  156. htmlContent := ``
  157. smsCond := ` AND conf_key = ? `
  158. smsPars := make([]interface{}, 0)
  159. smsPars = append(smsPars, "ChartViewUrl")
  160. conf := new(models.BusinessConf)
  161. conf, e := conf.GetItemByCondition(smsCond, smsPars)
  162. if e != nil {
  163. if utils.IsErrNoRow(e) {
  164. err = fmt.Errorf("请先配置公共图库的地址")
  165. return
  166. }
  167. err = fmt.Errorf("获取聚合短信配置信息失败, Err: %s", e.Error())
  168. return
  169. }
  170. if conf.ConfVal == "" {
  171. err = fmt.Errorf("请先配置公共图库的地址")
  172. return
  173. }
  174. chartRoot := conf.ConfVal
  175. if pageLen > 0 {
  176. htmlPrefix := `<p style="text-align: left; margin-top: 10px; font-size: 16px;">`
  177. htmlSuffix := `</p>`
  178. htmlBr := `<br>`
  179. for i := 0; i < pageLen; i++ {
  180. title := contents[i].Title
  181. if title != "" {
  182. htmlContent += `<p style="font-size: 16px; text-align: left;"><strong>`
  183. htmlContent += title
  184. htmlContent += `</strong></p>`
  185. }
  186. ele := contents[i].Elements
  187. sort.Slice(ele, func(k, j int) bool {
  188. return ele[k].Position < ele[j].Position
  189. })
  190. for _, v := range ele {
  191. htmlContent += htmlPrefix
  192. switch v.Type {
  193. case ElementsTypeText:
  194. htmlContent += v.RichContent
  195. case ElementsTypeImage:
  196. htmlContent += fmt.Sprint(`<img src="`, v.Src, `" class="fr-fic fr-dib fr-draggable">`)
  197. case ElementsTypeChart:
  198. if isEnglish {
  199. htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s&fromPage=en" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
  200. break
  201. }
  202. htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
  203. case ElementsTypeSheet:
  204. htmlContent += fmt.Sprintf(`<iframe src="%s/sheetshow?code=%s" class="iframe%s" width="100%%" height="%s" style="border-width:0px;"></iframe>`, chartRoot, v.SheetId, v.SheetId, v.SheetHeight)
  205. }
  206. htmlContent += htmlSuffix
  207. }
  208. currentPage := i + 1
  209. if currentPage != pageLen {
  210. htmlContent += htmlPrefix + htmlBr + htmlSuffix
  211. }
  212. }
  213. }
  214. htm = htmlContent
  215. return
  216. }
  217. func ResetPPTReport(reportId int, isEnglish bool) (err error) {
  218. defer func() {
  219. if err != nil {
  220. utils.FileLog.Info("%s", err.Error())
  221. go alarm_msg.SendAlarmMsg("重置PPT关联报告失败, ResetPPTReport Err: "+err.Error(), 3)
  222. }
  223. }()
  224. item, e := models.GetPptV2ByReportId(reportId)
  225. if e != nil && !utils.IsErrNoRow(e) {
  226. err = errors.New("获取PPT失败, Err: " + e.Error())
  227. return
  228. }
  229. if item != nil {
  230. updateCols := []string{"ReportId", "ReportCode"}
  231. item.ReportId = 0
  232. item.ReportCode = ""
  233. if e = item.Update(updateCols); e != nil {
  234. err = errors.New("更新PPT关联报告失败, Err: " + e.Error())
  235. return
  236. }
  237. }
  238. return
  239. }
  240. func saveReportPptImg(pptId, reportId int, pptUrl string) {
  241. var err error
  242. defer func() {
  243. if err != nil {
  244. utils.FileLog.Info(fmt.Sprintf("将ppt转图片失败, saveReportPptImg Err:%s", err.Error()))
  245. go alarm_msg.SendAlarmMsg("将ppt转图片失败, saveReportPptImg Err: "+err.Error(), 3)
  246. }
  247. }()
  248. report, e := models.GetReportByReportId(reportId)
  249. if e != nil && !utils.IsErrNoRow(e) {
  250. err = errors.New("获取报告失败, Err: " + e.Error())
  251. return
  252. }
  253. if report == nil {
  254. return
  255. }
  256. list, err := ppt2img.Ppt2Img(pptUrl)
  257. if err != nil {
  258. return
  259. }
  260. reportPptImgList := make([]*models.ReportPptImg, 0)
  261. for _, v := range list {
  262. reportPptImg := &models.ReportPptImg{
  263. PptId: pptId,
  264. ReportId: reportId,
  265. ReportChapterId: 0,
  266. ImgUrl: v,
  267. CreateTime: time.Now(),
  268. }
  269. reportPptImgList = append(reportPptImgList, reportPptImg)
  270. }
  271. err = models.AddAndEditMultiReportPptImg(pptId, reportPptImgList)
  272. return
  273. }
  274. func UpdatePptEditing(pptId, status, userId int, userName string, isEn bool) (ret models.PPTEditingCache, err error) {
  275. if pptId <= 0 {
  276. return
  277. }
  278. cacheKey := ""
  279. if isEn {
  280. cacheKey = fmt.Sprint(utils.CACHE_EN_PPT_EDITING, pptId)
  281. } else {
  282. cacheKey = fmt.Sprint(utils.CACHE_PPT_EDITING, pptId)
  283. }
  284. if status == 2 {
  285. _ = utils.Rc.Delete(cacheKey)
  286. return
  287. }
  288. var editor models.PPTEditingCache
  289. strCache, _ := utils.Rc.RedisString(cacheKey)
  290. fmt.Println(strCache)
  291. if strCache != "" {
  292. e := json.Unmarshal([]byte(strCache), &editor)
  293. if e != nil {
  294. err = fmt.Errorf("解析缓存内容失败: %s", e.Error())
  295. return
  296. }
  297. }
  298. if status == 1 {
  299. if !editor.IsEditing {
  300. ret.IsEditing = true
  301. ret.AdminId = userId
  302. ret.Editor = userName
  303. ret.Tips = fmt.Sprintf("当前%s正在编辑PPT", userName)
  304. b, _ := json.Marshal(ret)
  305. utils.Rc.SetNX(cacheKey, string(b), 3*time.Minute)
  306. return
  307. }
  308. if editor.IsEditing {
  309. if userId == editor.AdminId {
  310. b, _ := json.Marshal(editor)
  311. utils.Rc.Do("SETEX", cacheKey, int64(180), string(b))
  312. }
  313. ret = editor
  314. return
  315. }
  316. } else {
  317. ret = editor
  318. }
  319. return
  320. }