package services import ( "encoding/json" "errors" "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" "hongze/hongze_yb/services/wx_app" "hongze/hongze_yb/utils" "io/ioutil" "net/http" "os" "strings" "time" ) var ServerUrl = "http://127.0.0.1:5008/" // SharePosterReq 分享海报请求体 type SharePosterReq struct { CodePage string `json:"code_page" description:"太阳码page"` CodeScene string `json:"code_scene" description:"太阳码scene"` Source string `json:"source" description:"来源"` Version string `json:"version" description:"海报版本号" ` 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"` Data string `json:"data"` } // postHtml2Img 请求htm2img接口 func postHtml2Img(param map[string]interface{}) (resp *Html2ImgResp, err error) { // 目前仅此处调用该接口,暂不加授权、校验等 postUrl := ServerUrl + "htm2img" postData, err := json.Marshal(param) if err != nil { return } result, err := Html2ImgHttpPost(postUrl, string(postData), "application/json") if err != nil { return } if err = json.Unmarshal(result, &resp); err != nil { return } return resp, nil } // Html2ImgHttpPost post请求 func Html2ImgHttpPost(url, postData string, params ...string) ([]byte, error) { body := ioutil.NopCloser(strings.NewReader(postData)) client := &http.Client{} req, err := http.NewRequest("POST", url, body) if err != nil { return nil, err } contentType := "application/x-www-form-urlencoded;charset=utf-8" if len(params) > 0 && params[0] != "" { contentType = params[0] } req.Header.Set("Content-Type", contentType) resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) fmt.Println("HttpPost:" + string(b)) return b, err } // CreateAndUploadSunCode 生成太阳码并上传OSS func CreateAndUploadSunCode(page, scene, version string) (imgUrl string, err error) { if page == "" { err = errors.New("page不能为空") return } path := fmt.Sprint(page, "?", scene) exist, err := yb_poster_resource.GetPosterByCondition(path, "qrcode", version) if err != nil && err != utils.ErrNoRow { return } if exist != nil && exist.ImgURL != "" { return exist.ImgURL, nil } // scene超过32位会生成失败,md5处理至32位 sceneMD5 := "a=1" if scene != "" { sceneMD5 = utils.MD5(scene) } picByte, err := wx_app.GetSunCode(page, sceneMD5) if err != nil { return } // 生成图片 localPath := "./static/img" fileName := utils.GetRandStringNoSpecialChar(28) + ".png" fpath := fmt.Sprint(localPath, "/", fileName) f, err := os.Create(fpath) if err != nil { return } if _, err = f.Write(picByte); err != nil { return } defer func() { f.Close() os.Remove(fpath) }() // 上传OSS fileDir := "images/yb/suncode/" imgUrl, err = UploadAliyunToDir(fileName, fpath, fileDir) if err != nil { return } // 记录二维码信息 newPoster := &yb_poster_resource.YbPosterResource{ Path: path, ImgURL: imgUrl, Type: "qrcode", Version: version, CreateTime: time.Now(), } err = newPoster.Create() if err != nil { return } // 记录参数md5 if scene != "" { newPars := &yb_suncode_pars.YbSuncodePars{ Scene: scene, SceneKey: sceneMD5, CreateTime: time.Now(), } err = newPars.Create() } 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), ¶ms); 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 != "
" && st != "
" && !strings.Contains(phtml, "iframe") { abstract = abstract + "

" + phtml + "

" } }) 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 == "" { 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 != "
" && st != "
" && !strings.Contains(phtml, "iframe") { abstract = abstract + "

" + phtml + "

" } }) 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 }