|
@@ -6,6 +6,7 @@ import (
|
|
|
"fmt"
|
|
|
"github.com/PuerkitoBio/goquery"
|
|
|
"hongze/hongze_yb/global"
|
|
|
+ "hongze/hongze_yb/models/tables/yb_poster_config"
|
|
|
"hongze/hongze_yb/models/tables/yb_poster_resource"
|
|
|
"hongze/hongze_yb/models/tables/yb_suncode_pars"
|
|
|
"hongze/hongze_yb/services/alarm_msg"
|
|
@@ -51,7 +52,7 @@ func CreatePosterFromSource(codePage, codeScene, source, version, pars string) (
|
|
|
}
|
|
|
path := fmt.Sprint(codePage, "?", codeScene)
|
|
|
// 非列表来源获取历史图片,无则生成
|
|
|
- if !strings.Contains(source, "list") {
|
|
|
+ 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
|
|
@@ -72,6 +73,7 @@ func CreatePosterFromSource(codePage, codeScene, source, version, pars string) (
|
|
|
"chart_list": 1352,
|
|
|
"report_detail": 1420,
|
|
|
"report_list": 1344,
|
|
|
+ "price_driven": 1344,
|
|
|
}
|
|
|
widthMap := map[string]int{
|
|
|
"activity_detail": 1280,
|
|
@@ -82,6 +84,7 @@ func CreatePosterFromSource(codePage, codeScene, source, version, pars string) (
|
|
|
"chart_list": 1176,
|
|
|
"report_detail": 1176,
|
|
|
"report_list": 1176,
|
|
|
+ "price_driven": 1176,
|
|
|
}
|
|
|
width := widthMap[source]
|
|
|
height := heightMap[source]
|
|
@@ -245,37 +248,41 @@ func CreateAndUploadSunCode(page, scene, version string) (imgUrl string, err err
|
|
|
}
|
|
|
|
|
|
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"`
|
|
|
+ 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动态内容
|
|
@@ -382,12 +389,12 @@ func fillContent2Html(source, pars, sunCodeUrl string, height int) (contentStr s
|
|
|
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, "{{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, "{{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)
|
|
@@ -408,6 +415,12 @@ func fillContent2Html(source, pars, sunCodeUrl string, height int) (contentStr s
|
|
|
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",
|
|
@@ -464,3 +477,283 @@ func fillContent2Html(source, pars, sunCodeUrl string, height int) (contentStr s
|
|
|
contentStr = strings.Replace(contentStr, "{{SUN_CODE}}", sunCodeUrl, 1)
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+// GetRddpShareImg 获取日度点评分享图
|
|
|
+func GetRddpShareImg(title string) (imgUrl string, err error) {
|
|
|
+ if title == "" {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ template := fmt.Sprint("static/htm2img/rddp-share.html")
|
|
|
+ contentByte, e := ioutil.ReadFile(template)
|
|
|
+ if e != nil {
|
|
|
+ err = errors.New("读取模板失败, Err: " + e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ contentStr := string(contentByte)
|
|
|
+ contentStr = strings.Replace(contentStr, "{{TITLE}}", title, 1)
|
|
|
+ htm2ImgReq := make(map[string]interface{})
|
|
|
+ htm2ImgReq["html_content"] = contentStr
|
|
|
+ htm2ImgReq["width"] = 1000
|
|
|
+ htm2ImgReq["height"] = 800
|
|
|
+ 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
|
|
|
+}
|
|
|
+
|
|
|
+// CreatePosterFromSourceV2 生成分享海报(通过配置获取相关信息)
|
|
|
+func CreatePosterFromSourceV2(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
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ybPosterConfig, err := yb_poster_config.GetBySource(source)
|
|
|
+ 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
|
|
|
+ //生成太阳码
|
|
|
+ sunCodeUrl, err := CreateAndUploadSunCode(codePage, codeScene, version)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //sunCodeUrl := ``
|
|
|
+ // 填充html内容
|
|
|
+ contentStr, newHeight, err := fillContent2HtmlV2(source, pars, sunCodeUrl, height, *ybPosterConfig)
|
|
|
+ if err != nil {
|
|
|
+ errMsg = "html内容有误"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ global.LOG.Critical(contentStr)
|
|
|
+ //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
|
|
|
+}
|
|
|
+
|
|
|
+// HtmlReplaceConfig html替换配置
|
|
|
+type HtmlReplaceConfig struct {
|
|
|
+ TemplateStr string `json:"template_str"`
|
|
|
+ ReplaceStr string `json:"replace_str"`
|
|
|
+}
|
|
|
+
|
|
|
+// DefaultValueConfig 默认值的配置
|
|
|
+type DefaultValueConfig struct {
|
|
|
+ Key string `json:"key"`
|
|
|
+ UseOtherKey string `json:"use_other_key"`
|
|
|
+ Value string `json:"value"`
|
|
|
+ ConditionKey string `json:"condition_key"`
|
|
|
+}
|
|
|
+
|
|
|
+// fillContent2Html 填充HTML动态内容
|
|
|
+func fillContent2HtmlV2(source, pars, sunCodeUrl string, height float64, ybPosterConfig yb_poster_config.YbPosterConfig) (contentStr string, newHeight float64, err error) {
|
|
|
+ paramsMap := make(map[string]string)
|
|
|
+ if err = json.Unmarshal([]byte(pars), ¶msMap); err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //fmt.Println(paramsMap)
|
|
|
+
|
|
|
+ //html替换规则
|
|
|
+ htmlReplaceConfigList := make([]HtmlReplaceConfig, 0)
|
|
|
+ if err = json.Unmarshal([]byte(ybPosterConfig.HTMLReplaceConfig), &htmlReplaceConfigList); err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ newHeight = height
|
|
|
+ contentStr = ybPosterConfig.HTMLTemplate
|
|
|
+
|
|
|
+ // 默认数据替换
|
|
|
+ defaultValueConfigMap := make([]DefaultValueConfig, 0)
|
|
|
+ if ybPosterConfig.DefaultValueConfig != `` {
|
|
|
+ if err = json.Unmarshal([]byte(ybPosterConfig.DefaultValueConfig), &defaultValueConfigMap); err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 列表的动态内容不完整的用默认内容的填充
|
|
|
+ //var emptyTime1, emptyTime2 bool
|
|
|
+ conditionKeyValMap := make(map[string]string)
|
|
|
+ for _, v := range defaultValueConfigMap {
|
|
|
+ if v.ConditionKey == `` {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ conditionKeyVal, ok := conditionKeyValMap[v.ConditionKey]
|
|
|
+ if !ok {
|
|
|
+ conditionKeyVal = paramsMap[v.ConditionKey]
|
|
|
+ conditionKeyValMap[v.ConditionKey] = conditionKeyVal
|
|
|
+ }
|
|
|
+ if conditionKeyVal == `` {
|
|
|
+ paramsMap[v.Key] = v.Value
|
|
|
+ if v.UseOtherKey != `` {
|
|
|
+ if tmpVal, ok := paramsMap[v.UseOtherKey]; ok {
|
|
|
+ paramsMap[v.Key] = tmpVal
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 填充指定内容
|
|
|
+ switch source {
|
|
|
+ case "report_detail": //需要将简介处理下
|
|
|
+ reportAbstract := paramsMap["report_abstract"]
|
|
|
+ doc, tmpErr := goquery.NewDocumentFromReader(strings.NewReader(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>"
|
|
|
+ }
|
|
|
+ })
|
|
|
+ paramsMap["report_abstract"] = abstract
|
|
|
+ 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",
|
|
|
+ }
|
|
|
+
|
|
|
+ listTitle := paramsMap["list_title"]
|
|
|
+ status1 := paramsMap["status_1"]
|
|
|
+ if status1 != "未开始" {
|
|
|
+ newHeight = 1715
|
|
|
+ }
|
|
|
+ status2 := paramsMap["status_2"]
|
|
|
+ paramsMap["list_title"] = "弘则FICC周度电话会安排"
|
|
|
+ paramsMap["bg_color_1"] = bgColorMap[status1]
|
|
|
+ paramsMap["show_item_1"] = statusItemMap[status1]
|
|
|
+ paramsMap["show_offline_1"] = offlineMap[listTitle]
|
|
|
+ paramsMap["show_online_1"] = onlineMap[listTitle]
|
|
|
+
|
|
|
+ paramsMap["bg_color_2"] = bgColorMap[status2]
|
|
|
+ paramsMap["show_item_2"] = statusItemMap[status2]
|
|
|
+ paramsMap["show_offline_2"] = offlineMap[listTitle]
|
|
|
+ paramsMap["show_online_2"] = onlineMap[listTitle]
|
|
|
+
|
|
|
+ // 用默认内容填充的活动时间字体颜色调至看不见
|
|
|
+ color1 := "#999"
|
|
|
+ color2 := "#999"
|
|
|
+
|
|
|
+ if paramsMap["empty_time_1"] == "true" {
|
|
|
+ color1 = "#fff"
|
|
|
+ }
|
|
|
+ if paramsMap["empty_time_2"] == "true" {
|
|
|
+ color2 = "#fff"
|
|
|
+ }
|
|
|
+ paramsMap["time_color_1"] = color1
|
|
|
+ paramsMap["time_color_2"] = color2
|
|
|
+ }
|
|
|
+
|
|
|
+ contentStr = strings.Replace(contentStr, "{{SUN_CODE}}", sunCodeUrl, 1)
|
|
|
+
|
|
|
+ for _, v := range htmlReplaceConfigList {
|
|
|
+ tmpVal, ok := paramsMap[v.ReplaceStr]
|
|
|
+ if !ok {
|
|
|
+ tmpVal = ``
|
|
|
+ }
|
|
|
+ contentStr = strings.Replace(contentStr, v.TemplateStr, tmpVal, 1)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|