Kaynağa Gözat

Merge branch 'master' of http://8.136.199.33:3000/hongze/hongze_cygx into cygx_8.2

xingzai 2 yıl önce
ebeveyn
işleme
4fa9bd0b4c

+ 135 - 2
controllers/report.go

@@ -408,6 +408,7 @@ func (this *ReportController) IndustryList() {
 // @Title 产业下所关联的文章分类列表
 // @Description 产业下所关联的文章分类列表接口
 // @Param   IndustrialManagementId   query   int  true       "产业ID"
+// @Param   ShowTimeLine   query   int  true       "是否展示时间线 0不展示,1展示"
 // @Success 200 {object} models.IndustrialToArticleCategoryListRep
 // @router /toArticleCategoryList [get]
 func (this *ReportController) ArticleCategoryList() {
@@ -428,6 +429,7 @@ func (this *ReportController) ArticleCategoryList() {
 		br.Msg = "请输入分类ID"
 		return
 	}
+	showTimeLine, _ := this.GetInt("ShowTimeLine", 0)
 
 	detail, err := models.GetIndustrialManagementDetail(industrialManagementId)
 	if err != nil {
@@ -516,6 +518,24 @@ func (this *ReportController) ArticleCategoryList() {
 			videoSimple.ResourceUrl = ""
 		}
 	}
+
+	//detail, err := models.GetIndustrialManagementDetail(industrialManagementId)
+	//if err != nil {
+	//	br.Msg = "获取信息失败"
+	//	br.ErrMsg = "获取信息失败,Err:" + err.Error()
+	//	return
+	//}
+
+	//时间线
+	if showTimeLine == 1{
+		timeLineItem := models.IndustrialToArticleCategoryRep{
+			CategoryId:    99999,
+			MatchTypeName: "时间线",
+		}
+
+		list = append([]*models.IndustrialToArticleCategoryRep{&timeLineItem}, list...)
+	}
+
 	resp := new(models.IndustrialToArticleCategoryListRep)
 	resp.List = list
 	resp.LayoutTime = utils.TimeRemoveHms(detail.LayoutTime)
@@ -568,7 +588,7 @@ func (this *ReportController) List() {
 	startSize = paging.StartIndex(currentIndex, pageSize)
 	var pars []interface{}
 	var total int
-	resp := new(models.TacticsListResp)
+
 	page := paging.GetPaging(currentIndex, pageSize, total)
 
 	if categoryId < 1 {
@@ -579,7 +599,9 @@ func (this *ReportController) List() {
 		br.Msg = "请输入产业ID"
 		return
 	}
-	//获取该产业下所对应的行业图片
+	if categoryId != 99999 {
+		resp := new(models.TacticsListResp)
+		//获取该产业下所对应的行业图片
 	detail, errCategory := models.GetdetailByCategoryIdOne(categoryId)
 	if errCategory != nil {
 		br.Msg = "获取信息失败"
@@ -666,6 +688,117 @@ func (this *ReportController) List() {
 	br.Success = true
 	br.Msg = "获取成功"
 	br.Data = resp
+	} else {
+		//获取该产业下所对应的行业图片
+		//因为时间线不属于数据表里的二级分类,所以图片Id用产业id查到的list中的任意一个categoryId取到的图片替代
+		categoryList, err := models.IndustrialToArticleCategoryNew(industrialManagementId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+			return
+		}
+		var timeLineCategoryId int
+		if len(categoryList) > 0{
+			timeLineCategoryId = categoryList[0].CategoryId
+		}
+
+		var detail *models.ReportMapping
+		var errCategory error
+
+		if timeLineCategoryId >0 {
+			detail, errCategory = models.GetdetailByCategoryIdOne(timeLineCategoryId)
+			if errCategory != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取信息失败,Err:" + errCategory.Error() + "categoryID 不存在:" + strconv.Itoa(categoryId)
+				return
+			}
+		}
+
+		//对应行业的图片
+		detailChartPermissionUrl, err := models.GetConfigByCode("category_chart_permissionimg_url")
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "行业配置信息失败,Err:" + err.Error()
+			return
+		}
+		chartPermissionUrlList := strings.Split(detailChartPermissionUrl.ConfigValue, "{|}")
+		mapChartPermission := make(map[string]string)
+		var permissionName string
+		var imgUrlChartPermission string
+		for _, v := range chartPermissionUrlList {
+			vslice := strings.Split(v, "_")
+			permissionName = vslice[0]
+			imgUrlChartPermission = vslice[len(vslice)-1]
+			mapChartPermission[permissionName] = imgUrlChartPermission
+		}
+
+		total, err := models.GetTimeLineReportIndustrialCount(industrialManagementId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取帖子总数失败,Err:" + err.Error()
+			return
+		}
+		page = paging.GetPaging(currentIndex, pageSize, total)
+		list, err := models.GetTimeLineReportIndustrialList(industrialManagementId, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取帖子数据失败,Err:" + err.Error()
+			return
+		}
+		//对应分类的所图片
+		detailCategoryUrl, err := models.GetConfigByCode("category_map_img_url")
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "行业配置信息失败,Err:" + err.Error()
+			return
+		}
+		categoryUrlList := strings.Split(detailCategoryUrl.ConfigValue, "{|}")
+		mapCategoryUrl := make(map[string]string)
+		var categoryIdStr string
+		var imgUrlChart string
+		for _, v := range categoryUrlList {
+			vslice := strings.Split(v, "_")
+			categoryIdStr = vslice[0]
+			imgUrlChart = vslice[len(vslice)-1]
+			mapCategoryUrl[categoryIdStr] = imgUrlChart
+		}
+
+		//lenList := len(list)
+		//for i := 0; i < lenList; i++ {
+		//	item := list[i]
+		//	list[i].Content, _ = services.GetReportContentTextSub(item.Content)
+		//	//list[i].Abstract = html.UnescapeString(item.Abstract)
+		//	//list[i].Abstract, _ = services.GetReportContentTextSub(item.Abstract)
+		//}
+
+		for k, v := range list {
+			//if v.Readnum == 0 && user.CreatedTime.Before(utils.StrTimeToTime(v.PublishDate)) && utils.StrTimeToTime(utils.OnlineTime).Before(utils.StrTimeToTime(v.PublishDate)) {
+			//	list[k].IsRed = true
+			//}
+			if v.VideoUrl != "" {
+				list[k].IsHaveVideo = true
+			}
+			id := strconv.Itoa(timeLineCategoryId)
+			list[k].ImgUrlPc = mapCategoryUrl[id]
+
+			if mapCategoryUrl[id] == "" {
+				if detail.ChartPermissionId == utils.YI_YAO_ID {
+					list[k].ImgUrlPc = utils.YI_YAO_QI_TA
+				}
+			}
+		}
+
+
+		resp := new(models.TimeLineReportListResp)
+		resp.CategoryImgUrlPc = mapChartPermission[detail.ChartPermissionName]
+
+		resp.List = list
+		resp.Paging = page
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+	}
 }
 
 // @Title 置顶/取消置顶

+ 81 - 0
models/report.go

@@ -821,3 +821,84 @@ func GetReportPvBillboardList(pars []interface{}, condition string) (items []*Ar
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
+
+//获取产业报告+晨会点评数量
+func GetTimeLineReportIndustrialCount(industrialManagementId int) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT SUM(count) AS count FROM (
+SELECT
+	COUNT( 1 ) count 
+FROM
+	cygx_article AS a
+	INNER JOIN cygx_industrial_article_group_management AS man_g ON man_g.article_id = a.article_id 
+WHERE
+	a.publish_status = 1 
+	AND a.is_class = 1 
+	AND man_g.industrial_management_id = ?
+	UNION ALL
+	SELECT
+	COUNT( 1 ) count 
+	FROM
+	cygx_morning_meeting_review_chapter AS mmc
+	INNER JOIN cygx_morning_meeting_reviews AS mm
+	WHERE
+	mm.id = mmc.meeting_id
+	AND mm.status = 1
+	AND mmc.industry_id = ? ) AS t `
+	err = o.Raw(sql, industrialManagementId, industrialManagementId).QueryRow(&count)
+	return
+}
+
+type TimeLineReportItem struct {
+	Id              int    `description:"文章或晨报点评id"`
+	Title           string `description:"标题"`
+	PublishTime     string `description:"发布时间"`
+	Content         string `description:"内容"`
+	VideoUrl        string `description:"视频链接"`
+	IsHaveVideo     bool   `description:"是否包含视频"`
+	ImgUrlPc        string `description:"pc图片"`
+	SubCategoryName string `description:"二级分类"`
+}
+
+//获取产业报告+晨会点评列表
+func GetTimeLineReportIndustrialList(industrialManagementId, startSize, pageSize int) (items []*TimeLineReportItem, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	* 
+FROM
+	(
+		SELECT
+		a.article_id AS id,
+		a.title,
+		a.publish_date AS publish_time,
+		a.video_url,
+		a.sub_category_name,
+		'' AS content 
+	FROM
+		cygx_article AS a
+		INNER JOIN cygx_industrial_article_group_management AS man_g ON man_g.article_id = a.article_id 
+	WHERE
+		a.publish_status = 1 
+		AND a.is_class = 1 
+		AND man_g.industrial_management_id = ? GROUP BY id UNION ALL
+	SELECT
+		mmc.id,
+		'' AS title,
+		mm.meeting_time AS publish_time,
+		'' AS video_url,
+		'时间线' AS sub_category_name,
+		mmc.content 
+	FROM
+		cygx_morning_meeting_review_chapter AS mmc
+		INNER JOIN cygx_morning_meeting_reviews AS mm 
+	WHERE
+		mm.id = mmc.meeting_id 
+		AND mm.STATUS = 1 
+		AND mmc.industry_id = ? 
+	) AS t 
+`
+	sql += ` ORDER BY 
+	t.publish_time DESC LIMIT ?,? `
+	_, err = o.Raw(sql, industrialManagementId, industrialManagementId, startSize, pageSize).QueryRows(&items)
+	return
+}

+ 14 - 0
models/send_company_user.go

@@ -273,6 +273,20 @@ func GetWxUserOpLogSuspend(createTime string) (items []*WxUserOpLogDeleteResp, e
 	return
 }
 
+//获取指定时间内被移动的客户
+func GetCompanyOperationRecord(createTime string) (items []*WxUserOpLogDeleteResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				* 
+			FROM
+				company_operation_record AS p 
+			WHERE
+				 operation IN ('move_seller')
+				 AND p.create_time > '` + createTime + `'  GROUP BY company_id  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
 //获取指定时间内试用转冻结,冻结转流失的客户
 func GetCompanyFreezeAndLoss(createTime string) (items []*WxUserOpLogResp, err error) {
 	o := orm.NewOrm()

+ 7 - 0
models/tactics.go

@@ -132,3 +132,10 @@ func GetReportTacticsList(condition string, pars []interface{}, userId, startSiz
 	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
 	return
 }
+
+type TimeLineReportListResp struct {
+	Paging           *paging.PagingItem
+	MatchTypeName    string `description:"匹配类型"`
+	CategoryImgUrlPc string `description:"图片"`
+	List             []*TimeLineReportItem
+}

+ 11 - 0
services/send_company_user.go

@@ -146,6 +146,17 @@ func DotongbuShangHai(cont context.Context) (err error) {
 		}
 	}
 
+	//获取指定时间内被移动的客户
+	listOperationRecord, err := models.GetCompanyOperationRecord(updateTime)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return err
+	}
+	if len(listOperationRecord) > 0 {
+		for _, v := range listOperationRecord {
+			companyIds += strconv.Itoa(v.CompanyId) + ","
+		}
+	}
+
 	condition = ` AND p.is_suspend = 0  AND p.modify_time > ` + "'" + updateTime + "'"
 	companyIds = strings.TrimRight(companyIds, ",")
 

+ 57 - 0
services/wechat_send_msg.go

@@ -3,11 +3,13 @@ package services
 import (
 	"bytes"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"hongze/hongze_cygx/models"
 	"hongze/hongze_cygx/utils"
 	"io/ioutil"
 	"net/http"
+	"strings"
 	"time"
 )
 
@@ -225,3 +227,58 @@ type SendTemplateResponse struct {
 	Errmsg  string `json:"errmsg"`
 	MsgID   int    `json:"msgid"`
 }
+
+type SendWxTemplate struct {
+	WxAppId        string   `description:"公众号appId"`
+	First          string   `description:"模板消息first字段"`
+	Keyword1       string   `description:"模板消息keyword1字段"`
+	Keyword2       string   `description:"模板消息keyword2字段"`
+	Keyword3       string   `description:"模板消息keyword3字段"`
+	Keyword4       string   `description:"模板消息keyword4字段"`
+	Remark         string   `description:"模板消息remark字段"`
+	TemplateId     string   `description:"模板id"`
+	RedirectUrl    string   `description:"跳转地址"`
+	RedirectTarget int      `description:"小程序跳转目标:1:弘则研报小程序,2:随手办公小程序"`
+	Resource       string   `description:"资源唯一标识"`
+	SendType       int      `description:"发送的消息类型:1:报告,2:指标更新提醒,3:审批通知,4:销售领取客户通知,5:活动取消通知,6活动更改时间通知,7:关注的作者发布报告通知,8:发送日报(周报、双周报、月报)模板消息,9:活动预约/报名时间通知"`
+	OpenIdArr      []string `description:"消息接收者openid"`
+}
+
+//推送模板消息
+func PublicSendTemplateMsg(sendInfo *SendWxTemplate) (err error) {
+	postData, err := json.Marshal(sendInfo)
+	if err != nil {
+		utils.SendAlarmMsg("SendTemplateMsg json.Marshal Err:"+err.Error(), 1)
+		return err
+	}
+	body := ioutil.NopCloser(strings.NewReader(string(postData)))
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", utils.SendWxTemplateMsgUrl, body)
+	if err != nil {
+		utils.SendAlarmMsg("SendTemplateMsg http.NewRequest Err:"+err.Error(), 1)
+		return err
+	}
+	contentType := "application/json;charset=utf-8"
+	req.Header.Set("Content-Type", contentType)
+	req.Header.Set("Authorization", utils.SendTemplateMsgAuthorization)
+	resp, err := client.Do(req)
+	if err != nil {
+		fmt.Println("http client.Do Err:" + err.Error())
+		return err
+	}
+	defer resp.Body.Close()
+	b, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return err
+	}
+	result := new(models.BaseResponse)
+	err = json.Unmarshal(b, &result)
+	if err != nil {
+		return err
+	}
+	if result.Ret != 200 {
+		err = errors.New(string(b))
+		return err
+	}
+	return
+}

+ 52 - 27
services/wx_template_msg.go

@@ -61,43 +61,68 @@ func SendWxMsgWithAsk(name, askTime, askMsg, title string, openIdList []*models.
 		}
 		fmt.Println("line 21", err, msg)
 	}()
