activity_poster.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. package cygx
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "hongze/hz_crm_api/models"
  7. "hongze/hz_crm_api/models/cygx"
  8. "hongze/hz_crm_api/services"
  9. "hongze/hz_crm_api/services/alarm_msg"
  10. "hongze/hz_crm_api/utils"
  11. "io"
  12. "io/ioutil"
  13. "net/http"
  14. "os"
  15. "strconv"
  16. "strings"
  17. "time"
  18. )
  19. var (
  20. ServerUrl = "http://127.0.0.1:5008/"
  21. Cygx_activity_sigin_html = "cygx_activity_sigin_html"
  22. Cygx_mp3_html = "cygx_mp3_html"
  23. Cygx_mp4_html = "cygx_mp4_html"
  24. Cygx_mp3_yx_html = "cygx_mp3_yx_html"
  25. Cygx_mp4_yx_html = "cygx_mp4_yx_html"
  26. )
  27. type Html2ImgResp struct {
  28. Code int `json:"code"`
  29. Msg string `json:"msg"`
  30. Data string `json:"data"`
  31. }
  32. // postHtml2Img 请求htm2img接口
  33. func postHtml2Img(param map[string]interface{}) (resp *Html2ImgResp, err error) {
  34. // 目前仅此处调用该接口,暂不加授权、校验等
  35. postUrl := ServerUrl + "htm2img"
  36. postData, err := json.Marshal(param)
  37. if err != nil {
  38. return
  39. }
  40. result, err := Html2ImgHttpPost(postUrl, string(postData), "application/json")
  41. if err != nil {
  42. return
  43. }
  44. if err = json.Unmarshal(result, &resp); err != nil {
  45. return
  46. }
  47. return resp, nil
  48. }
  49. // Html2ImgHttpPost post请求
  50. func Html2ImgHttpPost(url, postData string, params ...string) ([]byte, error) {
  51. body := ioutil.NopCloser(strings.NewReader(postData))
  52. client := &http.Client{}
  53. req, err := http.NewRequest("POST", url, body)
  54. if err != nil {
  55. return nil, err
  56. }
  57. contentType := "application/x-www-form-urlencoded;charset=utf-8"
  58. if len(params) > 0 && params[0] != "" {
  59. contentType = params[0]
  60. }
  61. req.Header.Set("Content-Type", contentType)
  62. resp, err := client.Do(req)
  63. if err != nil {
  64. return nil, err
  65. }
  66. defer resp.Body.Close()
  67. b, err := ioutil.ReadAll(resp.Body)
  68. fmt.Println("HttpPost:" + string(b))
  69. return b, err
  70. }
  71. //func init() {
  72. // MakeActivitySigninImg(2161)
  73. //}
  74. // MakeActivitySigninImg 生成太阳码并上传OSS
  75. func MakeActivitySigninImg(activityId int) (imgUrl string, err error) {
  76. var msg string
  77. defer func() {
  78. if err != nil || msg != "" {
  79. fmt.Println(err)
  80. utils.FileLog.Info("MakeActivitySigninImg Err:", err.Error())
  81. go alarm_msg.SendAlarmMsg("扫码签到日志记录,失败,活动ID:"+strconv.Itoa(activityId)+err.Error()+";msg:"+msg, 3)
  82. }
  83. }()
  84. activityInfo, e := cygx.GetAddActivityInfoById(activityId)
  85. if e != nil {
  86. err = errors.New("活动不存在, Err: " + e.Error())
  87. return
  88. }
  89. if activityInfo == nil {
  90. return
  91. }
  92. if activityInfo.ActivityTypeId != 5 && activityInfo.ActivityTypeId != 6 && activityInfo.ActivityTypeId != 8 {
  93. return
  94. }
  95. itemToken, err := models.GetWxToken(utils.WxCygxAppId, utils.WxCygxAppSecret)
  96. if err != nil {
  97. return
  98. }
  99. if itemToken.AccessToken == "" {
  100. msg = "accessToken is empty"
  101. return
  102. }
  103. var envVersion string
  104. var resourceUrl string
  105. if utils.RunMode == "release" {
  106. envVersion = "release"
  107. } else {
  108. envVersion = "trial"
  109. }
  110. url := "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + itemToken.AccessToken
  111. method := "POST"
  112. payload := strings.NewReader(`{
  113. "page":"` + utils.WX_MSG_PATH_ACTIVITY_SIGNIN + `",
  114. "scene":"` + strconv.Itoa(activityId) + `",
  115. "env_version":"` + envVersion + `",
  116. "check_path":false,
  117. "auto_color":true
  118. }`)
  119. client := &http.Client{}
  120. req, err := http.NewRequest(method, url, payload)
  121. if err != nil {
  122. msg = "获取微信二维码失败,Err:" + err.Error()
  123. return
  124. }
  125. req.Header.Add("Content-Type", "application/json")
  126. postBody, err := client.Do(req)
  127. if err != nil {
  128. msg = "获取微信二维码失败,Err:" + err.Error()
  129. return
  130. }
  131. defer postBody.Body.Close()
  132. uploadDir := "static/img/share/"
  133. uuid := utils.GetRandStringNoSpecialChar(28)
  134. if !utils.FileIsExist(uploadDir) {
  135. err = os.MkdirAll(uploadDir, 0755)
  136. if err != nil {
  137. msg = "生成文件夹失败,Err:" + err.Error()
  138. return
  139. }
  140. }
  141. imagePath := uploadDir + uuid + ".jpg"
  142. switch header := postBody.Header.Get("Content-Type"); {
  143. case strings.HasPrefix(header, "application/json"):
  144. tokenResp := ReturnBodyRule{}
  145. decoder := json.NewDecoder(postBody.Body)
  146. if decodeErr := decoder.Decode(&tokenResp); decodeErr != nil {
  147. msg = "获取微信二维码失败,Err:" + decodeErr.Error()
  148. return
  149. }
  150. case strings.HasPrefix(header, "image"):
  151. reply, e := ioutil.ReadAll(postBody.Body)
  152. if e != nil {
  153. err = e
  154. msg = "获取微信二维码失败,Err:" + err.Error()
  155. return
  156. }
  157. imageContent, e := os.Create(imagePath)
  158. if e != nil {
  159. err = e
  160. msg = "获取微信二维码失败,Err:" + err.Error()
  161. return
  162. }
  163. writeStringRes, e := io.WriteString(imageContent, string(reply))
  164. if e != nil {
  165. err = e
  166. fmt.Println(writeStringRes)
  167. return
  168. }
  169. closeErr := imageContent.Close()
  170. if closeErr != nil {
  171. err = closeErr
  172. return
  173. }
  174. randStr := utils.GetRandStringNoSpecialChar(28)
  175. fileName := randStr + ".jpg"
  176. savePath := uploadDir + time.Now().Format("200601/20060102/")
  177. savePath += fileName
  178. //上传到阿里云
  179. err = services.UploadFileToAliyun(fileName, imagePath, savePath)
  180. if err != nil {
  181. fmt.Println("文件上传失败,Err:" + err.Error())
  182. return
  183. }
  184. fileHost := "https://hzstatic.hzinsights.com/"
  185. resourceUrl = fileHost + savePath
  186. defer func() {
  187. os.Remove(imagePath)
  188. }()
  189. default:
  190. msg = "生成二维码失败"
  191. return
  192. }
  193. detailConfig, e := cygx.GetCygxConfigDetailByCode(Cygx_activity_sigin_html)
  194. if e != nil {
  195. err = errors.New("GetCygxConfigDetailByCode 获取配置签到码格式信息失败, Err: " + e.Error())
  196. return
  197. }
  198. configValue := detailConfig.ConfigValue
  199. configValue = strings.Replace(configValue, "{{TITLE}}", activityInfo.ActivityName, -1)
  200. configValue = strings.Replace(configValue, "{{IMG}}", resourceUrl, -1)
  201. configValue = strings.Replace(configValue, "{{PLEASE}}", "请扫码确认签到", -1)
  202. configValue = strings.Replace(configValue, "{{SHOWTEXT}}", "将签到成功页面出示给接待人员", -1)
  203. htm2ImgReq := make(map[string]interface{})
  204. htm2ImgReq["html_content"] = configValue
  205. htm2ImgReq["width"] = 1364
  206. htm2ImgReq["height"] = 2060
  207. res, err := postHtml2Img(htm2ImgReq)
  208. if err != nil || res == nil {
  209. msg = "html转图片请求失败"
  210. return
  211. }
  212. if res.Code != 200 {
  213. msg = "html转图片请求失败"
  214. err = errors.New("html转图片失败: " + res.Msg)
  215. return
  216. }
  217. imgUrl = res.Data
  218. // 记录海报信息
  219. err = cygx.UpdateCygxActivitySigninImg(imgUrl, activityId)
  220. if err != nil {
  221. return
  222. }
  223. item := new(cygx.CygxActivityPoster)
  224. item.ActivityId = activityId
  225. item.ImgXcx = resourceUrl
  226. item.ImgPoster = imgUrl
  227. item.CreateTime = time.Now()
  228. err = cygx.AddCygxActivityPoster(item)
  229. return
  230. }
  231. // 生成音视频分享封面图
  232. func MakeCygxMp3HtmlImg(videoDuration string, chartPermissionId int) (imgUrl string, err error) {
  233. var msg string
  234. defer func() {
  235. if err != nil || msg != "" {
  236. fmt.Println(err)
  237. go alarm_msg.SendAlarmMsg("生成音视频分享封面图,失败 MakeCygxMp3HtmlImg:"+err.Error()+";msg:"+msg, 3)
  238. }
  239. }()
  240. var configCode string
  241. if chartPermissionId == utils.CHART_PERMISSION_ID_YANXUAN {
  242. configCode = Cygx_mp3_yx_html
  243. } else {
  244. configCode = Cygx_mp3_html
  245. }
  246. detailConfig, e := cygx.GetCygxConfigDetailByCode(configCode)
  247. if e != nil {
  248. err = errors.New("GetCygxConfigDetailByCode 获取配置生成音视频分享封面图格式信息失败, Err: " + e.Error())
  249. return
  250. }
  251. // 处理时长带有小数点的字符串
  252. slice := strings.Split(videoDuration, ".")
  253. for k, v := range slice {
  254. if k != 0 {
  255. continue
  256. }
  257. videoDuration = v
  258. }
  259. //先转换时长展示样式再替换
  260. secondNum, _ := strconv.Atoi(videoDuration)
  261. videoDuration = utils.HideSecondsToMs(secondNum)
  262. configValue := detailConfig.ConfigValue
  263. configValue = strings.Replace(configValue, "{{TIME}}", videoDuration, -1)
  264. htm2ImgReq := make(map[string]interface{})
  265. htm2ImgReq["html_content"] = configValue
  266. htm2ImgReq["width"] = 1364
  267. htm2ImgReq["height"] = 2060
  268. res, err := postHtml2Img(htm2ImgReq)
  269. if err != nil || res == nil {
  270. msg = "html转图片请求失败"
  271. return
  272. }
  273. if res.Code != 200 {
  274. msg = "html转图片请求失败"
  275. err = errors.New("html转图片失败: " + res.Msg)
  276. return
  277. }
  278. imgUrl = res.Data
  279. return
  280. }
  281. // 生成音视频分享封面图
  282. func MakeCygxMp4HtmlImg(videoDuration string, chartPermissionId int) (imgUrl string, err error) {
  283. var msg string
  284. defer func() {
  285. if err != nil || msg != "" {
  286. fmt.Println(err)
  287. go alarm_msg.SendAlarmMsg("生成音视频分享封面图,失败 MakeCygxMp4HtmlImg:"+err.Error()+";msg:"+msg, 3)
  288. }
  289. }()
  290. var configCode string
  291. if chartPermissionId == utils.CHART_PERMISSION_ID_YANXUAN {
  292. configCode = Cygx_mp4_yx_html
  293. } else {
  294. configCode = Cygx_mp4_html
  295. }
  296. detailConfig, e := cygx.GetCygxConfigDetailByCode(configCode)
  297. if e != nil {
  298. err = errors.New("GetCygxConfigDetailByCode 获取配置生成音视频分享封面图格式信息失败, Err: " + e.Error())
  299. return
  300. }
  301. // 处理时长带有小数点的字符串
  302. slice := strings.Split(videoDuration, ".")
  303. for k, v := range slice {
  304. if k != 0 {
  305. continue
  306. }
  307. videoDuration = v
  308. }
  309. //先转换时长展示样式再替换
  310. secondNum, _ := strconv.Atoi(videoDuration)
  311. videoDuration = utils.HideSecondsToMs(secondNum)
  312. configValue := detailConfig.ConfigValue
  313. configValue = strings.Replace(configValue, "{{TIME}}", videoDuration, -1)
  314. htm2ImgReq := make(map[string]interface{})
  315. htm2ImgReq["html_content"] = configValue
  316. htm2ImgReq["width"] = 1364
  317. htm2ImgReq["height"] = 2060
  318. res, err := postHtml2Img(htm2ImgReq)
  319. if err != nil || res == nil {
  320. msg = "html转图片请求失败"
  321. return
  322. }
  323. if res.Code != 200 {
  324. msg = "html转图片请求失败"
  325. err = errors.New("html转图片失败: " + res.Msg)
  326. return
  327. }
  328. imgUrl = res.Data
  329. return
  330. }
  331. //func init() {
  332. // //MakeActivityMomentsImg(2850)
  333. // var condition string
  334. // var pars []interface{}
  335. // condition = " AND chart_permission_id = 31 AND publish_status = 1 AND active_state = 1 ORDER BY activity_id DESC "
  336. // list, errList := cygx.GetActivityListAll(condition, pars, 0, 9999)
  337. // if errList != nil {
  338. // fmt.Println(errList)
  339. // return
  340. // }
  341. // fmt.Println("list", len(list))
  342. //
  343. // //return
  344. // for _, v := range list {
  345. // MakeActivityMomentsImg(v.ActivityId)
  346. // }
  347. //
  348. //}
  349. // 生成活动分享到朋友圈的图片
  350. func MakeActivityMomentsImg(activityId int) {
  351. var err error
  352. //time.Sleep(3*time.Second) // 有时候同时添加多个活动,延迟三秒
  353. defer func() {
  354. if err != nil {
  355. fmt.Println("err:", err)
  356. go alarm_msg.SendAlarmMsg("生成活动分享到朋友圈的图片失败,MakeActivityMomentsImg Err:"+err.Error()+"活动ID"+strconv.Itoa(activityId), 3)
  357. }
  358. }()
  359. detail, e := cygx.GetAddActivityInfoById(activityId)
  360. if e != nil {
  361. err = errors.New("GetCygxReportSelectionInfoById, Err: " + e.Error())
  362. return
  363. }
  364. // 不是研选活动不生成图片
  365. if detail.ChartPermissionId != utils.CHART_PERMISSION_ID_YANXUAN {
  366. return
  367. }
  368. var configCode string
  369. if detail.IsResearchPoints == 1 {
  370. configCode = "activity_moments_img_points_html" // 扣点活动
  371. } else {
  372. configCode = "activity_moments_img_html" // 非扣点活动
  373. }
  374. detailConfig, e := cygx.GetCygxConfigDetailByCode(configCode)
  375. if e != nil {
  376. err = errors.New("GetCygxConfigDetailByCode 获取生成活动分享到朋友圈的图片格式信息失败, Err: " + e.Error())
  377. return
  378. }
  379. configValue := detailConfig.ConfigValue
  380. configValue = strings.Replace(configValue, "{{Title}}", detail.ActivityName, -1)
  381. configValue = strings.Replace(configValue, "{{ActivityTypeName}}", detail.ActivityTypeName, -1)
  382. configValue = strings.Replace(configValue, "{{Label}}", detail.Label, -1)
  383. configValue = strings.Replace(configValue, "{{ActivityTimeText}}", detail.ActivityTimeText, -1)
  384. htm2ImgReq := make(map[string]interface{})
  385. htm2ImgReq["html_content"] = configValue
  386. htm2ImgReq["width"] = 2250
  387. htm2ImgReq["height"] = 3813
  388. res, err := postHtml2Img(htm2ImgReq)
  389. if err != nil || res == nil {
  390. err = errors.New("html转图片失败: ")
  391. return
  392. }
  393. if res.Code != 200 {
  394. err = errors.New("html转图片失败: " + res.Msg)
  395. return
  396. }
  397. imgUrl := res.Data
  398. // 记录海报信息
  399. err = cygx.UpdateCygxActivityMomentsImg(imgUrl, activityId)
  400. if err != nil {
  401. return
  402. }
  403. }
  404. // MakeMfyxActivitySigninImg 生成mfyx太阳码并上传OSS
  405. //func MakeMfyxActivitySigninImg(activityId int) (imgUrl string, err error) {
  406. // var msg string
  407. // defer func() {
  408. // if err != nil || msg != "" {
  409. // fmt.Println(err)
  410. // utils.FileLog.Info("MakeMfyxActivitySigninImg Err:", err.Error())
  411. // go alarm_msg.SendAlarmMsg("扫码签到日志记录,失败,活动ID:"+strconv.Itoa(activityId)+err.Error()+";msg:"+msg, 3)
  412. // }
  413. // }()
  414. // activityInfo, e := cygx.GetAddActivityInfoById(activityId)
  415. // if e != nil {
  416. // err = errors.New("活动不存在, Err: " + e.Error())
  417. // return
  418. // }
  419. // if activityInfo == nil {
  420. // return
  421. // }
  422. // if activityInfo.ActivityTypeId != 5 && activityInfo.ActivityTypeId != 6 && activityInfo.ActivityTypeId != 8 {
  423. // return
  424. // }
  425. // itemToken, err := models.GetWxToken(utils.WxMfyxAppId, utils.WxMfyxAppSecret)
  426. // if err != nil {
  427. // return
  428. // }
  429. // if itemToken.AccessToken == "" {
  430. // msg = "accessToken is empty"
  431. // return
  432. // }
  433. // var envVersion string
  434. // var resourceUrl string
  435. // if utils.RunMode == "release" {
  436. // envVersion = "release"
  437. // } else {
  438. // envVersion = "trial"
  439. // }
  440. // url := "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + itemToken.AccessToken
  441. // method := "POST"
  442. // payload := strings.NewReader(`{
  443. // "page":"` + utils.WX_MSG_PATH_ACTIVITY_SIGNIN + `",
  444. // "scene":"` + strconv.Itoa(activityId) + `",
  445. // "env_version":"` + envVersion + `",
  446. // "check_path":false,
  447. // "auto_color":true
  448. // }`)
  449. // client := &http.Client{}
  450. // req, err := http.NewRequest(method, url, payload)
  451. // if err != nil {
  452. // msg = "获取微信二维码失败,Err:" + err.Error()
  453. // return
  454. // }
  455. // req.Header.Add("Content-Type", "application/json")
  456. // postBody, err := client.Do(req)
  457. // if err != nil {
  458. // msg = "获取微信二维码失败,Err:" + err.Error()
  459. // return
  460. // }
  461. // defer postBody.Body.Close()
  462. // uploadDir := "static/img/share/"
  463. // uuid := utils.GetRandStringNoSpecialChar(28)
  464. // if !utils.FileIsExist(uploadDir) {
  465. // err = os.MkdirAll(uploadDir, 0755)
  466. // if err != nil {
  467. // msg = "生成文件夹失败,Err:" + err.Error()
  468. // return
  469. // }
  470. // }
  471. // imagePath := uploadDir + uuid + ".jpg"
  472. // switch header := postBody.Header.Get("Content-Type"); {
  473. // case strings.HasPrefix(header, "application/json"):
  474. // tokenResp := ReturnBodyRule{}
  475. // decoder := json.NewDecoder(postBody.Body)
  476. // if decodeErr := decoder.Decode(&tokenResp); decodeErr != nil {
  477. // msg = "获取微信二维码失败,Err:" + decodeErr.Error()
  478. // return
  479. // }
  480. // case strings.HasPrefix(header, "image"):
  481. // reply, e := ioutil.ReadAll(postBody.Body)
  482. // if e != nil {
  483. // err = e
  484. // msg = "获取微信二维码失败,Err:" + err.Error()
  485. // return
  486. // }
  487. // imageContent, e := os.Create(imagePath)
  488. // if e != nil {
  489. // err = e
  490. // msg = "获取微信二维码失败,Err:" + err.Error()
  491. // return
  492. // }
  493. // writeStringRes, e := io.WriteString(imageContent, string(reply))
  494. // if e != nil {
  495. // err = e
  496. // fmt.Println(writeStringRes)
  497. // return
  498. // }
  499. // closeErr := imageContent.Close()
  500. // if closeErr != nil {
  501. // err = closeErr
  502. // return
  503. // }
  504. // randStr := utils.GetRandStringNoSpecialChar(28)
  505. // fileName := randStr + ".jpg"
  506. // savePath := uploadDir + time.Now().Format("200601/20060102/")
  507. // savePath += fileName
  508. // //上传到阿里云
  509. // err = services.UploadFileToAliyun(fileName, imagePath, savePath)
  510. // if err != nil {
  511. // fmt.Println("文件上传失败,Err:" + err.Error())
  512. // return
  513. // }
  514. // fileHost := "https://hzstatic.hzinsights.com/"
  515. // resourceUrl = fileHost + savePath
  516. // defer func() {
  517. // os.Remove(imagePath)
  518. // }()
  519. // default:
  520. // msg = "生成二维码失败"
  521. // return
  522. // }
  523. //
  524. // detailConfig, e := cygx.GetCygxConfigDetailByCode(Cygx_activity_sigin_html)
  525. // if e != nil {
  526. // err = errors.New("GetCygxConfigDetailByCode 获取配置签到码格式信息失败, Err: " + e.Error())
  527. // return
  528. // }
  529. // configValue := detailConfig.ConfigValue
  530. // configValue = strings.Replace(configValue, "{{TITLE}}", activityInfo.ActivityName, -1)
  531. // configValue = strings.Replace(configValue, "{{IMG}}", resourceUrl, -1)
  532. // configValue = strings.Replace(configValue, "{{PLEASE}}", "请扫码确认签到", -1)
  533. // configValue = strings.Replace(configValue, "{{SHOWTEXT}}", "将签到成功页面出示给接待人员", -1)
  534. // htm2ImgReq := make(map[string]interface{})
  535. // htm2ImgReq["html_content"] = configValue
  536. // htm2ImgReq["width"] = 1364
  537. // htm2ImgReq["height"] = 2060
  538. // res, err := postHtml2Img(htm2ImgReq)
  539. // if err != nil || res == nil {
  540. // msg = "html转图片请求失败"
  541. // return
  542. // }
  543. // if res.Code != 200 {
  544. // msg = "html转图片请求失败"
  545. // err = errors.New("html转图片失败: " + res.Msg)
  546. // return
  547. // }
  548. // imgUrl = res.Data
  549. // // 记录海报信息
  550. //
  551. // err = cygx.UpdateCygxActivitySigninImg(imgUrl, activityId)
  552. // if err != nil {
  553. // return
  554. // }
  555. // item := new(cygx.CygxActivityPoster)
  556. // item.ActivityId = activityId
  557. // item.ImgXcx = resourceUrl
  558. // item.ImgPoster = imgUrl
  559. // item.CreateTime = time.Now()
  560. // err = cygx.AddCygxActivityPoster(item)
  561. // return
  562. //}