Răsfoiți Sursa

Merge branch 'master' of http://8.136.199.33:3000/hongze/hz_crm_api into crm/crm_16.8

zhangchuanxing 2 săptămâni în urmă
părinte
comite
1ab0c50dbf
49 a modificat fișierele cu 2720 adăugiri și 262 ștergeri
  1. 24 16
      controllers/company.go
  2. 11 2
      controllers/company_apply.go
  3. 42 32
      controllers/company_apply_v2.go
  4. 3 0
      controllers/company_permission.go
  5. 1 0
      controllers/cygx/activity.go
  6. 25 0
      controllers/cygx/activity_meet.go
  7. 13 0
      controllers/cygx/report_article.go
  8. 28 3
      controllers/cygx/summary_manage.go
  9. 24 7
      controllers/cygx/user.go
  10. 364 0
      controllers/cygx/user_rai_label.go
  11. 44 0
      controllers/roadshow/calendar.go
  12. 19 0
      controllers/roadshow/calendar_meeting_user.go
  13. 416 0
      controllers/roadshow/calendar_researcher_question.go
  14. 32 1
      controllers/roadshow/company.go
  15. 257 2
      controllers/roadshow/report.go
  16. 1 1
      controllers/seal/seal_approval.go
  17. 7 6
      go.mod
  18. 13 0
      go.sum
  19. 5 1
      models/company/company.go
  20. 9 0
      models/company/company_approval.go
  21. 9 0
      models/cygx/activity.go
  22. 8 0
      models/cygx/activity_signup_detail.go
  23. 11 0
      models/cygx/activity_special.go
  24. 1 2
      models/cygx/activity_video.go
  25. 8 0
      models/cygx/activity_voice.go
  26. 43 1
      models/cygx/askserie_video_history_record.go
  27. 50 49
      models/cygx/cygx_user.go
  28. 34 0
      models/cygx/industrial_article_group_management.go
  29. 32 0
      models/cygx/report_history_record.go
  30. 282 0
      models/cygx/wx_user_rai_label.go
  31. 3 0
      models/db.go
  32. 15 4
      models/roadshow/calendar.go
  33. 206 0
      models/roadshow/calendar_researcher_question.go
  34. 1 0
      models/roadshow/company.go
  35. 25 1
      models/roadshow/report_record.go
  36. 9 1
      models/roadshow/rs_calendar_meeting_user.go
  37. 20 20
      models/seal/seal.go
  38. 81 0
      routers/commentsRouter.go
  39. 1 0
      routers/router.go
  40. 4 4
      services/cygx/acitvity.go
  41. 21 1
      services/cygx/activity_meet.go
  42. 234 0
      services/cygx/activity_poster.go
  43. 12 75
      services/cygx/activity_special.go
  44. 110 2
      services/cygx/resource_data.go
  45. 92 0
      services/cygx/user_rai_label.go
  46. 1 1
      services/elastic/es_comprehensive.go
  47. 58 0
      services/roadshow/report.go
  48. 2 30
      services/seal/seal.go
  49. 9 0
      utils/constants.go

+ 24 - 16
controllers/company.go