-	utils.FileLog.Info("%s", "services SendMsg")
-	//accessToken, err := models.GetWxAccessToken()
-	accessToken, err := models.GetWxAccessTokenByXzs()
-	if err != nil {
-		msg = "GetWxAccessToken Err:" + err.Error()
-		return
-	}
-	if accessToken == "" {
-		msg = "accessToken is empty"
-		return
-	}
+	//utils.FileLog.Info("%s", "services SendMsg")
+	////accessToken, err := models.GetWxAccessToken()
+	//accessToken, err := models.GetWxAccessTokenByXzs()
+	//if err != nil {
+	//	msg = "GetWxAccessToken Err:" + err.Error()
+	//	return
+	//}
+	//if accessToken == "" {
+	//	msg = "accessToken is empty"
+	//	return
+	//}
 	var first string
 	var keyword1 string
+	var keyword2 string
 	var keyword3 string
 	var keyword4 string
 	var remark string
 	first = "研选报告有新的提问,请及时处理"
 	keyword1 = name
 	keyword3 = askTime
+	keyword2 = ""
 	keyword4 = askMsg
 	remark = title
-	sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
-	//templateId := utils.WxMsgTemplateIdAskMsg
-	templateId := utils.WxMsgTemplateIdAskMsgXzs
-	sendMap := make(map[string]interface{})
-	sendData := make(map[string]interface{})
-	sendMap["template_id"] = templateId
-	sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "pagepath": "pageMy/reportDetail/reportDetail?id=" + strconv.Itoa(articleId)}
-	//sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "path": "article/detail?ArticleId=1000001"}
-	sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
-	sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
-	sendData["keyword2"] = map[string]interface{}{"value": "", "color": "#173177"}
-	sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
-	sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
-	sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
-	sendMap["data"] = sendData
-	WxSendTemplateMsg(sendUrl, sendMap, openIdList, strconv.Itoa(articleId), utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD)
+	//sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
+	////templateId := utils.WxMsgTemplateIdAskMsg
+	//templateId := utils.WxMsgTemplateIdAskMsgXzs
+	//sendMap := make(map[string]interface{})
+	//sendData := make(map[string]interface{})
+	//sendMap["template_id"] = templateId
+	//sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "pagepath": "pageMy/reportDetail/reportDetail?id=" + strconv.Itoa(articleId)}
+	////sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId, "path": "article/detail?ArticleId=1000001"}
+	//sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
+	//sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
+	//sendData["keyword2"] = map[string]interface{}{"value": "", "color": "#173177"}
+	//sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
+	//sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
+	//sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
+	//sendMap["data"] = sendData
+	//WxSendTemplateMsg(sendUrl, sendMap, openIdList, strconv.Itoa(articleId), utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD)
+
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	redirectUrl := utils.WX_MSG_PATH_ARTICLE_DETAIL + strconv.Itoa(articleId)
+	sendInfo := new(SendWxTemplate)
+	sendInfo.First = first
+	sendInfo.Keyword1 = keyword1
+	sendInfo.Keyword2 = keyword2
+	sendInfo.Keyword3 = keyword3
+	sendInfo.Keyword4 = keyword4
+	sendInfo.Remark = remark
+	sendInfo.TemplateId = utils.WxMsgTemplateIdAskMsgXzs
+	sendInfo.RedirectUrl = redirectUrl
+	sendInfo.RedirectTarget = 3
+	sendInfo.Resource = strconv.Itoa(articleId)
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	err = PublicSendTemplateMsg(sendInfo)
+	if err != nil {
+		return
+	}
 	return
 }
 

