Przeglądaj źródła

语音播报动态分享图

hsun 2 lat temu
rodzic
commit
f2fe0afe9a

+ 30 - 9
controller/voice_broadcast/voice_broadcast.go

@@ -1,6 +1,7 @@
 package voice_broadcast
 
 import (
+	"encoding/json"
 	"fmt"
 	"github.com/gin-gonic/gin"
 	"hongze/hongze_yb/controller/response"
@@ -46,7 +47,7 @@ func BroadcastList(c *gin.Context) {
 	userinfo := user.GetInfoByClaims(c)
 	ok, checkInfo, _, err := company.CheckBaseFiccPermission(userinfo.CompanyID, int(userinfo.UserID))
 	if err != nil {
-		response.FailMsg("用户权限验证失败", "CheckBaseAuth-用户权限验证失败" + err.Error(), c)
+		response.FailMsg("用户权限验证失败", "CheckBaseAuth-用户权限验证失败"+err.Error(), c)
 		c.Abort()
 		return
 	}
@@ -81,7 +82,6 @@ func BroadcastList(c *gin.Context) {
 // @Router /add [post]
 func AddBroadcast(c *gin.Context) {
 	broadcastName := c.PostForm("broadcast_name")
-	fmt.Println("broadcastName:",broadcastName)
 	nsectionId := c.PostForm("section_id")
 	sectionId, _ := strconv.Atoi(nsectionId)
 	sectionName := c.PostForm("section_name")
@@ -97,6 +97,27 @@ func AddBroadcast(c *gin.Context) {
 		response.FailMsg("获取资源失败", "获取资源失败, Err:"+err.Error(), c)
 		return
 	}
+	if imgUrl == "" {
+		response.Fail("图片不能为空", c)
+		return
+	}
+	// 生成动态分享图
+	createTimeStr := time.Now().Local().Format(utils.FormatDate)
+	pars := services.VoiceBroadcastShareImgPars{
+		BackgroundImg: imgUrl,
+		Title:         sectionName,
+		CreateTime:    createTimeStr,
+	}
+	parsByte, e := json.Marshal(pars)
+	if e != nil {
+		response.Fail("分享图参数有误", c)
+		return
+	}
+	shareImg, e := services.GetDynamicShareImg(services.VoiceBroadcastShareImgSource, string(parsByte))
+	if e != nil {
+		response.Fail("生成分享图失败", c)
+		return
+	}
 
 	ext := path.Ext(file.Filename)
 	if ext != ".mp3" {
@@ -158,7 +179,7 @@ func AddBroadcast(c *gin.Context) {
 		VarietyName:      varietyName,
 		AuthorId:         authorId,
 		Author:           author,
-		ImgUrl:           imgUrl,
+		ImgUrl:           shareImg,
 		VoiceUrl:         resourceUrl,
 		VoicePlaySeconds: fmt.Sprint(seconds),
 		VoiceSize:        fmt.Sprint(mb),
@@ -219,7 +240,7 @@ func SectionList(c *gin.Context) {
 
 	//如果有被禁用的板块,去语音列表查找被禁用板块有没有语音
 	var lists []*voice_broadcast.VoiceBroadcast
-	if len(bannedIds) > 0{
+	if len(bannedIds) > 0 {
 		lists, err = voice_section.GetVoiceSectionFromBroadcast(bannedIds)
 		if err != nil {
 			response.FailMsg("查询语音播报禁用板块失败", "GetVoiceSectionFromBroadcast, Err:"+err.Error(), c)
@@ -235,7 +256,7 @@ func SectionList(c *gin.Context) {
 			bannedMap[broadcast.SectionId] = broadcast.SectionId
 		}
 		for _, section := range sList {
-			_,ok := bannedMap[section.SectionId]
+			_, ok := bannedMap[section.SectionId]
 			if section.Status != 0 || ok {
 				newsList = append(newsList, section)
 			}
@@ -262,7 +283,7 @@ func SectionList(c *gin.Context) {
 				sectionList = append(sectionList, section)
 			}
 		}
-		if len(sectionList) == 0{
+		if len(sectionList) == 0 {
 			continue
 		}
 		v.Children = sectionList
@@ -285,7 +306,7 @@ func DelBroadcast(c *gin.Context) {
 		response.FailMsg("转换id失败,请输入正确的id", "strconv.Atoi, Err:"+err.Error(), c)
 	}
 	if broadcastId <= 0 {
-		response.FailMsg("参数错误","参数有误", c)
+		response.FailMsg("参数错误", "参数有误", c)
 		return
 	}
 	var item voice_broadcast.VoiceBroadcast
@@ -310,11 +331,11 @@ func AddStatistics(c *gin.Context) {
 		return
 	}
 
-	if req.BroadcastId <= 0{
+	if req.BroadcastId <= 0 {
 		response.Fail("参数有误", c)
 	}
 	userinfo := user.GetInfoByClaims(c)
-	
+
 	go services.AddBroadcastRecord(userinfo, req.Source, req.BroadcastId)
 
 	response.Ok("新增记录成功", c)

+ 6 - 0
models/tables/voice_broadcast/create.go

@@ -6,4 +6,10 @@ import "hongze/hongze_yb/global"
 func (voiceBroadcast *VoiceBroadcast) AddVoiceBroadcast() (err error) {
 	err = global.DEFAULT_MYSQL.Create(voiceBroadcast).Error
 	return
+}
+
+// Update 更新语音播报
+func (voiceBroadcast *VoiceBroadcast) Update(updateCols []string) (err error) {
+	err = global.DEFAULT_MYSQL.Model(voiceBroadcast).Select(updateCols).Updates(*voiceBroadcast).Error
+	return
 }

+ 5 - 0
models/tables/voice_broadcast/query.go

@@ -23,4 +23,9 @@ func GetBroadcast(pageIndex, pageSize int) (list []*VoiceBroadcast, err error) {
 func GetBroadcastById(broadcastId int) (list *VoiceBroadcast, err error) {
 	err = global.DEFAULT_MYSQL.Model(VoiceBroadcast{}).Where("broadcast_id=?", broadcastId).First(&list).Error
 	return
+}
+
+func GetBroadcastList() (list []*VoiceBroadcast, err error) {
+	err = global.DEFAULT_MYSQL.Model(VoiceBroadcast{}).Scan(&list).Error
+	return
 }

+ 38 - 355
services/share_poster.go

@@ -19,7 +19,10 @@ import (
 	"time"
 )
 
-var ServerUrl = "http://127.0.0.1:5008/"
+var (
+	ServerUrl                    = "http://127.0.0.1:5008/"
+	VoiceBroadcastShareImgSource = "voice_broadcast_share_img"
+)
 
 // SharePosterReq 分享海报请求体
 type SharePosterReq struct {
@@ -30,108 +33,6 @@ type SharePosterReq struct {
 	Pars      string `json:"pars" description:"海报动态信息"`
 }
 
-// CreatePosterFromSource 生成分享海报
-func CreatePosterFromSource(codePage, codeScene, source, version, pars string) (imgUrl string, err error) {
-	var errMsg string
-	defer func() {
-		if err != nil {
-			global.LOG.Critical(fmt.Sprintf("CreatePosterFromSource: source=%s, pars:%s, errMsg:%s", source, pars, errMsg))
-			reqSlice := make([]string, 0)
-			reqSlice = append(reqSlice, fmt.Sprint("CodePage:", codePage, "\n"))
-			reqSlice = append(reqSlice, fmt.Sprint("CodeScene:", codeScene, "\n"))
-			reqSlice = append(reqSlice, fmt.Sprint("Source:", source, "\n"))
-			reqSlice = append(reqSlice, fmt.Sprint("Version:", version, "\n"))
-			reqSlice = append(reqSlice, fmt.Sprint("Pars:", pars, "\n"))
-			go alarm_msg.SendAlarmMsg("CreatePosterFromSource生成分享海报失败, Msg:"+errMsg+";Err:"+err.Error()+"\n;Req:\n"+strings.Join(reqSlice, ";"), 3)
-		}
-	}()
-	if codePage == "" || source == "" || pars == "" {
-		errMsg = "参数有误"
-		err = errors.New(errMsg)
-		return
-	}
-	path := fmt.Sprint(codePage, "?", codeScene)
-	// 非列表来源获取历史图片,无则生成
-	if !strings.Contains(source, "list") && source != "price_driven" {
-		poster, tmpErr := yb_poster_resource.GetPosterByCondition(path, "poster", version)
-		if tmpErr != nil && tmpErr != utils.ErrNoRow {
-			err = tmpErr
-			return
-		}
-		if poster != nil && poster.ImgURL != "" {
-			imgUrl = poster.ImgURL
-			return
-		}
-	}
-	// 图片长宽
-	heightMap := map[string]int{
-		"activity_detail":       1210,
-		"activity_list":         1948,
-		"special_column_detail": 1480,
-		"special_column_list":   1548,
-		"chart_detail":          1536,
-		"chart_list":            1352,
-		"report_detail":         1420,
-		"report_list":           1344,
-		"price_driven":          1344,
-	}
-	widthMap := map[string]int{
-		"activity_detail":       1280,
-		"activity_list":         1280,
-		"special_column_detail": 1176,
-		"special_column_list":   1176,
-		"chart_detail":          1176,
-		"chart_list":            1176,
-		"report_detail":         1176,
-		"report_list":           1176,
-		"price_driven":          1176,
-	}
-	width := widthMap[source]
-	height := heightMap[source]
-	if width == 0 || height == 0 {
-		errMsg = "图片长度有误"
-		err = errors.New(errMsg)
-		return "", err
-	}
-	// 生成太阳码
-	sunCodeUrl, err := CreateAndUploadSunCode(codePage, codeScene, version)
-	if err != nil {
-		return
-	}
-	// 填充html内容
-	contentStr, newHeight, err := fillContent2Html(source, pars, sunCodeUrl, height)
-	if err != nil {
-		errMsg = "html内容有误"
-		return
-	}
-	// 请求python服务htm2img
-	htm2ImgReq := make(map[string]interface{})
-	htm2ImgReq["html_content"] = contentStr
-	htm2ImgReq["width"] = width
-	htm2ImgReq["height"] = newHeight
-	res, err := postHtml2Img(htm2ImgReq)
-	if err != nil || res == nil {
-		errMsg = "html转图片请求失败"
-		return
-	}
-	if res.Code != 200 {
-		errMsg = "html转图片请求失败"
-		err = errors.New("html转图片失败: " + res.Msg)
-		return
-	}
-	imgUrl = res.Data
-	// 记录海报信息
-	newPoster := &yb_poster_resource.YbPosterResource{
-		Path:       path,
-		ImgURL:     imgUrl,
-		Type:       "poster",
-		Version:    version,
-		CreateTime: time.Now(),
-	}
-	err = newPoster.Create()
-	return
-}
-
 type Html2ImgResp struct {
 	Code int    `json:"code"`
 	Msg  string `json:"msg"`
@@ -247,237 +148,6 @@ func CreateAndUploadSunCode(page, scene, version string) (imgUrl string, err err
 	return
 }
 
-type PosterParsReq struct {
-	ActivityTitle     string `json:"activity_title"`
-	ActivityAvatar    string `json:"activity_avatar"`
-	ActivitySpeaker   string `json:"activity_speaker"`
-	ActivityTime      string `json:"activity_time"`
-	ChartName         string `json:"chart_name"`
-	ChartImage        string `json:"chart_image"`
-	ReportType        string `json:"report_type"`
-	ReportAvatar      string `json:"report_avatar"`
-	ReportTitle       string `json:"report_title"`
-	ReportAbstract    string `json:"report_abstract"`
-	Stage1            string `json:"stage_1"`
-	Avatar1           string `json:"avatar_1"`
-	Title1            string `json:"title_1"`
-	Author1           string `json:"author_1"`
-	Tag1              string `json:"tag_1"`
-	Img1              string `json:"img_1"`
-	Time1             string `json:"time_1"`
-	Abstract1         string `json:"abstract_1"`
-	Status1           string `json:"status_1"`
-	Speaker1          string `json:"speaker_1"`
-	Stage2            string `json:"stage_2"`
-	Avatar2           string `json:"avatar_2"`
-	Title2            string `json:"title_2"`
-	Author2           string `json:"author_2"`
-	Tag2              string `json:"tag_2"`
-	Img2              string `json:"img_2"`
-	Abstract2         string `json:"abstract_2"`
-	Time2             string `json:"time_2"`
-	Status2           string `json:"status_2"`
-	Speaker2          string `json:"speaker_2"`
-	ListTitle         string `json:"list_title"`
-	CoreDrivenType    string `json:"core_driven_type"`
-	CoreDrivenContent string `json:"core_driven_content"`
-	MainVariable      string `json:"main_variable"`
-	UpdateTime        string `json:"update_time"`
-}
-
-// fillContent2Html 填充HTML动态内容
-func fillContent2Html(source, pars, sunCodeUrl string, height int) (contentStr string, newHeight int, err error) {
-	params := new(PosterParsReq)
-	if err = json.Unmarshal([]byte(pars), &params); err != nil {
-		return
-	}
-	template := fmt.Sprint("static/htm2img/", source, ".html")
-	contentByte, err := ioutil.ReadFile(template)
-	if err != nil {
-		return
-	}
-	newHeight = height
-	contentStr = string(contentByte)
-	// 列表的动态内容不完整的用默认内容的填充
-	var emptyTime1, emptyTime2 bool
-	if strings.Contains(source, "list") {
-		if params.Title1 == "" || params.Title2 == "" {
-			defaultAvatar := "https://hzstatic.hzinsights.com/static/images/202112/20211210/wn6c3oYKTfT4NbTZgRGflRuIBZaa.png"
-			switch source {
-			case "activity_list":
-				if params.Title1 == "" {
-					params.ListTitle = "线下沙龙"
-					params.Status1 = "未开始"
-					params.Avatar1 = defaultAvatar
-					params.Title1 = "周度报告"
-					params.Speaker1 = "FICC研究员"
-					params.Time1 = "2022-5-10"
-					emptyTime1 = true
-				}
-				params.Status2 = params.Status1
-				params.Avatar2 = defaultAvatar
-				params.Title2 = "周度报告"
-				params.Speaker2 = "FICC研究员"
-				params.Time2 = "2022-5-10"
-				emptyTime2 = true
-			case "special_column_list":
-				if params.Title1 == "" {
-					params.Stage1 = "第1期"
-					params.Avatar1 = defaultAvatar
-					params.Title1 = "弘则FICC专栏"
-					params.Author1 = "弘则研究"
-					params.Tag1 = "FICC研究员"
-				}
-				params.Stage2 = "第2期"
-				params.Avatar2 = defaultAvatar
-				params.Title2 = "弘则FICC专栏"
-				params.Author2 = "弘则研究"
-				params.Tag2 = "FICC研究员"
-			case "chart_list":
-				if params.Title1 == "" {
-					params.Title1 = "螺纹仓单-热卷仓单季节性"
-					params.Img1 = "https://hzstatic.hzinsights.com/static/images/202112/20211227/8VBIH1l6VraYpLCoBS6qOIXA5Zoq.png"
-				}
-				params.Title2 = "卷螺期货现货价差"
-				params.Img2 = "https://hzstatic.hzinsights.com/static/images/202204/20220427/d8GRfdR3Xfrvk397SnYudcwVs9pV.png"
-			case "report_list":
-				if params.Title1 == "" {
-					params.Img1 = defaultAvatar
-					params.Title1 = "弘则FICC研报"
-					params.Time1 = "1期"
-				}
-				params.Img2 = defaultAvatar
-				params.Title2 = "弘则FICC研报"
-				params.Time2 = "2期"
-			}
-		}
-	}
-	// 填充指定内容
-	switch source {
-	case "activity_detail":
-		contentStr = strings.Replace(contentStr, "{{ACTIVITY_TITLE}}", params.ActivityTitle, 1)
-		contentStr = strings.Replace(contentStr, "{{ACTIVITY_AVATAR}}", params.ActivityAvatar, 1)
-		contentStr = strings.Replace(contentStr, "{{ACTIVITY_SPEAKER}}", params.ActivitySpeaker, 1)
-		contentStr = strings.Replace(contentStr, "{{ACTIVITY_TIME}}", params.ActivityTime, 1)
-	case "special_column_detail":
-		contentStr = strings.Replace(contentStr, "{{REPORT_AVATAR}}", params.ReportAvatar, 1)
-		contentStr = strings.Replace(contentStr, "{{REPORT_TITLE}}", params.ReportTitle, 1)
-		contentStr = strings.Replace(contentStr, "{{REPORT_ABSTRACT}}", params.ReportAbstract, 1)
-	case "chart_detail":
-		contentStr = strings.Replace(contentStr, "{{CHART_NAME}}", params.ChartName, 1)
-		contentStr = strings.Replace(contentStr, "{{CHART_IMAGE}}", params.ChartImage, 1)
-	case "report_detail":
-		doc, tmpErr := goquery.NewDocumentFromReader(strings.NewReader(params.ReportAbstract))
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-		abstract := ""
-		doc.Find("p").Each(func(i int, s *goquery.Selection) {
-			phtml, tmpErr := s.Html()
-			if tmpErr != nil {
-				err = tmpErr
-				return
-			}
-			st := s.Text()
-			if st != "" && st != "<br>" && st != "<br style=\"max-width: 100%;\">" && !strings.Contains(phtml, "iframe") {
-				abstract = abstract + "<p>" + phtml + "</p>"
-			}
-		})
-		contentStr = strings.Replace(contentStr, "{{REPORT_TYPE}}", params.ReportType, 1)
-		contentStr = strings.Replace(contentStr, "{{REPORT_TITLE}}", params.ReportTitle, 1)
-		contentStr = strings.Replace(contentStr, "{{REPORT_ABSTRACT}}", abstract, 1)
-	case "special_column_list":
-		contentStr = strings.Replace(contentStr, "{{LIST_TITLE}}", params.ListTitle, 1)
-		contentStr = strings.Replace(contentStr, "{{STAGE_1}}", "第"+params.Stage1+"期", 1)
-		contentStr = strings.Replace(contentStr, "{{AVATAR_1}}", params.Avatar1, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_1}}", params.Title1, 1)
-		contentStr = strings.Replace(contentStr, "{{AUTHOR_1}}", params.Author1, 1)
-		contentStr = strings.Replace(contentStr, "{{TAG_1}}", params.Tag1, 1)
-		contentStr = strings.Replace(contentStr, "{{STAGE_2}}", "第"+params.Stage2+"期", 1)
-		contentStr = strings.Replace(contentStr, "{{AVATAR_2}}", params.Avatar2, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_2}}", params.Title2, 1)
-		contentStr = strings.Replace(contentStr, "{{AUTHOR_2}}", params.Author2, 1)
-		contentStr = strings.Replace(contentStr, "{{TAG_2}}", params.Tag2, 1)
-	case "chart_list":
-		contentStr = strings.Replace(contentStr, "{{LIST_TITLE}}", params.ListTitle, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_1}}", params.Title1, 1)
-		contentStr = strings.Replace(contentStr, "{{IMG_1}}", params.Img1, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_2}}", params.Title2, 1)
-		contentStr = strings.Replace(contentStr, "{{IMG_2}}", params.Img2, 1)
-	case "report_list":
-		contentStr = strings.Replace(contentStr, "{{LIST_TITLE}}", params.ListTitle, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_1}}", params.Title1, 1)
-		contentStr = strings.Replace(contentStr, "{{ABSTRACT_1}}", params.Abstract1, 1)
-		contentStr = strings.Replace(contentStr, "{{IMG_1}}", params.Img1, 1)
-		contentStr = strings.Replace(contentStr, "{{TIME_1}}", params.Time1, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_2}}", params.Title2, 1)
-		contentStr = strings.Replace(contentStr, "{{ABSTRACT_2}}", params.Abstract2, 1)
-		contentStr = strings.Replace(contentStr, "{{IMG_2}}", params.Img2, 1)
-		contentStr = strings.Replace(contentStr, "{{TIME_2}}", params.Time2, 1)
-	case "price_driven":
-		contentStr = strings.Replace(contentStr, "{{LIST_TITLE}}", params.ListTitle, 1)
-		contentStr = strings.Replace(contentStr, "{{CORE_DRIVEN_TYPE}}", params.CoreDrivenType, 1)
-		contentStr = strings.Replace(contentStr, "{{CORE_DRIVEN_CONTENT}}", params.CoreDrivenContent, 1)
-		contentStr = strings.Replace(contentStr, "{{MAIN_VARIABLE}}", params.MainVariable, 1)
-		contentStr = strings.Replace(contentStr, "{{UPDATE_TIME}}", params.UpdateTime, 1)
-	case "activity_list":
-		bgColorMap := map[string]string{
-			"未开始": "#E3B377",
-			"进行中": "#3385FF",
-			"已结束": "#A2A2A2",
-		}
-		statusItemMap := map[string]string{
-			"未开始": "block",
-			"进行中": "none",
-			"已结束": "none",
-		}
-		offlineMap := map[string]string{
-			"线上会议": "none",
-			"线下沙龙": "block",
-		}
-		onlineMap := map[string]string{
-			"线上会议": "block",
-			"线下沙龙": "none",
-		}
-		if params.Status1 != "未开始" {
-			newHeight = 1715
-		}
-		contentStr = strings.Replace(contentStr, "{{LIST_TITLE}}", "弘则FICC周度电话会安排", 1)
-		contentStr = strings.Replace(contentStr, "{{BG_COLORE_1}}", bgColorMap[params.Status1], 1)
-		contentStr = strings.Replace(contentStr, "{{STATUS_1}}", params.Status1, 1)
-		contentStr = strings.Replace(contentStr, "{{AVATAR_1}}", params.Avatar1, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_1}}", params.Title1, 1)
-		contentStr = strings.Replace(contentStr, "{{SPEAKER_1}}", params.Speaker1, 1)
-		contentStr = strings.Replace(contentStr, "{{TIME_1}}", params.Time1, 1)
-		contentStr = strings.Replace(contentStr, "{{SHOW_ITEM_1}}", statusItemMap[params.Status1], 1)
-		contentStr = strings.Replace(contentStr, "{{SHOW_OFFLINE_1}}", offlineMap[params.ListTitle], 1)
-		contentStr = strings.Replace(contentStr, "{{SHOW_ONLINE_1}}", onlineMap[params.ListTitle], 1)
-		contentStr = strings.Replace(contentStr, "{{BG_COLORE_2}}", bgColorMap[params.Status2], 1)
-		contentStr = strings.Replace(contentStr, "{{STATUS_2}}", params.Status2, 1)
-		contentStr = strings.Replace(contentStr, "{{AVATAR_2}}", params.Avatar2, 1)
-		contentStr = strings.Replace(contentStr, "{{TITLE_2}}", params.Title2, 1)
-		contentStr = strings.Replace(contentStr, "{{SPEAKER_2}}", params.Speaker2, 1)
-		contentStr = strings.Replace(contentStr, "{{TIME_2}}", params.Time2, 1)
-		contentStr = strings.Replace(contentStr, "{{SHOW_ITEM_2}}", statusItemMap[params.Status2], 1)
-		contentStr = strings.Replace(contentStr, "{{SHOW_OFFLINE_2}}", offlineMap[params.ListTitle], 1)
-		contentStr = strings.Replace(contentStr, "{{SHOW_ONLINE_2}}", onlineMap[params.ListTitle], 1)
-		// 用默认内容填充的活动时间字体颜色调至看不见
-		color1 := "#999"
-		color2 := "#999"
-		if emptyTime1 {
-			color1 = "#fff"
-		}
-		if emptyTime2 {
-			color2 = "#fff"
-		}
-		contentStr = strings.Replace(contentStr, "{{TIME_COLOR_1}}", color1, 1)
-		contentStr = strings.Replace(contentStr, "{{TIME_COLOR_2}}", color2, 1)
-	}
-	contentStr = strings.Replace(contentStr, "{{SUN_CODE}}", sunCodeUrl, 1)
-	return
-}
-
 // GetRddpShareImg 获取日度点评分享图
 func GetRddpShareImg(title string) (imgUrl string, err error) {
 	if title == "" {
@@ -545,27 +215,6 @@ func CreatePosterFromSourceV2(codePage, codeScene, source, version, pars string)
 	if err != nil {
 		return
 	}
-	// 图片长宽
-	//heightMap := map[string]int{
-	//	"activity_detail":       1210,
-	//	"activity_list":         1948,
-	//	"special_column_detail": 1480,
-	//	"special_column_list":   1548,
-	//	"chart_detail":          1536,
-	//	"chart_list":            1352,
-	//	"report_detail":         1420,
-	//	"report_list":           1344,
-	//}
-	//widthMap := map[string]int{
-	//	"activity_detail":       1280,
-	//	"activity_list":         1280,
-	//	"special_column_detail": 1176,
-	//	"special_column_list":   1176,
-	//	"chart_detail":          1176,
-	//	"chart_list":            1176,
-	//	"report_detail":         1176,
-	//	"report_list":           1176,
-	//}
 
 	width := ybPosterConfig.Width
 	height := ybPosterConfig.Hight
@@ -757,3 +406,37 @@ func fillContent2HtmlV2(source, pars, sunCodeUrl string, height float64, ybPoste
 	}
 	return
 }
+
+// GetDynamicShareImg 生成动态分享图
+func GetDynamicShareImg(source, pars string) (imgUrl string, err error) {
+	if source == "" {
+		err = errors.New("图片来源有误")
+		return
+	}
+	imgConfig, e := yb_poster_config.GetBySource(source)
+	if e != nil {
+		err = errors.New("获取图片配置失败")
+		return
+	}
+	// 填充html内容
+	content, newHeight, e := fillContent2HtmlV2(source, pars, "", imgConfig.Hight, *imgConfig)
+	if e != nil {
+		err = errors.New("html内容有误")
+		return
+	}
+	htm2ImgReq := make(map[string]interface{})
+	htm2ImgReq["html_content"] = content
+	htm2ImgReq["width"] = imgConfig.Width
+	htm2ImgReq["height"] = newHeight
+	res, e := postHtml2Img(htm2ImgReq)
+	if e != nil || res == nil {
+		err = errors.New("html转图片请求失败")
+		return
+	}
+	if res.Code != 200 {
+		err = errors.New("html转图片请求失败: " + res.Msg)
+		return
+	}
+	imgUrl = res.Data
+	return
+}

+ 83 - 10
services/voice_broadcast.go

@@ -1,6 +1,7 @@
 package services
 
 import (
+	"encoding/json"
 	"errors"
 	"fmt"
 	"hongze/hongze_yb/global"
@@ -10,12 +11,13 @@ import (
 	"hongze/hongze_yb/models/tables/sys_role_admin"
 	"hongze/hongze_yb/models/tables/voice_broadcast"
 	"hongze/hongze_yb/models/tables/voice_broadcast_statistics"
+	"hongze/hongze_yb/models/tables/voice_section"
 	"hongze/hongze_yb/services/user"
 	"hongze/hongze_yb/utils"
 	"time"
 )
 
-func GetVoiceBroadcastList(pageindex, pagesize, sectionId, broadcastId int, userInfo user.UserInfo)  (list []response.Broadcast, err error){
+func GetVoiceBroadcastList(pageindex, pagesize, sectionId, broadcastId int, userInfo user.UserInfo) (list []response.Broadcast, err error) {
 	if broadcastId == 0 {
 		if sectionId == 0 {
 			broadList, e := voice_broadcast.GetBroadcast(pageindex, pagesize)
@@ -40,7 +42,7 @@ func GetVoiceBroadcastList(pageindex, pagesize, sectionId, broadcastId int, user
 					CreateTime:       item.CreateTime,
 					IsAuthor:         false,
 				}
-				if int(userInfo.UserID) == item.AuthorId{
+				if int(userInfo.UserID) == item.AuthorId {
 					respItem.IsAuthor = true
 				}
 				list = append(list, respItem)
@@ -71,7 +73,7 @@ func GetVoiceBroadcastList(pageindex, pagesize, sectionId, broadcastId int, user
 				CreateTime:       item.CreateTime,
 				IsAuthor:         false,
 			}
-			if int(userInfo.UserID) == item.AuthorId{
+			if int(userInfo.UserID) == item.AuthorId {
 				respItem.IsAuthor = true
 			}
 			list = append(list, respItem)
@@ -79,7 +81,7 @@ func GetVoiceBroadcastList(pageindex, pagesize, sectionId, broadcastId int, user
 		}
 		err = e
 		return
-	}else {
+	} else {
 		broadList, e := voice_broadcast.GetBroadcastByIdAndPage(pageindex, pagesize, broadcastId)
 		if e != nil {
 			e = errors.New("获取语音播报列表失败 Err:" + e.Error())
@@ -102,7 +104,7 @@ func GetVoiceBroadcastList(pageindex, pagesize, sectionId, broadcastId int, user
 				CreateTime:       item.CreateTime,
 				IsAuthor:         false,
 			}
-			if int(userInfo.UserID) == item.AuthorId{
+			if int(userInfo.UserID) == item.AuthorId {
 				respItem.IsAuthor = true
 			}
 			list = append(list, respItem)
@@ -151,8 +153,8 @@ func GetVoiceAdminByUserInfo(userInfo user.UserInfo) (ok bool, adminInfo *admin2
 	if adminInfo.Enabled != 1 {
 		return
 	}
-	_,err = sys_role_admin.GetVoiceAdmin(int(adminInfo.AdminID))
-	if err != nil && err != utils.ErrNoRow{
+	_, err = sys_role_admin.GetVoiceAdmin(int(adminInfo.AdminID))
+	if err != nil && err != utils.ErrNoRow {
 		return
 	}
 
@@ -162,7 +164,6 @@ func GetVoiceAdminByUserInfo(userInfo user.UserInfo) (ok bool, adminInfo *admin2
 	}
 	ok = true
 
-
 	return
 }
 
@@ -173,7 +174,7 @@ func AddBroadcastRecord(userinfo user.UserInfo, source, broadcastId int) {
 			global.LOG.Critical(fmt.Sprintf("AddBroadcastLog: userId=%d, err:%s", userinfo.UserID, err.Error()))
 		}
 	}()
-	companyProduct, err := company_product.GetByCompany2ProductId(userinfo.CompanyID,1)
+	companyProduct, err := company_product.GetByCompany2ProductId(userinfo.CompanyID, 1)
 	if err != nil {
 		return
 	}
@@ -206,4 +207,76 @@ func AddBroadcastRecord(userinfo user.UserInfo, source, broadcastId int) {
 		return
 	}
 	return
-}
+}
+
+// VoiceBroadcastShareImgPars 语音播报分享图参数
+type VoiceBroadcastShareImgPars struct {
+	BackgroundImg string `json:"background_img"`
+	Title         string `json:"title"`
+	CreateTime    string `json:"create_time"`
+}
+
+// UpdateVoiceBroadcastImgUrl 更新历史语音播报分享图
+func UpdateVoiceBroadcastImgUrl() (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err.Error())
+		}
+	}()
+	// 获取语音播报列表
+	list, e := voice_broadcast.GetBroadcastList()
+	if e != nil {
+		err = errors.New("获取语音播报列表失败")
+		return
+	}
+	// 获取语音播报板块分享图
+	sectionList, e := voice_section.GetVoiceSection()
+	if e != nil {
+		err = errors.New("获取语音播报列表失败")
+		return
+	}
+	sectionMap := make(map[int]string, 0)
+	sectionNameMap := make(map[int]string, 0)
+	for _, s := range sectionList {
+		sectionMap[s.SectionId] = s.ImgUrl
+		sectionNameMap[s.SectionId] = s.SectionName
+	}
+	// 生成语音分享图并更新
+	listLen := len(list)
+	fmt.Println("待更新数:", listLen)
+	updateCols := []string{"ImgUrl"}
+	for i := 0; i < listLen; i++ {
+		item := list[i]
+		fmt.Println("正在更新-Id:", item.BroadcastId)
+		imgUrl := sectionMap[item.SectionId]
+		if imgUrl == "" {
+			fmt.Println("背景图为空-Id:", item.BroadcastId)
+			continue
+		}
+		sectionName := sectionNameMap[item.SectionId]
+		timeDate := item.CreateTime[0:10]
+		pars := VoiceBroadcastShareImgPars{
+			BackgroundImg: imgUrl,
+			Title:         sectionName,
+			CreateTime:    timeDate,
+		}
+		parsByte, e := json.Marshal(pars)
+		if e != nil {
+			err = errors.New("分享图参数有误")
+			return
+		}
+		shareImg, e := GetDynamicShareImg(VoiceBroadcastShareImgSource, string(parsByte))
+		//fmt.Println(shareImg)
+		if e != nil {
+			err = errors.New("生成分享图失败")
+			return
+		}
+		item.ImgUrl = shareImg
+		if e = item.Update(updateCols); e != nil {
+			err = errors.New("更新语音播报失败")
+			return
+		}
+		fmt.Println("更新成功-Id:", item.BroadcastId)
+	}
+	return
+}