@@ -2723,22 +2723,6 @@ func (this *CompanyController) Add() {
 
 	//移除空格
 	req.CreditCode = utils.TrimStr(req.CreditCode)
-
-	var startDateTime, endDateTime time.Time
-	if req.Status == utils.COMPANY_STATUS_TRY_OUT {
-		startDateTime = time.Now()
-		endDateTime = time.Now().AddDate(0, 2, 0)
-	} else if req.Status == utils.COMPANY_STATUS_FOREVER {
-		startDateTime = time.Now()
-		endDateTime = time.Now().AddDate(100, 0, 0)
-	} else {
-		br.Msg = "无效的客户状态,请重新选择"
-		return
-	}
-	var startDate, endDate string
-	startDate = startDateTime.Format(utils.FormatDate)
-	endDate = endDateTime.Format(utils.FormatDate)
-
 	if req.CompanyType == "" {
 		br.Msg = "请选择客户类型"
 		return
@@ -2756,6 +2740,24 @@ func (this *CompanyController) Add() {
 		return
 	}
 
+	var startDateTime, endDateTime time.Time
+	if req.Status == utils.COMPANY_STATUS_TRY_OUT {
+		startDateTime = time.Now()
+		endDateTime = time.Now().AddDate(0, 2, 0)
+		if productId == utils.COMPANY_PRODUCT_RAI_ID {
+			endDateTime = time.Now().AddDate(0, 1, 0) // 权益客户试用期改为1个月
+		}
+	} else if req.Status == utils.COMPANY_STATUS_FOREVER {
+		startDateTime = time.Now()
+		endDateTime = time.Now().AddDate(100, 0, 0)
+	} else {
+		br.Msg = "无效的客户状态,请重新选择"
+		return
+	}
+	var startDate, endDate string
+	startDate = startDateTime.Format(utils.FormatDate)
+	endDate = endDateTime.Format(utils.FormatDate)
+
 	if req.IndustryId <= 0 {
 		br.Msg = "请选择行业"
 		return
@@ -2906,6 +2908,9 @@ func (this *CompanyController) Add() {
 	if req.Status == utils.COMPANY_STATUS_TRY_OUT {
 		item.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
 		item.CompanyType = 2
+		if productId == utils.COMPANY_PRODUCT_RAI_ID {
+			item.EndDate = time.Now().AddDate(0, 1, 0).Format(utils.FormatDate) // 权益客户试用期改为1个月
+		}
 	}
 
 	item.FirstStartDate = item.StartDate
@@ -5072,6 +5077,9 @@ func (this *CompanyController) Receive() {
 		if req.Status == utils.COMPANY_STATUS_TRY_OUT {
 			startDateTime = time.Now()
 			endDateTime = time.Now().AddDate(0, 2, 0)
+			if productId == utils.COMPANY_PRODUCT_RAI_ID {
+				endDateTime = time.Now().AddDate(0, 1, 0) // 权益客户试用期改为1个月。 需求池 1035
+			}
 		} else if req.Status == utils.COMPANY_STATUS_FOREVER {
 			startDateTime = time.Now()
 			endDateTime = time.Now().AddDate(100, 0, 0)

+ 11 - 2
controllers/company_apply.go

@@ -1406,7 +1406,11 @@ func (this *CompanyApplyController) ApplyThawOld() {
 					delayItem.CompanyApplyId = companyApprovalId
 					delayItem.ChartPermissionId = permissionId
 					delayItem.StartDate = time.Now().Format(utils.FormatDate)
-					delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+					if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+						delayItem.EndDate = time.Now().AddDate(0, 1, 0).Format(utils.FormatDate)
+					} else {
+						delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+					}
 					delayItem.CreateTime = time.Now()
 					delayItem.ModifyTime = time.Now()
 					err = company.AddCompanyDelayPermission(delayItem)
@@ -1599,7 +1603,12 @@ func (this *CompanyApplyController) ApplyDelayOld() {
 							delayItem.CompanyApplyId = companyApprovalId
 							delayItem.ChartPermissionId = permissionId
 							delayItem.StartDate = time.Now().Format(utils.FormatDate)
-							delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+							if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+								delayItem.EndDate = time.Now().AddDate(0, 1, 0).Format(utils.FormatDate)
+							} else {
+								delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+							}
+
 							delayItem.CreateTime = time.Now()
 							delayItem.ModifyTime = time.Now()
 							err = company.AddCompanyDelayPermission(delayItem)

+ 42 - 32
controllers/company_apply_v2.go

@@ -716,36 +716,37 @@ func (this *CompanyApplyController) ApplyTurnPositive() {
 			br.ErrMsg = "生成合同编码失败,Err:" + err.Error()
 			return
 		}
-		//如果是权益的合同,合同编号另 取
-
-		//if productId == 2 {
-		//	sealCount, err := seal.GetCountByDateAndCompanyId(req.StartDate, req.EndDate, req.CompanyId)
-		//	if err != nil {
-		//		br.Msg = "生成合同编码失败"
-		//		br.ErrMsg = "获取用印合同数量信息失败,Err:" + err.Error()
-		//		return
-		//	}
-		//	crmConfig, err := company.GetConfigDetailByCode("rai_seal_check") //权益非标合同是否校验用印提交
-		//	if err != nil {
-		//		br.Msg = "获取配置失败"
-		//		br.ErrMsg = "获取配置失败,Err:" + err.Error()
-		//		return
-		//	}
-		//
-		//	if sealCount == 0 && crmConfig.ConfigValue == "1" {
-		//		br.Msg = "此合同暂未申请用印,请核对合同期限是否有误"
-		//		return
-		//	}
-		//	if sealCount > 0 {
-		//		sealInfo, err := seal.GetSealInfoByDateAndCompanyId(req.StartDate, req.EndDate, req.CompanyId)
-		//		if err != nil {
-		//			br.Msg = "生成合同编码失败"
-		//			br.ErrMsg = "获取用印合同信息失败,Err:" + err.Error()
-		//			return
-		//		}
-		//		contractCode = sealInfo.Code
-		//	}
-		//}
+
+		//如果是权益的合同,合同编号另取
+
+		if productId == 2 {
+			sealCount, err := seal.GetCountByDateAndCompanyId(req.StartDate, req.EndDate, req.CompanyId)
+			if err != nil {
+				br.Msg = "生成合同编码失败"
+				br.ErrMsg = "获取用印合同数量信息失败,Err:" + err.Error()
+				return
+			}
+			crmConfig, err := company.GetConfigDetailByCode("rai_seal_check") //权益非标合同是否校验用印提交
+			if err != nil {
+				br.Msg = "获取配置失败"
+				br.ErrMsg = "获取配置失败,Err:" + err.Error()
+				return
+			}
+
+			if sealCount == 0 && crmConfig.ConfigValue == "1" {
+				br.Msg = "此合同暂未申请用印,请核对合同期限是否有误"
+				return
+			}
+			if sealCount > 0 {
+				sealInfo, err := seal.GetSealInfoByDateAndCompanyId(req.StartDate, req.EndDate, req.CompanyId)
+				if err != nil {
+					br.Msg = "生成合同编码失败"
+					br.ErrMsg = "获取用印合同信息失败,Err:" + err.Error()
+					return
+				}
+				contractCode = sealInfo.Code
+			}
+		}
 
 		var sealId int
 
@@ -1768,7 +1769,11 @@ func (this *CompanyApplyController) ApplyThaw() {
 					delayItem.CompanyApplyId = companyApprovalId
 					delayItem.ChartPermissionId = permissionId
 					delayItem.StartDate = time.Now().Format(utils.FormatDate)
-					delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+					if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+						delayItem.EndDate = time.Now().AddDate(0, 1, 0).Format(utils.FormatDate)
+					} else {
+						delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+					}
 					delayItem.CreateTime = time.Now()
 					delayItem.ModifyTime = time.Now()
 					err = company.AddCompanyDelayPermission(delayItem)
@@ -2271,7 +2276,12 @@ func (this *CompanyApplyController) ApplyReceive() {
 					delayItem.CompanyApplyId = companyApprovalId
 					delayItem.ChartPermissionId = permissionId
 					delayItem.StartDate = time.Now().Format(utils.FormatDate)
-					delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+					if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+						delayItem.EndDate = time.Now().AddDate(0, 1, 0).Format(utils.FormatDate)
+					} else {
+						delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+					}
+
 					delayItem.CreateTime = time.Now()
 					delayItem.ModifyTime = time.Now()
 					err = company.AddCompanyDelayPermission(delayItem)

+ 3 - 0
controllers/company_permission.go

@@ -932,6 +932,9 @@ func (this *CompanyPermissionController) PermissionAddTryOut() {
 	companyReportPermissionList := make([]*company.CompanyReportPermission, 0) //添加的品种
 	startDateTime := time.Now()
 	endDateTime := startDateTime.AddDate(0, 2, 0)
+	if product == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+		endDateTime = startDateTime.AddDate(0, 1, 0)
+	}
 	for _, v := range permissionArr {
 		permissionId, _ := strconv.Atoi(v)
 		count, err := company.GetCompanyPermissionCheck(req.CompanyId, permissionId)

+ 1 - 0
controllers/cygx/activity.go

@@ -851,6 +851,7 @@ func (this *ActivityCoAntroller) PreserveAndPublish() {
 				//}()
 			}
 			go cygxService.MakeActivitySigninImg(v)
+			go cygxService.MakeActivityDetailImg2(v)
 		}
 	} else {
 		if req.DoType == 1 {

+ 25 - 0
controllers/cygx/activity_meet.go

@@ -340,6 +340,30 @@ func (this *ActivityMeetCoAntroller) MeetingDo() {
 			utils.Rc.Delete(redisKey)
 		}()
 	}
+
+	var conditionOld string //点了到会,又点了取消的人,对应的活动标签给取消掉
+	conditionOld += ` AND s.is_meeting = 1  AND  s.activity_id = ` + strconv.Itoa(activityId)
+	listOld, err := cygx.GetOfflineMeetingList(conditionOld)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	var deleteUserids []int
+	sliceNew := strings.Split(meetingUids, ",")
+	mapNewUserIds := make(map[string]bool)
+	for _, v := range sliceNew {
+		mapNewUserIds[v] = true
+	}
+
+	for _, v := range listOld {
+		if !mapNewUserIds[strconv.Itoa(v.UserId)] {
+			deleteUserids = append(deleteUserids, v.UserId)
+		}
+	} //点了到会,又点了取消的人,对应的活动标签给取消掉 end
+
+	//return
 	//加入缓存机制,避免创建同一个名称的指标 end
 	activityInfo, errInfo := cygx.GetAddActivityInfoById(activityId)
 	if activityInfo == nil {
@@ -445,6 +469,7 @@ func (this *ActivityMeetCoAntroller) MeetingDo() {
 	go cygxService.AddctivitySignupDetailList(itemDs, activityId)                        // 处理个人以及机构到会数量
 	go cygxService.ActivityUserLabelLogAdd(activityId, userIdArr)                        // 处理用户标签
 	go cygxService.YanXuanActivityPointsBillSubmitMeeting(activityId, AdminUser.AdminId) // 处理用户到会研选扣点
+	go cygxService.DeleteActivityWxUserRaiLabel(deleteUserids, activityId)               // 点了到会,又点了取消的人,对应的活动标签给取消掉
 	//添加操作日志记录
 	br.Ret = 200
 	br.Success = true

+ 13 - 0
controllers/cygx/report_article.go

@@ -493,6 +493,17 @@ func (this *IndustrialSubjectController) ReportArticleClassification() {
 		return
 	}
 
+	detailIndustryNameList, err := cygx.GetIndustrialManagemenDetailByAaticleID(reportInfo.ArticleId)
+	if err != nil {
+		br.Msg = "分类失败"
+		br.ErrMsg = "获取报告原有分类失败,Err:" + err.Error()
+		return
+	}
+	var industryId []string
+	for _, v := range detailIndustryNameList {
+		industryId = append(industryId, strconv.Itoa(v.IndustrialManagementId))
+	}
+
 	industrialStrList := strings.Split(industrialManagementIdStr, ",")
 	for _, v := range industrialStrList {
 		condition = `AND industrial_management_id = ` + v
@@ -502,6 +513,7 @@ func (this *IndustrialSubjectController) ReportArticleClassification() {
 			br.ErrMsg = "操作失败,产业不存在IndustrialManagementId:" + v
 			return
 		}
+		industryId = append(industryId, v)
 	}
 	if req.IndustrialSubjectIdStr != "0" && req.IndustrialSubjectIdStr != "" {
 		strList := strings.Split(req.IndustrialSubjectIdStr, ",")
@@ -524,6 +536,7 @@ func (this *IndustrialSubjectController) ReportArticleClassification() {
 	}
 
 	go cygxService.DoArticleOnenIdWxTemplateMsg(reportInfo.ArticleId, 2)
+	go cygxService.UpdateIndustrialsourceHzResourceDataById(industryId, "Hz") //修改相关产业关联的报告信息
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "分类成功"

+ 28 - 3
controllers/cygx/summary_manage.go

@@ -80,6 +80,17 @@ func (this *SummaryManage) PreserveAndPublish() {
 	articleId := req.ArticleId
 	articleTypeId := req.ArticleTypeId
 
+	detailIndustryNameList, err := cygx.GetIndustrialManagemenDetailByAaticleID(articleId)
+	if err != nil {
+		br.Msg = "分类失败"
+		br.ErrMsg = "获取报告原有分类失败,Err:" + err.Error()
+		return
+	}
+	var industryId []string
+	for _, v := range detailIndustryNameList {
+		industryId = append(industryId, strconv.Itoa(v.IndustrialManagementId))
+	}
+
 	// 产业ID校验
 	industryIds := make([]int, 0)
 	industrialManagementIdList := strings.Split(industrialManagementIds, ",")
@@ -91,6 +102,7 @@ func (this *SummaryManage) PreserveAndPublish() {
 			return
 		}
 		industryIds = append(industryIds, i)
+		industryId = append(industryId, v)
 	}
 	if industrialSubjectIds != "" {
 		industrialSubjectIdList := strings.Split(industrialSubjectIds, ",")
@@ -319,9 +331,10 @@ func (this *SummaryManage) PreserveAndPublish() {
 		go cygxService.UpdateIndustryLayoutTime(industryIds, false)       // 查研观向7.4-更新产业布局时间
 		go elastic.AddComprehensiveIndustrialSource("Yx", item.ArticleId) // 查研观向10.6 更新搜索引擎的产业资源包
 	}
-	go elastic.AddComprehensiveArticle(item.ArticleId)       // ES添加文章:报告、纪要
-	go cygxService.UpdateArticleResourceData(item.ArticleId) //写入首页最新  cygx_resource_data 表
-	go cygxService.MakeArticleMomentsImg(item.ArticleId)     //生成文章分享到朋友圈的图片
+	go elastic.AddComprehensiveArticle(item.ArticleId)                        // ES添加文章:报告、纪要
+	go cygxService.UpdateArticleResourceData(item.ArticleId)                  //写入首页最新  cygx_resource_data 表
+	go cygxService.MakeArticleMomentsImg(item.ArticleId)                      //生成文章分享到朋友圈的图片
+	go cygxService.UpdateIndustrialsourceHzResourceDataById(industryId, "Yx") //修改相关产业关联的报告信息
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "操作成功"
@@ -411,6 +424,18 @@ func (this *SummaryManage) PublishAndCancel() {
 	}
 	go elastic.AddComprehensiveArticle(articleId)            // ES添加文章:报告、纪要
 	go cygxService.UpdateArticleResourceData(item.ArticleId) //写入首页最新  cygx_resource_data 表
+
+	detailIndustryNameList, err := cygx.GetIndustrialManagemenDetailByAaticleID(articleId)
+	if err != nil {
+		br.Msg = "分类失败"
+		br.ErrMsg = "获取报告原有分类失败,Err:" + err.Error()
+		return
+	}
+	var industryId []string
+	for _, v := range detailIndustryNameList {
+		industryId = append(industryId, strconv.Itoa(v.IndustrialManagementId))
+	}
+	go cygxService.UpdateIndustrialsourceHzResourceDataById(industryId, "Yx") //修改相关产业关联的报告信息
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "操作成功"

+ 24 - 7
controllers/cygx/user.go

@@ -20,6 +20,7 @@ import (
 	"strconv"
 	"strings"
 	"time"
+	"unicode/utf8"
 )
 
 // 权益用户管理
@@ -204,9 +205,19 @@ func (this *UserController) List() {
 			condition += ` AND (a.company_name LIKE '%` + keyWord + `%' OR a.credit_code LIKE '%` + keyWord + `%' ) `
 		}
 	}
-	if label != "" {
-		usercondition += ` AND u.user_label LIKE '%` + label + `%'`
+
+	var joinTable string
+	var tableField string
+	var labelSort string
+	if label != "" && utf8.RuneCountInString(label) > 1 {
+		//usercondition += ` AND u.user_label LIKE '%` + label + `%'`
+		//usercondition += ` AND u.user_id IN ( SELECT user_id  FROM ` + utils.GetCygxDatabase() + `.wx_user_rai_label WHERE label LIKE '%` + label + `%'  AND create_time >= '` + time.Now().AddDate(0, -4, 0).Format(utils.FormatDate) + `' ) `
+		usercondition += ` AND l.label LIKE '%` + label + `%'  AND l.create_time >= '` + time.Now().AddDate(0, -4, 0).Format(utils.FormatDate) + `' `
+		joinTable = ` 	INNER JOIN ` + utils.GetCygxDatabase() + `.wx_user_rai_label as l ON  l.user_id = u.user_id   `
+		tableField = ` MAX(l.create_time) as max_create_time,   `
+		labelSort = `  max_create_time DESC ,   `
 	}
+
 	//
 	usercondition += ` AND cp.product_id = 2  	AND sr.product_id = 2  `
 
@@ -218,23 +229,23 @@ func (this *UserController) List() {
 		usercondition += ` AND u.cygx_subscribe = 1 `
 	}
 	condition += ` AND cp.product_id = 2  `
-	total, err := cygx.GetCompanyListCount(usercondition, keyWord, kwywordcondition, condition, roleTypeCode, pars)
+	total, err := cygx.GetCompanyListCount(joinTable, usercondition, keyWord, kwywordcondition, condition, roleTypeCode, pars)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据总数失败,Err:" + err.Error()
 		return
 	}
 	if sortType == "" {
-		sqlOrder = ` GROUP by u.user_id  ORDER BY c.created_time  DESC, u.register_time  DESC `
+		sqlOrder = ` GROUP by u.user_id  ORDER BY ` + labelSort + ` c.created_time  DESC, u.register_time  DESC `
 	} else {
 		if sortType == "asc" {
-			sqlOrder = ` GROUP by u.user_id  ORDER BY u.interaction_num  ASC , u.register_time  DESC `
+			sqlOrder = ` GROUP by u.user_id  ORDER BY  u.interaction_num  ASC ,` + labelSort + ` u.register_time  DESC `
 		} else {
-			sqlOrder = ` GROUP by u.user_id  ORDER BY u.interaction_num  DESC , u.register_time  DESC  `
+			sqlOrder = ` GROUP by u.user_id  ORDER BY u.interaction_num  DESC , ` + labelSort + `  u.register_time  DESC  `
 		}
 	}
 
-	list, err := cygx.GetCygxCompanyUserList(usercondition, keyWord, kwywordcondition, condition, roleTypeCode, sqlOrder, parsUser, startSize, pageSize)
+	list, err := cygx.GetCygxCompanyUserList(joinTable, tableField, usercondition, keyWord, kwywordcondition, condition, roleTypeCode, sqlOrder, parsUser, startSize, pageSize)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -316,6 +327,7 @@ func (this *UserController) List() {
 		UserRemindListMap := cygxService.GetCygxUserRemindListMap(userIdArr)
 		mapIsUserMaker := cygxService.GetCompanyProductIsUserMakerByCompanyIds(companyIds) //根据公司ID获取近四周之内有决策人互动的客户
 		userHaveMoveMap := services.GetWxUserHaveMoveMap(mobilesSlice)                     // 处理用户是否移动过按钮回显
+		userLabelMap := cygxService.GetUserLabelByUserIdArr(userIdArr)                     // 根据多个userId 获取每个UserId最新的十条数据
 
 		for k, v := range list {
 			for _, vsplit := range splitList {
@@ -343,6 +355,11 @@ func (this *UserController) List() {
 			if v.Mobile != "" {
 				v.HaveMoveButton = userHaveMoveMap[v.Mobile]
 			}
+			if len(userLabelMap[int(v.UserId)]) == 0 {
+				list[k].RaiLabelList = make([]*cygx.WxUserRaiLabelListResp, 0)
+			} else {
+				list[k].RaiLabelList = userLabelMap[int(v.UserId)]
+			}
 		}
 		for k := range list {
 			list[k].InteractionNum = list[k].HistoryNum + list[k].CountNum + list[k].IndustryFllowNum + list[k].DepartmentFollowNum + list[k].KeyWordNum + list[k].OnLineNum + list[k].OfficeNum + list[k].ChartNum + list[k].TripNum + list[k].RoadshowVideoNum + list[k].ActivityVideoNum + list[k].ActivityVoiceNum + list[k].YanxuanspecialNum

+ 364 - 0
controllers/cygx/user_rai_label.go

@@ -0,0 +1,364 @@
+package cygx
+
+import (
+	"encoding/json"
+	"hongze/hz_crm_api/controllers"
+	"hongze/hz_crm_api/models"
+	"hongze/hz_crm_api/models/cygx"
+	"hongze/hz_crm_api/models/roadshow"
+	cygxService "hongze/hz_crm_api/services/cygx"
+	"hongze/hz_crm_api/utils"
+	"strconv"
+	"time"
+)
+
+// 权益用户标签
+type UserRaiLabelController struct {
+	controllers.BaseAuthController
+}
+
+// @Title 销售输入标签
+// @Description 销售输入标签接口
+// @Param	request	body cygx.WxUserRaiLabelAddReq true "type json string"
+// @Success 200 {object} "保存成功"
+// @router /use_rai_label/add [post]
+func (this *UserRaiLabelController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	AdminUser := this.SysUser
+	if AdminUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req cygx.WxUserRaiLabelAddReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	userId := req.UserId
+	label := req.Label
+	wxUser, err := models.GetWxUserItemByUserId(userId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, GetWxUserItemByUserId  Err:" + err.Error()
+		return
+	}
+	item := new(cygx.WxUserRaiLabel)
+	item.UserId = wxUser.UserId
+	item.RealName = wxUser.RealName
+	item.Mobile = wxUser.Mobile
+	item.Email = wxUser.Email
+	item.CompanyId = wxUser.CompanyId
+	item.CompanyName = wxUser.CompanyName
+	item.Label = label
+	item.SysUserId = AdminUser.AdminId
+	item.SysUserRealName = AdminUser.RealName
+	item.SourceType = 6
+	item.CreateTime = time.Now()
+	item.ModifyTime = time.Now()
+	err = cygx.AddWxUserRaiLabel(item)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "操作成功"
+}
+
+// @Title 删除销售输入标签
+// @Description 删除销售输入标签接口
+// @Param	request	body cygx.WxUserRaiLabelAddReq true "type json string"
+// @Success 200 {object} "保存成功"
+// @router /use_rai_label/delte [post]
+func (this *UserRaiLabelController) Delte() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	AdminUser := this.SysUser
+	if AdminUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req cygx.WxUserRaiLabelIdReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	raiLabelId := req.RaiLabelId
+	err = cygx.DeleteWxUserRaiLabel(raiLabelId)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "操作成功"
+}
+
+// @Title  标签详情
+// @Description 获取标签详情接口
+// @Param   RaiLabelId   query   int  true       "标签ID"
+// @Success Ret=200 {object} cygx.ActivityDetail
+// @router /use_rai_label/detail [get]
+func (this *UserRaiLabelController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	AdminUser := this.SysUser
+	if AdminUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	raiLabelId, _ := this.GetInt("RaiLabelId")
+	detail, err := cygx.GetWxUserRaiLabelDetailById(raiLabelId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,标签不存在Err:" + err.Error() + "RaiLabelId:" + strconv.Itoa(raiLabelId)
+		return
+	}
+	resp := new(cygx.WxUserRaiLabelDetailResp)
+	sourceType := detail.SourceType
+	sourceId := detail.SourceId
+	//来源1:搜索关键字标签、2:产业/个股标签(线下活动)、3:产业/个股标签(线下路演)、4:产业/个股标签(线上活动)、5:产业/个股标签(线上路演)、6:销售输入标签、7:产业/个股标签(报告)、8:报告类型标签
+	switch sourceType {
+	case 1:
+		item := new(cygx.WxUserRaiLabelKeyWordResp)
+		item.Label = detail.Label
+		item.CreateTime = detail.CreateTime.Format(utils.FormatDateTime)
+		resp.KeyWord = item
+	case 2, 4:
+		item := new(cygx.WxUserRaiLabelActivityResp)
+		activityInfo, errInfo := cygx.GetAddActivityInfoById(sourceId)
+		if activityInfo == nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(sourceId)
+			return
+		}
+		if errInfo != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+			return
+		}
+		activitySignupDetai, _ := cygx.GetCygxActivitySignupDetailDetailLast(sourceId, detail.Mobile)
+		item.ActivityName = activityInfo.ActivityName
+		item.ActivityTypeName = activityInfo.ActivityTypeName
+		item.ActivityTime = activityInfo.ActivityTime
+		if activitySignupDetai != nil {
+			item.Duration = activitySignupDetai.Duration
+		}
+		item.Label = detail.Label
+		resp.Activity = item
+	case 3, 5:
+		item := new(cygx.WxUserRaiLabelRoadShowResp)
+		rsCalendarMeetingUserItem, err := roadshow.GetRsCalendarMeetingUserFirst(sourceId)
+		if err != nil {
+			br.Msg = "获取数据失败!"
+			br.ErrMsg = "获取数据失败!GetRsCalendarMeetingUserFirst:" + err.Error()
+			return
+		}
+		if rsCalendarMeetingUserItem == nil {
+			br.Msg = "获取数据失败!"
+			br.ErrMsg = "获取数据失败!GetRsCalendarMeetingUserFirst:" + err.Error()
+			return
+		}
+		rsCalendarResearcherList, tmpErr := roadshow.GetRsCalendarResearcherListByRsCalendarId(sourceId)
+		if tmpErr != nil {
+			br.Msg = "获取数据失败!"
+			br.ErrMsg = "获取数据失败!GetRsCalendarResearcherListByRsCalendarId:" + tmpErr.Error()
+			return
+		}
+		for _, v := range rsCalendarResearcherList {
+			item.ResearcherName = v.ResearcherName
+			item.RoadShowTime = v.StartDate + " " + v.StartTime
+		}
+		item.Theme = rsCalendarMeetingUserItem.RoadShowTheme
+		item.Label = detail.Label
+		resp.RoadShow = item
+	case 6:
+		item := new(cygx.WxUserRaiLabelSellerResp)
+		item.Label = detail.Label
+		item.SysUserRealName = detail.SysUserRealName
+		item.CreateTime = detail.CreateTime.Format(utils.FormatDateTime)
+		resp.Seller = item
+	case 7, 8:
+		item := new(cygx.WxUserRaiLabelArticleResp)
+		switch detail.TableName {
+		case "cygx_article":
+			//文章
+			detailArticle, err := cygx.GetArticleIdInfoByArticleId(sourceId)
+			if err != nil {
+				br.Msg = "内容不存在"
+				br.ErrMsg = "操作失败,Err:" + err.Error()
+				return
+			}
+			historyDetail := new(cygx.CygxArticleHistoryRecordAll)
+			if detail.Mobile != "" {
+				historyDetail, err = cygx.GetCygxArticleHistoryRecordAllDetailLastByMobile(sourceId, detail.Mobile)
+			} else {
+				historyDetail, err = cygx.GetCygxArticleHistoryRecordAllDetailLast(sourceId, detail.UserId)
+			}
+
+			item.Title = detailArticle.Title
+			item.PublishDate = detailArticle.PublishDate.Format(utils.FormatDateTime)
+			item.CreateTime = detail.CreateTime.Format(utils.FormatDateTime)
+			item.SourceText = cygxService.GetArticleSourcePlatformText(historyDetail.RegisterPlatform)
+			item.StopTime = strconv.Itoa(historyDetail.StopTime)
+
+		case "cygx_report_selection":
+			//报告精选
+			detailReportSelection, err := cygx.GetCygxReportSelectionInfoById(sourceId)
+			if err != nil {
+				br.Msg = "内容不存在"
+				br.ErrMsg = "操作失败,Err:" + err.Error()
+				return
+			}
+			historyDetail, err := cygx.GetCygxReportHistoryRecordDetailLast(sourceId, detail.Mobile, "bgjx")
+			if err != nil {
+				br.Msg = "内容不存在"
+				br.ErrMsg = "操作失败,Err:" + err.Error()
+				return
+			}
+			item.Title = detailReportSelection.Title
+			item.PublishDate = detailReportSelection.PublishDate
+			item.CreateTime = detail.CreateTime.Format(utils.FormatDateTime)
+			item.SourceText = cygxService.GetArticleSourcePlatformText(historyDetail.RegisterPlatform)
+			item.StopTime = strconv.Itoa(historyDetail.StopTime)
+
+		case "cygx_research_summary":
+			//本周研究汇总
+			detailResearchSummary, err := cygx.GetCygxResearchSummaryInfoById(sourceId)
+			if err != nil {
+				br.Msg = "内容不存在"
+				br.ErrMsg = "操作失败,Err:" + err.Error()
+				return
+			}
+			historyDetail, err := cygx.GetCygxReportHistoryRecordDetailLast(sourceId, detail.Mobile, "bzyjhz")
+			if err != nil {
+				br.Msg = "内容不存在"
+				br.ErrMsg = "操作失败,Err:" + err.Error()
+				return
+			}
+			item.Title = detailResearchSummary.Title
+			item.PublishDate = detailResearchSummary.PublishDate
+			item.CreateTime = detail.CreateTime.Format(utils.FormatDateTime)
+			item.SourceText = cygxService.GetArticleSourcePlatformText(historyDetail.RegisterPlatform)
+			item.StopTime = strconv.Itoa(historyDetail.StopTime)
+		}
+
+		item.Label = detail.Label
+		resp.Article = item
+
+	case 9:
+		item := new(cygx.WxUserRaiLabelActivityVivoResp)
+		activityInfo, err := cygx.GetAddActivityInfoById(sourceId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取信息失败,GetAddActivityInfoById Err:" + err.Error()
+			return
+		}
+		var title string
+		totalVoice, err := cygx.GetCygxActivityVoiceCountByActivityId(sourceId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取信息失败, GetCygxActivityVoiceCountByActivityId :" + err.Error()
+			return
+		}
+		if totalVoice > 0 {
+			voiceDetail, err := cygx.GetCygxActivityVoiceReqDetail(sourceId)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取信息失败, GetCygxActivityVoiceReqDetail :" + err.Error()
+				return
+			}
+			title = voiceDetail.VoiceName
+		} else {
+			totalVideo, err := cygx.GetActivityVideoCountByActivityId(sourceId)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取信息失败, GetActivityVideoCountByActivityId :" + err.Error()
+				return
+			}
+
+			if totalVideo > 0 {
+				videoDetail, err := cygx.GetCygxActivityVideoReqDetail(sourceId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "GetCygxActivityVideoReqDetail,Err:" + err.Error() + "activityId:" + strconv.Itoa(sourceId)
+					return
+				}
+				title = videoDetail.VideoName
+			}
+		}
+
+		item.Title = title
+		item.ActivityTime = activityInfo.ActivityTime
+		item.Label = detail.Label
+		item.CreateTime = detail.CreateTime.Format(utils.FormatDateTime)
+		resp.ActivityVivo = item
+	}
+
+	resp.SourceType = detail.SourceType
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title  标签详情
+// @Description 获取标签详情接口
+// @Param   UserId   query   int  true       "用户ID"
+// @Success Ret=200 {object} cygx.ActivityDetail
+// @router /use_rai_label/list [get]
+func (this *UserRaiLabelController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	AdminUser := this.SysUser
+	if AdminUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	userId, _ := this.GetInt("UserId")
+
+	resp := new(cygx.WxUserRaiLabelList)
+	list, err := cygx.GetWxUserRaiLabelListByUserId(userId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error() + "userId:" + strconv.Itoa(userId)
+		return
+	}
+	if len(list) == 0 {
+		list = make([]*cygx.WxUserRaiLabelListResp, 0)
+	}
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 44 - 0
controllers/roadshow/calendar.go

@@ -72,6 +72,17 @@ func (this *CalendarController) Add() {
 	researcherMap := make(map[int]string)
 	var checkIsAdd []string
 
+	var companyStatus string // 海外客户记录当时客户状态
+	if req.EnglishCompany == 1 {
+		englishCompany, err := models.GetEnglishCompanyById(req.CompanyId)
+		if err != nil {
+			br.Msg = "客户已被删除, 请刷新页面"
+			br.ErrMsg = "获取失败,GetEnglishCompanyById Err: " + err.Error()
+			return
+		}
+		companyStatus = englishCompany.OverseasStatus
+	}
+
 	//获取所有自定义的权益研究员
 	sysUserList, err := cygx.GetAskEmailListResearcher()
 	if err != nil {
@@ -228,6 +239,7 @@ func (this *CalendarController) Add() {
 	rsCalendar.ActivityCategory = req.ActivityCategory
 	rsCalendar.Source = 0
 	rsCalendar.EnglishCompany = req.EnglishCompany
+	rsCalendar.CompanyStatus = companyStatus //海外客户记录当时客户状态
 	rsCalendar.Title = getTitle(req.ActivityType, req.RoadshowType, req.ActivityCategory, req.RoadshowPlatform, req.Province, req.City)
 	if productItemRai != nil {
 		rsCalendar.SellerId = productItemRai.SellerId
@@ -1158,6 +1170,10 @@ func (this *CalendarController) ResearcherList() {
 // @Param   PageSize   query   int  true       "每页数据条数"
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   CalendarType   query   int  true       "1:待处理申请,2:已处理申请,3:内部会议,4:报告电话会"
+// @Param   Status   query   int  true       "1:待接受,2:已接受,3:已拒绝,4:已删除,5:已撤回,6:已结束"
+// @Param   StartDate   query   string  true       "开始日期"
+// @Param   EndDate   query   string  true       "结束日期"
+// @Param   Keyword			query	string	false	"关键词: 客户名称/社会信用码"
 // @Success 200 {object} roadshow.CalendarListResp
 // @router /calendar/list [get]
 func (this *CalendarController) CalendarList() {
@@ -1180,6 +1196,11 @@ func (this *CalendarController) CalendarList() {
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
 
+	status, _ := this.GetInt("Status")
+	startDate := this.GetString("StartDate")
+	endDate := this.GetString("EndDate")
+	keyword := this.GetString("Keyword")
+
 	var total int
 	page := paging.GetPaging(currentIndex, pageSize, total)
 
@@ -1256,6 +1277,29 @@ func (this *CalendarController) CalendarList() {
 		br.ErrMsg = "参数错误,calendarType:" + strconv.Itoa(calendarType)
 		return
 	}
+
+	if status > 0 {
+		condition += ` AND b.status = ?`
+		pars = append(pars, status)
+	}
+
+	if startDate != "" {
+		condition += ` AND b.start_date >= ?`
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += ` AND b.start_date <= ?`
+		pars = append(pars, endDate)
+	}
+
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		condition += ` AND a.company_name LIKE ? `
+		pars = append(pars, kw)
+	}
+
 	fmt.Println(condition)
 	resp := new(roadshow.CalendarListResp)
 	total, err := roadshow.GetCalendarListCount(condition, pars, calendarType)

+ 19 - 0
controllers/roadshow/calendar_meeting_user.go

@@ -7,6 +7,7 @@ import (
 	"hongze/hz_crm_api/models"
 	"hongze/hz_crm_api/models/cygx"
 	"hongze/hz_crm_api/models/roadshow"
+	cygxService "hongze/hz_crm_api/services/cygx"
 	"hongze/hz_crm_api/utils"
 	"strconv"
 	"strings"
@@ -115,6 +116,10 @@ func (this *CalendarMeetingUserController) Add() {
 		br.ErrMsg = "操作失败-MultiAddRsCalendarMeetingUser!Err:" + err.Error()
 		return
 	}
+
+	for _, v := range items {
+		cygxService.RoadShowWxUserRaiLabelRedisAdd(rsCalendarId, v.UserId, v.CreateTime) //添加用户参加路演标签到Redis
+	}
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "添加成功"
@@ -268,6 +273,20 @@ func (this *CalendarMeetingUserController) Delete() {
 	}
 
 	rsCalendarMeetingUserId := req.RsCalendarMeetingUserId
+
+	//rsCalendarMeetingUserItem, err := roadshow.GetRsCalendarMeetingUserByRsCalendarMeetingUserId(rsCalendarMeetingUserId)
+	//if err != nil {
+	//	br.Msg = "获取数据失败!"
+	//	br.ErrMsg = "获取数据失败!GetRsCalendarMeetingUserFirst:" + err.Error()
+	//	return
+	//}
+	//err = cygx.DeleteWxUserRaiLabelWithRoadshow(rsCalendarMeetingUserItem.UserId, rsCalendarMeetingUserItem.RsCalendarId) // 路演到会删除后,删除对应的标签
+	//if err != nil {
+	//	br.Msg = "删除失败!"
+	//	br.ErrMsg = "删除失败-DeleteWxUserRaiLabelWithRoadshow!Err:" + err.Error()
+	//	return
+	//}
+
 	err = roadshow.DeleteRsCalendarMeetingUser(rsCalendarMeetingUserId)
 	if err != nil {
 		br.Msg = "删除失败!"

+ 416 - 0
controllers/roadshow/calendar_researcher_question.go

@@ -0,0 +1,416 @@
+package roadshow
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
+	"hongze/hz_crm_api/models"
+	"hongze/hz_crm_api/models/roadshow"
+	"hongze/hz_crm_api/utils"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// @Title 路演客户问答保存接口
+// @Description 路演客户问答保存接口
+// @Param	request	body roadshow.RoadShowQuestionSaveReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /question/save [post]
+func (this *CalendarController) QuestionAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	deleteCache := true
+	cacheKey := "CACHE_RS_ACTIVITY_QUESTION_SAVE_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 5*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req roadshow.RoadShowQuestionSaveReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.RsCalendarId <= 0 || req.RsCalendarResearcherId <= 0 {
+		br.Msg = "参数错误!"
+		return
+	}
+
+	calendarResearcherItem, err := roadshow.GetRsCalendarResearcherById(req.RsCalendarResearcherId)
+	if err != nil {
+		br.Msg = "获取路演记录失败!"
+		br.ErrMsg = "获取路演记录失败,Err:" + err.Error()
+		return
+	}
+
+	if calendarResearcherItem.QuestionStatus == 1 {
+		br.Msg = "问答已填写,不可重复提交!"
+		return
+	}
+
+	err = roadshow.RoadShowQuestionSave(&req)
+	if err != nil {
+		br.Msg = "保存失败!"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.IsAddLog = true
+}
+
+// ResearcherList
+// @Title 获取路演客户问答信息接口
+// @Description 获取路演客户问答信息接口
+// @Param   RsCalendarId   query   int  true       "路演日历ID"
+// @Param   RsCalendarResearcherId   query   int  true       "路演研究员记录ID"
+// @Success 200 {object} roadshow.ResearcherGroup
+// @router /question/list [get]
+func (this *CalendarController) QuestionList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	rsCalendarId, _ := this.GetInt("RsCalendarId")
+
+	rsCalendarResearcherId, _ := this.GetInt("RsCalendarResearcherId")
+	if rsCalendarResearcherId <= 0 && rsCalendarId <= 0 {
+		br.Msg = "参数错误!"
+		return
+	}
+
+	var condition string
+	var pars []interface{}
+
+	if rsCalendarId > 0 {
+		condition += ` AND a.rs_calendar_id = ? `
+		pars = append(pars, rsCalendarId)
+	}
+
+	if rsCalendarResearcherId > 0 {
+		condition += ` AND a.rs_calendar_researcher_id = ? `
+		pars = append(pars, rsCalendarResearcherId)
+	}
+
+	list, err := roadshow.GetRoadShowQuestionList(condition, pars)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败!"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// @Title 获取客户路演问题汇总
+// @Description 获取客户路演问题汇总
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   StartDate   query   string  true       "开始日期"
+// @Param   EndDate   query   string  true       "结束日期"
+// @Param   ResearcherId   query   string  true       "研究员id"
+// @Param   CompanyId   query   int  true       "客户ID"
+// @Param   CompanyIndustry			query	string	false	"客户行业"
+// @Param   CompanyClassify			query	string	false	"客户分类"
+// @Param   Keyword			query	string	false	"关键词: 客户名称/社会信用码"
+// @Success 200 {object} roadshow.QuestionSummaryListResp
+// @router /question/summary/list [get]
+func (this *CalendarController) CalendarSummaryList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	startDate := this.GetString("StartDate")
+	endDate := this.GetString("EndDate")
+	researcherId := this.GetString("ResearcherId")
+	companyIndustry := this.GetString("CompanyIndustry")
+	companyClassify := this.GetString("CompanyClassify")
+	keyword := this.GetString("Keyword")
+
+	var total int
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize10
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+
+	condition += ` AND b.question_status = 1 `
+
+	if startDate != "" {
+		condition += ` AND b.start_date >= ?`
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += ` AND b.start_date <= ?`
+		pars = append(pars, endDate)
+	}
+
+	if researcherId != "" {
+		condition += ` AND b.researcher_id IN(` + researcherId + `)`
+	}
+
+	if companyIndustry != "" {
+		condition += ` AND b.company_industry = ?`
+		pars = append(pars, companyIndustry)
+	}
+
+	if companyClassify != "" {
+		condition += ` AND b.company_classify = ?`
+		pars = append(pars, companyClassify)
+	}
+
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		condition += ` AND a.company_name LIKE ? `
+		pars = append(pars, kw)
+	}
+
+	total, err := roadshow.GetQuestionSummaryListCount(condition, pars)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取数据总数失败,GetQuestionSummaryListCount,Err:" + err.Error()
+		return
+	}
+
+	dataList, err := roadshow.GetQuestionSummaryList(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取数据失败,GetQuestionSummaryList,Err:" + err.Error()
+		return
+	}
+
+	page = paging.GetPaging(currentIndex, pageSize, total)
+
+	resp := new(roadshow.QuestionSummaryListResp)
+
+	resp.Paging = page
+	resp.List = dataList
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 导出客户路演问题汇总
+// @Description 导出客户路演问题汇总
+// @Param   StartDate   query   string  true       "开始日期"
+// @Param   EndDate   query   string  true       "结束日期"
+// @Param   ResearcherId   query   string  true       "研究员id"
+// @Param   CompanyId   query   int  true       "客户ID"
+// @Param   CompanyIndustry			query	string	false	"客户行业"
+// @Param   CompanyClassify			query	string	false	"客户分类"
+// @Param   Keyword			query	string	false	"关键词: 客户名称/社会信用码"
+// @Success 200 {object} roadshow.QuestionSummaryListResp
+// @router /question/summary/export [get]
+func (this *CalendarController) CalendarSummaryExport() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	startDate := this.GetString("StartDate")
+	endDate := this.GetString("EndDate")
+	researcherId := this.GetString("ResearcherId")
+	companyIndustry := this.GetString("CompanyIndustry")
+	companyClassify := this.GetString("CompanyClassify")
+	keyword := this.GetString("Keyword")
+
+	var condition string
+	var pars []interface{}
+
+	condition += ` AND b.question_status = 1 `
+
+	if startDate != "" {
+		condition += ` AND b.start_date >= ?`
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += ` AND b.start_date <= ?`
+		pars = append(pars, endDate)
+	}
+
+	if researcherId != "" {
+		condition += ` AND b.researcher_id IN(` + researcherId + `)`
+	}
+
+	if companyIndustry != "" {
+		condition += ` AND b.company_industry = ?`
+		pars = append(pars, companyIndustry)
+	}
+
+	if companyClassify != "" {
+		condition += ` AND b.company_classify = ?`
+		pars = append(pars, companyClassify)
+	}
+
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		condition += ` AND a.company_name LIKE ? `
+		pars = append(pars, kw)
+	}
+
+	dataList, err := roadshow.GetQuestionSummaryExport(condition, pars)
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取数据失败,GetQuestionSummaryList,Err:" + err.Error()
+		return
+	}
+
+	var rsCalendarIdArr []string
+
+	for _, v := range dataList {
+		rsCalendarIdArr = append(rsCalendarIdArr, strconv.Itoa(v.RsCalendarId))
+	}
+
+	questionMap := make(map[int][]*roadshow.RsCalendarResearcherQuestionView)
+	var questionMax int
+
+	if len(rsCalendarIdArr) > 0 {
+		var questionCondition string
+		var questionPars []interface{}
+
+		condition += ` AND a.rs_calendar_id IN (` + strings.Join(rsCalendarIdArr, ",") + `) `
+
+		questionList, err := roadshow.GetRoadShowQuestionList(questionCondition, questionPars)
+		if err != nil {
+			br.Msg = "获取指标信息失败"
+			br.ErrMsg = "获取数据失败,GetRoadShowQuestionList,Err:" + err.Error()
+			return
+		}
+
+		for _, qv := range questionList {
+			if items, ok := questionMap[qv.RsCalendarId]; ok {
+				items = append(items, qv)
+				questionMap[qv.RsCalendarId] = items
+
+				if len(items) > questionMax {
+					questionMax = len(items)
+				}
+			} else {
+				items = make([]*roadshow.RsCalendarResearcherQuestionView, 0)
+				items = append(items, qv)
+				questionMap[qv.RsCalendarId] = items
+				if len(items) > questionMax {
+					questionMax = len(items)
+				}
+			}
+		}
+	}
+
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+	downloadPath := exPath + "/" + time.Now().Format(utils.FormatDateUnSpace) + "客户路演汇总" + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+	sheet, e := xlsxFile.AddSheet("客户路演汇总")
+	if e != nil {
+		br.Msg = "新增Sheet失败"
+		br.ErrMsg = "新增Sheet失败, Err: " + e.Error()
+		return
+	}
+
+	titleRow := sheet.AddRow()
+	titleRow.AddCell().SetString("路演时间")
+	titleRow.AddCell().SetString("客户名称")
+	titleRow.AddCell().SetString("发起人")
+	titleRow.AddCell().SetString("研究员")
+	titleRow.AddCell().SetString("客户行业")
+	titleRow.AddCell().SetString("客户分类")
+
+	for i := 1; i <= questionMax; i++ {
+		titleRow.AddCell().SetString("Q" + strconv.Itoa(i))
+		titleRow.AddCell().SetString("A" + strconv.Itoa(i))
+	}
+
+	for _, v := range dataList {
+		dataRow := sheet.AddRow()
+		dataRow.AddCell().SetString(v.StartDate + " " + v.StartTime)
+		dataRow.AddCell().SetString(v.CompanyName)
+		dataRow.AddCell().SetString(v.SysUserRealName)
+		dataRow.AddCell().SetString(v.ResearcherName)
+		dataRow.AddCell().SetString(v.CompanyIndustry)
+		dataRow.AddCell().SetString(v.CompanyClassify)
+		questionList := questionMap[v.RsCalendarId]
+		for _, qv := range questionList {
+			dataRow.AddCell().SetString(qv.QuestionContent)
+			dataRow.AddCell().SetString(qv.ReplyContent)
+		}
+	}
+
+	if e = xlsxFile.Save(downloadPath); e != nil {
+		br.Msg = "导出失败"
+		br.ErrMsg = "保存文件失败"
+		return
+	}
+	fileName := time.Now().Format(utils.FormatDateUnSpace) + "客户路演汇总" + ".xlsx"
+	this.Ctx.Output.Download(downloadPath, fileName)
+	defer func() {
+		_ = os.Remove(downloadPath)
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 32 - 1
controllers/roadshow/company.go

@@ -10,6 +10,7 @@ import (
 	"hongze/hz_crm_api/utils"
 	"strconv"
 	"strings"
+	"time"
 )
 
 // @Title 我的日历列表
@@ -65,6 +66,7 @@ func (this *CalendarController) CompanySearch() {
 // @Param   EnglishCompany   query   int  true       "是否为英文客户"
 // @Param   CompanyType   query   string  true       "客户类型:'ficc','权益',传空默认为ficc,"
 // @Param   RsReportRecordId   query   int	  true       "路演统计Id"
+// @Param   SellerId   query   int	  true       "销售ID"
 // @Success 200 {object} roadshow.CompanyDetailView
 // @router /company/detail [get]
 func (this *CalendarController) CompanyDetail() {
@@ -91,6 +93,8 @@ func (this *CalendarController) CompanyDetail() {
 	englishCompany, _ := this.GetInt("EnglishCompany")
 	companyType := this.GetString("CompanyType")
 	rsReportRecordId, _ := this.GetInt("RsReportRecordId")
+	sellerId, _ := this.GetInt("SellerId")
+
 	productId := services.GetProductId(sysUser.RoleTypeCode)
 	if productId == 0 {
 		productId = 1
@@ -99,6 +103,28 @@ func (this *CalendarController) CompanyDetail() {
 	if companyType == utils.COMPANY_CLASSIFY_RAI {
 		productId = 2
 	}
+
+	if sellerId > 0 {
+		ficcSellerMap := make(map[int]int)
+		//raiSellerMap := make(map[int]int)
+		_, groupIdRelationMap, err := services.GetFiccSystemGroup()
+		if err != nil {
+			br.Msg = "获取信息失败!"
+			br.ErrMsg = "获取FICC销售信息失败!Err:" + err.Error()
+			return
+		}
+		ficcSellerList, err := services.GetFiccSeller(time.Now(), groupIdRelationMap)
+		for _, v := range ficcSellerList {
+			ficcSellerMap[v.AdminId] = v.AdminId
+		}
+
+		if _, ok := ficcSellerMap[sellerId]; ok {
+			productId = 1
+		} else {
+			productId = 2
+		}
+	}
+
 	detailView := new(roadshow.CompanyDetailView)
 	if englishCompany == 0 {
 		var companyStatus string
@@ -152,6 +178,11 @@ func (this *CalendarController) CompanyDetail() {
 			detailView.ReportReadTotal = viewTotal
 		}
 
+		if productId == 1 {
+			detailView.CompanyType = "FICC"
+		} else {
+			detailView.CompanyType = "权益"
+		}
 		br.Ret = 200
 		br.Success = true
 		br.Msg = "获取成功"
@@ -168,7 +199,7 @@ func (this *CalendarController) CompanyDetail() {
 	}
 	detailView.CompanyId = enItem.CompanyId
 	detailView.CompanyName = enItem.CompanyName
-	detailView.Status = "正常"
+	detailView.Status = enItem.OverseasStatus
 	detailView.EnglishCompany = 1
 	detailView.EnglishCountry = enItem.Country
 	detailView.EnglishViewTotal = enItem.ViewTotal

+ 257 - 2
controllers/roadshow/report.go

@@ -3,6 +3,7 @@ package roadshow
 import (
 	"encoding/json"
 	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
 	"hongze/hz_crm_api/models"
 	"hongze/hz_crm_api/models/company"
 	"hongze/hz_crm_api/models/cygx"
@@ -11,6 +12,8 @@ import (
 	"hongze/hz_crm_api/services"
 	roadshowService "hongze/hz_crm_api/services/roadshow"
 	"hongze/hz_crm_api/utils"
+	"os"
+	"path/filepath"
 	"strconv"
 	"strings"
 	"time"
@@ -19,7 +22,7 @@ import (
 // ResearcherReportList
 // @Title 研究员路演统计
 // @Description 研究员路演统计接口
-// @Param   DataType   query   string  true       "枚举值:week、month、time_interval"
+// @Param   DataType   query   string  true       "枚举值:week、month、time_interval、quarter(季度)"
 // @Param   StartDate   query   string  true       "开始日期,格式:2022-04-06"
 // @Param   EndDate   query   string  true       "结束日期,格式:2022-04-06"
 // @Param   CompanyType   query   string  true       "客户类型:'ficc','权益',传空默认为ficc,"
@@ -73,6 +76,18 @@ func (this *CalendarController) ResearcherReportList() {
 			br.ErrMsg = "数据异常,Err:" + err.Error()
 			return
 		}
+	case "quarter":
+		adminDataList, _, err = roadshowService.GetQuarterData("researcher", "company_status")
+		if err != nil {
+			br.Msg = "数据异常"
+			br.ErrMsg = "数据异常,Err:" + err.Error()
+			return
+		}
+		if err != nil {
+			br.Msg = "数据异常"
+			br.ErrMsg = "数据异常,Err:" + err.Error()
+			return
+		}
 	}
 
 	var group []*roadshow.ResearcherGroup
@@ -187,6 +202,7 @@ func (this *CalendarController) ResearcherReportList() {
 	tmpAllMeetingNumMap := make(map[int]int)
 	tmpAllRoadShowNumMap := make(map[int]int)
 	tmpAllSalonNumMap := make(map[int]int)
+	tmpAllAskNumMap := make(map[int]int)
 	for _, v := range group {
 		v.ResearcherList = groupMap[v.GroupId]
 		tmpGroupAdminReportRecord := make([]roadshow.AdminReportRecord, 0)
@@ -200,6 +216,7 @@ func (this *CalendarController) ResearcherReportList() {
 		tmpGroupMeetingNumMap := make(map[int]int)
 		tmpGroupRoadShowNumMap := make(map[int]int)
 		tmpGroupSalonMapNumMap := make(map[int]int)
+		tmpGroupAskMapNumMap := make(map[int]int)
 		for _, researcher := range groupMap[v.GroupId] {
 			//组内研究员数据
 			//每个区间的数据
@@ -208,7 +225,7 @@ func (this *CalendarController) ResearcherReportList() {
 				startDateIndexList[index] = adminData.StartDate
 				endDateIndexList[index] = adminData.EndDate
 
-				var tmpTryOutNum, tmpFormalNum, tmpMeetingNum, tmpRoadShowNum, tmpSalonNum int
+				var tmpTryOutNum, tmpFormalNum, tmpMeetingNum, tmpRoadShowNum, tmpSalonNum, tmpAskNum int
 				if num, ok := adminData.TryOutMap[researcher.AdminId]; ok {
 					tmpTryOutNum = num
 				}
@@ -225,12 +242,17 @@ func (this *CalendarController) ResearcherReportList() {
 					tmpSalonNum = num
 				}
 
+				if num, ok := adminData.AskMap[researcher.AdminId]; ok { //路演总次数
+					tmpAskNum = num
+				}
+
 				tmpAdminRsReportRecordNum := roadshow.RsReportRecordNum{
 					TryOutNum:   tmpTryOutNum,
 					FormalNum:   tmpFormalNum,
 					MeetingNum:  tmpMeetingNum,
 					RoadShowNum: tmpRoadShowNum,
 					SalonNum:    tmpSalonNum,
+					AskNum:      tmpAskNum,
 					StartDate:   adminData.StartDate,
 					EndDate:     adminData.EndDate,
 				}
@@ -252,11 +274,15 @@ func (this *CalendarController) ResearcherReportList() {
 				if _, ok := tmpGroupSalonMapNumMap[index]; !ok {
 					tmpGroupSalonMapNumMap[index] = 0
 				}
+				if _, ok := tmpGroupAskMapNumMap[index]; !ok {
+					tmpGroupAskMapNumMap[index] = 0
+				}
 				tmpGroupTryOutNumMap[index] += tmpTryOutNum
 				tmpGroupFormalNumMap[index] += tmpFormalNum
 				tmpGroupMeetingNumMap[index] += tmpMeetingNum
 				tmpGroupRoadShowNumMap[index] += tmpRoadShowNum
 				tmpGroupSalonMapNumMap[index] += tmpSalonNum
+				tmpGroupAskMapNumMap[index] += tmpAskNum
 
 				//总数据汇总
 				if _, ok := tmpAllTryOutNumMap[index]; !ok {
@@ -274,11 +300,15 @@ func (this *CalendarController) ResearcherReportList() {
 				if _, ok := tmpGroupSalonMapNumMap[index]; !ok {
 					tmpGroupSalonMapNumMap[index] = 0
 				}
+				if _, ok := tmpGroupAskMapNumMap[index]; !ok {
+					tmpGroupAskMapNumMap[index] = 0
+				}
 				tmpAllTryOutNumMap[index] += tmpTryOutNum
 				tmpAllFormalNumMap[index] += tmpFormalNum
 				tmpAllMeetingNumMap[index] += tmpMeetingNum
 				tmpAllRoadShowNumMap[index] += tmpRoadShowNum
 				tmpAllSalonNumMap[index] += tmpSalonNum
+				tmpAllAskNumMap[index] += tmpAskNum
 			}
 			tmpAdminReportRecord := roadshow.AdminReportRecord{
 				Name:                  researcher.RealName,
@@ -295,6 +325,7 @@ func (this *CalendarController) ResearcherReportList() {
 				MeetingNum:  tmpGroupMeetingNumMap[i],
 				RoadShowNum: tmpGroupRoadShowNumMap[i],
 				SalonNum:    tmpGroupSalonMapNumMap[i],
+				AskNum:      tmpGroupAskMapNumMap[i],
 				StartDate:   startDateIndexList[i],
 				EndDate:     endDateIndexList[i],
 			}
@@ -662,6 +693,8 @@ func (this *CalendarController) SellerReportList() {
 // @Param   AdminId   query   int  true       "用户id"
 // @Param   StartDate   query   string  true       "开始日期,格式:2022-04-06"
 // @Param   EndDate   query   string  true       "结束日期,格式:2022-04-06"
+// @Param   Status   query   int  true       "0:全部,1:已完成"
+// @Param   EnglishCompany   query   int  true       "-1:全部,0:国内,1:海外"
 // @Success 200 {object} []roadshow.RsReportRecordList
 // @router /report/calendar/list [get]
 func (this *CalendarController) ReportCalendarList() {
@@ -687,6 +720,10 @@ func (this *CalendarController) ReportCalendarList() {
 		return
 	}
 
+	status, _ := this.GetInt("Status")
+
+	englishCompany, _ := this.GetInt("EnglishCompany")
+
 	//正式客户
 	var condition string
 	var pars []interface{}
@@ -739,12 +776,43 @@ func (this *CalendarController) ReportCalendarList() {
 		return
 	}
 
+	if status == 1 {
+		condition += ` and c.question_status = ? `
+		pars = append(pars, 1)
+	}
+
+	if englishCompany != -1 {
+		condition += ` and b.english_company = ? `
+		pars = append(pars, englishCompany)
+	}
+
 	list, err := roadshow.GetRsReportRecordList(condition, pars)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取失败,ERR:" + err.Error()
 		return
 	}
+
+	ficcSellerMap := make(map[int]int)
+	//raiSellerMap := make(map[int]int)
+	_, groupIdRelationMap, err := services.GetFiccSystemGroup()
+	if err != nil {
+		br.Msg = "获取信息失败!"
+		br.ErrMsg = "获取FICC销售信息失败!Err:" + err.Error()
+		return
+	}
+	ficcSellerList, err := services.GetFiccSeller(time.Now(), groupIdRelationMap)
+	for _, v := range ficcSellerList {
+		ficcSellerMap[v.AdminId] = v.AdminId
+	}
+
+	for _, v := range list {
+		if _, ok := ficcSellerMap[v.SellerId]; ok {
+			v.CompanyType = "FICC"
+		} else {
+			v.CompanyType = "权益"
+		}
+	}
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"
@@ -1878,3 +1946,190 @@ func (this *CalendarController) OverseasCalendarList() {
 	br.Data = list
 	return
 }
+
+// @Title 导出研究员路演统计
+// @Description 导出研究员路演统计接口
+// @Param   DataType   query   string  true       "枚举值:week、month、time_interval"
+// @Param   StartDate   query   string  true       "开始日期,格式:2022-04-06"
+// @Param   EndDate   query   string  true       "结束日期,格式:2022-04-06"
+// @Param   CompanyType   query   string  true       "客户类型:'ficc','权益',传空默认为ficc,"
+// @Success 200 {object} roadshow.RsReportRecordResp
+// @router /report/researcher/export [get]
+func (this *CalendarController) ResearcherReportExport() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	dataType := this.GetString("DataType")
+	startDate := this.GetString("StartDate")
+	endDate := this.GetString("EndDate")
+	companyType := this.GetString("CompanyType", "ficc")
+
+	var err error
+	//获取列表
+	switch dataType {
+	case "week":
+		startDate = utils.GetNowWeekMonday().AddDate(0, 0, -7).Format(utils.FormatDate)
+		endDate = utils.GetNowWeekLastDay().AddDate(0, 0, 7).Format(utils.FormatDate)
+	case "month":
+		startDate = utils.GetNowMonthFirstDay().AddDate(0, -4, 0).Format(utils.FormatDate)
+		endDate = utils.GetNowMonthLastDay().Format(utils.FormatDate)
+	case "time_interval":
+		if startDate == `` || endDate == `` {
+			br.Msg = "开始日期或结束日期不能为空"
+			br.ErrMsg = "开始日期或结束日期不能为空,Err:" + err.Error()
+			return
+		}
+	}
+
+	var researcherIdArr []string
+	ficcSellerMap := make(map[int]int)
+	//raiSellerMap := make(map[int]int)
+	switch companyType {
+	case utils.COMPANY_CLASSIFY_FICC:
+		researcherList, err := roadshow.GetResearcherV2()
+		if err != nil {
+			br.Msg = "获取信息失败!"
+			br.ErrMsg = "获取分组信息失败!,GetResearcherV2 Err:" + err.Error()
+			return
+		}
+		for _, v := range researcherList {
+			if v.AdminId > 0 {
+				researcherId := strconv.Itoa(v.AdminId)
+				researcherIdArr = append(researcherIdArr, researcherId)
+			}
+		}
+
+		_, groupIdRelationMap, err := services.GetFiccSystemGroup()
+		if err != nil {
+			br.Msg = "获取信息失败!"
+			br.ErrMsg = "获取FICC销售信息失败!Err:" + err.Error()
+			return
+		}
+		ficcSellerList, err := services.GetFiccSeller(time.Now(), groupIdRelationMap)
+		for _, v := range ficcSellerList {
+			ficcSellerMap[v.AdminId] = v.AdminId
+		}
+	case utils.COMPANY_CLASSIFY_RAI:
+		askUserList, err := cygx.GetAskEmailListResearcher()
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,GetAskEmailListResearcher Err: " + err.Error()
+			return
+		}
+		for _, v := range askUserList {
+			if v.AdminId > 0 {
+				researcherId := strconv.Itoa(v.AdminId)
+				researcherIdArr = append(researcherIdArr, researcherId)
+			}
+		}
+
+		//_, groupIdRelationMap, err := services.GetRaiSystemGroup()
+		//if err != nil {
+		//	br.Msg = "获取信息失败!"
+		//	br.ErrMsg = "获取分组信息失败!Err:" + err.Error()
+		//	return
+		//}
+		//raiSellList, err := services.GetRaiSeller(groupIdRelationMap)
+		//if err != nil {
+		//	br.Msg = "获取信息失败!"
+		//	br.ErrMsg = "获取权益销售信息失败!Err:" + err.Error()
+		//	return
+		//}
+		//
+		//for _, v := range raiSellList {
+		//	raiSellerMap[v.AdminId] = v.AdminId
+		//}
+	}
+
+	var condition string
+	var pars []interface{}
+
+	condition += ` AND c.researcher_id IN(` + strings.Join(researcherIdArr, ",") + `) `
+
+	if startDate != "" {
+		condition += ` AND c.start_date >= ? `
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += ` AND c.start_date <= ? `
+		pars = append(pars, endDate)
+	}
+
+	condition += ` AND b.activity_type = '路演' `
+	condition += ` AND b.roadshow_type <> '' `
+	condition += ` AND c.question_status = 1 `
+
+	list, err := roadshow.GetReportResearcherExport(condition, pars)
+	if err != nil {
+		br.Msg = "获取信息失败!"
+		br.ErrMsg = "获取数据失败!Err:" + err.Error()
+		return
+	}
+
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+	downloadPath := exPath + "/" + time.Now().Format(utils.FormatDateUnSpace) + "研究员已完成路演统计" + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+	sheet, e := xlsxFile.AddSheet("已完成路演统计")
+	if e != nil {
+		br.Msg = "新增Sheet失败"
+		br.ErrMsg = "新增Sheet失败, Err: " + e.Error()
+		return
+	}
+
+	titleRow := sheet.AddRow()
+	titleRow.AddCell().SetString("研究员")
+	titleRow.AddCell().SetString("路演时间")
+	titleRow.AddCell().SetString("客户名称")
+	titleRow.AddCell().SetString("路演形式")
+	titleRow.AddCell().SetString("发起人")
+	titleRow.AddCell().SetString("客户类型")
+	titleRow.AddCell().SetString("客户状态")
+	titleRow.AddCell().SetString("客户行业")
+	titleRow.AddCell().SetString("客户分类")
+	titleRow.AddCell().SetString("所属区域")
+
+	for _, v := range list {
+		dataRow := sheet.AddRow()
+		dataRow.AddCell().SetString(v.ResearcherName)
+		dataRow.AddCell().SetString(v.StartDate + " " + v.StartTime)
+		dataRow.AddCell().SetString(v.CompanyName)
+		dataRow.AddCell().SetString(v.RoadshowType)
+		dataRow.AddCell().SetString(v.SellerName)
+		if _, ok := ficcSellerMap[v.SellerId]; ok {
+			dataRow.AddCell().SetString("FICC")
+		} else {
+			dataRow.AddCell().SetString("权益")
+		}
+		dataRow.AddCell().SetString(v.CompanyStatus)
+		dataRow.AddCell().SetString(v.CompanyIndustry)
+		dataRow.AddCell().SetString(v.CompanyClassify)
+		if v.EnglishCompany == 0 {
+			dataRow.AddCell().SetString("国内")
+		} else {
+			dataRow.AddCell().SetString("海外")
+		}
+	}
+
+	if e = xlsxFile.Save(downloadPath); e != nil {
+		br.Msg = "导出失败"
+		br.ErrMsg = "保存文件失败"
+		return
+	}
+	fileName := time.Now().Format(utils.FormatDateUnSpace) + "研究员已完成路演统计" + ".xlsx"
+	this.Ctx.Output.Download(downloadPath, fileName)
+	defer func() {
+		_ = os.Remove(downloadPath)
+	}()
+	return
+}

+ 1 - 1
controllers/seal/seal_approval.go

@@ -473,7 +473,7 @@ func (this *SealApprovalController) Apply() {
 		"Use":         {utils.NotEmpty()},
 		"CompanyName": {utils.NotEmpty()},
 		"CreditCode":  {utils.NotEmpty()},
-		//"ServiceType":       {utils.NotEmpty()} /、/权益非标合同不校验合同类型
+		//"ServiceType":       {utils.NotEmpty()},
 		"SealType":          {utils.NotEmpty()},
 		"FileUrls":          {utils.NotEmpty()},
 		"AffiliatedCompany": {utils.NotEmpty()},

+ 7 - 6
go.mod

@@ -32,6 +32,7 @@ require (
 	github.com/tealeg/xlsx v1.0.5
 	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.541
 	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ses v1.0.541
+	github.com/wechatpay-apiv3/wechatpay-go v0.2.18
 	github.com/xuri/excelize/v2 v2.6.1
 	github.com/yidane/formula v0.0.0-20210902154546-0782e1736717
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
@@ -63,6 +64,7 @@ require (
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/garyburd/redigo v1.6.3 // indirect
 	github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc // indirect
+	github.com/go-resty/resty/v2 v2.16.5 // indirect
 	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac // indirect
@@ -97,15 +99,14 @@ require (
 	github.com/tidwall/match v1.1.1 // indirect
 	github.com/tidwall/pretty v1.2.0 // indirect
 	github.com/tjfoc/gmsm v1.3.2 // indirect
-	github.com/wechatpay-apiv3/wechatpay-go v0.2.18 // indirect
 	github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
 	github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
-	golang.org/x/crypto v0.5.0 // indirect
+	golang.org/x/crypto v0.31.0 // indirect
 	golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect
-	golang.org/x/net v0.9.0 // indirect
-	golang.org/x/sys v0.7.0 // indirect
-	golang.org/x/text v0.9.0 // indirect
-	golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
+	golang.org/x/net v0.33.0 // indirect
+	golang.org/x/sys v0.28.0 // indirect
+	golang.org/x/text v0.21.0 // indirect
+	golang.org/x/time v0.6.0 // indirect
 	google.golang.org/protobuf v1.30.0 // indirect
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect

+ 13 - 0
go.sum

@@ -13,6 +13,7 @@ github.com/SebastiaanKlippert/go-wkhtmltopdf v1.7.2 h1:LORAatv6KuKheYq8HXehiwx3f
 github.com/SebastiaanKlippert/go-wkhtmltopdf v1.7.2/go.mod h1:TY8r0gmwEL1c5Lbd66NgQCkL4ZjGDJCMVqvbbFvUx20=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
 github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -153,6 +154,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
 github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
 github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc h1:jZY+lpZB92nvBo2f31oPC/ivGll6NcsnEOORm8Fkr4M=
 github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc/go.mod h1:25mL1NKxbJhB63ihiK8MnNeTRd+xAizd6bOdydrTLUQ=
+github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM=
+github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -454,6 +457,8 @@ golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0
 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
 golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
+golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=
@@ -493,6 +498,8 @@ golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfS
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
+golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -536,6 +543,8 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
 golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -549,10 +558,14 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
 golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
+golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

+ 5 - 1
models/company/company.go

@@ -965,7 +965,11 @@ func MoveSeller(companyId, productId, sellerId, groupId, departmentId int, selle
 	}()
 
 	startDateTime = time.Now()
-	endDateTime = time.Now().AddDate(0, 2, 0)
+	if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+		endDateTime = time.Now().AddDate(0, 1, 0)
+	} else {
+		endDateTime = time.Now().AddDate(0, 2, 0)
+	}
 
 	startDate := startDateTime.Format(utils.FormatDate)
 	endDate := endDateTime.Format(utils.FormatDate)

+ 9 - 0
models/company/company_approval.go

@@ -403,6 +403,9 @@ func FreezeToTryOut(companyId, productId, sellerId, companyApprovalId, applyUser
 	}()
 	startDate = time.Now().Format(utils.FormatDate)
 	endDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+	if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+		endDate = time.Now().AddDate(0, 1, 0).Format(utils.FormatDate)
+	}
 
 	//sellerItem, err := system.GetSysAdminById(applyUserId)
 	//if err != nil {
@@ -643,6 +646,9 @@ func TryOutDelay(companyId, productId, sellerId, companyApprovalId int, sellerNa
 		return
 	}
 	newEndDate = endDateTime.AddDate(0, 2, 0).Format(utils.FormatDate)
+	if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+		newEndDate = endDateTime.AddDate(0, 1, 0).Format(utils.FormatDate)
+	}
 	//更新用户产品状态
 	sql := `UPDATE company_product SET approve_status='已审批',is_suspend=0,end_date=?,modify_time=NOW() WHERE company_id=? AND product_id=? `
 	_, err = to.Raw(sql, newEndDate, companyId, productId).Exec()
@@ -767,6 +773,9 @@ func ApplyReceive(companyId, productId, sysUserId, companyApprovalId int, seller
 
 	startDate = time.Now().Format(utils.FormatDate)
 	endDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
+	if productId == utils.COMPANY_PRODUCT_RAI_ID { // 权益客户试用期改为1个月。 需求池 1035
+		endDate = time.Now().AddDate(0, 1, 0).Format(utils.FormatDate)
+	}
 
 	//更新用户产品状态
 	sql := `UPDATE company_product SET status='试用',try_out_time=NULL,last_description_time=NULL,is_suspend=0,approve_status='已审批', start_date=?,end_date=?,seller_id=?,seller_name=?,group_id=?,department_id=?,modify_time=NOW(),try_stage=1 WHERE company_id=? AND product_id=? `

+ 9 - 0
models/cygx/activity.go

@@ -586,6 +586,7 @@ type CygxActivityList struct {
 	SigninImg                 string `description:"签到码图片"`
 	ChartPermissionNameDeputy string `description:"副行业名称"`
 	TopTime                   int    `description:"置顶时间"`
+	XcxDetailImg              string `description:"小程序二维码详情图片"`
 }
 
 type GetCygxActivityListRep struct {
@@ -740,6 +741,14 @@ func UpdateCygxActivityMomentsImg(momentsImg string, activityId int) (err error)
 	return
 }
 
+// 添加活动详情图片
+func UpdateCygxActivityXcxDetailImg(xcxDetailImg string, activityId int) (err error) {
+	sql := `UPDATE cygx_activity SET  xcx_detail_img=?  WHERE activity_id=? `
+	o := orm.NewOrmUsingDB("hz_cygx")
+	_, err = o.Raw(sql, xcxDetailImg, activityId).Exec()
+	return
+}
+
 // UpdateCygxActivityyidongActivityId  ,建立与易董的活动关联
 func UpdateCygxActivityyidongActivityId(yidongActivityId string, activityId int) (err error) {
 	o := orm.NewOrmUsingDB("hz_cygx")

+ 8 - 0
models/cygx/activity_signup_detail.go

@@ -156,3 +156,11 @@ func UpdateActivitySignupDetailMultiByYiDong(items []*CygxActivitySignupDetail)
 	}
 	return
 }
+
+// 根据用户ID,文章ID获取用户最新一条参会记录
+func GetCygxActivitySignupDetailDetailLast(articleId int, mobile string) (item *CygxActivitySignupDetail, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT * FROM cygx_activity_signup_detail WHERE   activity_id = ?  AND mobile = ?     ORDER BY id DESC    LIMIT 1 `
+	err = o.Raw(sql, articleId, mobile).QueryRow(&item)
+	return
+}

+ 11 - 0
models/cygx/activity_special.go

@@ -499,3 +499,14 @@ func GetactivitySpecilIdsByLabel(name string) (activityIds string, err error) {
 	err = o.Raw(sql).QueryRow(&activityIds)
 	return
 }
+
+// 获取数量
+func GetActivitySpecilCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity_special as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrmUsingDB("hz_cygx")
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}

+ 1 - 2
models/cygx/activity_video.go

@@ -105,8 +105,7 @@ func GetActivityVideoCountByActivityId(activityId int) (count int, err error) {
 	o := orm.NewOrmUsingDB("hz_cygx")
 	sqlCount := ` SELECT
 				COUNT( 1 ) AS count 
-			FROM
-   				JOIN cygx_activity_video
+			FROM cygx_activity_video
 			WHERE activity_id = ? `
 	err = o.Raw(sqlCount, activityId).QueryRow(&count)
 	return

+ 8 - 0
models/cygx/activity_voice.go

@@ -67,6 +67,14 @@ func GetCygxActivityVoiceCount(condition string, pars []interface{}) (count int,
 	return
 }
 
+// 获取数量
+func GetCygxActivityVoiceCountByActivityId(activityId int) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity_voice   WHERE activity_id= ?  `
+	o := orm.NewOrmUsingDB("hz_cygx")
+	err = o.Raw(sqlCount, activityId).QueryRow(&count)
+	return
+}
+
 // 列表
 func GetCygxActivityVoiceReqList(activityId int) (items []*CygxActivityVoiceReq, err error) {
 	o := orm.NewOrmUsingDB("hz_cygx")

+ 43 - 1
models/cygx/askserie_video_history_record.go

@@ -1,6 +1,9 @@
 package cygx
 
-import "github.com/beego/beego/v2/client/orm"
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
 
 type CygxAskserieVideoHistoryRecordResp struct {
 	Id               int    `orm:"column(id);pk"`
@@ -72,3 +75,42 @@ func GetCygxAskserieVideoCollectionList(condition string, pars []interface{}) (i
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
+
+type CygxArticleHistoryRecordAll struct {
+	Id               int `orm:"column(id);pk"`
+	ArticleId        int
+	UserId           int
+	CreateTime       string
+	ModifyTime       time.Time
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	StopTime         int       `description:"停留时间"`
+	OutType          int       `description:"退出方式,1正常退出,2强制关闭"`
+	Source           string    `description:"来源,MOBILE:手机端,PC:电脑端"`
+	RealName         string    `description:"用户实际名称"`
+	CreateDateApi    time.Time `description:"同步创建时间"`
+	CelueHistoryId   int       `description:"策略平台记录的ID"`
+	Platfor          int       `description:"PV阅读记录来源,1:查研观向,2:策略平台"`
+	IsDel            int       `description:"是否删除"`
+	RegisterPlatform int       `description:"来源"`
+	CompanyStatus    string    `description:"公司状态"`
+	SellerName       string    `description:"所属销售"`
+}
+
+// 根据用户ID,文章ID获取用户最新一条阅读记录
+func GetCygxArticleHistoryRecordAllDetailLast(articleId, userId int) (item *CygxArticleHistoryRecordAll, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT * FROM cygx_article_history_record_all WHERE   article_id = ?  AND user_id = ?   AND is_del = 0  AND stop_time > 0  ORDER BY id DESC    LIMIT 1 `
+	err = o.Raw(sql, articleId, userId).QueryRow(&item)
+	return
+}
+
+// 根据用户ID,文章ID获取用户最新一条阅读记录
+func GetCygxArticleHistoryRecordAllDetailLastByMobile(articleId int, mobile string) (item *CygxArticleHistoryRecordAll, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT * FROM cygx_article_history_record_all WHERE   article_id = ?  AND mobile = ?   AND is_del = 0  AND stop_time > 0 ORDER BY id DESC    LIMIT 1 `
+	err = o.Raw(sql, articleId, mobile).QueryRow(&item)
+	return
+}

+ 50 - 49
models/cygx/cygx_user.go

@@ -12,50 +12,51 @@ import (
 )
 
 type CygxCompanyUser struct {
-	UserId                      int64  `orm:"column(user_id);pk"`
-	Mobile                      string `description:"手机号"`
-	Email                       string `description:"邮箱"`
-	CompanyId                   int    `description:"公司id"`
-	CompanyName                 string `description:"公司名称"`
-	RealName                    string `description:"姓名"`
-	CreatedTime                 string `description:"创建时间"`
-	IsMaker                     int    `description:"是否决策人,1:是,0:否"`
-	IsRegister                  bool   `description:"是否注册,true:已注册,false:未注册"`
-	Status                      string `description:"客户状态"`
-	RegisterTime                string `description:"注册时间"`
-	SellerName                  string `description:"销售名称"`
-	InteractionNum              int    `description:"互动量"`
-	CompanyInteractionNum       int    `description:"企业互动量"`
-	CompanyInteractionNumSeller int    `description:"销售可见企业互动量"`
-	Labels                      string `description:"标签,用英文,隔开"`
-	ActivityLabel               string `description:"活动标签,用英文,隔开"`
-	IsShowSee                   bool   `description:"是否展示查看"`
-	IsShowSeeNum                int    `description:"是否展示查看"`
-	HistoryNum                  int    `description:"报告阅读"`
-	CountNum                    int    `description:"报告收藏"`
-	IndustryFllowNum            int    `description:"产业关注"`
-	DepartmentFollowNum         int    `description:"作者关注"`
-	KeyWordNum                  int    `description:"搜索关键词"`
-	OnLineNum                   int    `description:"线上互动活动"`
-	OfficeNum                   int    `description:"线下互动活动"`
-	ChartNum                    int    `description:"图表收藏数量"`
-	TripNum                     int    `description:"图表数量"`
-	RoadshowVideoNum            int    `description:"产业视频播放量"`
-	ActivityVideoNum            int    `description:"活动视频播放量"`
-	ActivityVoiceNum            int    `description:"活动音频播放量"`
-	YanxuanspecialNum           int    `description:"研选专栏查看数量"`
-	RsCalendarNum               int    `description:"1V1 路演数量"`
-	FeedbackNum                 int    `description:"交流反馈数量"`
-	PackageType                 int    `description:"套餐类型,0:无,1:大套餐,2:小套餐"`
-	TryStage                    int    `description:"试用客户子标签:0全部、1未分类、2 推进、3 跟踪、4 预备"`
-	Content                     string `description:"备注信息"`
-	IsRemind                    bool   `description:"是否添加互动提醒"`
-	IsSubscribeCygx             int    `description:"是否关注了查研观向微信公众号: 0-未关注; 1-已关注"`
-	IsSubscribeMfyx             int    `description:"是否关注了买方研选微信公众号: 0-未关注; 1-已关注"`
-	IsUserMaker                 int    `description:"近四周之内是否包含决策人互动过 ,0否,1是"`
-	HaveMoveButton              bool   `description:"是否移动过"`
-	MfyxIsBinding               bool   `description:"买方研选是否绑定"`
-	Position                    string `description:"职位"`
+	UserId                      int64                     `orm:"column(user_id);pk"`
+	Mobile                      string                    `description:"手机号"`
+	Email                       string                    `description:"邮箱"`
+	CompanyId                   int                       `description:"公司id"`
+	CompanyName                 string                    `description:"公司名称"`
+	RealName                    string                    `description:"姓名"`
+	CreatedTime                 string                    `description:"创建时间"`
+	IsMaker                     int                       `description:"是否决策人,1:是,0:否"`
+	IsRegister                  bool                      `description:"是否注册,true:已注册,false:未注册"`
+	Status                      string                    `description:"客户状态"`
+	RegisterTime                string                    `description:"注册时间"`
+	SellerName                  string                    `description:"销售名称"`
+	InteractionNum              int                       `description:"互动量"`
+	CompanyInteractionNum       int                       `description:"企业互动量"`
+	CompanyInteractionNumSeller int                       `description:"销售可见企业互动量"`
+	Labels                      string                    `description:"标签,用英文,隔开"`
+	ActivityLabel               string                    `description:"活动标签,用英文,隔开"`
+	IsShowSee                   bool                      `description:"是否展示查看"`
+	IsShowSeeNum                int                       `description:"是否展示查看"`
+	HistoryNum                  int                       `description:"报告阅读"`
+	CountNum                    int                       `description:"报告收藏"`
+	IndustryFllowNum            int                       `description:"产业关注"`
+	DepartmentFollowNum         int                       `description:"作者关注"`
+	KeyWordNum                  int                       `description:"搜索关键词"`
+	OnLineNum                   int                       `description:"线上互动活动"`
+	OfficeNum                   int                       `description:"线下互动活动"`
+	ChartNum                    int                       `description:"图表收藏数量"`
+	TripNum                     int                       `description:"图表数量"`
+	RoadshowVideoNum            int                       `description:"产业视频播放量"`
+	ActivityVideoNum            int                       `description:"活动视频播放量"`
+	ActivityVoiceNum            int                       `description:"活动音频播放量"`
+	YanxuanspecialNum           int                       `description:"研选专栏查看数量"`
+	RsCalendarNum               int                       `description:"1V1 路演数量"`
+	FeedbackNum                 int                       `description:"交流反馈数量"`
+	PackageType                 int                       `description:"套餐类型,0:无,1:大套餐,2:小套餐"`
+	TryStage                    int                       `description:"试用客户子标签:0全部、1未分类、2 推进、3 跟踪、4 预备"`
+	Content                     string                    `description:"备注信息"`
+	IsRemind                    bool                      `description:"是否添加互动提醒"`
+	IsSubscribeCygx             int                       `description:"是否关注了查研观向微信公众号: 0-未关注; 1-已关注"`
+	IsSubscribeMfyx             int                       `description:"是否关注了买方研选微信公众号: 0-未关注; 1-已关注"`
+	IsUserMaker                 int                       `description:"近四周之内是否包含决策人互动过 ,0否,1是"`
+	HaveMoveButton              bool                      `description:"是否移动过"`
+	MfyxIsBinding               bool                      `description:"买方研选是否绑定"`
+	Position                    string                    `description:"职位"`
+	RaiLabelList                []*WxUserRaiLabelListResp `description:"权益用户标签列表'"`
 }
 
 type CompanyUserListResp struct {
@@ -64,7 +65,7 @@ type CompanyUserListResp struct {
 }
 
 // 获取数量
-func GetCompanyListCount(userCondition, keyWord, kwywordcondition, condition, roleTypeCode string, pars []interface{}) (count int, err error) {
+func GetCompanyListCount(joinTable, userCondition, keyWord, kwywordcondition, condition, roleTypeCode string, pars []interface{}) (count int, err error) {
 	o := orm.NewOrm()
 	companyCondition := `SELECT a.company_id FROM company AS a  INNER JOIN company_product AS b ON a.company_id=b.company_id   WHERE a.enabled=1  `
 	kwywordcondition = companyCondition + kwywordcondition
@@ -78,7 +79,7 @@ func GetCompanyListCount(userCondition, keyWord, kwywordcondition, condition, ro
 			INNER JOIN company AS c ON c.company_id = u.company_id
 			INNER JOIN company_product AS cp ON cp.company_id = c.company_id
 			INNER JOIN admin AS m ON m.admin_id = cp.seller_id 
-			INNER JOIN user_seller_relation AS sr ON sr.user_id = u.user_id 
+			INNER JOIN user_seller_relation AS sr ON sr.user_id = u.user_id ` + joinTable + `
 			 WHERE  u.company_id IN (` + companyCondition + `)`
 	if userCondition != "" {
 		sql += userCondition
@@ -96,14 +97,14 @@ func GetCompanyListCount(userCondition, keyWord, kwywordcondition, condition, ro
 }
 
 // 列表
-func GetCygxCompanyUserList(userCondition, keyWord, kwywordcondition, condition, roleTypeCode, sqlOrder string, pars []interface{}, startSize, pageSize int) (items []*CygxCompanyUser, err error) {
+func GetCygxCompanyUserList(joinTable, tableField, userCondition, keyWord, kwywordcondition, condition, roleTypeCode, sqlOrder string, pars []interface{}, startSize, pageSize int) (items []*CygxCompanyUser, err error) {
 	o := orm.NewOrm()
 	companyCondition := `SELECT a.company_id FROM company AS a  INNER JOIN company_product AS b ON a.company_id=b.company_id   WHERE a.enabled=1  `
 	kwywordcondition = companyCondition + kwywordcondition
 	if condition != "" {
 		companyCondition += condition
 	}
-	sql := `SELECT
+	sql := `SELECT` + tableField + `
 			u.user_id,
 			u.mobile,
 			u.email,
@@ -129,7 +130,7 @@ func GetCygxCompanyUserList(userCondition, keyWord, kwywordcondition, condition,
 			INNER JOIN company AS c ON c.company_id = u.company_id
 			INNER JOIN company_product AS cp ON cp.company_id = c.company_id
 			INNER JOIN admin AS m ON m.admin_id = cp.seller_id 
-			INNER JOIN user_seller_relation AS sr ON sr.user_id = u.user_id 
+			INNER JOIN user_seller_relation AS sr ON sr.user_id = u.user_id ` + joinTable + `
 			 WHERE u.company_id IN (` + companyCondition + `)`
 	if userCondition != "" {
 		sql += userCondition

+ 34 - 0
models/cygx/industrial_article_group_management.go

@@ -208,3 +208,37 @@ func GetSearchResourceList(userId int, condition string, startSize, pageSize int
 	_, err = o.Raw(sql).QueryRows(&items)
 	return
 }
+
+// GetIndustrialManagementGroupArticleMaxPublishDateByHz 获取产业ID关联最新发布文章的发布时间(弘则资源包)
+func GetIndustrialManagementGroupArticleMaxPublishDateByHz(industrialManagementId int) (maxTime string, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := ` SELECT
+			MAX( a.publish_date ) AS max_time 
+		FROM
+			cygx_industrial_article_group_management AS m
+			INNER JOIN cygx_article AS a ON a.article_id = m.article_id 
+		WHERE
+			1 = 1 
+			AND m.industrial_management_id = ? 
+			AND a.publish_status = 1 
+			AND a.article_type_id = 0 `
+	err = o.Raw(sql, industrialManagementId).QueryRow(&maxTime)
+	return
+}
+
+// GetIndustrialManagementGroupArticleMaxPublishDateByYx 获取产业ID关联最新发布文章的发布时间(研选资源包)
+func GetIndustrialManagementGroupArticleMaxPublishDateByYx(industrialManagementId int) (maxTime string, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT
+			MAX( a.publish_date ) AS max_time 
+		FROM
+			cygx_industrial_article_group_management AS m
+			INNER JOIN cygx_article AS a ON a.article_id = m.article_id 
+		WHERE
+			1 = 1 
+			AND m.industrial_management_id = ? 
+			AND a.publish_status = 1  
+			AND a.article_type_id > 0 `
+	err = o.Raw(sql, industrialManagementId).QueryRow(&maxTime)
+	return
+}

+ 32 - 0
models/cygx/report_history_record.go

@@ -0,0 +1,32 @@
+package cygx
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxReportHistoryRecord struct {
+	Id               int `orm:"column(id);pk"`
+	ArticleId        int
+	UserId           int
+	CreateTime       time.Time
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	ModifyTime       time.Time `description:"修改时间"`
+	ReportType       string    `description:"报告类型,bgjx:报告精选、bzyjhz:本周研究汇总、szjyhz:上周纪要汇总"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	StopTime         int       `description:"停留时间"`
+	OutType          int       `description:"退出方式,1正常退出,2强制关闭"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+}
+
+// 根据用户ID,文章ID获取用户最新一条阅读记录
+func GetCygxReportHistoryRecordDetailLast(articleId int, mobile, reportType string) (item *CygxArticleHistoryRecordAll, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT * FROM cygx_report_history_record WHERE   article_id = ?  AND mobile = ?   AND report_type = ?    ORDER BY id DESC    LIMIT 1 `
+	err = o.Raw(sql, articleId, mobile, reportType).QueryRow(&item)
+	return
+}

+ 282 - 0
models/cygx/wx_user_rai_label.go

@@ -0,0 +1,282 @@
+package cygx
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hz_crm_api/utils"
+	"time"
+)
+
+type WxUserRaiLabel struct {
+	RaiLabelId      int       `orm:"column(rai_label_id);pk"`
+	UserId          int       `description:"用户ID"`
+	RealName        string    `description:"用户实际名称"`
+	Mobile          string    `description:"手机号"`
+	Email           string    `description:"邮箱"`
+	CompanyId       int       `description:"公司id"`
+	CompanyName     string    `description:"公司名称"`
+	Label           string    `description:"标签内容"`
+	SourceId        int       `description:"来源ID"`
+	SourceType      int       `description:"来源1:搜索关键字标签、2:产业/个股标签(线下活动)、3:产业/个股标签(线下路演)、4:产业/个股标签(线上活动)、5:产业/个股标签(线上路演)、6:销售输入标签、7:产业/个股标签(报告)、8:报告类型标签"`
+	SysUserId       int       `description:"创建人id"`
+	SysUserRealName string    `description:"创建人名称"`
+	CreateTime      time.Time `description:"创建时间"`
+	ModifyTime      time.Time `description:"更新时间"`
+	TableName       string    `description:"数据来源的表名"`
+}
+
+// 标签记录表,所有内容都不删除
+type WxUserRaiLabelLog struct {
+	RaiLabelId       int       `orm:"column(rai_label_id);pk"`
+	UserId           int       `description:"用户ID"`
+	RealName         string    `description:"用户实际名称"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	Label            string    `description:"标签内容"`
+	SourceId         int       `description:"来源ID"`
+	SourceType       int       `description:"来源1:搜索关键字标签、2:产业/个股标签(线下活动)、3:产业/个股标签(线下路演)、4:产业/个股标签(线上活动)、5:产业/个股标签(线上路演)、6:销售输入标签、7:产业/个股标签(报告)、8:报告类型标签"`
+	SysUserId        int       `description:"创建人id"`
+	SysUserRealName  string    `description:"创建人名称"`
+	CreateTime       time.Time `description:"创建时间"`
+	ModifyTime       time.Time `description:"更新时间"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+	TableName        string    `description:"数据来源的表名"`
+}
+
+type WxUserRaiLabelList struct {
+	List []*WxUserRaiLabelListResp
+}
+
+type WxUserRaiLabelListResp struct {
+	UserId     int    `description:"用户ID"`
+	RaiLabelId int    `description:"ID"`
+	Label      string `description:"标签内容"`
+	SourceType int    `description:"来源1:搜索关键字标签、2:产业/个股标签(线下活动)、3:产业/个股标签(线下路演)、4:产业/个股标签(线上活动)、5:产业/个股标签(线上路演)、6:销售输入标签、7:产业/个股标签(报告)、8:报告类型标签"`
+}
+
+type WxUserRaiLabelAddReq struct {
+	UserId int    `description:"用户ID"`
+	Label  string `description:"标签内容"`
+}
+
+type WxUserRaiLabelIdReq struct {
+	RaiLabelId int `description:"ID"`
+}
+
+// 添加
+//func AddWxUserRaiLabel(item *WxUserRaiLabel) (err error) {
+//	o := orm.NewOrmUsingDB("hz_cygx")
+//	_, err = o.Insert(item)
+//	return
+//}
+
+func AddWxUserRaiLabel(item *WxUserRaiLabel) (err error) {
+	o, err := orm.NewOrmUsingDB("hz_cygx").Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+
+	//删除原有数据
+	sql := ` DELETE FROM wx_user_rai_label WHERE user_id = ? AND label = ?  `
+	_, err = o.Raw(sql, item.UserId, item.Label).Exec()
+	if err != nil {
+		return
+	}
+
+	_, err = o.Insert(item)
+
+	if err != nil {
+		return
+	}
+
+	itemLog := new(WxUserRaiLabelLog)
+	itemLog.UserId = item.UserId
+	itemLog.RealName = item.RealName
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Label = item.Label
+	itemLog.SourceId = item.SourceId
+	itemLog.SourceType = item.SourceType
+	itemLog.SysUserId = item.SysUserId
+	itemLog.SysUserRealName = item.SysUserRealName
+	itemLog.CreateTime = item.CreateTime
+	itemLog.ModifyTime = item.ModifyTime
+	//itemLog.RegisterPlatform = item.RegisterPlatform
+	itemLog.TableName = item.TableName
+	_, err = o.Insert(itemLog)
+	return
+}
+
+// DeleteWxUserRaiLabel 根据主键ID删除数据
+func DeleteWxUserRaiLabel(raiLabelId int) (err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := ` DELETE FROM wx_user_rai_label WHERE rai_label_id = ? `
+	_, err = o.Raw(sql, raiLabelId).Exec()
+	return
+}
+
+// DeleteWxUserRaiLabelWithRoadshow 路演到会删除后,删除对应的标签
+func DeleteWxUserRaiLabelWithRoadshow(userId, sourceId int) (err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := ` DELETE FROM wx_user_rai_label WHERE user_id  = ?  AND source_id =?  AND  source_type IN  (3,5) `
+	_, err = o.Raw(sql, userId, sourceId).Exec()
+	return
+}
+
+// DeleteWxUserRaiLabelWithActivity 线下活动取消到会后,删除对应的标签
+func DeleteWxUserRaiLabelWithActivity(userIds []int, sourceId int) (err error) {
+	lenArr := len(userIds)
+	if lenArr == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := ` DELETE FROM wx_user_rai_label WHERE user_id IN (` + utils.GetOrmInReplace(lenArr) + `)  AND source_id =?  AND  source_type IN  (2,4) `
+	_, err = o.Raw(sql, userIds, sourceId).Exec()
+	return
+}
+
+// GetWxUserRaiLabelListByUserIds 根据多个userId 获取每个UserId最新的十条数据
+func GetWxUserRaiLabelListByUserIds(userIdArr []int) (list []*WxUserRaiLabelListResp, err error) {
+	lenArr := len(userIdArr)
+	if lenArr == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT
+			t.rai_label_id,
+			t.user_id,
+			t.label,
+			t.source_type 
+		FROM
+			(
+			SELECT
+				rai_label_id,
+				user_id,
+				label,
+				source_type,
+				create_time,
+				@row_number :=
+			IF
+				( @prev_user_id = user_id, @row_number + 1, 1 ) AS rank,
+				@prev_user_id := user_id 
+			FROM
+				wx_user_rai_label,
+				( SELECT @row_number := 0, @prev_user_id := NULL ) AS vars 
+			WHERE
+				user_id IN ( ` + utils.GetOrmInReplace(lenArr) + ` ) 
+				AND create_time > ?
+			ORDER BY
+				create_time DESC 
+			) AS t 
+		WHERE
+			t.rank <= 10 
+		ORDER BY
+			t.create_time DESC  `
+	_, err = o.Raw(sql, userIdArr, time.Now().AddDate(0, -4, 0).Format(utils.FormatDate)).QueryRows(&list)
+	return
+}
+
+// GetWxUserRaiLabelListByUserId 根据用户ID,获取最近四个月的数据信息
+func GetWxUserRaiLabelListByUserId(userId int) (list []*WxUserRaiLabelListResp, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT
+			rai_label_id,
+			user_id,
+			label,
+			source_type 
+		FROM
+			wx_user_rai_label
+		WHERE
+			 user_id = ? AND  create_time >= ?
+		ORDER BY
+		    create_time DESC  LIMIT  1000  `
+	_, err = o.Raw(sql, userId, time.Now().AddDate(0, -4, 0).Format(utils.FormatDate)).QueryRows(&list)
+	return
+}
+
+// 通过纪要ID获取详情
+func GetWxUserRaiLabelDetailById(raiLabelId int) (item *WxUserRaiLabel, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT
+			*
+		FROM
+			wx_user_rai_label 
+		WHERE
+			rai_label_id =? `
+	err = o.Raw(sql, raiLabelId).QueryRow(&item)
+	return
+}
+
+type WxUserRaiLabelDetailResp struct {
+	SourceType   int `description:"来源1:搜索关键字标签、2:产业/个股标签(线下活动)、3:产业/个股标签(线下路演)、4:产业/个股标签(线上活动)、5:产业/个股标签(线上路演)、6:销售输入标签、7:产业/个股标签(报告)、8:报告类型标签"`
+	KeyWord      *WxUserRaiLabelKeyWordResp
+	Activity     *WxUserRaiLabelActivityResp
+	RoadShow     *WxUserRaiLabelRoadShowResp
+	Seller       *WxUserRaiLabelSellerResp
+	Article      *WxUserRaiLabelArticleResp
+	ActivityVivo *WxUserRaiLabelActivityVivoResp
+}
+
+type WxUserRaiLabelKeyWordResp struct {
+	Label      string `description:"标签内容"`
+	CreateTime string `description:"创建时间"`
+}
+
+type WxUserRaiLabelActivityResp struct {
+	ActivityName     string `description:"活动名称"`
+	ActivityTypeName string `description:"活动类型名称"`
+	ActivityTime     string `description:"活动时间"`
+	Duration         string `description:"参会时长"`
+	Label            string `description:"标签内容"`
+}
+
+type WxUserRaiLabelActivityVivoResp struct {
+	Title        string `description:"活动名称"`
+	ActivityTime string `description:"活动时间"`
+	Label        string `description:"标签内容"`
+	CreateTime   string `description:"查看时间"`
+}
+
+type WxUserRaiLabelRoadShowResp struct {
+	Theme          string `description:"会议主题"`
+	ResearcherName string `description:"研究员名称"`
+	RoadShowTime   string `description:"开始时间"`
+	Label          string `description:"标签内容"`
+}
+
+type WxUserRaiLabelSellerResp struct {
+	Label           string `description:"标签内容"`
+	SysUserRealName string `description:"创建人名称"`
+	CreateTime      string `description:"创建时间"`
+}
+
+type WxUserRaiLabelArticleResp struct {
+	Title       string `description:"标题"`
+	PublishDate string `description:"发布时间"`
+	CreateTime  string `description:"创建时间"`
+	SourceText  string `description:"阅读来源"`
+	StopTime    string `description:"阅读停留时间"`
+	Label       string `description:"标签内容"`
+}
+
+type WxUserRaiLabelRedis struct {
+	UserId           int       `description:"用户ID"`
+	SourceId         int       `description:"资源ID"`
+	Label            string    `description:"标签内容"`
+	SourceType       int       `description:"来源1:搜索关键字标签、2:产业/个股标签(线下活动)、3:产业/个股标签(线下路演)、4:产业/个股标签(线上活动)、5:产业/个股标签(线上路演)、6:销售输入标签、7:产业/个股标签(报告)、8:报告类型标签"`
+	CreateTime       time.Time `description:"创建时间"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+	TableName        string    `description:"数据来源的表名"`
+}

+ 3 - 0
models/db.go

@@ -389,6 +389,7 @@ func initRoadShow() {
 		new(roadshow.RsCalendarMeetingLabelGroup), //路演参会名单关联的标签表
 		new(roadshow.RsCalendarApiLog),            //上海路演三方接口请求记录日志表
 		new(roadshow.RsReportRecordPermission),    //路演公司权限记录
+		new(roadshow.RsCalendarResearcherQuestion),
 	)
 }
 
@@ -490,6 +491,8 @@ func initCygx() {
 		new(cygx.CygxUserFeedback),
 		new(cygx.CygxReportSelectionThirdName),
 		new(cygx.CygxGushouTimeLine),
+		new(cygx.WxUserRaiLabel),
+		new(cygx.WxUserRaiLabelLog),
 	)
 }
 

+ 15 - 4
models/roadshow/calendar.go

@@ -66,6 +66,7 @@ type RsCalendar struct {
 	EnglishCompany   int    `description:"是否为英文客户: 0-否; 1-是"`
 	SellerId         int    `description:"销售id"`
 	ShareSellerId    int    `description:"共享销售员id"`
+	CompanyStatus    string `description:"客户状态:'试用','永续','冻结','流失','正式','潜在'"`
 }
 
 type RsCalendarResearcher struct {
@@ -90,6 +91,10 @@ type RsCalendarResearcher struct {
 	IsSynced               int       `description:"是否与上海同步 0:未同步 1:已同步"`
 	ResearcherSort         int       `description:"研究员新增排序"`
 	UnionCode              string    `description:"公开会议联合编码"`
+	CompanyIndustry        string    `description:"客户行业"`
+	CompanyClassify        string    `description:"客户分类"`
+	QuestionStatus         int       `description:"问答状态:0-未填写;1-已填写"`
+	QuestionMsgStatus      int       `description:"问答模板消息:0-未发送;1-已发送"`
 }
 
 func GetRsCalendarById(rsCalendarId int) (item *RsCalendar, err error) {
@@ -301,6 +306,10 @@ type CalendarListView struct {
 	SubmitButton           bool   `description:"提交按钮是否展示"`
 	ViewButton             bool   `description:"查看按钮是否展示"`
 	EditButton             bool   `description:"修改按钮是否展示"`
+	CompanyIndustry        string `description:"客户行业"`
+	CompanyClassify        string `description:"客户分类"`
+	QuestionStatus         int    `description:"问答状态:0-未填写;1-已填写"`
+	QuestionMsgStatus      int    `description:"问答模板消息:0-未发送;1-已发送"`
 }
 
 type CalendarListResp struct {
@@ -340,7 +349,8 @@ func GetCalendarList(condition string, pars []interface{}, startSize, pageSize,
 				b.rs_calendar_researcher_id,b.start_date,
 				b.end_date,b.start_time,b.end_time,b.start_week,b.end_week,b.status,b.refuse_reason,b.refuse_time,
                 b.delete_reason,a.sys_user_real_name,a.city,a.province,a.company_name,a.company_id,
-                a.cooperation_name,a.theme,a.activity_category,a.english_company
+                a.cooperation_name,a.theme,a.activity_category,a.english_company,
+                b.company_industry,b.company_classify,b.question_status,b.question_msg_status
 				FROM  rs_calendar AS a
 				INNER JOIN rs_calendar_researcher AS b ON a.rs_calendar_id=b.rs_calendar_id
 				WHERE 1=1
@@ -362,7 +372,8 @@ func GetCalendarList(condition string, pars []interface{}, startSize, pageSize,
 				b.modify_time,b.researcher_id,b.researcher_name,
 				b.rs_calendar_researcher_id,b.start_date,
 				b.end_date,b.start_time,b.end_time,b.start_week,b.end_week,b.status,b.refuse_reason,b.refuse_time,
-                b.delete_reason,a.sys_user_real_name,a.city,a.province,a.company_name,a.company_id,a.cooperation_name,a.theme,a.activity_category,a.english_company
+                b.delete_reason,a.sys_user_real_name,a.city,a.province,a.company_name,a.company_id,a.cooperation_name,a.theme,a.activity_category,a.english_company,
+                b.company_industry,b.company_classify,b.question_status,b.question_msg_status
         FROM  rs_calendar AS a
 		INNER JOIN rs_calendar_researcher AS b ON a.rs_calendar_id=b.rs_calendar_id
 		WHERE 1=1 `
@@ -946,7 +957,7 @@ func GetOverseaCustomCalendarList2(sellerId, researcherId, startDate, endDate, c
 
 	pars := make([]interface{}, 0)
 
-	sql1 := `SELECT b.start_date,b.end_date,b.start_time,b.end_time,a.rs_calendar_id,b.seller_id,b.seller_name,b.researcher_name,b.company_name,b.company_id,d.overseas_status as company_status,b.roadshow_type,a.theme,a.roadshow_platform,a.province as province,a.city as city FROM  rs_calendar AS a
+	sql1 := `SELECT b.start_date,b.end_date,b.start_time,b.end_time,a.rs_calendar_id,b.seller_id,b.seller_name,b.researcher_name,b.company_name,b.company_id,d.overseas_status as company_status,b.roadshow_type,a.theme,a.roadshow_platform,a.province as province,a.city as city ,a.english_company FROM  rs_calendar AS a
     INNER JOIN rs_report_record  AS b ON a.rs_calendar_id=b.rs_calendar_id
          JOIN company_product AS c ON a.company_id=c.company_id AND c.product_id=1
          JOIN company AS d ON c.company_id=d.company_id 
@@ -971,7 +982,7 @@ func GetOverseaCustomCalendarList2(sellerId, researcherId, startDate, endDate, c
 	if researcherId != "" {
 		sql1 += fmt.Sprintf(` AND b.researcher_id in (%s) `, researcherId)
 	}
-	sql2 := fmt.Sprintf(`SELECT bb.start_date,bb.end_date,bb.start_time,bb.end_time,aa.rs_calendar_id,bb.seller_id,bb.seller_name,bb.researcher_name,aa.company_name,aa.company_id,cc.overseas_status as company_status,bb.roadshow_type,aa.theme,aa.roadshow_platform,aa.province as province,aa.city as city FROM  rs_calendar AS aa
+	sql2 := fmt.Sprintf(`SELECT bb.start_date,bb.end_date,bb.start_time,bb.end_time,aa.rs_calendar_id,bb.seller_id,bb.seller_name,bb.researcher_name,aa.company_name,aa.company_id,cc.overseas_status as company_status,bb.roadshow_type,aa.theme,aa.roadshow_platform,aa.province as province,aa.city as city ,aa.english_company FROM  rs_calendar AS aa
     INNER JOIN rs_report_record  AS bb ON aa.rs_calendar_id=bb.rs_calendar_id
     INNER JOIN %s.english_company AS cc ON aa.company_id=cc.company_id
 		where aa.english_company= 1 AND aa.source = 0 AND cc.is_deleted=0  AND bb.rs_calendar_researcher_status=2 AND bb.researcher_id != 0 `, databaseName)

+ 206 - 0
models/roadshow/calendar_researcher_question.go

@@ -0,0 +1,206 @@
+package roadshow
+
+import (
+	"context"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+type RsCalendarResearcherQuestion struct {
+	RsCalendarResearcherQuestionId int       `orm:"column(rs_calendar_researcher_question_id);pk"`
+	RsCalendarId                   int       `description:"路演日历ID"`
+	RsCalendarResearcherId         int       `description:"路演研究员记录ID"`
+	QuestionContent                string    `description:"提问内容"`
+	ReplyContent                   string    `description:"回复内容"`
+	CreateTime                     time.Time `description:"创建时间"`
+	ModifyTime                     time.Time `description:"更新时间"`
+}
+
+type RoadShowQuestionSaveReq struct {
+	RsCalendarId           int                                    `description:"路演ID"`
+	RsCalendarResearcherId int                                    `description:"路演研究员记录ID"`
+	CompanyIndustry        string                                 `description:"客户行业"`
+	CompanyClassify        string                                 `description:"客户分类"`
+	QuestionList           []*RsCalendarResearcherQuestionSaveReq `description:"问答列表"`
+}
+
+type RsCalendarResearcherQuestionSaveReq struct {
+	QuestionContent string `description:"提问内容"`
+	ReplyContent    string `description:"回复内容"`
+}
+
+func RoadShowQuestionSave(req *RoadShowQuestionSaveReq) (err error) {
+	o := orm.NewOrm()
+	tx, err := o.BeginWithCtx(context.Background())
+	if err != nil {
+		return err
+	}
+
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	sql := ` UPDATE rs_calendar_researcher SET company_industry = ?,company_classify = ?,question_status=1 WHERE rs_calendar_researcher_id = ? `
+	_, err = tx.Raw(sql, req.CompanyIndustry, req.CompanyClassify, req.RsCalendarResearcherId).Exec()
+	if err != nil {
+		return err
+	}
+	list := make([]*RsCalendarResearcherQuestion, 0)
+	for _, v := range req.QuestionList {
+		item := new(RsCalendarResearcherQuestion)
+		item.RsCalendarId = req.RsCalendarId
+		item.RsCalendarResearcherId = req.RsCalendarResearcherId
+		item.QuestionContent = v.QuestionContent
+		item.ReplyContent = v.ReplyContent
+		item.ModifyTime = time.Now()
+		item.CreateTime = time.Now()
+		list = append(list, item)
+	}
+	_, err = tx.InsertMulti(len(list), &list)
+	return err
+}
+
+type RsCalendarResearcherQuestionView struct {
+	RsCalendarResearcherQuestionId int    `orm:"column(rs_calendar_researcher_question_id);pk"`
+	RsCalendarId                   int    `description:"路演日历ID"`
+	RsCalendarResearcherId         int    `description:"路演研究员记录ID"`
+	QuestionContent                string `description:"提问内容"`
+	ReplyContent                   string `description:"回复内容"`
+	ResearcherId                   int    `description:"研究员ID"`
+	ResearcherName                 string `description:"研究员名称"`
+	CreateTime                     string `description:"创建时间"`
+	ModifyTime                     string `description:"更新时间"`
+}
+
+func GetRoadShowQuestionList(condition string, pars []interface{}) (item []*RsCalendarResearcherQuestionView, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT a.*,b.researcher_id,b.researcher_name FROM rs_calendar_researcher_question AS a
+         LEFT JOIN rs_calendar_researcher AS b ON a.rs_calendar_researcher_id=b.rs_calendar_researcher_id
+         WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY a.create_time DESC  `
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+type QuestionSummary struct {
+	RsCalendarId           int    `orm:"column(rs_calendar_id);pk"`
+	SysUserId              int    `description:"创建人id"`
+	SysUserRealName        string `description:"创建人名称"`
+	ActivityType           string `description:"活动类型"`
+	RoadshowType           string `description:"路演形式"`
+	RoadshowPlatform       string `description:"路演平台"`
+	CompanyId              int    `description:"客户id"`
+	CompanyName            string `description:"客户名称"`
+	RsCalendarResearcherId int    `description:"活动研究员id"`
+	ResearcherId           string `description:"研究员id"`
+	ResearcherName         string `description:"研究员名称"`
+	StartDate              string `description:"开始日期"`
+	EndDate                string `description:"结束日期"`
+	StartTime              string `description:"开始时间"`
+	EndTime                string `description:"结束时间"`
+	StartWeek              string `description:"开始日期对应周"`
+	EndWeek                string `description:"结束日期对应周"`
+	Status                 int    `description:"状态:1:待接受,2:已接受,3:已拒绝,4:已删除,5:已撤回,6:已结束"`
+	RefuseReason           string `description:"拒绝理由"`
+	RefuseTime             string `description:"拒绝时间"`
+	DeleteReason           string `description:"删除原因"`
+	Province               string `description:"省"`
+	ProvinceCode           string `description:"省编码"`
+	City                   string `description:"市"`
+	CityCode               string `description:"市编码"`
+	District               string `description:"区"`
+	Theme                  string `description:"会议主题"`
+	CooperationName        string `description:"合作方名称"`
+	ActivityCategory       string `description:"活动类别"`
+	Source                 int    `description:"来源,0:自系统,1:上海方的"`
+	Title                  string `description:"日历展示标题"`
+	CompanyStatus          string `description:"新增客户状态"`
+	UnionCode              string `description:"公开会议联合编码"`
+	EnglishCompany         int    `description:"是否为英文客户: 0-否; 1-是"`
+	EnglishCountry         string `description:"英文客户-国家"`
+	EnglishViewTotal       int    `description:"英文客户-累计点击量"`
+	SubmitButton           bool   `description:"提交按钮是否展示"`
+	ViewButton             bool   `description:"查看按钮是否展示"`
+	EditButton             bool   `description:"修改按钮是否展示"`
+	CompanyIndustry        string `description:"客户行业"`
+	CompanyClassify        string `description:"客户分类"`
+	QuestionStatus         int    `description:"问答状态:0-未填写;1-已填写"`
+	QuestionMsgStatus      int    `description:"问答模板消息:0-未发送;1-已发送"`
+}
+
+type QuestionSummaryListResp struct {
+	Paging *paging.PagingItem
+	List   []*QuestionSummary
+}
+
+func GetQuestionSummaryListCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM(SELECT COUNT(1) AS count
+				FROM  rs_calendar AS a
+				INNER JOIN rs_calendar_researcher AS b ON a.rs_calendar_id=b.rs_calendar_id
+				WHERE 1=1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY a.rs_calendar_id ) AS t `
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func GetQuestionSummaryList(condition string, pars []interface{}, startSize, pageSize int) (list []*QuestionSummary, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT a.sys_user_id,a.sys_user_real_name,a.rs_calendar_id,a.activity_type,a.roadshow_type,a.activity_category,a.roadshow_platform,a.english_company,b.create_time,a.district,
+				b.modify_time,GROUP_CONCAT(b.researcher_id ORDER BY researcher_sort ASC) AS researcher_id,GROUP_CONCAT(b.researcher_name ORDER BY researcher_sort ASC) AS researcher_name,
+				b.rs_calendar_researcher_id,b.start_date,
+				b.end_date,b.start_time,b.end_time,b.start_week,b.end_week,b.status,b.refuse_reason,b.refuse_time,
+                b.delete_reason,a.sys_user_real_name,a.city,a.province,a.company_name,a.company_id,
+                a.cooperation_name,a.theme,a.activity_category,a.english_company,
+                b.question_status,b.question_msg_status,
+ 				GROUP_CONCAT(b.company_industry) AS company_industry,
+ 				GROUP_CONCAT(b.company_classify) AS company_classify
+				FROM  rs_calendar AS a
+				INNER JOIN rs_calendar_researcher AS b ON a.rs_calendar_id=b.rs_calendar_id
+				WHERE 1=1
+ `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY a.rs_calendar_id
+				 ORDER BY b.create_time DESC LIMIT ?,? `
+
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+func GetQuestionSummaryExport(condition string, pars []interface{}) (list []*QuestionSummary, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT a.rs_calendar_id,a.activity_type,a.roadshow_type,a.activity_category,a.roadshow_platform,b.create_time,a.district,
+				b.modify_time,GROUP_CONCAT(b.researcher_id ORDER BY researcher_sort ASC) AS researcher_id,GROUP_CONCAT(b.researcher_name ORDER BY researcher_sort ASC) AS researcher_name,
+				b.rs_calendar_researcher_id,b.start_date,
+				b.end_date,b.start_time,b.end_time,b.start_week,b.end_week,b.status,b.refuse_reason,b.refuse_time,
+                b.delete_reason,a.sys_user_real_name,a.city,a.province,a.company_name,a.company_id,
+                a.cooperation_name,a.theme,a.activity_category,a.english_company,
+                b.question_status,b.question_msg_status,
+ 				GROUP_CONCAT(b.company_industry) AS company_industry,
+ 				GROUP_CONCAT(b.company_classify) AS company_classify
+				FROM  rs_calendar AS a
+				INNER JOIN rs_calendar_researcher AS b ON a.rs_calendar_id=b.rs_calendar_id
+				WHERE 1=1
+ `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY a.rs_calendar_id
+				 ORDER BY b.create_time DESC `
+
+	_, err = o.Raw(sql, pars).QueryRows(&list)
+	return
+}

+ 1 - 0
models/roadshow/company.go

@@ -105,4 +105,5 @@ type CompanyDetailView struct {
 	EnglishCompany   int    `description:"是否为英文客户: 0-否; 1-是"`
 	EnglishCountry   string `description:"英文客户-国家"`
 	EnglishViewTotal int    `description:"英文客户-累计点击量"`
+	CompanyType      string `description:"客户类型"`
 }

+ 25 - 1
models/roadshow/report_record.go

@@ -66,6 +66,7 @@ type RsReportRecordNum struct {
 	OfflineNum  int    `description:"线上路演次数"`
 	RoadShowNum int    `description:"路演总次数"`
 	SalonNum    int    `description:"沙龙路演次数"`
+	AskNum      int    `description:"提交过问答的路演次数"`
 	StartDate   string `description:"开始日期"`
 	EndDate     string `description:"结束日期"`
 	IsLook      bool   `description:"是否可以查看详情"`
@@ -145,14 +146,21 @@ type RsReportRecordList struct {
 	Province                   string    `description:"省"`
 	City                       string    `description:"市"`
 	CooperationName            string    `description:"合作方名称"`
+	CompanyIndustry            string    `description:"客户行业"`
+	CompanyClassify            string    `description:"客户分类"`
+	QuestionStatus             int       `description:"问答状态:0-未填写;1-已填写"`
+	QuestionMsgStatus          int       `description:"问答模板消息:0-未发送;1-已发送"`
+	CompanyType                string    `description:"客户类型:FICC/权益"`
+	EnglishCompany             int       `description:"是否为英文客户: 0-否; 1-是"`
 }
 
 // GetRsReportRecordList 获取路演统计详情返回数据
 func GetRsReportRecordList(condition string, pars []interface{}) (list []*RsReportRecordList, err error) {
 	o := orm.NewOrm()
-	sql := ` SELECT a.*,b.theme,b.roadshow_platform,b.province,b.city,b.cooperation_name
+	sql := ` SELECT a.*,b.theme,b.roadshow_platform,b.province,b.city,b.cooperation_name,b.english_company,c.company_industry,c.company_classify,c.question_status,c.question_msg_status
 				FROM  rs_report_record a 
 				join rs_calendar b on a.rs_calendar_id=b.rs_calendar_id
+				inner join rs_calendar_researcher AS c ON a.rs_calendar_id=c.rs_calendar_id AND a.rs_calendar_researcher_id=c.rs_calendar_researcher_id
 				WHERE 1=1 and a.rs_calendar_researcher_status = 2 
  `
 	if condition != "" {
@@ -483,3 +491,19 @@ func UpdateRsReportRecordInteractionNumnMulti(items []*RsReportRecord) (err erro
 	}
 	return
 }
+
+func GetReportResearcherExport(condition string, pars []interface{}) (list []*RsReportRecordList, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT a.*,b.theme,b.roadshow_platform,b.province,b.city,b.cooperation_name,c.company_industry,c.company_classify,c.question_status,c.question_msg_status,b.english_company
+				FROM  rs_report_record a 
+				join rs_calendar b on a.rs_calendar_id=b.rs_calendar_id
+				inner join rs_calendar_researcher AS c ON a.rs_calendar_id=c.rs_calendar_id AND a.rs_calendar_researcher_id=c.rs_calendar_researcher_id
+				WHERE 1=1 and a.rs_calendar_researcher_status = 2 
+ `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` order BY a.start_date DESC,a.start_time DESC`
+	_, err = o.Raw(sql, pars).QueryRows(&list)
+	return
+}

+ 9 - 1
models/roadshow/rs_calendar_meeting_user.go

@@ -85,13 +85,21 @@ func MultiAddRsCalendarMeetingUser(items []*RsCalendarMeetingUser, roadShowTheme
 }
 
 // 获取第一个提交参会信息内容
-func GetRsCalendarMeetingUserFirst(rsCalendarId int) (item *RsCalendarResearcher, err error) {
+func GetRsCalendarMeetingUserFirst(rsCalendarId int) (item *RsCalendarMeetingUser, err error) {
 	o := orm.NewOrm()
 	sql := `SELECT * FROM rs_calendar_meeting_user WHERE rs_calendar_id=? LIMIT 1   `
 	err = o.Raw(sql, rsCalendarId).QueryRow(&item)
 	return
 }
 
+// 获取第一个提交参会信息内容
+func GetRsCalendarMeetingUserByRsCalendarMeetingUserId(rsCalendarMeetingUserId int) (item *RsCalendarMeetingUser, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM rs_calendar_meeting_user WHERE rs_calendar_meeting_user_id =?  `
+	err = o.Raw(sql, rsCalendarMeetingUserId).QueryRow(&item)
+	return
+}
+
 // 删除
 func DeleteRsCalendarMeetingUser(rsCalendarMeetingUserID int) (err error) {
 	o := orm.NewOrm()

+ 20 - 20
models/seal/seal.go

@@ -256,25 +256,25 @@ func GetList(condition string, pars []interface{}, startSize, pageSize int) (lis
 //}
 
 type SealApprovalItem struct {
-	ContractApprovalId       int                     `description:"审批单ID"`
-	ContractId               int                     `description:"合同ID"`
-	ContractApprovalRecordId int                     `description:"审批流ID"`
-	Code                     string                  `description:"合同编号"`
-	Use                      string                  `description:"用印用途,枚举值:'销售合同','渠道合同','付款通知函','招投标','战略合作协议'"`
-	ContractType             string                  `description:"合同类型,枚举值:'新签合同','续约合同','补充协议','代付合同'"`
-	Status                   string                  `description:"合同状态,枚举值:待审批','已审批','已驳回','已撤回','已签回',默认待审批"`
-	ApproveStatus            string                  `json:"-" description:"审批单状态,枚举值:待审批','已审批','已驳回','已撤回',默认待审批"`
-	ApplyContent             string                  `description:"申请内容"`
-	ApplyUserId              int                     `description:"申请人ID"`
-	ApplyUserName            string                  `description:"申请人名称"`
-	ContractDetail           string                  `json:"-" description:"提交审批时的合同信息;用印快照"`
-	ContractInfo             contract.ContractDetail `json:"-" description:"提交审批时的合同信息;用印快照"`
-	ApproveRemark            string                  `description:"审核备注"`
-	SealType                 string                  `description:"用印类型"`
-	CompanyName              string                  `description:"客户名称"`
-	FileUrl                  string                  `description:"合同下载地址"`
-	CurrNodeId               int                     `description:"当前审批节点id"`
-	StartNodeId              int                     `description:"开始审批节点id"`
+	ContractApprovalId       int `description:"审批单ID"`
+	ContractId               int `description:"合同ID"`
+	ContractApprovalRecordId int `description:"审批流ID"`
+	//ContractCode             string                  `description:"合同编号"`
+	Use            string                  `description:"用印用途,枚举值:'销售合同','渠道合同','付款通知函','招投标','战略合作协议'"`
+	ContractType   string                  `description:"合同类型,枚举值:'新签合同','续约合同','补充协议','代付合同'"`
+	Status         string                  `description:"合同状态,枚举值:待审批','已审批','已驳回','已撤回','已签回',默认待审批"`
+	ApproveStatus  string                  `json:"-" description:"审批单状态,枚举值:待审批','已审批','已驳回','已撤回',默认待审批"`
+	ApplyContent   string                  `description:"申请内容"`
+	ApplyUserId    int                     `description:"申请人ID"`
+	ApplyUserName  string                  `description:"申请人名称"`
+	ContractDetail string                  `json:"-" description:"提交审批时的合同信息;用印快照"`
+	ContractInfo   contract.ContractDetail `json:"-" description:"提交审批时的合同信息;用印快照"`
+	ApproveRemark  string                  `description:"审核备注"`
+	SealType       string                  `description:"用印类型"`
+	CompanyName    string                  `description:"客户名称"`
+	FileUrl        string                  `description:"合同下载地址"`
+	CurrNodeId     int                     `description:"当前审批节点id"`
+	StartNodeId    int                     `description:"开始审批节点id"`
 	//UserId                   int                     `description:"申请人id"`
 	//UserName                 string                  `description:"申请人名称"`
 	SealId               int       `description:"用印审批ID"`
@@ -322,7 +322,7 @@ func GetSealApprovalListByWhere(condition, joinCondition string, pars []interfac
 	//git
 	o := orm.NewOrm()
 	fields := `a.contract_approval_id,c.contract_id,a.apply_content,a.approve_remark,a.apply_user_id,a.apply_user_name,a.curr_node_id,a.start_node_id,c.create_time,a.modify_time,a.status approval_status,
-			   c.status,c.seal_id,c.seal_type,c.service_type contract_type,c.use,c.company_name,c.file_url,c.approve_time,c.invalid_time,c.code,c.credit_code,c.check_back_file_time,c.check_back_file_url,c.product_id,c.affiliated_company `
+			   c.status,c.seal_id,c.seal_type,c.service_type contract_type,c.use,c.company_name,c.file_url,c.approve_time,c.invalid_time,c.code,c.credit_code,c.check_back_file_time,c.check_back_file_url,c.affiliated_company `
 	sql := `SELECT ` + fields + ` from contract_approval a JOIN ( SELECT max( contract_approval_id ) max_id,contract_id FROM contract_approval where 1=1 and approval_type = "seal" `
 	sql += ` GROUP BY contract_id ) b on a.contract_approval_id=b.max_id
 	JOIN seal c ON c.seal_id = a.contract_id 

+ 81 - 0
routers/commentsRouter.go

@@ -3328,6 +3328,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/use_rai_label/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"],
+        beego.ControllerComments{
+            Method: "Delte",
+            Router: `/use_rai_label/delte`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/use_rai_label/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:UserRaiLabelController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/use_rai_label/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:YanxuanSpecialController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:YanxuanSpecialController"],
         beego.ControllerComments{
             Method: "ApprovalLogList",
@@ -7774,6 +7810,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "QuestionList",
+            Router: `/question/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "QuestionAdd",
+            Router: `/question/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "CalendarSummaryExport",
+            Router: `/question/summary/export`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "CalendarSummaryList",
+            Router: `/question/summary/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
         beego.ControllerComments{
             Method: "Refuse",
@@ -7819,6 +7891,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "ResearcherReportExport",
+            Router: `/report/researcher/export`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
         beego.ControllerComments{
             Method: "ResearcherReportList",

+ 1 - 0
routers/router.go

@@ -165,6 +165,7 @@ func init() {
 				&cygx.RaiServeCoAntroller{},
 				&cygx.UserFeedbackController{},
 				&cygx.GushouTimeLineController{},
+				&cygx.UserRaiLabelController{},
 			),
 		),
 		web.NSNamespace("/advisory",

+ 4 - 4
services/cygx/acitvity.go

@@ -44,7 +44,7 @@ func AddCygxActivityRestrictSignupByAdmin(activityId int) (err error) {
 	}
 	mobileList, _ := cygx.GetUserMeetingMobile(activityId)
 	var userIdArr []int
-	if len(mobileList) >= 0 {
+	if len(mobileList) > 0 {
 		for _, v := range mobileList {
 			userIdArr = append(userIdArr, v.UserId)
 		}
@@ -56,7 +56,7 @@ func AddCygxActivityRestrictSignupByAdmin(activityId int) (err error) {
 		pars = append(pars, userIdArr)
 		restrictSignupList, e := cygx.GetCygxActivityRestrictSignupList(condition, pars, 0, 9999)
 		if e != nil {
-			err = errors.New("GetCygxActivityRestrictSignupList" + e.Error())
+			err = errors.New("GetCygxActivityRestrictSignupList 1 " + e.Error())
 			return
 		}
 		//获取这些用户是否被加入到限制报名了
@@ -120,7 +120,7 @@ func AddCygxActivityRestrictSignupByAdmin(activityId int) (err error) {
 		item.SellerName = v.SellerName
 		items = append(items, item)
 	}
-	if len(list) == 0 {
+	if len(userIdSiginArr) == 0 {
 		return
 	}
 
@@ -133,7 +133,7 @@ func AddCygxActivityRestrictSignupByAdmin(activityId int) (err error) {
 	pars = append(pars, userIdSiginArr)
 	restrictSignupList, e := cygx.GetCygxActivityRestrictSignupList(condition, pars, 0, 9999)
 	if e != nil {
-		err = errors.New("GetCygxActivityRestrictSignupList" + e.Error())
+		err = errors.New("GetCygxActivityRestrictSignupList 2" + e.Error())
 		return
 	}
 	//获取这些用户是否被加入到限制报名了

+ 21 - 1
services/cygx/activity_meet.go

@@ -100,7 +100,7 @@ func AddCygxActivityMeetDetailLogOffline(meetingUids string, activityId int) (er
 			itemsUpdateCompany = append(itemsUpdateCompany, item)
 		}
 	}
-	fmt.Println(111)
+
 	var itemsUpdateMobile []*cygx.MeetDetailLoggGroupCount
 	lenmobileArr := len(mobileArr)
 	if lenmobileArr > 0 {
@@ -225,6 +225,13 @@ func AddctivitySignupDetailList(itemsDetail []*cygx.CygxActivitySignupDetail, ac
 		}
 	}
 
+	//添加到Redis队列消息中,处理用户标签
+	for _, v := range itemsAdd {
+		if v.UserId > 0 {
+			ActivityWxUserRaiLabelRedisAdd(v.ActivityId, v.UserId, v.CreateTime)
+		}
+	}
+
 	return err
 }
 
@@ -346,6 +353,12 @@ func AddctivitySignupDetailListByHand(itemsDetail []*cygx.CygxActivityAttendance
 		}
 	}
 
+	//添加到Redis队列消息中,处理用户标签
+	for _, v := range itemsAdd {
+		if v.UserId > 0 {
+			ActivityWxUserRaiLabelRedisAdd(v.ActivityId, v.UserId, v.CreateTime)
+		}
+	}
 	return err
 }
 
@@ -435,6 +448,13 @@ func AddctivitySignupDetailListByAdminSignup(activityIdsStr string) (err error)
 			err = errors.New("AddCygxActivitySignupDetail, Err: " + e.Error())
 			return
 		}
+
+		//添加到Redis队列消息中,处理用户标签
+		for _, v := range items {
+			if v.UserId > 0 {
+				ActivityWxUserRaiLabelRedisAdd(v.ActivityId, v.UserId, v.CreateTime)
+			}
+		}
 	}
 
 	return err

+ 234 - 0
services/cygx/activity_poster.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"github.com/go-resty/resty/v2"
 	"hongze/hz_crm_api/models"
 	"hongze/hz_crm_api/models/cygx"
 	"hongze/hz_crm_api/services"
@@ -198,6 +199,7 @@ func MakeActivitySigninImg(activityId int) (imgUrl string, err error) {
 		return
 	}
 
+	fmt.Println("resourceUrl", resourceUrl)
 	detailConfig, e := cygx.GetCygxConfigDetailByCode(Cygx_activity_sigin_html)
 	if e != nil {
 		err = errors.New("GetCygxConfigDetailByCode 获取配置签到码格式信息失败, Err: " + e.Error())
@@ -582,3 +584,235 @@ func MakeActivityMomentsImg(activityId int) {
 //	err = cygx.AddCygxActivityPoster(item)
 //	return
 //}
+
+//func init() {
+//	MakeActivityDetailImg2(2992)
+//}
+
+//func init() {
+//	var condition string
+//	var pars []interface{}
+//
+//	condition = " AND active_state = 1   AND xcx_detail_img = ''   "
+//	list, errList := cygx.GetActivityListAll(condition, pars, 0, 999)
+//	if errList != nil {
+//		fmt.Println(errList)
+//		return
+//	}
+//
+//	for _, v := range list {
+//		MakeActivityDetailImg2(v.ActivityId)
+//	}
+//}
+
+// MakeActivityDetailImg  生成活动详情二维码 生成太阳码并上传OSS 30天有效
+func MakeActivityDetailImg(activityId int) (imgUrl string, err error) {
+	var msg string
+	defer func() {
+		if err != nil || msg != "" {
+			fmt.Println(err)
+			go alarm_msg.SendAlarmMsg("生成活动详情二维码,失败,MakeActivityDetailImg 活动ID:"+strconv.Itoa(activityId)+err.Error()+";msg:"+msg, 3)
+		}
+	}()
+	activityInfo, e := cygx.GetAddActivityInfoById(activityId)
+	if e != nil {
+		err = errors.New("活动不存在, Err: " + e.Error())
+		return
+	}
+	if activityInfo == nil {
+		return
+	}
+	itemToken, err := models.GetWxToken(utils.WxCygxAppId, utils.WxCygxAppSecret)
+	if err != nil {
+		return
+	}
+	if itemToken.AccessToken == "" {
+		msg = "accessToken is empty"
+		return
+	}
+	client := resty.New()
+	resp, err := client.R().
+		SetQueryParam("access_token", itemToken.AccessToken).
+		SetBody(map[string]interface{}{
+			"path":  "activityPages/activityDetail/activityDetail?id=" + strconv.Itoa(activityId),
+			"width": 430,
+		}).
+		Post("https://api.weixin.qq.com/wxa/getwxacode")
+
+	if err != nil {
+		return
+	}
+	if resp.StatusCode() != http.StatusOK {
+		return
+	}
+	fmt.Println(resp.Status())
+	var resourceUrl string
+
+	uploadDir := "static/img/share/"
+	uuid := utils.GetRandStringNoSpecialChar(28)
+	if !utils.FileIsExist(uploadDir) {
+		err = os.MkdirAll(uploadDir, 0755)
+		if err != nil {
+			msg = "生成文件夹失败,Err:" + err.Error()
+			return
+		}
+	}
+	imagePath := uploadDir + uuid + ".jpg"
+	imageContent, e := os.Create(imagePath)
+	if e != nil {
+		err = e
+		msg = "获取微信二维码失败,Err:" + err.Error()
+		return
+	}
+	writeStringRes, e := io.WriteString(imageContent, string(resp.Body()))
+	if e != nil {
+		err = e
+		fmt.Println("writeStringRes", writeStringRes)
+		return
+	}
+	closeErr := imageContent.Close()
+	if closeErr != nil {
+		err = closeErr
+		return
+	}
+	randStr := utils.GetRandStringNoSpecialChar(28)
+	fileName := randStr + ".jpg"
+	savePath := uploadDir + time.Now().Format("200601/20060102/")
+	savePath += fileName
+	//上传到阿里云
+	err = services.UploadFileToAliyun(fileName, imagePath, savePath)
+	if err != nil {
+		fmt.Println("文件上传失败,Err:" + err.Error())
+		return
+	}
+	fileHost := "https://hzstatic.hzinsights.com/"
+	resourceUrl = fileHost + savePath
+	defer func() {
+		os.Remove(imagePath)
+	}()
+	fmt.Println(resourceUrl)
+	return
+}
+
+// MakeActivityDetailImg2  生成活动详情二维码 生成太阳码并上传OSS 永久有效
+func MakeActivityDetailImg2(activityId int) (imgUrl string, err error) {
+	var msg string
+	defer func() {
+		if err != nil || msg != "" {
+			fmt.Println(err)
+			go alarm_msg.SendAlarmMsg("生成活动详情二维码,失败,活动ID:"+strconv.Itoa(activityId)+err.Error()+";msg:"+msg, 3)
+		}
+	}()
+	activityInfo, e := cygx.GetAddActivityInfoById(activityId)
+	if e != nil {
+		err = errors.New("活动不存在, Err: " + e.Error())
+		return
+	}
+	if activityInfo == nil {
+		return
+	}
+
+	itemToken, err := models.GetWxToken(utils.WxCygxAppId, utils.WxCygxAppSecret)
+	if err != nil {
+		return
+	}
+	if itemToken.AccessToken == "" {
+		msg = "accessToken is empty"
+		return
+	}
+	var envVersion string
+	var resourceUrl string
+	if utils.RunMode == "release" {
+		envVersion = "release"
+	} else {
+		envVersion = "trial"
+	}
+	url := "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + itemToken.AccessToken
+	method := "POST"
+	payload := strings.NewReader(`{
+		"page":"activityPages/activityDetail/activityDetail",
+		"scene":"` + strconv.Itoa(activityId) + `",
+		"env_version":"` + envVersion + `",
+		"check_path":false,
+		"auto_color":true
+				}`)
+	client := &http.Client{}
+	req, err := http.NewRequest(method, url, payload)
+	if err != nil {
+		msg = "获取微信二维码失败,Err:" + err.Error()
+		return
+	}
+	req.Header.Add("Content-Type", "application/json")
+	postBody, err := client.Do(req)
+	if err != nil {
+		msg = "获取微信二维码失败,Err:" + err.Error()
+		return
+	}
+	defer postBody.Body.Close()
+	uploadDir := "static/img/share/"
+	uuid := utils.GetRandStringNoSpecialChar(28)
+	if !utils.FileIsExist(uploadDir) {
+		err = os.MkdirAll(uploadDir, 0755)
+		if err != nil {
+			msg = "生成文件夹失败,Err:" + err.Error()
+			return
+		}
+	}
+	imagePath := uploadDir + uuid + ".jpg"
+	switch header := postBody.Header.Get("Content-Type"); {
+	case strings.HasPrefix(header, "application/json"):
+		tokenResp := ReturnBodyRule{}
+		decoder := json.NewDecoder(postBody.Body)
+		if decodeErr := decoder.Decode(&tokenResp); decodeErr != nil {
+			msg = "获取微信二维码失败,Err:" + decodeErr.Error()
+			return
+		}
+	case strings.HasPrefix(header, "image"):
+		reply, e := ioutil.ReadAll(postBody.Body)
+		if e != nil {
+			err = e
+			msg = "获取微信二维码失败,Err:" + err.Error()
+			return
+		}
+		imageContent, e := os.Create(imagePath)
+		if e != nil {
+			err = e
+			msg = "获取微信二维码失败,Err:" + err.Error()
+			return
+		}
+		writeStringRes, e := io.WriteString(imageContent, string(reply))
+		if e != nil {
+			err = e
+			fmt.Println(writeStringRes)
+			return
+		}
+		closeErr := imageContent.Close()
+		if closeErr != nil {
+			err = closeErr
+			return
+		}
+		randStr := utils.GetRandStringNoSpecialChar(28)
+		fileName := randStr + ".jpg"
+		savePath := uploadDir + time.Now().Format("200601/20060102/")
+		savePath += fileName
+		//上传到阿里云
+		err = services.UploadFileToAliyun(fileName, imagePath, savePath)
+		if err != nil {
+			fmt.Println("文件上传失败,Err:" + err.Error())
+			return
+		}
+		fileHost := "https://hzstatic.hzinsights.com/"
+		resourceUrl = fileHost + savePath
+		defer func() {
+			os.Remove(imagePath)
+		}()
+	default:
+		msg = "生成二维码失败"
+		return
+	}
+
+	err = cygx.UpdateCygxActivityXcxDetailImg(resourceUrl, activityId)
+	fmt.Println("resourceUrl", resourceUrl)
+
+	return
+}

+ 12 - 75
services/cygx/activity_special.go

@@ -629,20 +629,22 @@ func ActivitySpecialCompanyApproval(companyId, companyContractId int, companyNam
 			mapRaiSubjectivity[v.ChartPermissionId] = true
 			mapPermissionName[v.ChartPermissionId] = v.ChartPermissionName
 		}
+		var points int
 		for _, v := range list {
 			//如果是升级则加点
 			if v.IsUpgrade == 1 && mapRaiSubjectivity[v.ChartPermissionId] {
-				item := new(cygx.CygxActivitySpecialPermissionPoints)
-				item.Points = 5
-				item.CompanyId = companyId
-				item.CompanyName = companyName
-				item.ChartPermissionId = v.ChartPermissionId
-				item.ChartPermissionName = mapPermissionName[v.ChartPermissionId]
-				item.CreateTime = time.Now()
-				item.ModifyTime = time.Now()
-				items = append(items, item)
+				points += 4
 			}
 		}
+		item := new(cygx.CygxActivitySpecialPermissionPoints)
+		item.Points = points
+		item.CompanyId = companyId
+		item.CompanyName = companyName
+		item.ChartPermissionId = 0
+		item.ChartPermissionName = ""
+		item.CreateTime = time.Now()
+		item.ModifyTime = time.Now()
+		items = append(items, item)
 		itemBill.Content = "行业升级套餐转正"
 	}
 
@@ -668,7 +670,7 @@ func ActivitySpecialCompanyApproval(companyId, companyContractId int, companyNam
 			itemBillTotal = append(itemBillTotal, fmt.Sprint(v.ChartPermissionName, v.Points, "次"))
 			itemBillTotalMap[v.ChartPermissionName] = fmt.Sprint(v.ChartPermissionName, v.Points, "次")
 		}
-		itemBill.BillDetailed = 5 * len(items)
+		itemBill.BillDetailed = 4 * len(items)
 		permissionNameSlice := []string{"医药", "消费", "科技", "智造"}
 		var itemBillTotalNew []string
 		for _, v := range permissionNameSlice {
@@ -971,68 +973,3 @@ func HandleActivitySpecialTripBillTotalText(companyId int) (totalText string, er
 	}
 	return
 }
-
-func initnee885() {
-	list, err := cygx.GetBestNewBillList()
-	if err != nil {
-		fmt.Println(err)
-	}
-	var items []*cygx.CygxActivitySpecialPermissionPoints
-	for _, v := range list {
-		fmt.Println(v.Total)
-		if v.Total == "" || v.Total == "0" || v.Total == "0次" {
-			continue
-		}
-		//智造5次+科技5次+消费5次+医药4次
-		sliceTotal := strings.Split(v.Total, "+")
-
-		for _, vs := range sliceTotal {
-			var points string
-			item := new(cygx.CygxActivitySpecialPermissionPoints)
-			if strings.Contains(vs, "医药") {
-				item.ChartPermissionName = "医药"
-				points := strings.Replace(vs, "医药", "", -1)
-				fmt.Println(points)
-				points = strings.Replace(points, "次", "", -1)
-				item.Points, _ = strconv.Atoi(points)
-				item.ChartPermissionId = 22
-			} else if strings.Contains(vs, "消费") {
-				item.ChartPermissionName = "消费"
-				points := strings.Replace(vs, "消费", "", -1)
-				points = strings.Replace(points, "次", "", -1)
-				item.ChartPermissionId = 21
-				item.Points, _ = strconv.Atoi(points)
-			} else if strings.Contains(vs, "科技") {
-				item.ChartPermissionName = "科技"
-				points := strings.Replace(vs, "科技", "", -1)
-				points = strings.Replace(points, "次", "", -1)
-				item.ChartPermissionId = 20
-				item.Points, _ = strconv.Atoi(points)
-			} else if strings.Contains(vs, "智造") {
-				item.ChartPermissionName = "智造"
-				points := strings.Replace(vs, "智造", "", -1)
-				points = strings.Replace(points, "次", "", -1)
-				item.ChartPermissionId = 19
-				item.Points, _ = strconv.Atoi(points)
-			} else {
-				points = strings.Replace(vs, "次", "", -1)
-				item.Points, _ = strconv.Atoi(points)
-			}
-			fmt.Println("points", points)
-			fmt.Println(vs)
-
-			item.CompanyId = v.CompanyId
-			item.CompanyName = v.CompanyName
-			item.CreateTime = time.Now()
-			item.ModifyTime = time.Now()
-			fmt.Println(item)
-			items = append(items, item)
-		}
-
-	}
-
-	fmt.Println(len(items))
-	err = cygx.MultiAddCygxActivitySpecialPermissionPoints(items)
-	fmt.Println(err)
-
-}

+ 110 - 2
services/cygx/resource_data.go

@@ -7,6 +7,7 @@ import (
 	"hongze/hz_crm_api/services/alarm_msg"
 	"hongze/hz_crm_api/utils"
 	"strconv"
+	"strings"
 	"time"
 )
 
@@ -181,7 +182,7 @@ func UpdateActivitySpecialResourceData(sourceId int) {
 	var pars []interface{}
 	condition = ` AND publish_status = 1  AND  activity_id = ?  `
 	pars = append(pars, sourceId)
-	total, e := cygx.GetActivityCount(condition, pars)
+	total, e := cygx.GetActivitySpecilCount(condition, pars)
 	if e != nil {
 		err = errors.New("GetCygxReportSelection, Err: " + e.Error())
 		return
@@ -229,7 +230,6 @@ func UpdateActivitySpecialResourceData(sourceId int) {
 		} else {
 			item.SearchOrderTime = activityInfo.PublishDate
 		}
-
 		if totalData == 0 {
 			newId, e := cygx.AddCygxResourceData(item)
 			if e != nil {
@@ -1290,6 +1290,114 @@ func UpdateAskserieVideoResourceData(sourceId int) {
 	return
 }
 
+//func init() {
+//	UpdateIndustrialsourceHzResourceData(731, "HZ")
+//}
+
+func UpdateIndustrialsourceHzResourceDataById(industrialManagementIds []string, sourceType string) {
+	for _, v := range industrialManagementIds {
+		if v == "" {
+			continue
+		}
+		industrialManagementId, _ := strconv.Atoi(v)
+		if industrialManagementId < 1 {
+			continue
+		}
+		UpdateIndustrialsourceHzResourceData(industrialManagementId, sourceType)
+	}
+
+}
+
+// 更新产业资源包  写入首页最新  cygx_resource_data 表
+func UpdateIndustrialsourceHzResourceData(sourceId int, sourceType string) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go alarm_msg.SendAlarmMsg(fmt.Sprint("UpdateIndustrialsourceHzResourceData 失败: ", sourceId, err.Error()), 2)
+		}
+	}()
+	var source string
+	var e error
+	var maxData string
+	if sourceType == "Hz" {
+		maxData, e = cygx.GetIndustrialManagementGroupArticleMaxPublishDateByHz(sourceId)
+		if e != nil {
+			err = errors.New("GetIndustrialManagementGroupArticleMaxPublishDateByHz, Err: " + e.Error())
+			return
+		}
+		source = "industrialsourceHz"
+	} else {
+		maxData, e = cygx.GetIndustrialManagementGroupArticleMaxPublishDateByYx(sourceId)
+		if e != nil {
+			err = errors.New("GetIndustrialManagementGroupArticleMaxPublishDateByYx, Err: " + e.Error())
+			return
+		}
+		source = "industrialsourceYx"
+	}
+
+	if maxData == "" {
+		e = cygx.DeleteResourceData(sourceId, source)
+		if e != nil {
+			err = errors.New("DeleteResourceData, Err: " + e.Error())
+			return
+		}
+		return
+	}
+
+	industrialItem, e := cygx.GetIndustrialManagementInfo(sourceId)
+	if e != nil {
+		err = errors.New("GetIndustrialManagementInfo, Err: " + e.Error())
+		return
+	}
+
+	var subjectNames []string
+	listSub, e := cygx.GetcygxIndustrialSubject(sourceId)
+	if e != nil {
+		err = errors.New("GetcygxIndustrialSubject, Err: " + e.Error())
+		return
+	}
+	for _, v := range listSub {
+		subjectNames = append(subjectNames, v.SubjectName)
+	}
+
+	//判断是否存在,如果不存在就新增,存在就更新
+	totalData, e := cygx.GetCygxResourceDataBySourceAndIdCount(sourceId, source)
+	if e != nil {
+		err = errors.New("GetCygxResourceDataBySourceAndIdCount, Err: " + e.Error())
+		return
+	}
+
+	item := new(cygx.CygxResourceData)
+	item.SourceId = sourceId
+	item.Source = source
+	item.PublishDate = maxData
+	item.CreateTime = time.Now()
+	if len(subjectNames) == 0 {
+		item.SearchTitle = industrialItem.IndustryName
+	} else {
+		item.SearchTitle = industrialItem.IndustryName + "," + strings.Join(subjectNames, ",")
+	}
+	item.SearchContent = ""
+	item.SearchOrderTime = maxData
+	//fmt.Println(item)
+	//return
+	if totalData == 0 {
+		_, e := cygx.AddCygxResourceData(item)
+		if e != nil {
+			err = errors.New("AddCygxResourceData, Err: " + e.Error())
+			return
+		}
+	} else {
+		e = cygx.UpdateResourceDataByItem(item)
+		if e != nil {
+			err = errors.New("UpdateResourceDataByItem, Err: " + e.Error())
+			return
+		}
+	}
+	return
+}
+
 func init300() {
 	//var condition string
 	//var pars []interface{}

+ 92 - 0
services/cygx/user_rai_label.go

@@ -0,0 +1,92 @@
+package cygx
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hz_crm_api/models/cygx"
+	"hongze/hz_crm_api/services/alarm_msg"
+	"hongze/hz_crm_api/utils"
+	"time"
+)
+
+// GetUserLabelByUserIdArr 根据多个userId 获取每个UserId最新的十条数据
+func GetUserLabelByUserIdArr(userIdArr []int) (mapRsp map[int][]*cygx.WxUserRaiLabelListResp) {
+	if len(userIdArr) == 0 {
+		return
+	}
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go alarm_msg.SendAlarmMsg(fmt.Sprint("根据多个userId 获取每个UserId最新的十条数据失败:"+err.Error(), "userIdArr", userIdArr), 2)
+		}
+	}()
+	labelList, e := cygx.GetWxUserRaiLabelListByUserIds(userIdArr)
+	if e != nil {
+		err = errors.New("GetWxUserRaiLabelListByUserIds, Err: " + e.Error())
+		return
+	}
+	mapRsp = make(map[int][]*cygx.WxUserRaiLabelListResp)
+	for _, v := range labelList {
+		mapRsp[v.UserId] = append(mapRsp[v.UserId], v)
+	}
+	return
+}
+
+// DeleteActivityWxUserRaiLabel 点了到会,又点了取消的人,对应的活动标签给取消掉
+func DeleteActivityWxUserRaiLabel(userIdArr []int, activityId int) {
+	if len(userIdArr) == 0 {
+		return
+	}
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go alarm_msg.SendAlarmMsg(fmt.Sprint("点了到会,又点了取消的人,对应的活动标签给取消掉失败, DeleteActivityWxUserRaiLabel Err:"+err.Error(), "userIdArr", userIdArr), 2)
+		}
+	}()
+	e := cygx.DeleteWxUserRaiLabelWithActivity(userIdArr, activityId)
+	if e != nil {
+		err = errors.New("DeleteWxUserRaiLabelWithActivity, Err: " + e.Error())
+		return
+	}
+	return
+}
+
+// 添加用户参加活动标签到Redis
+func ActivityWxUserRaiLabelRedisAdd(sourceId, uid int, createTime time.Time) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			msg := fmt.Sprint("sourceId:", sourceId, "userId:", uid)
+			go alarm_msg.SendAlarmMsg("添加用户参加活动标签,写入Redis队列消息失败:"+err.Error()+msg, 2)
+		}
+	}()
+	log := &cygx.WxUserRaiLabelRedis{UserId: uid, SourceId: sourceId, SourceType: 2, CreateTime: createTime}
+	if utils.Re == nil {
+		err := utils.Rc.LPush(utils.WX_USER_RAI_LABEL_KEY, log)
+		if err != nil {
+			fmt.Println("ActivityWxUserRaiLabelRedisAdd LPush Err:" + err.Error())
+		}
+	}
+	return
+}
+
+// 添加用户参加路演标签到Redis
+func RoadShowWxUserRaiLabelRedisAdd(sourceId, uid int, createTime time.Time) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			msg := fmt.Sprint("sourceId:", sourceId, "userId:", uid)
+			go alarm_msg.SendAlarmMsg("添加用户参加路演标签,写入Redis队列消息失败:"+err.Error()+msg, 2)
+		}
+	}()
+	log := &cygx.WxUserRaiLabelRedis{UserId: uid, SourceId: sourceId, SourceType: 3, CreateTime: createTime}
+	if utils.Re == nil {
+		err := utils.Rc.LPush(utils.WX_USER_RAI_LABEL_KEY, log)
+		if err != nil {
+			fmt.Println("RoadShowWxUserRaiLabelRedisAdd LPush Err:" + err.Error())
+		}
+	}
+	return
+}

+ 1 - 1
services/elastic/es_comprehensive.go

@@ -578,7 +578,7 @@ func AddComprehensiveIndustrialSource(sourceType string, articleId int) {
 		item.SubjectNames = strings.Join(mapActivitySubject[v.IndustrialManagementId], ",")
 		item.PublishDate = v.PublishDate + " 00:00:00"
 		EsAddOrEditComprehensiveData(item)
-		UpdateComprehensiveIndustrialResourceData(item)
+		//UpdateComprehensiveIndustrialResourceData(item)
 	}
 }
 

+ 58 - 0
services/roadshow/report.go

@@ -137,6 +137,41 @@ func GetMonthData(adminType, dimensionType string) (adminDataMapList []AdminData
 	return
 }
 
+// GetQuarterData 季度数据
+func GetQuarterData(adminType, dimensionType string) (adminDataMapList []AdminDataMap, firstDate time.Time, err error) { //三个协程返回
+	nowQuarterFirstDay := utils.GetNowQuarterFirstDay()                            //本季度第一天
+	nowQuarterLastDay := nowQuarterFirstDay.AddDate(0, 3, 0).Add(-1 * time.Second) //本季度最后一天
+
+	lastQuarterFirstDay1 := nowQuarterFirstDay.AddDate(0, -3, 0)                       //上个季度第一天
+	lastQuarterLastDay1 := lastQuarterFirstDay1.AddDate(0, 1, 0).Add(-1 * time.Second) //上个季度最后一天
+
+	lastQuarterFirstDay2 := nowQuarterFirstDay.AddDate(0, -6, 0)                       //上上个季度第一天
+	lastQuarterLastDay2 := lastQuarterFirstDay2.AddDate(0, 1, 0).Add(-1 * time.Second) //上上个季度最后一天
+
+	ch1 := make(chan AdminDataMap, 0)
+	ch2 := make(chan AdminDataMap, 0)
+	ch3 := make(chan AdminDataMap, 0)
+
+	go getSectionData(nowQuarterFirstDay, nowQuarterLastDay, adminType, dimensionType, ch1)
+	go getSectionData(lastQuarterFirstDay1, lastQuarterLastDay1, adminType, dimensionType, ch2)
+	go getSectionData(lastQuarterFirstDay2, lastQuarterLastDay2, adminType, dimensionType, ch3)
+
+	var nowMonthAdminDataMap, lastMonthAdminDataMap1, lastMonthAdminDataMap2 AdminDataMap
+
+	nowMonthAdminDataMap = <-ch1
+	close(ch1)
+
+	lastMonthAdminDataMap1 = <-ch2
+	close(ch2)
+
+	lastMonthAdminDataMap2 = <-ch3
+	close(ch3)
+
+	adminDataMapList = make([]AdminDataMap, 0)
+	adminDataMapList = append(adminDataMapList, nowMonthAdminDataMap, lastMonthAdminDataMap1, lastMonthAdminDataMap2)
+	return
+}
+
 // GetMonthDataV2 月度数据
 func GetMonthDataV2(adminType, dimensionType string, dataNum int) (adminDataMapList []AdminDataMap, firstDate time.Time, err error) { //三个协程返回
 	nowMonthFirstDay := utils.GetNowMonthFirstDay() //本月第一天
@@ -197,6 +232,7 @@ type AdminDataMap struct {
 	OfflineMap  map[int]int `description:"线上路演次数"`
 	RoadShowMap map[int]int `description:"路演总次数"`
 	SalonMap    map[int]int `description:"沙龙路演次数"`
+	AskMap      map[int]int `description:"沙龙路演次数"`
 	StartDate   string      `description:"开始日期"`
 	EndDate     string      `description:"开始日期"`
 }
@@ -223,6 +259,7 @@ func getResearcherSectionData(startDate, endDate time.Time) (adminDataMap AdminD
 	meetingMap := make(map[int]int)
 	roadShowMap := make(map[int]int) // 路演总次数
 	salonMap := make(map[int]int)    //沙龙路演次数
+	askMap := make(map[int]int)      //填写过客户问答的路演次数
 	//正式客户
 	{
 		var condition string
@@ -237,6 +274,16 @@ func getResearcherSectionData(startDate, endDate time.Time) (adminDataMap AdminD
 		for _, v := range data {
 			formalMap[v.AdminId] = v.Num
 		}
+
+		condition += ` and  question_status = 1  `
+		dataAsk, tmpErr := roadshow.GetGroupResearcherRecordList(condition, pars)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		for _, v := range dataAsk {
+			askMap[v.AdminId] = v.Num
+		}
 	}
 
 	//试用客户
@@ -255,6 +302,16 @@ func getResearcherSectionData(startDate, endDate time.Time) (adminDataMap AdminD
 			//fmt.Println(v)
 			tryOutMap[v.AdminId] = v.Num
 		}
+
+		condition += ` and  question_status = 1  `
+		dataAsk, tmpErr := roadshow.GetGroupResearcherRecordList(condition, pars)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		for _, v := range dataAsk {
+			askMap[v.AdminId] = v.Num
+		}
 	}
 
 	//试用客户
@@ -314,6 +371,7 @@ func getResearcherSectionData(startDate, endDate time.Time) (adminDataMap AdminD
 		MeetingMap:  meetingMap,
 		RoadShowMap: roadShowMap,
 		SalonMap:    salonMap,
+		AskMap:      askMap,
 		StartDate:   startDate.Format(utils.FormatDate),
 		EndDate:     endDate.Format(utils.FormatDate),
 	}

+ 2 - 30
services/seal/seal.go

@@ -123,7 +123,6 @@ func ApplySeal(sysUser *system.Admin, req request.SealApprovalApplyReq) (err err
 	}()
 
 	// 添加用印
-	//sealInfo, err := addSeal(sysUser.AdminId, req.ContractId, req.FileNum, req.CompanyId, sysUser.RealName, req.Use, req.CompanyName, req.UseCompanyName, req.CreditCode, req.ServiceType, req.SealType, req.Remark, req.FileUrls, req.AffiliatedCompany, req.StartDate, req.EndDate)
 	sealInfo, err := addSeal(sysUser.AdminId, req.ContractId, req.FileNum, req.CompanyId, sysUser.RealName, req.Use, req.CompanyName, req.UseCompanyName, req.CreditCode, req.ServiceType, req.SealType, req.Remark, req.FileUrls, req.AffiliatedCompany, req.StartDate, req.EndDate)
 	if err != nil {
 		return
@@ -150,27 +149,8 @@ func addSeal(userId, contractId, fileNum, companyId int, userName, use, companyN
 		err = errors.New("业务类型异常")
 		return
 	}
-	adminAll, err := system.GetAdminList()
-	if err != nil {
-		return
-	}
-	//adminMap := make(map[int]*system.AdminView)
-	mapRaiSllerId := make(map[int]bool) // 是否为权益销售
-	for _, v := range adminAll {
-		//adminMap[v.AdminId] = v
-		if v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
-			mapRaiSllerId[v.AdminId] = true
-		}
-	}
 
-	var sealCode string
-	var productId int
-	if mapRaiSllerId[userId] {
-		sealCode, err = seal.GetSealCodeRai()
-		productId = utils.COMPANY_PRODUCT_RAI_ID
-	} else {
-		sealCode, err = seal.GetSealCode()
-	}
+	sealCode, err := seal.GetSealCode()
 	if err != nil {
 		return
 	}
@@ -199,12 +179,7 @@ func addSeal(userId, contractId, fileNum, companyId int, userName, use, companyN
 		ModifyTime:        now,
 		CreateTime:        now,
 		AffiliatedCompany: affiliatedCompany,
-		ProductId:         productId,
-		CompanyId:         companyId,
-		StartDate:         startDate,
-		EndDate:           endDate,
 	}
-
 	err = seal.AddSeal(sealInfo)
 	if err != nil {
 		return
@@ -696,6 +671,7 @@ func GetSealApprovalPageList(condition, joinCondition string, pars []interface{}
 					}*/
 				}
 			}
+
 			// 合同编码
 
 			//if selfContract, has := selfContractMap[item.ContractId]; has {
@@ -708,10 +684,6 @@ func GetSealApprovalPageList(condition, joinCondition string, pars []interface{}
 
 			if selfContract, has := selfContractMap[item.ContractId]; has {
 				list[i].ContractCode = selfContract.ContractCode
-			} else {
-				if item.ProductId == utils.COMPANY_PRODUCT_RAI_ID {
-					list[i].ContractCode = item.Code
-				}
 			}
 
 			// 取出item对应approval_id的审批流

+ 9 - 0
utils/constants.go

@@ -425,6 +425,7 @@ const (
 	CHART_PERMISSION_ID_45W                        = 2002     // 权益45w大套餐表示的权限ID(自定义)
 	HONG_GUAN_NAME                          string = "宏观"
 	CYGX_ARTICLE_TIME_LINE_KEY                     = "CYGX_ARTICLE_TIME_LINE_KEY" //产业时间线关联的文章key
+	WX_USER_RAI_LABEL_KEY                          = "CYGX_WX_USER_RAI_LABEL_KEY" //用户列表标签key
 )
 
 // 权益cygx_config配置主键以后放这里
@@ -595,6 +596,14 @@ func GetWeeklyDatabase() (databaseName string) {
 	}
 	return
 }
+func GetCygxDatabase() (databaseName string) {
+	if RunMode == "release" {
+		databaseName = `hz_cygx`
+	} else {
+		databaseName = `test_hz_cygx`
+	}
+	return
+}
 
 const (
 	EnCompanyIdStep = 10000000