package services import ( "context" "encoding/json" "errors" "fmt" "github.com/wenzhenxi/gorsa" "hongze/hongze_task/models" "hongze/hongze_task/models/yb" "hongze/hongze_task/services/alarm_msg" "hongze/hongze_task/utils" "io/ioutil" "net/http" "net/url" "strconv" "strings" "time" ) //func init() { // report, _ := models.GetReportById(836) // SendReportToThs(report) //} // SendWaitReport 定时向同花顺推送报告(定时任务) func SendWaitReport(cont context.Context) (err error) { defer func() { if err != nil { //fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "延时任务发送报告至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("延时任务发送报告至同花顺失败 ErrMsg:"+err.Error(), 3) } }() list, err := models.GetWaitReportSendThsDetailList() if err != nil { return } for _, detail := range list { //先标记为 _ = models.ModifyReportSendThsDetailStatus(detail.SendId, 0, "") go SendToThs(detail.SendId, detail.ReportId, detail.ReportType) } return } // SyncWxGroupEveryDay 每日定时向同花顺同步客户时间 func SyncWxGroupEveryDay(cont context.Context) (err error) { defer func() { if err != nil { fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "同步微信群组信息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "同步微信群组信息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) } }() //查询校验当天数据是否已经生成 _, err = models.GetCompanyEndDate(time.Now().Format(utils.FormatDate)) if err == nil || err.Error() != utils.ErrNoRow() { err = errors.New(fmt.Sprint(time.Now().Format(utils.FormatDate), "当天数据已经同步")) return } //永续、正式、试用、冻结 list, err := models.GetAllCompanyProduct() if err != nil { return } timeLoc, _ := time.LoadLocation("Asia/Shanghai") //需要入库的数据 companyEndDateMap := make(map[string]*models.CompanyEndDate) //实际需要推送的数据 companyEndDatePushMap := make(map[string]*models.CompanyEndDate) //微信群组开放编号code companyProductOpenCode := make(map[string]string) for _, companyProduct := range list { key := fmt.Sprint(companyProduct.CompanyId, "_", companyProduct.ProductId) endDate, _ := time.ParseInLocation(utils.FormatDate, companyProduct.EndDate, timeLoc) if companyProduct.Status == "冻结" { endDate = time.Now().AddDate(0, 0, -1) } tmpCompanyEndDate := &models.CompanyEndDate{ CompanyId: companyProduct.CompanyId, ProductId: companyProduct.ProductId, Status: companyProduct.Status, EndDate: endDate, CreateTime: time.Now(), } companyEndDateMap[key] = tmpCompanyEndDate companyEndDatePushMap[key] = tmpCompanyEndDate companyProductOpenCode[key] = companyProduct.OpenCode } startDate := time.Now().AddDate(0, 0, -1).Format(utils.FormatDate) endDate := time.Now().Format(utils.FormatDate) endDateList, err := models.GetAllCompanyProductEndDate(startDate, endDate) for _, endDate := range endDateList { key := fmt.Sprint(endDate.CompanyId, "_", endDate.ProductId) if companyEndDate, ok := companyEndDatePushMap[key]; ok { if companyEndDate.Status == "冻结" { //获取当天的零点时间 endDateStr := time.Now().AddDate(0, 0, -1).Format(utils.FormatDate) companyEndDate.EndDate, _ = time.ParseInLocation(utils.FormatDate, endDateStr, timeLoc) } if companyEndDate.EndDate.Equal(endDate.EndDate) { delete(companyEndDatePushMap, key) } } } for _, companyEndDate := range companyEndDatePushMap { fmt.Println("待推送数据:", companyEndDate) key := fmt.Sprint(companyEndDate.CompanyId, "_", companyEndDate.ProductId) //同步至同花顺 if openCode, ok := companyProductOpenCode[key]; ok { SyncWxGroup(openCode, companyEndDate.EndDate.Format(utils.FormatDate)) } } for _, companyEndDate := range companyEndDateMap { models.AddCompanyEndDate(companyEndDate) } return } var permissionMap map[string]string = map[string]string{ "化里化外日评": "原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱", "股债日评": "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢", "贵金属复盘": "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢", "每日经济数据备忘录": "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢", "宏观商品复盘": "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢", "知白守黑日评": "钢材,铁矿,双焦(焦煤、焦炭)", "有声有色日度闲篇": "有色(铜、铝),有色(锌、铅),镍+不锈钢", "EIA原油库存点评": "原油", "苯乙烯数据点评": "苯乙烯", "API原油库存点评": "原油", "铁矿航运数据点评": "铁矿", "中观需求点评": "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢", "聚酯数据点评": "PTA,MEG", "钢材周度数据点评": "钢材", "寻根知本": "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢", "国际宏观": "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢", "能化百家谈": "原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱", "有色百家谈": "有色(铜、铝),有色(锌、铅),镍+不锈钢", "黑色百家谈": "钢材,铁矿,双焦(焦煤、焦炭)", } // permissionLabelMap 品种与同花顺标签的映射关系 var permissionLabelMap = map[string]string{ "宏观经济": "宏观", "利率债": "利率债", "原油": "原油", "PTA": "PTA", "MEG": "MEG", "织造终端": "织造终端", "甲醇": "甲醇", "聚烯烃": "聚烯烃", "沥青": "沥青", "纯苯+苯乙烯": "纯苯+苯乙烯", "玻璃纯碱": "玻璃纯碱", "钢材": "钢材", "铁矿": "铁矿", "双焦(焦煤、焦炭)": "双焦(焦煤、焦炭)", "有色(锌)": "有色(锌)", "有色(铜、铝)": "有色(铜、铝)", "镍+不锈钢": "镍+不锈钢", "PVC": "PVC", "聚酯": "聚酯", "钴锂": "钴锂", "策略": "策略", "苯乙烯": "纯苯+苯乙烯", "锌": "有色(锌)", "双焦": "双焦(焦煤、焦炭)", "铜/铝": "有色(铜、铝)", "镍/不锈钢": "镍+不锈钢", "成品油": "成品油", "油品": "成品油", "纺服": "织造终端", } //TshResult 同花顺返回信息 type TshResult struct { ErrorCode int `json:"error" description:"错误状态码"` Message string `json:"message" description:"提示信息"` } // func SendToThs(sendDetailId, reportId int, reportType string) (err error) { switch reportType { case "日度点评": tmpErr := SendReportToThs(reportId) if tmpErr != nil { err = tmpErr } case "研报小程序", "研报": tmpErr := SendReportMiniToThs(reportId) if tmpErr != nil { err = tmpErr } case "研报视频社区", "视频社区": tmpErr := SendYbCommunityVideoToThs(reportId) if tmpErr != nil { err = tmpErr } case "研报线上路演", "线上路演": tmpErr := SendYbRoadVideoToThs(reportId) if tmpErr != nil { err = tmpErr } case "研报价格驱动", "价格驱动": tmpErr := SendYbPriceDrivenToThs(reportId) if tmpErr != nil { err = tmpErr } case "语音播报": tmpErr := SendYbVoiceBroadcastToThs(reportId) if tmpErr != nil { err = tmpErr } default: err = errors.New("异常类型") } if err != nil { _ = models.ModifyReportSendThsDetailStatus(sendDetailId, -1, err.Error()) err = nil return } _ = models.ModifyReportSendThsDetailStatus(sendDetailId, 1, "") return } // SendReportToThs 发送报告到同花顺 func SendReportToThs(reportId int) (err error) { defer func() { if err != nil { //fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送报告至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("发送报告至同花顺失败 ErrMsg:"+err.Error(), 3) } }() report, tmpErr := models.GetReportById(reportId) if tmpErr != nil { err = tmpErr return } //获取分类信息(标签) permissionName := report.ClassifyNameSecond classifyItem, err := models.GetClassifyById(report.ClassifyIdSecond) if err != nil { err = errors.New(fmt.Sprint("获取分类失败:", permissionName)) } //获取权限标签名称 var permissionStr string if classifyItem != nil { permissionStr = classifyItem.ClassifyLabel if permissionStr == "" { var isOk bool permissionStr, isOk = permissionMap[permissionName] if !isOk { err = errors.New(fmt.Sprint("没有该权限的标签,权限名:", permissionName)) return } } } else { var isOk bool permissionStr, isOk = permissionMap[permissionName] if !isOk { err = errors.New(fmt.Sprint("没有该权限的标签,权限名:", permissionName)) return } } if permissionStr == "" { err = errors.New(fmt.Sprint("没有该权限的标签,权限名:", permissionName)) return } //fmt.Println("sendDetailId:", sendDetailId) stageStr := fmt.Sprintf("%v", report.Stage) createDate, err := time.Parse(utils.FormatDateTime, report.CreateTime) createDateFrom := createDate.Format("0102") title := `【第` + stageStr + `期|FICC】` + report.Title + `(` + createDateFrom + ")" // 跳转地址 jumpBaseUrl := `http://rddpweb.brilliantstart.cn/reportdtl?id=` //生产环境地址 if utils.RunMode == "release" { jumpBaseUrl = `https://ficc.hzinsights.com/reportdtl?id=` } jumpUrl := fmt.Sprint(jumpBaseUrl, report.Id) // logo 地址 logoUrl := `https://hongze.oss-cn-shanghai.aliyuncs.com/hzyj.png` // 简介 abstract := report.Abstract // 实际推送到同花顺 err = SendThs(title, permissionStr, abstract, jumpUrl, logoUrl, "1") return } // SendThs 发送消息到同花顺 func SendThs(title, labelStr, abstract, jumpBaseUrl, logoUrl, dataType string) (err error) { defer func() { if err != nil { //fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("发送消息至同花顺失败 ErrMsg:"+err.Error(), 3) } }() pubKey := utils.THS_PubKey sendUrl := utils.THS_SendUrl //fmt.Println("sendUrl:", sendUrl) //标题字符长度截取,最多50位字符 title = utils.SubStr(title, 50) utils.FileLog.Info(fmt.Sprintf("title:%s", title)) title, err = gorsa.PublicEncrypt(title, pubKey) if err != nil { return } //简介字符长度截取,最多50位字符 abstract = utils.SubStr(abstract, 50) utils.FileLog.Info(fmt.Sprintf("abstract:%s", abstract)) abstract, err = gorsa.PublicEncrypt(abstract, pubKey) if err != nil { return } // 关联后的标签数据 newLabelList := make([]string, 0) labelList := strings.Split(labelStr, ",") for _, v := range labelList { tmpLabel, ok := permissionLabelMap[v] //判断是否在关联标签里面 if !ok { //如果不在关联标签里面,那么就把原始的值赋值给 tmpLabel = v } newLabelList = append(newLabelList, tmpLabel) } labelStr = strings.Join(newLabelList, ",") utils.FileLog.Info(fmt.Sprintf("labelStr:%s", labelStr)) label, err := gorsa.PublicEncrypt(labelStr, pubKey) if err != nil { return } jumpUrl, err := gorsa.PublicEncrypt(jumpBaseUrl, pubKey) if err != nil { return } picUrl, err := gorsa.PublicEncrypt(logoUrl, pubKey) if err != nil { return } dataTypeEncript, err := gorsa.PublicEncrypt(dataType, pubKey) if err != nil { return } //开始发送 client := http.Client{} form := url.Values{} form.Add("title", title) form.Add("description", abstract) form.Add("label", label) form.Add("url", jumpUrl) form.Add("icon", picUrl) form.Add("dataType", dataTypeEncript) utils.FileLog.Info(fmt.Sprintf("SendThs parms:%s", form.Encode())) resp, err := client.PostForm(sendUrl, form) if err != nil { return } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) //fmt.Println(string(body)) utils.FileLog.Info(fmt.Sprintf("ThsResult parms:%s", string(body))) //同花顺接口返回数据 var tshResult TshResult err = json.Unmarshal(body, &tshResult) if err != nil { err = errors.New(fmt.Sprint("同花顺接口返回数据转换成结构体异常,Err:", err)) return } if tshResult.ErrorCode != 1 { err = errors.New(fmt.Sprint("发送数据到同花顺接口异常,result:", string(body))) return } return } // SyncWxGroup 同步同花顺 微信群信息 func SyncWxGroup(openCompanyCode, deadline string) (err error) { defer func() { if err != nil { //fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "同步同花顺微信群信息失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "同步同花顺微信群信息失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("同步同花顺微信群信息失败 ErrMsg:"+err.Error(), 3) } }() pubKey := utils.THS_PubKey sendUrl := utils.THS_SyncWxGroupUrl openCompanyCode, err = gorsa.PublicEncrypt(openCompanyCode, pubKey) if err != nil { return } deadline, err = gorsa.PublicEncrypt(deadline, pubKey) if err != nil { return } status := `1` status, err = gorsa.PublicEncrypt(status, pubKey) if err != nil { return } //开始发送 client := http.Client{} form := url.Values{} form.Add("thirdWechatGroupId", openCompanyCode) form.Add("deadline", deadline) form.Add("status", status) utils.FileLog.Info(fmt.Sprintf("SendThs SyncWxGroup parms:%s", form.Encode())) resp, err := client.PostForm(sendUrl, form) if err != nil { return } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) utils.FileLog.Info(fmt.Sprintf("SyncWxGroup ThsResult parms:%s", string(body))) //同花顺接口返回数据 var tshResult TshResult err = json.Unmarshal(body, &tshResult) if err != nil { err = errors.New(fmt.Sprint("同花顺接口返回数据转换成结构体异常,Err:", err)) return } if tshResult.ErrorCode != 1 { err = errors.New(fmt.Sprint("发送数据到同花顺接口异常,result:", string(body))) return } return } // SendReportMiniToThs 发送报告小程序到同花顺 func SendReportMiniToThs(reportId int) (err error) { defer func() { if err != nil { //fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "SendReportMiniToThs延时任务发送报告至同花顺失败, ReportId:"+strconv.Itoa(reportId)+", ErrMsg:"+err.Error(), utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("SendReportMiniToThs延时任务发送报告至同花顺失败, ReportId:"+strconv.Itoa(reportId)+", ErrMsg:"+err.Error(), 3) } }() report, tmpErr := models.GetReportById(reportId) if tmpErr != nil { err = tmpErr return } //小程序跳转地址 jumpBaseUrl := utils.WxYbAppId + `/pages-report/reportDetail?reportId=` jumpUrl := fmt.Sprint(jumpBaseUrl, report.Id) logoUrl := `https://hongze.oss-cn-shanghai.aliyuncs.com/hzyj.png` var permissionStr string if report.HasChapter == 0 { // 获取分类信息(标签) permissionName := report.ClassifyNameSecond classifyItem, tmpErr := models.GetClassifyById(report.ClassifyIdSecond) if tmpErr != nil { err = errors.New(fmt.Sprint("获取分类失败:", permissionName)) return } // 获取权限标签名称 if classifyItem != nil { permissionStr = classifyItem.ClassifyLabel if permissionStr == "" { var isOk bool permissionStr, isOk = permissionMap[permissionName] if !isOk { err = errors.New(fmt.Sprint("没有该权限的标签,权限名:", permissionName)) return } } } else { var isOk bool permissionStr, isOk = permissionMap[permissionName] if !isOk { err = errors.New(fmt.Sprint("没有该权限的标签,权限名:", permissionName)) return } } if permissionStr == "" { err = errors.New(fmt.Sprint("没有该权限的标签,权限名:", permissionName)) return } } else { // 同php的 permissionStr = "宏观,利率债,原油,PTA,MEG,织造终端,甲醇,聚烯烃,沥青,橡胶,苯乙烯,玻璃纯碱,钢材,铁矿,双焦(焦煤、焦炭),有色(铜、铝),有色(锌、铅),镍+不锈钢" } // 实际推送到同花顺 err = SendThs(report.Title, permissionStr, report.Abstract, jumpUrl, logoUrl, "2") return } // SendYbPriceDrivenToThs 推送研报小程序价格驱动客群消息 func SendYbPriceDrivenToThs(priceDrivenId int) (err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("SendYbPriceDrivenToThs-延时任务发送报告至同花顺失败, PriceDrivenId:"+strconv.Itoa(priceDrivenId)+", ErrMsg:"+err.Error(), 3) } }() priceDriven, e := yb.GetPriceDrivenById(priceDrivenId) if e != nil { err = errors.New("获取价格驱动信息失败, Err:" + e.Error()) return } // 标签信息 if priceDriven.VarietyTagId <= 0 { return } varietyTag, err := models.GetVarietyTagById(priceDriven.VarietyTagId) if err != nil { return } permissionName := varietyTag.ChartPermissionName if permissionName == "" { err = errors.New("客群标签为空, 不可推送") return } if permissionName == "宏观经济" { permissionName = "宏观" } title := fmt.Sprintf("%s价格驱动", permissionName) jumpUrl := fmt.Sprintf(`%s/pages/pricedriven/pricedriven?default_classify_first=%d&default_classify_sub=%d`, utils.WxYbAppId, varietyTag.VarietyClassifyId, varietyTag.VarietyTagId) logoUrl := `https://hongze.oss-cn-shanghai.aliyuncs.com/hzyj.png` // 推送至同花顺 dataType := "2" err = SendThs(title, permissionName, title, jumpUrl, logoUrl, dataType) return } // SendYbCommunityVideoToThs 推送研报小程序视频社区客群消息 func SendYbCommunityVideoToThs(videoId int) (err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("SendYbCommunityVideoToThs-延时任务发送报告至同花顺失败, CommunityVideoId:"+strconv.Itoa(videoId)+", ErrMsg:"+err.Error(), 3) } }() video, e := yb.GetVideoById(videoId) if e != nil { err = errors.New("获取视频信息失败, Err:" + e.Error()) return } permissionName := "宏观" // 所有客群都推 title := video.Title jumpUrl := fmt.Sprint(utils.WxYbAppId+`/pages/video/videoList?videoId=`, videoId) logoUrl := `https://hongze.oss-cn-shanghai.aliyuncs.com/hzyj.png` // 推送至同花顺 dataType := "2" err = SendThs(title, permissionName, title, jumpUrl, logoUrl, dataType) return } // SendYbRoadVideoToThs 推送研报路演视频客群消息 func SendYbRoadVideoToThs(videoId int) (err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("SendYbRoadVideoToThs-延时任务发送报告至同花顺失败, RoadVideoId:"+strconv.Itoa(videoId)+", ErrMsg:"+err.Error(), 3) } }() video, e := yb.GetRoadVideoById(videoId) if e != nil { err = errors.New("获取视频信息失败, Err:" + e.Error()) return } chartPermissionIds := video.ChartPermissionIds // 标签信息 if chartPermissionIds == "" { return } chartPermissionIdSlice := strings.Split(chartPermissionIds, ",") chartList, e := models.GetChartPermissionByIds(chartPermissionIdSlice) if e != nil { err = errors.New("获取品种信息失败, Err:" + e.Error()) return } permissionName := "" for _, v := range chartList { if v.PermissionName == "宏观经济" { v.PermissionName = "宏观" } permissionName += v.PermissionName + "," } if permissionName == "" { err = errors.New("客群标签为空, 不可推送") return } permissionName = strings.Trim(permissionName, ",") //permissionName := "宏观" //写死宏观,默认所有群都推 title := video.Title jumpUrl := fmt.Sprint(utils.WxYbAppId+`/pages/roadShow/video/list?videoId=`, videoId) logoUrl := `https://hongze.oss-cn-shanghai.aliyuncs.com/hzyj.png` // 推送至同花顺 dataType := "2" err = SendThs(title, permissionName, title, jumpUrl, logoUrl, dataType) return } // SendYbVoiceBroadcastToThs 推送研报小程序语音播报客群消息 func SendYbVoiceBroadcastToThs(voiceId int) (err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("SendYbCommunityVideoToThs-延时任务发送报告至同花顺失败, voiceBroadcastId:"+strconv.Itoa(voiceId)+", ErrMsg:"+err.Error(), 3) } }() voice, e := yb.GetBroadcastById(voiceId) if e != nil { err = errors.New("获取语音播报信息失败, Err:" + e.Error()) return } permissionName := "宏观" // 所有客群都推 title := voice.BroadcastName jumpUrl := fmt.Sprint(utils.WxYbAppId+`/pages-voice/voiceDetail?voiceId=`, voiceId) logoUrl := `https://hongze.oss-cn-shanghai.aliyuncs.com/hzyj.png` // 推送至同花顺 dataType := "2" err = SendThs(title, permissionName, title, jumpUrl, logoUrl, dataType) return } //TshListResult 同花顺返回信息 type TshListResult struct { Error int64 `json:"error"` Message string `json:"message"` Rows TshListRowsResult `json:"rows"` } // TshListRowsResult 同花顺列表数据 type TshListRowsResult struct { BeginPageIndex int64 `json:"beginPageIndex"` CurrentPage int64 `json:"currentPage"` EndPageIndex int64 `json:"endPageIndex"` HasNext bool `json:"hasNext"` HasPre bool `json:"hasPre"` NextPage int64 `json:"nextPage"` NumPerPage int64 `json:"numPerPage"` PageCount int64 `json:"pageCount"` PrePage int64 `json:"prePage"` RecordList []struct { Ctime int64 `json:"ctime" description:"创建时间"` DataType int64 `json:"dataType" description:"数据类型;1-文章,2-小程序"` Description string `json:"description" description:"描述"` Icon string `json:"icon" description:"图标"` ID int64 `json:"id" description:""` Label string `json:"label" description:"标签"` OrgCode string `json:"orgCode" description:""` PushTime string `json:"pushTime" description:""` Pushed int64 `json:"pushed" description:"已推微信群数量"` QueryRowCount int64 `json:"queryRowCount" description:""` Title string `json:"title" description:"标题"` Total int64 `json:"total" description:"推送微信群总数量"` URL string `json:"url" description:"跳转地址"` } `json:"recordList"` TotalCount int64 `json:"totalCount"` } // CheckThsReportList 定时检测同花顺客群推送状态信息 func CheckThsReportList(cont context.Context) (err error) { errMsgList := make([]string, 0) defer func() { if len(errMsgList) > 0 { emailStr := `317699326@qq.com;984198890@qq.com;pdzhao@hzinsights.com` go alarm_msg.SendAlarmMsgWithEmail("定时检测同花顺客群推送状态:
"+strings.Join(errMsgList, "
"), emailStr, 3) //fmt.Println("定时检测同花顺客群推送状态:\n"+strings.Join(errMsgList, "\n"), 3) } }() tshListRowsResult, err := thsReportList(`50`) if err != nil { return } for _, v := range tshListRowsResult.RecordList { if v.Pushed == 0 { //一个群都没有推送的情况 tmpTime := time.Unix(v.Ctime/1000, 0) //入库时间 //超时五分钟还未推送,那么就要去通知了 if time.Now().Sub(tmpTime).Minutes() > 5 { errMsg := fmt.Sprintf("报告名称:《%s》超时未推送客群,接口通知同花顺时间:%s;报告跳转地址:%s", v.Title, tmpTime.Format(utils.FormatDateTime), v.URL) errMsgList = append(errMsgList, errMsg) } } } return } // thsReportList 同花顺列表接口 func thsReportList(numPerPageStr string) (tshListRowsResult TshListRowsResult, err error) { defer func() { if err != nil { //fmt.Println(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "发送消息至同花顺失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("定时获取同花顺列表数据接口失败 ErrMsg:"+err.Error(), 3) } }() sendUrl := utils.THS_List_Url //sendUrl := `https://board.10jqka.com.cn/gateway/ps/syncNews/listPage` pageNumStr := `1` // 页码;默认1 utils.FileLog.Info(fmt.Sprintf("pageNum:%s", pageNumStr)) if err != nil { return } //numPerPageStr := "10" // 每页数量;默认10 否 utils.FileLog.Info(fmt.Sprintf("numPerPage:%s", numPerPageStr)) if err != nil { return } //pageNum int 页码;默认1 否 //numPerPage int 每页数量;默认10 否 //title String 标题 否 //startDate String 开始日期;如2022-08-12 否 //endDate String 结束日期;如2022-08-12 否 //开始发送 client := http.Client{} form := url.Values{} form.Add("pageNum", pageNumStr) form.Add("numPerPage", numPerPageStr) //utils.FileLog.Info(fmt.Sprintf("Ths List parms:%s", form.Encode())) resp, err := client.PostForm(sendUrl, form) if err != nil { return } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) //fmt.Println(string(body)) //utils.FileLog.Info(fmt.Sprintf("Ths List Result :%s", string(body))) //同花顺接口返回数据 var tshResult TshListResult err = json.Unmarshal(body, &tshResult) if err != nil { err = errors.New(fmt.Sprint("同花顺接口返回数据转换成结构体异常,Err:", err)) return } if tshResult.Error != 1 { err = errors.New(fmt.Sprint("发送数据到同花顺接口异常,result:", string(body))) return } tshListRowsResult = tshResult.Rows return }