+ 7 - 1
utils/config.go

@@ -82,6 +82,11 @@ var (
 	ShangHaiCrmApiLink        string //上海CRM用户同步api调用地址
 )
 
+//模板消息推送
+var (
+	SendWxTemplateMsgUrl string
+)
+
 func init() {
 	tmpRunMode, err := web.AppConfig.String("run_mode")
 	if err != nil {
@@ -170,7 +175,7 @@ func init() {
 		ArticleTaskClassMobile = "15557270714,18767183922,15216736473,15000123056,18701809782,17706316791,18652179672"
 
 		ShangHaiCrmApiLink = "https://crm.hzinsights.com/"
-
+		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
 	} else {
 		WxAppId = "wxcc32b61f96720d2f"
 		WxAppSecret = "06894933fafb24dafead7eaae09c08e0"
@@ -204,6 +209,7 @@ func init() {
 		ArticleTaskClassMobile = "15557270714,18767183922,17706316791"
 
 		ShangHaiCrmApiLink = "http://106.15.192.100:8100/"
+		SendWxTemplateMsgUrl = "http://127.0.0.1:8086/v1/wechat/send_template_msg"
 	}
 
 	//查研观向小助手

+ 10 - 0
utils/constants.go

@@ -133,3 +133,13 @@ const (
 	COMPANY_PRODUCT_RAI_ID    = 2
 	COMPANY_PRODUCT_RAI_NAME  = "权益"
 )
+
+//微信模板消息推送公共接口的秘钥
+const (
+	SendTemplateMsgAuthorization = "dc855fce962a639faa779cbdd4cd332f"
+)
+
+//模板消息地址路由
+const (
+	WX_MSG_PATH_ARTICLE_DETAIL = "pageMy/reportDetail/reportDetail?id="
+)