xingzai 1 anno fa
commit
e6cf6aadd7
100 ha cambiato i file con 22233 aggiunte e 0 eliminazioni
  1. 11 0
      .gitignore
  2. 37 0
      README.md
  3. 2613 0
      controllers/activity.go
  4. 489 0
      controllers/activity_sign.go
  5. 1259 0
      controllers/article.go
  6. 182 0
      controllers/banner.go
  7. 141 0
      controllers/base_auth.go
  8. 137 0
      controllers/base_auth_mobile.go
  9. 124 0
      controllers/base_common.go
  10. 177 0
      controllers/collection.go
  11. 331 0
      controllers/config.go
  12. 524 0
      controllers/home.go
  13. 842 0
      controllers/research.go
  14. 95 0
      controllers/resource.go
  15. 584 0
      controllers/search.go
  16. 128 0
      controllers/tag.go
  17. 1935 0
      controllers/user.go
  18. 609 0
      controllers/wechat.go
  19. 1295 0
      controllers/yanxuan_special.go
  20. 57 0
      main.go
  21. 28 0
      models/about_us_video_history.go
  22. 1295 0
      models/activity.go
  23. 237 0
      models/activity_appointment.go
  24. 203 0
      models/activity_attendance_detail.go
  25. 22 0
      models/activity_fastsearch_keywords.go
  26. 78 0
      models/activity_help_ask.go
  27. 202 0
      models/activity_meeting_reminder.go
  28. 41 0
      models/activity_mirror_word.go
  29. 91 0
      models/activity_offline_meeting_detail.go
  30. 179 0
      models/activity_points_bill.go
  31. 42 0
      models/activity_points_company.go
  32. 90 0
      models/activity_points_set.go
  33. 40 0
      models/activity_restrict_signup.go
  34. 25 0
      models/activity_seaarch_history.go
  35. 142 0
      models/activity_signin.go
  36. 677 0
      models/activity_signup.go
  37. 66 0
      models/activity_signup_break.go
  38. 203 0
      models/activity_signup_detail.go
  39. 75 0
      models/activity_special.go
  40. 35 0
      models/activity_special_meeting_detail.go
  41. 158 0
      models/activity_special_signup.go
  42. 195 0
      models/activity_special_trip.go
  43. 189 0
      models/activity_special_trip_bill.go
  44. 82 0
      models/activity_type.go
  45. 78 0
      models/activity_user_search_content.go
  46. 178 0
      models/activity_video.go
  47. 73 0
      models/activity_video_history.go
  48. 154 0
      models/activity_voice.go
  49. 65 0
      models/activity_voice_history.go
  50. 113 0
      models/admin.go
  51. 32 0
      models/advice.go
  52. 77 0
      models/apply_collection.go
  53. 99 0
      models/apply_record.go
  54. 959 0
      models/article.go
  55. 33 0
      models/article_and_yanxuan_record.go
  56. 39 0
      models/article_apply_appointment_expert.go
  57. 30 0
      models/article_ask.go
  58. 27 0
      models/article_author.go
  59. 106 0
      models/article_category_mapping.go
  60. 29 0
      models/article_celue_push.go
  61. 266 0
      models/article_collect.go
  62. 86 0
      models/article_comment.go
  63. 28 0
      models/article_data.go
  64. 299 0
      models/article_department.go
  65. 80 0
      models/article_department_follow.go
  66. 153 0
      models/article_history_record.go
  67. 49 0
      models/article_history_record_all.go
  68. 351 0
      models/article_history_record_newpv.go
  69. 80 0
      models/article_interview_apply.go
  70. 85 0
      models/article_top_history_record.go
  71. 70 0
      models/article_type.go
  72. 24 0
      models/article_view_record.go
  73. 49 0
      models/askserie_video_collect.go
  74. 36 0
      models/askserie_video_collection.go
  75. 50 0
      models/askserie_video_history_record.go
  76. 91 0
      models/banner.go
  77. 29 0
      models/banner_history.go
  78. 74 0
      models/banner_yx_survey.go
  79. 31 0
      models/base.go
  80. 154 0
      models/chart_permission.go
  81. 276 0
      models/company.go
  82. 33 0
      models/company/company_approval.go
  83. 26 0
      models/company/company_contract.go
  84. 174 0
      models/company_activity_trip.go
  85. 76 0
      models/company_interaction_num.go
  86. 24 0
      models/company_product.go
  87. 46 0
      models/company_report_permission.go
  88. 23 0
      models/company_user_type.go
  89. 113 0
      models/config.go
  90. 322 0
      models/crm_company.go
  91. 45 0
      models/cygx_activity_special_points_company.go
  92. 43 0
      models/cygx_industry_top.go
  93. 96 0
      models/cygx_morning_meeting_gather.go
  94. 74 0
      models/cygx_morning_meeting_review_chapter.go
  95. 125 0
      models/cygx_morning_meeting_reviews.go
  96. 138 0
      models/cygx_tag.go
  97. 29 0
      models/cygx_tag_history.go
  98. 36 0
      models/cygx_user_record.go
  99. 358 0
      models/cygx_yanxuan_special.go
  100. 34 0
      models/cygx_yanxuan_special_approval_log.go

+ 11 - 0
.gitignore

@@ -0,0 +1,11 @@
+/*.exe
+/rdlucklog
+/binlog
+/.idea
+/conf
+/lastupdate.tmp
+/*.zip
+/riot-index
+/hongze_mfyx
+/static
+/README.md

+ 37 - 0
README.md

@@ -0,0 +1,37 @@
+# hongze_mfyx
+
+#### 介绍
+买方研选->小程序端
+
+#### 软件架构
+软件架构说明
+
+
+#### 安装教程
+
+1.  xxxx
+2.  xxxx
+3.  xxxx
+
+#### 使用说明
+
+1.  xxxx
+2.  xxxx
+3.  xxxx
+
+#### 参与贡献
+
+1.  Fork 本仓库
+2.  新建 Feat_xxx 分支
+3.  提交代码
+4.  新建 Pull Request
+
+
+#### 特技
+
+1.  使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
+2.  Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
+3.  你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
+4.  [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
+5.  Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
+6.  Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

+ 2613 - 0
controllers/activity.go

@@ -0,0 +1,2613 @@
+package controllers
+
+import (
+	"encoding/json"
+	"fmt"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/medivhzhan/weapp/v2"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// 活动
+type ActivityCoAntroller struct {
+	BaseAuthController
+}
+
+type ActivityABaseController struct {
+	BaseCommonController
+}
+
+type ActivityNoLoginController struct {
+	BaseAuthMobileController
+}
+
+// @Title 活动类型列表
+// @Description活动类型列表接口
+// @Param   IsResearch   query   bool  true       "是否为研选"
+// @Success 200 {object} models.ActivityTypeListResp
+// @router /activityTypelist [get]
+func (this *ActivityCoAntroller) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	resp := new(models.ActivityTypeListResp)
+	isResearch, _ := this.GetBool("IsResearch", false)
+	var condition string
+
+	//是否仅展示研选下的活动类型
+	if isResearch {
+		condition = " AND source_type IN (0,2) "
+	}
+	list, err := models.GetActivityTypeList(condition)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 我的日程
+// @Description 我的日程列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   Source   query   int  false     "来源 0:手机 ,1:Pc 默认0"
+// @Success 200 {object} models.GetCygxActivityListRep
+// @router /scheduleList [get]
+func (this *ActivityCoAntroller) ScheduleList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+	uid := user.UserId
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	source, _ := this.GetInt("Source")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+	var condition string
+	var conditionCount string
+	var pars []interface{}
+	condition += ` AND art.publish_status = 1    `
+	if source == 1 {
+		condition += ` AND art.yidong_activity_id = '' `
+		conditionCount += ` AND art.yidong_activity_id = '' `
+	}
+	total, err := models.GetScheduleCount(conditionCount, uid)
+	specialtotal, err := models.GetSpecialScheduleCount(uid)
+	page := paging.GetPaging(currentIndex, pageSize, total+specialtotal)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	conditionCount = ` 	AND art.active_state = 2 `
+	totalCount, err := models.GetScheduleCount(conditionCount, uid) //获取正在进行中的活动数量
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	var list []*models.ActivityDetail
+	//全部都是进行中的活动
+	if totalCount > currentIndex*pageSize {
+		condition += ` AND art.active_state IN(2) `
+		if source == 1 {
+			condition += ` AND art.yidong_activity_id = '' `
+		}
+		listHave, errList := models.GetScheduleList(condition, pars, uid, startSize, pageSize)
+		list = listHave
+		if errList != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + errList.Error()
+			return
+		}
+	} else if totalCount > currentIndex-1*pageSize && totalCount < currentIndex*pageSize { //部分是进行中的活动
+		condition = `  AND art.publish_status = 1 AND art.active_state IN(2) `
+		if source == 1 {
+			condition += ` AND art.yidong_activity_id = '' `
+		}
+		listHave, errList := models.GetScheduleList(condition, pars, uid, startSize, pageSize)
+		list = listHave
+		if errList != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + errList.Error()
+			return
+		}
+		pageSize = pageSize - len(listHave)
+		condition = ` AND art.publish_status = 1 AND art.active_state IN(1,3) `
+		if source == 1 {
+			condition += ` AND art.yidong_activity_id = '' `
+		}
+		//listOther, errList := models.GetScheduleList(condition, pars, uid, startSize, pageSize)
+		listOther, errList := services.GetScheduleAndSpecilList(user, condition, startSize, pageSize)
+		if errList != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + errList.Error()
+			return
+		}
+		if len(listOther) > 0 {
+			for _, v := range listOther {
+				list = append(list, v)
+			}
+		}
+	} else {
+		condition += ` AND art.active_state IN(1,3)` //全部都不是进行中的活动
+		//listOther, errList := models.GetScheduleList(condition, pars, uid, startSize, pageSize)
+		listOther, errList := services.GetScheduleAndSpecilList(user, condition, startSize, pageSize)
+		list = listOther
+		if errList != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + errList.Error()
+			return
+		}
+	}
+	var isShow bool
+	isShow = services.GetShowSustainable()
+	detail, err := models.GetConfigByCode("city_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "城市配置信息失败,Err:" + err.Error()
+		return
+	}
+	detailChart, err := models.GetConfigByCode("chart_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "行业配置信息失败,Err:" + err.Error()
+		return
+	}
+
+	addressList := strings.Split(detail.ConfigValue, "{|}")
+	mapAddress := make(map[string]string)
+	chartList := strings.Split(detailChart.ConfigValue, "{|}")
+	mapChart := make(map[string]string)
+	var cityName string
+	var chartName string
+	var imgUrl string
+	var imgUrlChart string
+	var mapActivityId []int
+	for _, v := range addressList {
+		vslice := strings.Split(v, "_")
+		cityName = vslice[0]
+		imgUrl = vslice[len(vslice)-1]
+		mapAddress[cityName] = imgUrl
+	}
+	for _, v := range chartList {
+		vslice := strings.Split(v, "_")
+		chartName = vslice[0]
+		imgUrlChart = vslice[len(vslice)-1]
+		mapChart[chartName] = imgUrlChart
+	}
+
+	for k, v := range list {
+		if strings.Contains(v.ActivityName, "【") {
+			list[k].IsBrackets = 1
+		}
+		if v.SignupNum > v.LimitPeopleNum {
+			list[k].SignupNum = v.LimitPeopleNum
+		}
+		//是否展示限免标签
+		if isShow && strings.Contains(v.ChartPermissionName, "研选") {
+			list[k].IsShowSustainable = true
+		}
+		if strings.Contains(v.ChartPermissionName, "研选") && v.ActivityTypeId == 1 {
+			//list[k].ActivityTypeName = "买方研选电话会"
+			list[k].ImgUrlText = utils.YAN_XUAN_IMG
+		}
+		if v.ActivityType == 0 {
+			if mapAddress[v.City] != "" {
+				list[k].ImgUrl = mapAddress[v.City]
+			} else {
+				list[k].ImgUrl = mapAddress["其它"]
+			}
+		} else {
+			if mapChart[v.ChartPermissionName] != "" {
+				list[k].ImgUrl = mapChart[v.ChartPermissionName]
+			}
+		}
+		expertTxt, _ := services.GetReportContentTextSub(v.Expert)
+		list[k].Expert = expertTxt
+		if v.IsHideAppointment == 0 {
+			list[k].IsShowAppointment = services.IsShowAppointment(v.ActivityTypeId, v.ChartPermissionName)
+		}
+		if v.ActivityTypeId == utils.C_CLASS_ACTIVITY_TYPE_ID {
+			list[k].IsCClassMeeting = true
+		}
+		mapActivityId = append(mapActivityId, v.ActivityId)
+	}
+
+	//添加我的日程访问记录
+	//item := new(models.CygxPageHistoryRecord)
+	//item.UserId = user.UserId
+	//item.CreateTime = time.Now()
+	//item.Mobile = user.Mobile
+	//item.Email = user.Email
+	//item.CompanyId = user.CompanyId
+	//item.CompanyName = user.CompanyName
+	//item.PageType = "MySchedule"
+	//go models.AddCygxPageHistoryRecord(item)
+	resp := new(models.GetCygxActivityListRep)
+
+	//处理音频回放
+	mapActivityVoice, err := services.GetActivityVoiceResp(mapActivityId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetActivityVoiceResp,Err:" + err.Error()
+		return
+	}
+
+	//处理视频回放
+	mapActivityVideo, err := services.GetActivityVideoResp(mapActivityId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetActivityVideoResp,Err:" + err.Error()
+		return
+	}
+
+	//处理不同的报名方式按钮回显
+	mapActivitySignup, err := services.GetActivitySignupResp(mapActivityId, user)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetActivitySignupResp,Err:" + err.Error()
+		return
+	}
+	for k, v := range list {
+		if mapActivityVoice[v.ActivityId] != nil {
+			list[k].FileType = 1
+			list[k].AudioLink = true
+			list[k].VoiceList = mapActivityVoice[v.ActivityId]
+		}
+		if mapActivityVideo[v.ActivityId] != nil {
+			list[k].FileType = 2
+			list[k].AudioLink = true
+			list[k].VideoDetail = mapActivityVideo[v.ActivityId]
+		}
+		v.SignupType = mapActivitySignup[v.ActivityId]
+		//处理列表的标签是否展示逻辑
+		resp.List = append(resp.List, services.ActivityButtonShow(v))
+	}
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title  活动详情
+// @Description 获取活动详情接口
+// @Param   ActivityId   query   int  true       "活动ID"
+// @Param   IsSendWx   query   int  false       "是否是通过微信模版进来的 1是,其它否"
+// @Success Ret=200 {object} models.CygxActivityResp
+// @router /detail [get]
+func (this *ActivityCoAntroller) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	activityId, _ := this.GetInt("ActivityId")
+	isSendWx, _ := this.GetInt("IsSendWx")
+	if activityId < 1 {
+		br.Msg = "请输入活动ID"
+		return
+	}
+	resp := new(models.CygxActivityResp)
+	activityInfo, err := models.GetAddActivityInfoByIdShow(uid, activityId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取活动详情信息失败,Err:" + err.Error()
+		return
+	}
+	if activityInfo == nil {
+		br.Msg = "活动不存在"
+		br.ErrMsg = "活动ID错误,Err:" + "activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+
+	signupCount, err := models.GetActivitySignupSuccessByUserCountNoHz(activityId)
+	if err != nil {
+		br.Msg = "获取信息"
+		br.ErrMsg = "GetActivitySignupSuccessByUserCountNoHz,Err:" + err.Error()
+		return
+	}
+	activityInfo.SignupNum = signupCount
+
+	havePower, isResearchSpecial, err := services.GetActivityDetailUserPower(user, activityInfo)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "校验用户权限失败,Err:" + err.Error()
+		return
+	}
+	resp.IsResearchSpecial = isResearchSpecial
+	if havePower {
+		//是否展示限免标签
+		if services.GetShowSustainable() && strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+			activityInfo.IsShowSustainable = true
+		}
+		resp.HasPermission = 1
+		configCode := "description_of_research"
+		detail, err := models.GetConfigByCode(configCode)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
+			return
+		}
+		activityInfo.Description = detail.ConfigValue
+		if activityInfo.SignupNum > activityInfo.LimitPeopleNum {
+			activityInfo.SignupNum = activityInfo.LimitPeopleNum
+		}
+		if activityInfo.ChartPermissionNames != "" {
+			activityInfo.ChartPermissionName = activityInfo.ChartPermissionNames
+		}
+		if activityInfo.IsHideAppointment == 0 {
+			activityInfo.IsShowAppointment = services.IsShowAppointment(activityInfo.ActivityTypeId, activityInfo.ChartPermissionName)
+		}
+		activityInfo.ActivityTypeName = strings.Replace(activityInfo.ActivityTypeName, "(C类)", "", -1)
+
+		//处理活动关联的产业
+		industrialList, err := models.GetIndustrialActivityGroupManagementList(activityId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取活动关联的产业列表信息失败,Err:" + err.Error() + "activityId:" + strconv.Itoa(activityId)
+			return
+		}
+		if activityInfo.TemporaryLabel != "" {
+			industrialList = make([]*models.IndustrialManagementRep, 0)
+			item := new(models.IndustrialManagementRep)
+			item.IndustryName = activityInfo.Label
+			industrialList = append(industrialList, item)
+		} else {
+			industryIds := make([]int, 0)
+			var industrialManagementId string
+			for k, v := range industrialList {
+				if v.ChartPermissionId == utils.CHART_PERMISSION_ID_YANXUAN {
+					industrialList[k].IsResearch = true
+				}
+				industryIds = append(industryIds, v.IndustrialManagementId)
+				industrialManagementId += strconv.Itoa(v.IndustrialManagementId) + ","
+			}
+
+			// 查研观向7.4-行业新标签
+			industryNewMap, e := services.GetIndustryNewLabelMap(industryIds)
+			if e != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取产业新标签失败, Err: " + e.Error()
+				return
+			}
+
+			//判断产业下是否有关联的报告,并处理是否跳转
+			industrialManagementId = strings.TrimRight(industrialManagementId, ",")
+			if industrialManagementId != "" {
+				var condition string
+				condition = ` AND m.industrial_management_id IN (` + industrialManagementId + `)`
+				condition += ` AND a.article_id < ` + strconv.Itoa(utils.SummaryArticleId)
+				listIndustrialGrop, err := models.GetSearchResourceList(user.UserId, condition, 0, 0)
+				if err != nil && err.Error() != utils.ErrNoRow() {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "GetSearchResourceList,Err:" + err.Error() + "activityId:" + strconv.Itoa(activityId)
+					return
+				}
+				mapIndustrial := make(map[int]int)
+				if len(listIndustrialGrop) > 0 {
+					for _, v := range listIndustrialGrop {
+						mapIndustrial[v.IndustrialManagementId] = v.IndustrialManagementId
+					}
+				}
+				for k, v := range industrialList {
+					if mapIndustrial[v.IndustrialManagementId] > 0 && !industrialList[k].IsResearch {
+						industrialList[k].IsJump = true
+					}
+					//非买方研选下的才展示New标签
+					if activityInfo.ChartPermissionId != utils.CHART_PERMISSION_ID_YANXUAN {
+						industrialList[k].IndustryNewLabel = industryNewMap[v.IndustrialManagementId]
+					}
+				}
+			}
+		}
+		activityInfo.Listndustrial = industrialList
+		if activityInfo.YidongActivityId != "" {
+			ydTgc, _ := services.GetYiDongCreateUserInfo(user)
+			yidongLongLink, err := services.GetYiDongOriginalLink(activityInfo)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "GetYiDongOriginalLink,Err:" + err.Error() + "activityId:" + strconv.Itoa(activityId)
+				return
+			}
+			//yidongKwy := activityInfo.YidongActivityUrl
+			//activityInfo.YidongActivityUrl = yidongLongLink + "?source=11&fromHz=true&tgc=" + ydTgc
+			activityInfo.YidongActivityUrl = yidongLongLink + "%26source=11%26fromHz=true%26tgc=" + ydTgc
+		}
+		//处理音频回放
+		var mapActivityId []int
+		mapActivityId = append(mapActivityId, activityId)
+		mapActivityVoice, err := services.GetActivityVoiceResp(mapActivityId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "GetActivityVoiceResp,Err:" + err.Error() + "activityId:" + strconv.Itoa(activityId)
+			return
+		}
+		if mapActivityVoice[activityId] != nil {
+			activityInfo.FileType = 1
+			activityInfo.AudioLink = true
+			activityInfo.VoiceList = mapActivityVoice[activityId]
+		}
+
+		//处理视频回放
+		mapActivityVideo, err := services.GetActivityVideoResp(mapActivityId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "GetActivityVideoResp,Err:" + err.Error()
+			return
+		}
+		if mapActivityVideo[activityId] != nil {
+			activityInfo.FileType = 2
+			activityInfo.AudioLink = true
+			activityInfo.VideoDetail = mapActivityVideo[activityId]
+		}
+		//8.5 小程序活动详情页 除专家电话外 其余属于新产业的活动 ,不显示 new 标签
+		if activityInfo.ActivityTypeName != "专家电话会" {
+			for _, rep := range activityInfo.Listndustrial {
+				rep.IndustryNewLabel = false
+			}
+		}
+		//8.5 买方研选的活动去掉限免标签
+		if strings.Contains(activityInfo.ChartPermissionName, "研选") {
+			activityInfo.IsShowSustainable = false
+		}
+		//处理不同的报名方式按钮回显
+		mapActivitySignup, err := services.GetActivitySignupResp(mapActivityId, user)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "GetActivitySignupResp,Err:" + err.Error()
+			return
+		}
+		activityInfo.SignupType = mapActivitySignup[activityId]
+		//处理活动关联的产业
+		industrialListNew, err := models.GetIndustrialActivityGroupManagementList(activityId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取活动关联的产业列表信息失败,Err:" + err.Error() + "activityId:" + strconv.Itoa(activityId)
+			return
+		}
+		//判断是不是通过微信模版推送消息进来的
+		if isSendWx == 1 && len(industrialListNew) > 0 {
+			industryUserFollowMap, err := services.GetIndustryUserFollowMap(user)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "GetActivitySignupResp,Err:" + err.Error()
+				return
+			}
+			for _, v := range industrialListNew {
+				if industryUserFollowMap[v.IndustrialManagementId] {
+					activityInfo.IsFollowButton = true
+				}
+			}
+			activityInfo.IsShowFollowButton = true
+		}
+		if activityInfo.ReportLink != "" {
+			artList, err := services.GetActivityReportLinkToArticleList(activityInfo)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "解析文章关联的报告内容失败:" + activityInfo.ReportLink
+				return
+			}
+			activityInfo.ArticleList = artList
+		} else {
+			activityInfo.ArticleList = make([]*models.ActivityArticleResp, 0)
+		}
+		if services.GetBelongingRai(user.Mobile) && activityInfo.SigninImg != "" {
+			activityInfo.IsShowSigninButton = true
+			activityInfo.IsShowSignUpDetail = true
+		}
+		//处理按钮是否展示问题
+		resp.Detail = services.ActivityButtonShow(activityInfo)
+	} else {
+		//用户未登录(绑定登录信息)的时候也能展示 v12.2.1
+		if user.UserId == 0 {
+			resp.HasPermission = 1
+			resp.Detail = services.ActivityButtonShow(activityInfo)
+		} else {
+			hasPermission, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionActivity(user, activityInfo)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+				return
+			}
+			resp.PopupMsg = popupMsg
+			resp.HasPermission = hasPermission
+			resp.SellerName = sellerName
+			resp.SellerMobile = sellerMobile
+		}
+
+	}
+
+	collectCount1, err := models.GetActivityVoiceCollectCount(uid, activityId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已收藏失败,Err:" + strconv.Itoa(uid) + ";activityId" + strconv.Itoa(activityId)
+		return
+	}
+	collectCount2, err := models.GetActivityVideoCollectCountByActivityId(uid, activityId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已收藏失败,Err:" + strconv.Itoa(uid) + ";activityId" + strconv.Itoa(activityId)
+		return
+	}
+	if collectCount1+collectCount2 > 0 {
+		resp.Detail.IsCollect = true
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 活动报名
+// @Description 活动报名接口
+// @Param	request	body models.ActivitySingnupRep true "type json string"
+// @Success Ret=200 {object} models.SignupStatus
+// @router /signup/add [post]
+func (this *ActivityCoAntroller) SignupAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	signupStatus := ""
+	var req models.ActivitySingnupRep
+	resp := new(models.SignupStatus)
+	//var total int
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if user.Mobile == "" {
+		user.Mobile = user.OutboundMobile
+	}
+	activityId := req.ActivityId
+	signupType := req.SignupType
+	hasPermission := 0
+	if signupType == 1 && user.Mobile == "" && user.OutboundMobile == "" {
+		resp.GoBindEmail = true
+	}
+
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+	detailActivityType, err := models.GetActivityTypeDetailById(activityInfo.ActivityTypeId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,GetActivityTypeDetailById Err:" + err.Error()
+		return
+	}
+	// 如果是 易董办会 且没有勾选 可提供外呼 默认为自主入会
+	if activityInfo.IsYidongConduct && activityInfo.IsCanOutboundCall == 0 {
+		signupType = 4
+	}
+	//SignupStatus "报名状态:人数已满:FullStarffed、单机构超过两人:TwoPeople、爽约次数过多:BreakPromise、超时:Overtime 、成功:Success"`
+	//HasPermission "1:有该行业权限,正常展示,2:无该行业权限,3:潜在客户,未提交过申请,4:潜在客户,已提交过申请"`
+
+	var userType int
+	userType, _, err = services.GetUserType(user.CompanyId)
+	if err != nil {
+		br.Msg = "获取信息失败!"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if userType == 1 && strings.Contains(activityInfo.ChartPermissionName, "研选") {
+		br.Msg = "您暂无查看该活动权限"
+		br.ErrMsg = "被分享客户不可见,永续客户无法查看研选行业"
+		return
+	}
+	item := new(models.CygxActivitySignup)
+
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+
+	havePower, isResearchSpecial, err := services.GetActivityDetailUserPower(user, activityInfo)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "校验用户权限失败,Err:" + err.Error()
+		return
+	}
+	resp.IsResearchSpecial = isResearchSpecial
+	if havePower {
+		hasPermission = 1
+		signupStatus = "Success"
+		resp.HasPermission = hasPermission
+		resultTime := utils.StrTimeToTime(activityInfo.ActivityTime) //时间字符串格式转时间格式
+		if time.Now().After(resultTime.Add(-time.Minute * 60)) {
+			signupStatus = "Overtime"
+			resp.SignupType = signupType
+			resp.SignupStatus = signupStatus
+			resp.HasPermission = hasPermission
+			resp.PopupMsg = "活动开始前1小时内无法预约,请联系对口销售处理"
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
+
+		var sellerName string
+		sellerName, err = models.GetCompanySellerName(user.CompanyId)
+		if err != nil {
+			br.Msg = "报名失败!"
+			br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
+			return
+		}
+
+		popupMsg, err := services.CheckActivityUserAll(activityInfo, user)
+		if err != nil {
+			br.Msg = "报名失败!"
+			br.ErrMsg = "CheckActivityUserAll,Err:" + err.Error()
+			return
+		}
+		if popupMsg != "" {
+			br.Msg = popupMsg
+			br.ErrMsg = fmt.Sprint("userId:", uid, "Activity:id", popupMsg)
+			return
+		}
+		//人数已满:FullStarffed、单机构超过两人:TwoPeople、爽约次数过多:BreakPromise、超时:Overtime 、成功:Success"`
+		//如果是下面几种情况则对报名信息做判断限制 (公司调研电话会(限制人数)、公司线下调研、专家/分析师线下沙龙)
+		//if (activityInfo.ActivityTypeId == 3 && activityInfo.IsLimitPeople == 1) || activityInfo.ActivityTypeId > 3 {
+		if activityInfo.IsLimitPeople == 1 {
+			signupStatus, resp.PopupMsg, item.FailType, err = services.CheckActivitySignUpLimit(user, activityInfo)
+			//判断优先级:总人数限制→单机构2人限制→爽约3次限制
+			totalRestrict, err := models.GetUserRestrictCount(user.Mobile)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+				return
+			}
+
+			totalUserRestrictCount, err := models.GetActivitySignupByUserRestrictCount(uid, activityId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+			//解除报名限制之后二次报名相同活动
+			if totalUserRestrictCount > 0 && totalRestrict == 0 && resp.GoBindEmail != true {
+				item.UserId = uid
+				item.RealName = user.RealName
+				item.SellerName = sellerName
+				item.ActivityId = activityId
+				item.CreateTime = time.Now()
+				item.Mobile = user.Mobile
+				item.Email = user.Email
+				item.CompanyId = user.CompanyId
+				item.CompanyName = user.CompanyName
+				item.SignupType = signupType
+				item.FailType = 0
+				item.DoFailType = 0
+				_, errSignup := models.AddActivitySignupByRestrict(item)
+				if errSignup != nil {
+					br.Msg = "操作失败"
+					br.ErrMsg = "操作失败,Err:" + errSignup.Error()
+					return
+				}
+				resp.HaqveJurisdiction = true
+				resp.SignupType = signupType
+				resp.SignupStatus = "Success"
+				resp.HasPermission = hasPermission
+				resp.ActivityId = activityId
+				//total, err = models.GetUserMeetingReminderCount(user.UserId)
+				//if err != nil {
+				//	br.Msg = "获取信息失败"
+				//	br.ErrMsg = "获取日程数量信息失败,Err:" + err.Error()
+				//	return
+				//}
+				//if total == 0 {
+				//	resp.GoFollow = true
+				//}
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "操作成功"
+				br.Data = resp
+				return
+			}
+			totalMy, err := models.GetActivitySignupByUserCount(uid, activityId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+
+			if signupStatus != "Success" && totalMy == 0 && resp.GoBindEmail != true {
+				item.UserId = uid
+				item.RealName = user.RealName
+				item.SellerName = sellerName
+				item.ActivityId = activityId
+				item.CreateTime = time.Now()
+				item.Mobile = user.Mobile
+				item.Email = user.Email
+				item.CompanyId = user.CompanyId
+				item.CompanyName = user.CompanyName
+				item.SignupType = signupType
+				item.DoFailType = item.FailType
+				if user.OutboundMobile != "" {
+					item.OutboundMobile = user.OutboundMobile
+					if user.OutboundCountryCode == "" {
+						item.CountryCode = "86"
+					} else {
+						item.CountryCode = user.OutboundCountryCode
+					}
+				} else {
+					item.OutboundMobile = user.Mobile
+					if user.CountryCode == "" {
+						item.CountryCode = "86"
+					} else {
+						item.CountryCode = user.CountryCode
+					}
+				}
+				//添加报名信息,但是不加入日程
+				_, errSignup := models.AddActivitySignupNoSchedule(item)
+				if errSignup != nil {
+					br.Msg = "操作失败"
+					br.ErrMsg = "操作失败,Err:" + errSignup.Error()
+					return
+				}
+			}
+		}
+		totalMySuccess, err := models.GetActivitySignupCount(uid, activityId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		if totalMySuccess > 0 {
+			br.Msg = "您已报名这个活动"
+			return
+		}
+		if signupStatus == "Success" && resp.GoBindEmail != true {
+			item.UserId = uid
+			item.RealName = user.RealName
+			item.SellerName = sellerName
+			item.ActivityId = activityId
+			item.CreateTime = time.Now()
+			item.Mobile = user.Mobile
+			item.Email = user.Email
+			item.CompanyId = user.CompanyId
+			item.CompanyName = user.CompanyName
+			item.SignupType = signupType
+			item.FailType = 0
+			item.DoFailType = 0
+			item.OutboundMobile = user.Mobile
+			if user.OutboundMobile != "" {
+				item.OutboundMobile = user.OutboundMobile
+				if user.OutboundCountryCode == "" {
+					item.CountryCode = "86"
+				} else {
+					item.CountryCode = user.OutboundCountryCode
+				}
+			} else {
+				item.OutboundMobile = user.Mobile
+				if user.CountryCode == "" {
+					item.CountryCode = "86"
+				} else {
+					item.CountryCode = user.CountryCode
+				}
+			}
+			_, errSignup := models.AddActivitySignup(item)
+			if errSignup != nil {
+				br.Msg = "操作失败"
+				br.ErrMsg = "操作失败,Err:" + errSignup.Error()
+				return
+			}
+			resp.HaqveJurisdiction = true
+			//1:预约外呼 、2:设置会议提醒 、 3:预约纪要 、4:活动报名
+			if signupType == 1 {
+				go services.ActivityUserRemind(user, activityInfo, 1)
+				//resp.PopupMsg = "<b>预约成功,已加入您的活动日程</b><br/><br/>想要及时获取活动信息变更通知,请关注【查研观向小助手】公众号"
+				resp.PopupMsg = "<b>预约成功,已加入您的活动日程</b><br/><br/>是否将活动日程加入您的系统日历,\n\n活动开始前获取手机日历提醒?"
+			} else if signupType == 4 {
+				go services.ActivityUserRemind(user, activityInfo, 4)
+				//resp.PopupMsg = "<b>报名成功,请复制腾讯会议号打开腾讯会议app参会</b><br/>想要及时获取活动信息变更通知,请关注【查研观向小助手】公众号"
+				resp.PopupMsg = "<b>报名成功,请复制腾讯会议号打开腾讯会议app参会</b><br/>是否将活动日程加入您的系统日历,\n\n活动开始前获取手机日历提醒?"
+			} else {
+				go services.ActivityUserRemind(user, activityInfo, 4)
+				//resp.PopupMsg = "<b>报名成功,已加入您的活动日程</b><br/>想要及时获取活动信息变更通知,请关注【查研观向小助手】公众号"
+				resp.PopupMsg = "<b>报名成功,已加入您的活动日程</b><br/>是否将活动日程加入您的系统日历,\n\n活动开始前获取手机日历提醒?"
+			}
+			go services.YanXuanActivityPointsBillSignupAdd(activityId, uid) // 用户报名添加到处理研选扣点
+		}
+	} else {
+		hasPermission, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionActivity(user, activityInfo)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+			return
+		}
+		resp.PopupMsg = popupMsg
+		resp.HasPermission = hasPermission
+		resp.SellerName = sellerName
+		resp.SellerMobile = sellerMobile
+	}
+
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+
+	//公司线下调研活动客户报名后给建会人,所属销售推送模板信息
+	if signupStatus == "Success" {
+		go services.SendResearchActivitiesTemplateMsg(user, activityInfo, "报名")
+	}
+	if signupType == 1 && user.IsMsgOutboundMobile == 0 {
+		resp.GoOutboundMobile = true
+		if user.Mobile != "" || user.OutboundMobile != "" {
+			go models.ModifyWxUserIsMsgOutboundMobile(user.UserId)
+		}
+	}
+	if user.OutboundMobile == "" {
+		resp.Mobile = user.Mobile
+		if user.CountryCode == "" && len(user.Mobile) == 11 {
+			resp.CountryCode = "86"
+		} else {
+			resp.CountryCode = user.CountryCode
+		}
+	} else {
+		resp.Mobile = user.OutboundMobile
+		resp.CountryCode = user.OutboundCountryCode
+	}
+	//如果用户有绑定手机号,但是没有绑定外呼手机号
+	if signupType == 1 && user.Mobile != "" && user.OutboundMobile == "" {
+		var countryCode string
+		if len(user.Mobile) == 8 {
+			countryCode = "852"
+		} else if len(user.Mobile) == 9 {
+			countryCode = "886"
+		} else if len(user.Mobile) == 10 {
+			countryCode = "1"
+		} else if len(user.Mobile) >= 11 {
+			countryCode = "86"
+		}
+		models.BindUserOutboundMobileByMobile(user.Mobile, countryCode, uid)
+	}
+	resp.SignupType = signupType
+	resp.SignupStatus = signupStatus
+	//resp.HasPermission = hasPermission
+	//if signupStatus == "Success" {
+	resp.ActivityId = activityId
+	resp.ActivityTypeName = activityInfo.ActivityName
+	resp.ActivityTime = activityInfo.ActivityTime
+	resp.ActivityType = detailActivityType.ActivityType
+	//}
+
+	//去关注12.6小程序添加日历 去关注公众号强制取消关注
+	//total, err = models.GetUserSignupCount(user.UserId)
+	//if err != nil {
+	//	br.Msg = "获取信息失败"
+	//	br.ErrMsg = "获取日程数量信息失败,Err:" + err.Error()
+	//	return
+	//}
+	//if total <= 1 {
+	//	resp.GoFollow = true
+	//}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	br.Data = resp
+}
+
+// @Title 活动取消报名
+// @Description 活动取消报名接口
+// @Param	request	body models.ActivitySingnupRep true "type json string"
+// @Success Ret=200 {object} models.SignupStatus
+// @router /signup/cancel [post]
+func (this *ActivityCoAntroller) SignupCancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	var req models.ActivitySingnupRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	activityId := req.ActivityId
+	signupType := req.SignupType
+	item := new(models.CygxActivitySignup)
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+	cancelDeadlineMsg := services.CheckCancelDeadline(activityInfo)
+	if cancelDeadlineMsg != "" {
+		br.Msg = cancelDeadlineMsg
+		br.ErrMsg = cancelDeadlineMsg
+		return
+	}
+
+	resultTime := utils.StrTimeToTime(activityInfo.ActivityTime) //时间字符串格式转时间格式
+	if time.Now().After(resultTime.Add(-time.Minute * 60)) {
+		if signupType == 1 {
+			br.Msg = "活动开始前1小时内无法取消预约外呼,请联系对口销售处理"
+		} else {
+			br.Msg = "活动开始前1小时内无法取消报名,请联系对口销售处理"
+		}
+		return
+	}
+	total, err := models.GetActivitySignupCount(uid, activityId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if total == 0 {
+		br.Msg = "您暂未报名这个活动"
+		return
+	}
+	item.UserId = uid
+	item.ActivityId = activityId
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	resp := new(models.SignupStatus)
+	resp.ActivityId = activityId
+	_, errSignup := models.CancelActivitySignup(item)
+	if errSignup != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errSignup.Error()
+		return
+	}
+
+	// 如果是买方研选下的专家沙龙,同时推给内容组四人
+	if activityInfo.ActivityTypeId == 5 {
+		go services.SendActivitieCancelSignTemplateMsg(user, activityInfo)
+	}
+
+	go services.SendResearchActivitiesTemplateMsg(user, activityInfo, "取消报名") //公司线下调研活动客户报名后给建会人,所属销售推送模板信息
+
+	go services.YanXuanActivityPointsBillSignupCancel(activityId, uid) // 用户取消报名添加到处理研选扣点
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	br.Data = resp
+}
+
+// @Title  用户搜索详情
+// @Description 获取用户搜索详情接口
+// @Param   IsShowJurisdiction   query   int  true       "是否仅展示有权限的,默认为0,1是,2否 "
+// @Param   IsHideResearch   query   int  true       "是否隐藏研选行业 "
+// @Success Ret=200 {object} models.ActivityUserSearchContentList
+// @router /getUserSearchContent [get]
+func (this *ActivityCoAntroller) GetUserSearchContent() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	isHideResearch, _ := this.GetBool("IsHideResearch", false)
+	uid := user.UserId
+	detailSeearch := new(models.CygxActivityUserSearchContent)
+	detailSeearch.IsShowJurisdiction = 0
+	detailSeearch.ChartPermissionids = ""
+	detailSeearch.ActiveState = ""
+	resp := new(models.ActivityUserSearchContentList)
+	detail, _ := models.GetUserSearchContentByUid(uid)
+	if detail == nil {
+		detail = detailSeearch
+	}
+	isShowJurisdiction, _ := this.GetInt("IsShowJurisdiction")
+	listActivityType, errActivityType := models.GetActivityTypeList("")
+	if errActivityType != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + errActivityType.Error()
+		return
+	}
+	var listChartPermissionid []*models.ActivityChartPermission
+	var errChart error
+	if isShowJurisdiction == 1 {
+		listChartPermissionidAll, errChartAll := models.GetUserCompanyPermission(user.CompanyId)
+		listChartPermissionid = listChartPermissionidAll
+		errChart = errChartAll
+	} else if isShowJurisdiction == 2 {
+		listChartPermissionidAll, errChartAll := models.GetChartPermissionActivity()
+		listChartPermissionid = listChartPermissionidAll
+		errChart = errChartAll
+	} else {
+		if detail.IsShowJurisdiction == 1 {
+			listChartPermissionidAll, errChartAll := models.GetUserCompanyPermission(user.CompanyId)
+			listChartPermissionid = listChartPermissionidAll
+			errChart = errChartAll
+		} else {
+			listChartPermissionidAll, errChartAll := models.GetChartPermissionActivity()
+			listChartPermissionid = listChartPermissionidAll
+			errChart = errChartAll
+		}
+	}
+
+	if errChart != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + errChart.Error()
+		return
+	}
+	if detail.IsShowJurisdiction == 1 {
+		resp.IsShowJurisdiction = true
+	}
+	if isShowJurisdiction == 1 || detail.IsShowJurisdiction == 1 {
+		resp.IsShowJurisdiction = true
+		for k, _ := range listChartPermissionid {
+			listChartPermissionid[k].IsChoose = true
+		}
+	}
+	if isShowJurisdiction == 2 {
+		resp.IsShowJurisdiction = false
+	}
+	activeStateList := []models.ActivityStaus{models.ActivityStaus{Id: 1, StatusName: "未开始", IsChoose: true}, models.ActivityStaus{Id: 2, StatusName: "进行中"}, models.ActivityStaus{Id: 3, StatusName: "已结束"}}
+	list2, err := models.GetChartPermissionActivity()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+
+	if activeStateList[1].IsChoose == activeStateList[2].IsChoose == false {
+		activeStateList[0].IsChoose = true
+	}
+	var userType int
+	userType, _, err = services.GetUserType(user.CompanyId)
+	if err != nil {
+		br.Msg = "获取信息失败!"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	var listChartPermissionidNew2 []*models.ActivityChartPermission
+	for _, v := range list2 {
+		if userType == 1 || isHideResearch {
+			//if v.PermissionName != "研选" {
+			if !strings.Contains(v.PermissionName, "研选") {
+				listChartPermissionidNew2 = append(listChartPermissionidNew2, v)
+			}
+		} else {
+			listChartPermissionidNew2 = append(listChartPermissionidNew2, v)
+		}
+	}
+	resp.ListChartPermission2 = listChartPermissionidNew2
+	var listChartPermissionidNew []*models.ActivityChartPermission
+	for _, v := range listChartPermissionid {
+		if userType == 1 || isHideResearch {
+			if !strings.Contains(v.PermissionName, "研选") {
+				listChartPermissionidNew = append(listChartPermissionidNew, v)
+			}
+		} else {
+			listChartPermissionidNew = append(listChartPermissionidNew, v)
+		}
+	}
+	resp.ListActivityType = listActivityType
+	resp.ListChartPermission = listChartPermissionidNew
+	resp.ListActivityStaus = activeStateList
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 添加会议提醒
+// @Description 添加会议提醒接口
+// @Param	request	body models.ActivityIdRep true "type json string"
+// @Success Ret=200 {object} models.SignupStatus
+// @router /meetingReminder/add [post]
+func (this *ActivityCoAntroller) MeetingReminderAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	//var signupStatus string
+	signupStatus := "Success"
+	var req models.ActivityIdRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	activityId := req.ActivityId
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+
+	//SignupStatus string `description:"报名状态:人数已满:FullStarffed、单机构超过两人:TwoPeople、爽约次数过多:BreakPromise、超时:Overtime 、成功:Success"`
+	item := new(models.CygxActivityMeetingReminder)
+	resp := new(models.SignupStatus)
+	hasPermission := 0
+	resultTime := utils.StrTimeToTime(activityInfo.ActivityTime) //时间字符串格式转时间格式
+	if time.Now().After(resultTime.Add(-time.Minute * 15)) {
+		br.Msg = "活动开始前15分钟无法设置会议提醒"
+		return
+	}
+
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+
+	havePower, isResearchSpecial, err := services.GetActivityDetailUserPower(user, activityInfo)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "校验用户权限失败,Err:" + err.Error()
+		return
+	}
+	resp.IsResearchSpecial = isResearchSpecial
+	if havePower {
+		hasPermission = 1
+		signupStatus = "Success"
+
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
+
+		totalMeeting, errMeeting := models.GetActivityMeetingReminderCount(uid, activityId)
+		if errMeeting != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + errMeeting.Error()
+			return
+		}
+		if totalMeeting > 0 {
+			br.Msg = "您已预约,请勿重复预约"
+			return
+		}
+		item.UserId = uid
+		item.ActivityId = activityId
+		item.CreateTime = time.Now()
+		item.Mobile = user.Mobile
+		item.Email = user.Email
+		item.CompanyId = user.CompanyId
+		item.CompanyName = user.CompanyName
+		resp.HasPermission = hasPermission
+		_, errSignup := models.AddActivityMeetingReminder(item)
+		if errSignup != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + errSignup.Error()
+			return
+		}
+		resp.HaqveJurisdiction = true
+		//1:预约外呼 、2:设置会议提醒 、 3:预约纪要 、4:活动报名
+		go services.ActivityUserRemind(user, activityInfo, 2)
+	} else {
+		hasPermission, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionActivity(user, activityInfo)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+			return
+		}
+		resp.PopupMsg = popupMsg
+		resp.HasPermission = hasPermission
+		resp.SellerName = sellerName
+		resp.SellerMobile = sellerMobile
+	}
+
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+
+	resp.SignupStatus = signupStatus
+	resp.ActivityId = activityId
+	//var total int
+	//total, err = models.GetUserActivityMeetingReminderCount(user.UserId)
+	//if err != nil {
+	//	br.Msg = "获取信息失败"
+	//	br.ErrMsg = "获取日程数量信息失败,Err:" + err.Error()
+	//	return
+	//}
+	//if total <= 1 {
+	//	resp.GoFollow = true
+	//}
+	detailActivityType, err := models.GetActivityTypeDetailById(activityInfo.ActivityTypeId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,GetActivityTypeDetailById Err:" + err.Error()
+		return
+	}
+	resp.ActivityTypeName = activityInfo.ActivityName
+	resp.ActivityTime = activityInfo.ActivityTime
+	resp.ActivityType = detailActivityType.ActivityType
+	br.Ret = 200
+	br.Success = true
+	if hasPermission == 1 {
+		br.Msg = "设置成功,会前15分钟会为您推送微信消息提醒"
+		resp.PopupMsg = "设置成功,会前15分钟会为您推送微信消息提醒<br/><br/>是否将活动日程加入您的系统日历,\n\n活动开始前获取手机日历提醒?"
+		//resp.PopupMsg = "设置成功,会前15分钟会为您推送微信消息提醒<br/><br/>请关注【查研观向小助手】公众号,以获取微信消息提醒"
+	}
+	br.Data = resp
+}
+
+// @Title 取消会议提醒
+// @Description 取消会议提醒接口
+// @Param	request	body models.ActivityIdRep true "type json string"
+// @Success Ret=200 {object} models.SignupStatus
+// @router /meetingReminder/cancel [post]
+func (this *ActivityCoAntroller) MeetingReminderCancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	var req models.ActivityIdRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	activityId := req.ActivityId
+	signupStatus := "Success"
+	item := new(models.CygxActivityMeetingReminder)
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+
+	//if signupStatus == "Success" {
+	total, err := models.GetActivityMeetingReminderCount(uid, activityId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if total == 0 {
+		br.Msg = "您暂未添加该活动会议提醒"
+		return
+	}
+	resultTime := utils.StrTimeToTime(activityInfo.ActivityTime) //时间字符串格式转时间格式
+	if time.Now().After(resultTime.Add(-time.Minute * 15)) {
+		br.Msg = "活动开始前15分钟无法取消会议提醒"
+		return
+	}
+	item.UserId = uid
+	item.ActivityId = activityId
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	_, errSignup := models.CancelActivityMeetingReminder(item)
+	if errSignup != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errSignup.Error()
+		return
+	}
+	//}
+	resp := new(models.SignupStatus)
+	resp.SignupStatus = signupStatus
+	resp.ActivityId = activityId
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "会议提醒已取消"
+	br.Data = resp
+}
+
+// @Title 敏捷搜索关键词的列表
+// @Description 获取敏捷搜索关键词的列表接口
+// @Success 200 {object} models.ActivityFastsearchKeywordsListResp
+// @router /fastSearchKeWord [get]
+func (this *ActivityABaseController) FastSearch() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	resp := new(models.ActivityFastsearchKeywordsListResp)
+	list, err := models.GetActivityFastsearchKeywordsList()
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 活动带问
+// @Description 新增活动带问接口
+// @Param	request	body models.AddCygxActivityHelpAsk true "type json string"
+// @Success Ret=200 新增成功
+// @router /askAdd [post]
+func (this *ActivityCoAntroller) AskAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.CygxActivityHelpAsk
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.Content == "" {
+		br.Msg = "建议内容不可为空"
+		return
+	}
+	content := req.Content
+	itemToken, err := services.WxGetToken()
+	if err != nil {
+		br.Msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if itemToken.AccessToken == "" {
+		br.Msg = "accessToken is empty"
+		return
+	}
+	commerr, err := weapp.MSGSecCheck(itemToken.AccessToken, content)
+	if err != nil {
+		br.Msg = "内容校验失败!"
+		br.ErrMsg = "内容校验失败,Err:" + err.Error()
+		return
+	}
+	if commerr.ErrCode != 0 {
+		br.Msg = "内容违规,请重新提交!"
+		br.ErrMsg = "颜文字内容违规,Err:" + commerr.ErrMSG
+		return
+	}
+	activityId := req.ActivityId
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+	//resultTime := utils.StrTimeToTime(activityInfo.ActivityTime) //时间字符串格式转时间格式
+	//if activityInfo.ActivityTypeId == 1 && activityInfo.ChartPermissionId != 31 {
+	//	if time.Now().After(resultTime.Add(-time.Minute * 15)) {
+	//		br.Msg = "活动开始前15分钟内无法提交问题"
+	//		return
+	//	}
+	//} else {
+	//	if time.Now().After(resultTime.Add(-time.Minute * 60)) {
+	//		br.Msg = "活动开始前1小时内无法提交问题"
+	//		return
+	//	}
+	//}
+
+	companyDetail, err := models.GetCompanyDetailById(user.CompanyId)
+	if err != nil {
+		br.Msg = "提交失败!"
+		br.ErrMsg = "获取客户详情失败,Err:" + err.Error()
+		return
+	}
+	if companyDetail == nil {
+		br.Msg = "提交失败!"
+		br.ErrMsg = "客户不存在,uid:" + strconv.Itoa(user.UserId)
+		return
+	}
+	item := new(models.CygxActivityHelpAsk)
+	item.UserId = user.UserId
+	item.ActivityId = req.ActivityId
+	item.CompanyId = user.CompanyId
+	item.CompanyName = companyDetail.CompanyName
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.Content = content
+	msgId, err := models.AddActivityHelpAsk(item)
+	if err != nil {
+		br.Msg = "提交失败"
+		br.ErrMsg = "提交带问失败,Err:" + err.Error()
+		return
+	}
+	fmt.Println(msgId)
+	var isSendMsg bool
+	resultTime := utils.StrTimeToTime(activityInfo.ActivityTime) //时间字符串格式转时间格式
+	if activityInfo.ActivityTypeId == 1 && activityInfo.ChartPermissionId != 31 {
+		if time.Now().After(resultTime.Add(-time.Minute * 15)) {
+			isSendMsg = true
+		}
+	} else {
+		if time.Now().After(resultTime.Add(-time.Minute * 60)) {
+			isSendMsg = true
+		}
+	}
+	if isSendMsg {
+		listEmail, err := models.GetAskEmail()
+		if err != nil {
+			br.Msg = "提交失败"
+			br.ErrMsg = "提交带问失败,Err:" + err.Error()
+			return
+		}
+		var sendMobile string
+		for _, v := range listEmail {
+			if strings.Index(activityInfo.Host, v.Name) > 0 {
+				sendMobile = v.Mobile
+			}
+		}
+		//如果是研选的就推送给汪洋
+		if activityInfo.ChartPermissionId == 31 {
+			sendMobile = utils.ActSendMsgMobile
+		}
+
+		//获取销售信息
+		sellerItem, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "提交失败"
+			br.ErrMsg = "获取销售信息失败,Err:" + err.Error()
+			return
+		}
+		//给研究员发送消息
+		if sendMobile != "" {
+			openIpItem, _ := models.GetUserRecordByMobile(4, sendMobile)
+			if openIpItem != nil && openIpItem.OpenId != "" {
+				if sellerItem != nil {
+					//services.SendActivityAskApplyTemplateMsgV2(user.RealName+"——"+user.CompanyName+"("+sellerItem.RealName+")", "提问:"+activityInfo.ActivityName, time.Now().Format(utils.FormatDateTime), req.Content, activityInfo.ActivityName, openIpItem, activityInfo, int(msgId))
+				}
+			}
+		}
+		// 给所属销售发送消息
+		if sellerItem != nil {
+			openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
+			if openIpItem != nil && openIpItem.OpenId != "" {
+				//services.SendActivityAskApplyTemplateMsgV2(user.RealName+"——"+user.CompanyName+"("+sellerItem.RealName+")", "提问:"+activityInfo.ActivityName, time.Now().Format(utils.FormatDateTime), req.Content, activityInfo.ActivityName, openIpItem, activityInfo, int(msgId))
+			}
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "提交成功"
+}
+
+// @Title 更多主题列表(4.3版本)
+// @Description 获取活动更多主题列表接口(4.3版本)
+// @Success 200 {object} models.GetCygxActivityLabelListRep
+// @router /labelMoreList [get]
+func (this *ActivityCoAntroller) LabelMoreList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+	userType, permissionStr, err := services.GetUserType(user.CompanyId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	var startSize, pageSize int
+	pageSize = 24
+	var condition string
+	var sortTime string
+	//var conditionStatus string
+	var pars []interface{}
+	//活动可见限制
+	var sqlExport string
+	resp := new(models.GetCygxActivityLabelListRep)
+	slicePer := strings.Split(permissionStr, ",")
+	var permissionSqlStr string
+	for _, v := range slicePer {
+		if userType == 1 {
+			//if v != "研选" {
+			if !strings.Contains(v, "研选") {
+				permissionSqlStr += "'" + v + "',"
+			}
+		} else {
+			permissionSqlStr += "'" + v + "',"
+		}
+	}
+	permissionSqlStr = strings.TrimRight(permissionSqlStr, ",")
+	permissionSqlStr = strings.Replace(permissionSqlStr, "(主观)", "", -1)
+	permissionSqlStr = strings.Replace(permissionSqlStr, "(客观)", "", -1)
+	permissionSqlStr = ` AND art.chart_permission_name  IN (` + permissionSqlStr + `)`
+	sqlExport = ` AND (art.customer_type_ids LIKE '%` + strconv.Itoa(userType) + `%' `
+	if userType == 2 {
+		sqlExport += ` OR  art.customer_type_ids LIKE '%3%' `
+	}
+	if (userType == 2 || userType == 3) && strings.Contains(permissionStr, "专家") {
+		sqlExport += ` OR  art.customer_type_ids LIKE '%4%' `
+	}
+	sqlExport += `) `
+
+	//进行中的活动
+	condition = ` AND art.publish_status = 1  AND art.label != ''  AND art.active_state = 2 `
+	var conditionOr string
+	if (userType == 2 || userType == 3 || userType == 4) && strings.Contains(permissionStr, "专家") {
+		conditionOr += ` OR (  art.is_limit_people = 1 AND art.customer_type_ids LIKE '%4%'	 ` + condition + `) `
+	}
+	if (userType == 5) && strings.Contains(permissionStr, "专家") {
+		conditionOr += ` OR (  art.is_limit_people = 1 AND art.customer_type_ids LIKE '%5%'	 ` + condition + `) `
+	}
+	if userType == 1 {
+		conditionOr += ` OR ( art.is_limit_people = 0 ` + condition + permissionSqlStr + `) `
+	} else {
+		conditionOr += ` OR ( art.is_limit_people = 0 ` + condition + `) `
+	}
+	//判断客户规模是否属于可见范围的活动
+	companyProduct, err := models.GetCompanyProductDetail(user.CompanyId, 2)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+		return
+	}
+
+	if companyProduct != nil {
+		if companyProduct.Scale != "" {
+			conditionOr += ` OR (  art.scale LIKE '%` + companyProduct.Scale + `%'	 ` + condition + `) `
+		}
+	}
+	condition += `AND art.is_limit_people = 1 ` + permissionSqlStr + sqlExport + conditionOr
+
+	//进行中的活动
+	sortTime = ` mintimesort ASC `
+	list, errList := models.GetActivityLabelListAll(condition, sortTime, pars, startSize, pageSize)
+	if errList != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + errList.Error()
+		return
+	}
+
+	//已结束的活动
+	conditionOr = ""
+	condition = ` AND art.publish_status = 1  AND art.label != ''  AND art.active_state = 3 `
+	if (userType == 2 || userType == 3 || userType == 4) && strings.Contains(permissionStr, "专家") {
+		conditionOr += ` OR (  art.is_limit_people = 1 AND art.customer_type_ids LIKE '%4%'	 ` + condition + `) `
+	}
+	if (userType == 5) && strings.Contains(permissionStr, "专家") {
+		conditionOr += ` OR (  art.is_limit_people = 1 AND art.customer_type_ids LIKE '%5%'	 ` + condition + `) `
+	}
+	if userType == 1 {
+		conditionOr += ` OR ( art.is_limit_people = 0 ` + condition + permissionSqlStr + `) `
+	} else {
+		conditionOr += ` OR ( art.is_limit_people = 0 ` + condition + `) `
+	}
+	condition += `AND art.is_limit_people = 1 ` + permissionSqlStr + sqlExport + conditionOr
+	startSize = 0
+	pageSize = 24 - len(list)
+
+	//已结束的活动
+	sortTime = ` timesort DESC `
+	listEnd, err := models.GetActivityLabelListAll(condition, sortTime, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range listEnd {
+		list = append(list, v)
+	}
+	//标签字段关联的产业与标签处理
+	for k, v := range list {
+		list[k].KeyWord = services.LabelStr(v.KeyWord)
+	}
+	//添加更多主题访问记录
+	item := new(models.CygxPageHistoryRecord)
+	item.UserId = user.UserId
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	item.PageType = "LabelMore"
+	go models.AddCygxPageHistoryRecord(item)
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 活动列表(4.3版本)
+// @Description 获取活动列表接口(4.3版本)
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   Label   query   string  false       "搜索主题 多个用 , 隔开"
+// @Param   ChartPermissionIds   query   string  false     "行业id 多个用 , 隔开"
+// @Param   WhichDay   query   string  false       "哪一天 1今天、2明天,3本周,4上周,5本月,6上月 多个用 , 隔开"
+// @Param   ActiveState   query   string  false       "活动进行状态 未开始:1、进行中2、已结束3"
+// @Param   ActivityTypeId   query   string  false     "活动类型id 多个用 , 隔开"
+// @Param   Source   query   int  false     "来源 0手机 ,1Pc 默认0"
+// @Param   IsPower   query   int  false       "是否选择有权限行业 ,1是 0 否 默认0"
+// @Param   PlayBack   query   int  false       "是否仅展示回放 1:是、0:否 默认0"
+// @Param   KeyWord   query   string  false       "搜索关键词 多个用 , 隔开"
+// @Param   ActivityId   query   int  false       "活动列表传过来的活动ID"
+// @Param   Filter			query	int		false	"筛选条件 0:全部 1:视频 2:音频"
+// @Param   TypeName   query   string  false       "电话会类型 ,1专家电话会 2分析师电话会"
+// @Param   IsExternalLabel   query   int  false       "是否仅展示外部资源 1:是、0:否 默认0"
+// @Param   IsResearchPoints   query   string  false       "是否仅展示研选扣点 1:展示研选扣点、2:展示外部资源 ,1,2两者都展示" //兼容前端
+// @Param   IsResearch   query   bool  true       "是否为研选"
+// @Success 200 {object} models.GetCygxActivityListRep
+// @router /listNew [get]
+func (this *ActivityCoAntroller) ActivityListNew() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+
+	uid := user.UserId
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	//source, _ := this.GetInt("Source")
+	label := this.GetString("Label")
+	chartPermissionIds := this.GetString("ChartPermissionIds")
+	whichDay := this.GetString("WhichDay")
+	//whichTime := this.GetString("WhichTime")
+	activeState := this.GetString("ActiveState")
+	activityTypeId := this.GetString("ActivityTypeId")
+	keyWord := this.GetString("KeyWord")
+	playBack, _ := this.GetInt("PlayBack")
+	filter, _ := this.GetInt("Filter")
+	isPower, _ := this.GetInt("IsPower")
+	activityId, _ := this.GetInt("ActivityId") // 仅用于判断【新】标签
+	//isExternalLabel, _ := this.GetInt("IsExternalLabel")   //
+	isResearchPoints := this.GetString("IsResearchPoints") //
+	isResearch, _ := this.GetBool("IsResearch", true)      // 是否为研选 查研观向11.0 (研选活动独立显示)
+	if label == "undefined" {
+		label = ""
+	}
+	if chartPermissionIds == "undefined" {
+		chartPermissionIds = ""
+	}
+	// 查研观向7.4-始终查询宏观的活动
+	if chartPermissionIds != "" {
+		chartPermissionIds += ",1"
+	}
+
+	if whichDay == "undefined" {
+		whichDay = ""
+	}
+	if activeState == "undefined" {
+		activeState = ""
+	}
+	if activityTypeId == "undefined" {
+		activityTypeId = ""
+	}
+
+	if activityTypeId == "5" {
+		activityTypeId = "5,8" //专家线下沙龙可以查看买方线下交流
+	}
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+	//userType, permissionStr, err := services.GetUserType(user.CompanyId)
+	var condition string
+	var conditioninit string //初始化搜索条件
+	var pars []interface{}
+	var activityList []*models.ActivityDetail
+	mapDingActivityId := make(map[int]int)
+
+	//主题
+	if label != "" {
+		conditioninit += ` AND art.label  LIKE "%` + label + `%" `
+	}
+	//是否是研选
+	if isResearch {
+		chartPermissionIds = strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN)
+	} else {
+		conditioninit += ` AND ( art.chart_permission_id  !=  ` + strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN) + `  OR  ( art.is_show_hz = 1 AND art.chart_permission_id  =  ` + strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN) + `)  )`
+
+		conditioninit += ` AND IF (	 art.active_state = 3, art.chart_permission_id != ` + strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN) + `, 1 = 1 ) ` //V 11.0 研选活动结束后就不在已结束页面展示了
+	}
+
+	//行业名称 易董过来的会,按照 副行业来筛选
+	if len(chartPermissionIds) > 0 {
+		//conditioninit += ` AND art.chart_permission_id  IN (` + chartPermissionIds + `)`
+		conditioninit += `  AND IF ( art.yidong_activity_id != '' , art.chart_permission_id_deputy  IN (` + chartPermissionIds + `) ,1=1 ) `
+		conditioninit += `  AND IF ( art.yidong_activity_id = '' , art.chart_permission_id  IN (` + chartPermissionIds + `) ,1=1 ) `
+	}
+	//哪一天
+	if whichDay != "" {
+		var startDate string
+		var endDate string
+		if whichDay == "1" {
+			startDate = time.Now().Format(utils.FormatDate)
+			endDate = startDate
+		} else if whichDay == "2" {
+			startDate = time.Now().AddDate(0, 0, +1).Format(utils.FormatDate)
+			endDate = startDate
+		} else if whichDay == "3" {
+			startDate = utils.GetNowWeekMonday().Format(utils.FormatDate)
+			endDate = utils.GetNowWeekSunday().Format(utils.FormatDate)
+		} else if whichDay == "4" {
+			startDate = utils.GetLastWeekMonday().Format(utils.FormatDate)
+			endDate = utils.GetLastWeekSunday().Format(utils.FormatDate)
+		} else if whichDay == "5" {
+			startDate = utils.GetNowMonthFirstDay().Format(utils.FormatDate)
+			endDate = utils.GetNowMonthLastDay().Format(utils.FormatDate)
+		} else if whichDay == "6" {
+			startDate = utils.GetLastMonthFirstDay().Format(utils.FormatDate)
+			endDate = utils.GetLastMonthLastDay().Format(utils.FormatDate)
+		} else if whichDay == "1,2" {
+			startDate = time.Now().Format(utils.FormatDate)
+			endDate = time.Now().AddDate(0, 0, +1).Format(utils.FormatDate)
+		} else if whichDay == "3,4" {
+			startDate = utils.GetLastWeekMonday().Format(utils.FormatDate)
+			endDate = utils.GetNowWeekSunday().Format(utils.FormatDate)
+		} else if whichDay == "5,6" {
+			startDate = utils.GetLastMonthFirstDay().Format(utils.FormatDate)
+			endDate = utils.GetNowMonthLastDay().Format(utils.FormatDate)
+		} else {
+			startDate = time.Now().Format(utils.FormatDate)
+			endDate = time.Now().AddDate(0, 0, +1).Format(utils.FormatDate)
+		}
+		conditioninit += ` AND art.activity_time >= ` + "'" + startDate + " 00:00:00'"
+		conditioninit += ` AND art.activity_time <= ` + "'" + endDate + " 23:59:59'"
+	}
+
+	//活动状态搜索
+	if activeState != "" {
+		// 默认查看未开始跟进行中
+		if activeState == "1" {
+			conditioninit += ` AND art.active_state  IN (1,2)`
+		} else {
+			conditioninit += ` AND art.active_state  IN (` + activeState + `)`
+		}
+	} else {
+		conditioninit += ` AND art.active_state  IN (1,2)`
+	}
+
+	// 如果是分析师电话会,那么可以连同C类一起查看
+	if activityTypeId != "" {
+		if activityTypeId == strconv.Itoa(utils.ANALYST_TELL_ACTIVITY_TYPE_ID) {
+			conditioninit += `  AND art.activity_type_id IN (` + activityTypeId + "," + strconv.Itoa(utils.C_CLASS_ACTIVITY_TYPE_ID) + `)`
+		} else {
+			conditioninit += `  AND art.activity_type_id IN (` + activityTypeId + `)`
+		}
+	}
+
+	//关键词搜索
+	if keyWord != "" {
+		conditioninit += ` AND (art.label   REGEXP '` + keyWord + `' OR art.activity_name  REGEXP '` + keyWord + `' ) `
+	}
+
+	//回放
+	if playBack == 1 {
+		//获取所有带回放的活动ID
+		playBackActivityIds, err := services.GetActivityPlayBackActivityIds()
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		conditioninit += ` AND art.activity_id IN ( ` + playBackActivityIds + `) `
+	}
+
+	//音频视频  1:视频 2:音频
+	if filter > 0 {
+		videoOrVoiceActivityIds, err := services.GetActivityVideoOrVoiceActivityIds(filter)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		conditioninit += ` AND art.activity_id IN ( ` + videoOrVoiceActivityIds + `) `
+	}
+	//外部资源,研选扣点的并集搜索
+	if isResearchPoints == "1,2" || isResearchPoints == "2,1" {
+		conditioninit += ` AND ( art.is_external_label = 1  OR art.is_research_points = 1 )`
+	} else {
+		// 是否为研选扣点
+		if isResearchPoints == "1" {
+			conditioninit += ` AND art.is_research_points = 1 `
+		}
+		//是否为外部资源
+		if isResearchPoints == "2" {
+			conditioninit += ` AND art.is_external_label = 1 `
+		}
+	}
+
+	//活动可见限制
+	//conditionActivityAll, err := services.GetActivityonditionList(user, activityTypeId, chartPermissionIds, whichDay, activeState, label, 0, source, keyWord, playBack, 3)
+	conditionActivity, err := services.ActivityConditioninitSql(user, conditioninit, isPower)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取活动权限数据失败,Err:" + err.Error()
+		return
+	}
+	condition += `  AND art.publish_status = 1 ` + conditionActivity
+	//var conditionCount string
+	//conditionCount = condition + conditionActivityAll
+	total, err := models.GetActivityCount(condition, playBack, pars, filter)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	//搜索关键词初始化
+	//conditionActivityKey, err := services.GetActivityonditionList(user, activityTypeId, chartPermissionIds, whichDay, activeState, label, 0, source, keyWord, playBack, 1)
+	//if err != nil && err.Error() != utils.ErrNoRow() {
+	//	br.Msg = "获取失败"
+	//	br.ErrMsg = "获取失败,Err:" + err.Error()
+	//	return
+	//}
+	var conditionOrder string
+	if activeState == "2" || activeState == "3" {
+		conditionOrder = ` ORDER BY art.activity_time DESC  `
+	} else if activeState == "2,3" {
+		conditionOrder = ` ORDER BY art.active_state ASC, art.activity_time DESC  `
+	} else {
+		conditionOrder = ` ORDER BY art.activity_time DESC ,  art.active_state ASC   `
+	}
+	if label != "" && activeState == "1" {
+		conditionOrder = ` ORDER BY art.activity_time ASC  `
+	}
+	//未开始进行中默认按照时间正序
+	if activeState == "1" || activeState == "1,2" || activeState == "" {
+		conditionOrder = ` ORDER BY  art.top_time DESC , art.activity_time ASC  `
+	}
+	//conditionActivityKey += condition + conditionOrder
+	condition += conditionOrder
+	//fmt.Println(conditionOrder)
+
+	list, errList := models.GetActivityListNew(condition, pars, uid, startSize, pageSize, playBack, filter, "")
+	if errList != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + errList.Error()
+		return
+	}
+
+	var isShow bool
+	isShow = services.GetShowSustainable()
+	detail, err := models.GetConfigByCode("city_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "城市配置信息失败,Err:" + err.Error()
+		return
+	}
+	detailChart, err := models.GetConfigByCode("chart_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "行业配置信息失败,Err:" + err.Error()
+		return
+	}
+
+	addressList := strings.Split(detail.ConfigValue, "{|}")
+	mapAddress := make(map[string]string)
+	chartList := strings.Split(detailChart.ConfigValue, "{|}")
+	mapChart := make(map[string]string)
+	var cityName string
+	var chartName string
+	var imgUrl string
+	var imgUrlChart string
+	var mapActivityId []int
+	for _, v := range addressList {
+		vslice := strings.Split(v, "_")
+		cityName = vslice[0]
+		imgUrl = vslice[len(vslice)-1]
+		mapAddress[cityName] = imgUrl
+	}
+	for _, v := range chartList {
+		vslice := strings.Split(v, "_")
+		chartName = vslice[0]
+		imgUrlChart = vslice[len(vslice)-1]
+		mapChart[chartName] = imgUrlChart
+	}
+
+	for k, v := range list {
+		if strings.Contains(v.ActivityName, "【") {
+			list[k].IsBrackets = 1
+		}
+		if v.SignupNum > v.LimitPeopleNum {
+			list[k].SignupNum = v.LimitPeopleNum
+		}
+		if isShow && strings.Contains(v.ChartPermissionName, "研选") {
+			list[k].IsShowSustainable = true
+		}
+		if strings.Contains(v.ChartPermissionName, "研选") && v.ActivityTypeId == 1 {
+			//list[k].ActivityTypeName = "买方研选电话会"
+			//list[k].ImgUrlText = "https://hongze.oss-cn-shanghai.aliyuncs.com/static/images/202112/20211221/bIdfv8t86xrFRpDOeGGHXOmKEuKl.png"
+			list[k].ImgUrlText = utils.YAN_XUAN_IMG
+		}
+		if v.ActivityType == 0 {
+			if mapAddress[v.City] != "" {
+				list[k].ImgUrl = mapAddress[v.City]
+			} else {
+				list[k].ImgUrl = mapAddress["其它"]
+			}
+		} else {
+			if mapChart[v.ChartPermissionName] != "" {
+				list[k].ImgUrl = mapChart[v.ChartPermissionName]
+			}
+		}
+		expertTxt, _ := services.GetReportContentTextSub(v.Expert)
+		list[k].Expert = expertTxt
+		if v.IsHideAppointment == 0 {
+			list[k].IsShowAppointment = services.IsShowAppointment(v.ActivityTypeId, v.ChartPermissionName)
+		}
+		if v.ActivityTypeId == utils.C_CLASS_ACTIVITY_TYPE_ID {
+			list[k].IsCClassMeeting = true
+		}
+		mapActivityId = append(mapActivityId, v.ActivityId)
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(models.GetCygxActivityListRep)
+	resp.Label = label
+	if activityTypeId != "" {
+		activityTypeIdint, err := strconv.Atoi(activityTypeId)
+		if err == nil {
+			detail, errDetail := models.GetActivityTypeDetailById(activityTypeIdint)
+			if errDetail != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取信息失败,Err:" + errDetail.Error()
+				return
+			}
+			resp.ImgUrl = detail.OnlineIco
+			resp.Label = detail.ActivityTypeName
+		}
+	}
+	//处理音频回放
+	mapActivityVoice, err := services.GetActivityVoiceResp(mapActivityId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetActivityVoiceResp,Err:" + err.Error()
+		return
+	}
+
+	//处理视频回放
+	mapActivityVideo, err := services.GetActivityVideoResp(mapActivityId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetActivityVideoResp,Err:" + err.Error()
+		return
+	}
+	//处理不同的报名方式按钮回显
+	mapActivitySignup, err := services.GetActivitySignupResp(mapActivityId, user)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetActivitySignupResp,Err:" + err.Error()
+		return
+	}
+	for _, v := range list {
+		if mapDingActivityId[v.ActivityId] == 0 {
+			activityList = append(activityList, v)
+		}
+		v.SignupType = mapActivitySignup[v.ActivityId]
+	}
+	for k, v := range activityList {
+		if mapActivityVoice[v.ActivityId] != nil {
+			list[k].FileType = 1
+			list[k].AudioLink = true
+			list[k].VoiceList = mapActivityVoice[v.ActivityId]
+		}
+		if mapActivityVideo[v.ActivityId] != nil {
+			list[k].FileType = 2
+			list[k].AudioLink = true
+			list[k].VideoDetail = mapActivityVideo[v.ActivityId]
+		}
+		//resp.List = append(resp.List, services.ActivityButtonShow(v))
+	}
+	resp.List = services.ActivityArrButtonShow(activityList)
+	// 查研观向7.4-判断标签是否为产业, 为产业时是否跳转资源包
+	if label != "" {
+		industry, e := models.GetIndustryByName(label)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取标签产业失败, Err:" + e.Error()
+			return
+		}
+		if industry != nil {
+			sourceIndustry, e := models.GetSourceIndustryByName(label)
+			if e != nil && e.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取标签产业资源包失败, Err:" + e.Error()
+				return
+			}
+			if sourceIndustry != nil {
+				resp.IndustrialManagementId = sourceIndustry.IndustrialManagementId
+				resp.IsJump = true
+				// 研选产业不跳资源包
+				if sourceIndustry.ChartPermissionId == utils.CHART_PERMISSION_ID_YANXUAN {
+					resp.IsJump = false
+				}
+			}
+		}
+		// 新标签
+		if activityId > 0 {
+			activityIds := []int{activityId}
+			activityNewMap, _, e := services.GetActivityNewLabelMap(activityIds)
+			if e != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取活动新标签失败, Err: " + e.Error()
+				return
+			}
+			resp.IndustryNewLabel = activityNewMap[activityId]
+		}
+	}
+
+	//添加活动搜索记录
+	//if keyWord != "" {
+	//	go services.AddActivitykeyWordSearch(keyWord, user)
+	//}
+
+	if activityTypeId == "3" || activityTypeId == "5" {
+		resp.IsShowResearchPoints = true
+	}
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 校验活动带问是否有权限
+// @Description 校验活动带问是否有权限接口
+// @Param	request	body models.ActivityIdRep true "type json string"
+// @Success Ret=200 {object} models.SignupStatus
+// @router /checkAsk [post]
+func (this *ActivityCoAntroller) CheckAsk() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var signupStatus string
+	var req models.ActivityIdRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	activityId := req.ActivityId
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+	resp := new(models.SignupStatus)
+	hasPermission := 0
+	havePower, isResearchSpecial, err := services.GetActivityDetailUserPower(user, activityInfo)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "校验用户权限失败,Err:" + err.Error()
+		return
+	}
+	resp.IsResearchSpecial = isResearchSpecial
+	if havePower {
+		hasPermission = 1
+		signupStatus = "Success"
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
+		resp.HaqveJurisdiction = true
+		resp.HasPermission = hasPermission
+		resp.SignupStatus = signupStatus
+	} else {
+		hasPermission, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionActivity(user, activityInfo)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+			return
+		}
+		resp.PopupMsg = popupMsg
+		resp.HasPermission = hasPermission
+		resp.SellerName = sellerName
+		resp.SellerMobile = sellerMobile
+	}
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+
+	resp.ActivityId = activityId
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 预约纪要
+// @Description 预约纪要接口
+// @Param	request	body models.ActivityIdRep true "type json string"
+// @Success Ret=200 {object} models.AppointmentResp
+// @router /appointment/add [post]
+func (this *ActivityCoAntroller) ActivityAppointmentAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	signupStatus := "Success"
+	var req models.ActivityIdRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	activityId := req.ActivityId
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+	//判断是否已经预约过
+	totalAppointment, err := models.GetUserCygxActivityAppointmentCount(uid, activityId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if totalAppointment > 0 {
+		br.Msg = "您已预约!"
+		return
+	}
+
+	//SignupStatus string `description:"报名状态:人数已满:FullStarffed、单机构超过两人:TwoPeople、爽约次数过多:BreakPromise、超时:Overtime 、成功:Success"`
+	item := new(models.CygxActivityAppointment)
+	resp := new(models.SignupStatus)
+	hasPermission := 0
+	havePower, isResearchSpecial, err := services.GetActivityDetailUserPower(user, activityInfo)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "校验用户权限失败,Err:" + err.Error()
+		return
+	}
+	resp.IsResearchSpecial = isResearchSpecial
+	if havePower {
+		hasPermission = 1
+		signupStatus = "Success"
+		//限制人数为1人的专家电话会 用户操作时的消息提示
+		if activityInfo.LimitPeopleNum == 1 && activityInfo.ActivityTypeId == 1 {
+			resp.HasPermission = hasPermission
+			resp.SignupStatus = utils.FULLSTARFFED_MSG
+			resp.PopupMsg = utils.ACTIVITY_ZJDHH_V1_MSG
+			br.Ret = 200
+			br.Success = true
+			br.Msg = ""
+			br.Data = resp
+			return
+		}
+		totalMeeting, errMeeting := models.GetUserCygxActivityAppointmentCount(uid, activityId)
+		if errMeeting != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + errMeeting.Error()
+			return
+		}
+		if totalMeeting > 0 {
+			br.Msg = "您已预约,请勿重复预约"
+			return
+		}
+		var sellerName string
+		sellerName, err = models.GetCompanySellerName(user.CompanyId)
+		if err != nil {
+			br.Msg = "报名失败!"
+			br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
+			return
+		}
+		item.UserId = uid
+		item.ActivityId = activityId
+		item.CreateTime = time.Now()
+		item.Mobile = user.Mobile
+		item.Email = user.Email
+		item.CompanyId = user.CompanyId
+		item.CompanyName = user.CompanyName
+		item.SellerName = sellerName
+		item.RealName = user.RealName
+		err = models.AddCygxActivityAppointment(item)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + err.Error()
+			return
+		}
+		resp.HaqveJurisdiction = true
+		//1:预约外呼 、2:设置会议提醒 、 3:预约纪要 、4:活动报名
+		go services.ActivityUserRemind(user, activityInfo, 3)
+		resp.HasPermission = hasPermission
+		resp.SignupStatus = signupStatus
+	} else {
+		hasPermission, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionActivity(user, activityInfo)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+			return
+		}
+		resp.PopupMsg = popupMsg
+		resp.HasPermission = hasPermission
+		resp.SellerName = sellerName
+		resp.SellerMobile = sellerMobile
+	}
+
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+
+	resp.ActivityId = activityId
+	//var total int
+	//total, err = models.GetUserCygxActivityAppointmentCountByUid(user.UserId)
+	//if err != nil {
+	//	br.Msg = "获取信息失败"
+	//	br.ErrMsg = "获取日程数量信息失败,Err:" + err.Error()
+	//	return
+	//}
+	//if total <= 1 {
+	//	resp.GoFollow = true
+	//}
+	detailActivityType, err := models.GetActivityTypeDetailById(activityInfo.ActivityTypeId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,GetActivityTypeDetailById Err:" + err.Error()
+		return
+	}
+	resp.ActivityTypeName = activityInfo.ActivityName
+	resp.ActivityTime = activityInfo.ActivityTime
+	resp.ActivityType = detailActivityType.ActivityType
+	br.Ret = 200
+	br.Success = true
+	if hasPermission == 1 {
+		br.Msg = "请关注【查研观向小助手】公众号,若有调研纪要发布/更新,将及时为您推送微信消息"
+		resp.PopupMsg = "会议纪要预约成功<br/><br/>请关注【查研观向小助手】公众号,若有调研纪要发布/更新,将及时为您推送微信消息"
+	}
+	br.Data = resp
+}
+
+// @Title 取消预约纪要
+// @Description 取消预约纪要接口
+// @Param	request	body models.ActivityIdRep true "type json string"
+// @Success Ret=200 {object} models.SignupStatus
+// @router /appointment/cancel [post]
+func (this *ActivityCoAntroller) ActivityAppointmentCancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	var req models.ActivityIdRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	activityId := req.ActivityId
+	signupStatus := "Success"
+	item := new(models.CygxActivityAppointment)
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+	total, err := models.GetUserCygxActivityAppointmentCount(uid, activityId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if total == 0 {
+		br.Msg = "您暂未预约该纪要"
+		return
+	}
+
+	item.UserId = uid
+	item.ActivityId = activityId
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	_, errSignup := models.CancelcygxActivityAppointment(item)
+	if errSignup != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errSignup.Error()
+		return
+	}
+	resp := new(models.SignupStatus)
+	resp.SignupStatus = signupStatus
+	resp.ActivityId = activityId
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "已取消"
+	br.Data = resp
+}
+
+// @Title 活动报名之前的校验(权限、时间、点数、邮箱)
+// @Description 活动报名之前的校验(权限、时间、点数、邮箱)接口
+// @Param	request	body models.ActivityIdRep true "type json string"
+// @Success Ret=200 {object} models.SignupStatus
+// @router /check [post]
+func (this *ActivityCoAntroller) Check() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.ActivityIdRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	activityId := req.ActivityId
+	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
+	if activityInfo == nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	if errInfo != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + errInfo.Error()
+		return
+	}
+	//这里的文案顺序提示 权限>时间>研选扣点>邮箱绑定。
+	resp := new(models.ActivityCheck)
+	resp.CancelPopupMsg, err = services.ActivityCancelDeadlineMsg(activityInfo) //处理取消报名截止时间的弹窗文案
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + err.Error()
+		return
+	}
+	hasPermission := 0
+	havePower, isResearchSpecial, err := services.GetActivityDetailUserPower(user, activityInfo)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "校验用户权限失败,Err:" + err.Error()
+		return
+	}
+	resp.IsResearchSpecial = isResearchSpecial
+	if havePower {
+		hasPermission = 1
+		resp.CheckPermission = true
+		resp.HasPermission = hasPermission
+	} else {
+		hasPermission, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionActivity(user, activityInfo)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+			return
+		}
+		resp.PopupMsg = popupMsg
+		resp.HasPermission = hasPermission
+		resp.SellerName = sellerName
+		resp.SellerMobile = sellerMobile
+	}
+	if resp.CheckPermission {
+		//如果权限通过了校验,那么就来校验时间
+		resp.CheckTime, resp.PopupMsg = services.CheckSiginupDeadline(activityInfo)
+	}
+	if resp.CheckTime {
+		// 如果时间通过校验就校验点数
+		resp.CheckPoints, resp.PopupMsg, resp.CompanyPoints, resp.ActivityPoints, err = services.CheckActivityPoints(activityInfo, user)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "CheckActivityPoints,Err:" + err.Error()
+			return
+		}
+	}
+	if resp.CheckPoints {
+		//如果通过点数的校验,就来校验邮箱
+		resp.CheckEmail, resp.PopupMsg = services.CheckActivityUserEmail(activityInfo, user)
+	}
+	// 判断是否属于研选类型的活动
+	if strings.Contains(activityInfo.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		resp.IsResearch = true
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}

+ 489 - 0
controllers/activity_sign.go

@@ -0,0 +1,489 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 活动
+type ActivitySignCoAntroller struct {
+	BaseAuthController
+}
+
+// @Title  活动扫码自动签到
+// @Description 活动扫码签到接口
+// @Param   ActivityId   query   int  true       "活动ID"
+// @Success Ret=200 {object} models.CygxActivityResp
+// @router /detail [get]
+func (this *ActivitySignCoAntroller) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	activityId, _ := this.GetInt("ActivityId")
+	if activityId < 1 {
+		br.Msg = "请输入活动ID"
+		return
+	}
+	resp := new(models.CygxActivitySigninDetailResp)
+	activityInfo, err := models.GetAddActivityInfoByIdShow(uid, activityId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取活动详情信息失败,Err:" + err.Error()
+		return
+	}
+	if activityInfo == nil {
+		br.Msg = "活动不存在"
+		br.ErrMsg = "活动ID错误,Err:" + "activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	totalMySuccess, err := models.GetActivitySignupCount(uid, activityId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	detail := new(models.CygxActivitySigninResp)
+	if totalMySuccess > 0 {
+		detail.IsSignup = true
+	}
+	var condition string
+	var pars []interface{}
+	condition = " AND  open_id = ?  AND activity_id = ?  "
+	pars = append(pars, user.OpenId, activityId)
+	total, err := models.GetCygxActivitySigninCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	//判断是否已经申请过
+	applyCount, err := models.GetApplyRecordCount(uid)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+		return
+	}
+
+	item := new(models.CygxActivitySignin)
+	item.ActivityId = activityId
+	item.UserId = user.UserId
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.RealName = user.RealName
+	item.CompanyName = user.CompanyName
+	item.IsSignup = totalMySuccess
+	item.CountryCode = user.CountryCode
+	item.OpenId = user.OpenId
+	item.CreateTime = time.Now()
+	if total == 0 && (user.Mobile != "" || user.Email != "") && (applyCount > 0 || user.CompanyId > 1) {
+		err = models.AddCygxActivitySignin(item)
+		if err != nil {
+			br.Msg = "签到失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	//记录签到信息到用户到会表
+	if user.CompanyId > 1 {
+		pars = make([]interface{}, 0)
+		condition = " AND  user_id = ?  AND activity_id = ?  "
+		pars = append(pars, user.UserId, activityId)
+		totalOfflineMeeting, err := models.GetCygxActivityOfflineMeetingDetailCount(condition, pars)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+		if totalOfflineMeeting == 0 {
+			itemOfflineMeeting := new(models.CygxActivityOfflineMeetingDetail)
+			itemOfflineMeeting.UserId = user.UserId
+			itemOfflineMeeting.ActivityId = activityId
+			itemOfflineMeeting.CreateTime = time.Now()
+			itemOfflineMeeting.Mobile = user.Mobile
+			itemOfflineMeeting.CompanyId = user.CompanyId
+			itemOfflineMeeting.CompanyName = user.CompanyName
+			itemOfflineMeeting.IsMeeting = 1
+			err = models.AddCygxActivityOfflineMeetingDetail(itemOfflineMeeting)
+			if err != nil {
+				br.Msg = "签到失败"
+				br.ErrMsg = "获取失败AddCygxActivityOfflineMeetingDetail,Err:" + err.Error()
+				return
+			}
+		}
+		//添加日志记录
+		services.AddCygxActivitySigninLog(item)
+
+		//把报名信息写入签到到会表
+		services.AddCygxActivityOfflineMeetingDetail(activityId, user.UserId)
+
+		//后期扫码签到,处理是否爽约限制
+		services.CygxActivityRestrictSignupByuid(user.UserId, activityId)
+
+		//线下调研活动扫码签到给对应销售发模版消息
+		services.SendActivitieSignTemplateMsg(user, activityInfo)
+
+		//处理用户标签
+		services.ActivityUserLabelLogAdd(activityId, []string{user.Mobile})
+
+		{
+			//用做后台联系人列表查询
+			itemD := new(models.CygxActivityAttendanceDetail)
+			itemD.ActivityId = activityId
+			itemD.RealName = user.RealName
+			itemD.Mobile = user.Mobile
+			itemD.CompanyName = user.CompanyName
+			itemD.IsMeetingStr = 1
+			itemD.CreateTime = time.Now()
+			var itemDs []*models.CygxActivityAttendanceDetail
+			itemDs = append(itemDs, itemD)
+			services.AddctivitySignupDetailByJmcjNew(itemDs, []int{activityId})
+		}
+
+	}
+	//1,没有签到记录不为潜在客户
+	//2,没有签到记录,手机号不为空,没有申请记录
+	//3,已经有签到记录的
+	if total == 0 && user.CompanyId > 1 || ((user.Mobile != "" || user.Email != "") && applyCount > 0) || total > 0 {
+		resp.IsBindingMobile = true
+	}
+	if user.CompanyId == 1 {
+		detail.IsNewUser = true
+	}
+
+	//潜在客户提交过申请的显示提交时候的公司
+	if applyCount > 0 && (user.Mobile != "" || user.Email != "") && user.CompanyId == 1 {
+		detail, err := models.GetCygxApplyRecordByMobile(user.Mobile)
+		if err != nil {
+			br.Msg = "签到失败"
+			br.ErrMsg = "GetCygxApplyRecordByMobile,Err:" + err.Error()
+			return
+		}
+		user.CompanyName = detail.CompanyName
+	}
+	detail.ActivityId = activityId
+	detail.ActivityName = activityInfo.ActivityName
+	detail.Mobile = user.Mobile
+	if user.Mobile == "" {
+		detail.Mobile = user.Email
+	}
+	detail.RealName = user.RealName
+	detail.CompanyName = user.CompanyName
+
+	//用于前端二次回显
+	if user.Mobile == "" {
+		pars = make([]interface{}, 0)
+		condition = " AND  open_id = ?  AND activity_id = ?  "
+		pars = append(pars, user.OpenId, activityId)
+		signinDetail, err := models.GetCygxActivitySigninDetail(condition, pars)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "签到失败"
+			br.ErrMsg = "获取失败GetCygxActivitySigninDetail,Err:" + err.Error()
+			return
+		}
+		if signinDetail != nil {
+			detail.BusinessCard = signinDetail.BusinessCard
+			detail.Mobile = signinDetail.Mobile
+			if signinDetail.Mobile == "" {
+				detail.Mobile = signinDetail.Email
+			}
+			detail.RealName = signinDetail.RealName
+			detail.CompanyName = signinDetail.CompanyName
+			detail.IsNewUser = true
+		}
+	}
+	resp.Detail = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title  活动扫码手动签到
+// @Description 活动扫码手动签到接口
+// @Param   ActivityId   query   int  true       "活动ID"
+// @Success Ret=200 {object} models.CygxActivityResp
+// @router /byHand [post]
+func (this *ActivitySignCoAntroller) ByHand() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+
+	uid := user.UserId
+	resp := new(models.CygxActivitySigninDetailResp)
+	var req models.CygxActivitySigninReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	signinType := req.SigninType
+	activityId := req.ActivityId
+	CountryCode := req.CountryCode
+	Mobile := req.Mobile
+	CompanyName := req.CompanyName
+	BusinessCard := req.BusinessCard
+	RealName := req.RealName
+	if activityId < 1 {
+		br.Msg = "请输入活动ID"
+		return
+	}
+	user.RealName = RealName
+	user.CompanyName = CompanyName
+	activityInfo, err := models.GetAddActivityInfoByIdShow(uid, activityId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取活动详情信息失败,Err:" + err.Error()
+		return
+	}
+	if activityInfo == nil {
+		br.Msg = "活动不存在"
+		br.ErrMsg = "活动ID错误,Err:" + "activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	totalMySuccess, err := models.GetActivitySignupCount(uid, activityId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	item := new(models.CygxActivitySignin)
+
+	var condition string
+	var pars []interface{}
+	condition = " AND  open_id = ?  AND activity_id = ?  "
+	pars = append(pars, user.OpenId, activityId)
+	total, err := models.GetCygxActivitySigninCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if user.Mobile == "" && user.Email == "" {
+		if signinType == 1 {
+			if req.Mobile == "" {
+				br.Msg = "参数错误"
+				br.ErrMsg = "参数错误,手机号为空 为空"
+				return
+			}
+			itemMsgCode, err := models.GetMsgCode(req.Mobile, req.VCode)
+			if err != nil {
+				if err.Error() == utils.ErrNoRow() {
+					br.Msg = "验证码错误,请重新输入"
+					br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+					return
+				} else {
+					br.Msg = "验证码错误,请重新输入"
+					br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+					return
+				}
+			}
+			if itemMsgCode == nil {
+				br.Msg = "验证码错误,请重新输入"
+				return
+			}
+			userMobile, err := models.GetWxUserItemByMobile(Mobile)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "签到失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+			if userMobile != nil {
+				user = userMobile
+			}
+		} else {
+			if BusinessCard == "" {
+				br.Msg = "签到失败"
+				br.ErrMsg = "签到失败名片地址为空,Err:"
+				return
+			}
+			item.BusinessCard = BusinessCard
+		}
+	} else {
+		if signinType == 1 {
+			if CompanyName == "" {
+				br.Msg = "请输入公司名称"
+				return
+			}
+			if RealName == "" {
+				br.Msg = "请输入姓名"
+				return
+			}
+		}
+	}
+	//如果是用邮箱登录的,就把手机号置空
+	if strings.Contains(Mobile, "@") {
+		Mobile = ""
+	}
+	item.ActivityId = activityId
+	item.UserId = user.UserId
+	item.Mobile = Mobile
+	item.CountryCode = CountryCode
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.RealName = user.RealName
+	item.CompanyName = user.CompanyName
+	item.IsSignup = totalMySuccess
+	item.BusinessCard = BusinessCard
+	item.OpenId = user.OpenId
+	item.CreateTime = time.Now()
+	if total == 0 {
+		err = models.AddCygxActivitySignin(item)
+		if err != nil {
+			br.Msg = "签到失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+	} else {
+		pars = make([]interface{}, 0)
+		condition = " AND  open_id = ?  AND activity_id = ?  "
+		pars = append(pars, user.OpenId, activityId)
+		signinDetail, err := models.GetCygxActivitySigninDetail(condition, pars)
+		if err != nil {
+			br.Msg = "签到失败"
+			br.ErrMsg = "获取失败GetCygxActivitySigninDetail,Err:" + err.Error()
+			return
+		}
+		item.Id = signinDetail.Id
+		err = models.UpdateCygxActivitySignin(item)
+		if err != nil {
+			br.Msg = "签到失败"
+			br.ErrMsg = "获取失败,UpdateCygxActivitySignin,Err:" + err.Error()
+			return
+		}
+	}
+	detail := new(models.CygxActivitySigninResp)
+	if totalMySuccess > 0 {
+		detail.IsSignup = true
+	}
+	//添加日志记录
+	go services.AddCygxActivitySigninLog(item)
+	if user.CompanyId <= 1 {
+		detail.IsNewUser = true
+	}
+	if user.UserId == 0 {
+		detail.IsNewUser = true
+	}
+	detail.ActivityId = activityId
+	detail.ActivityName = activityInfo.ActivityName
+	detail.Mobile = Mobile
+	detail.RealName = RealName
+	detail.CompanyName = CompanyName
+	resp.Detail = detail
+	resp.IsBindingMobile = true
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title  活动签到到会详情
+// @Description 活动签到到会详情接口
+// @Param   ActivityId   query   int  true       "活动ID"
+// @Success Ret=200 {object} models.CygxActivityResp
+// @router /signup/detail [get]
+func (this *ActivitySignCoAntroller) SignupDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+
+	activityId, _ := this.GetInt("ActivityId")
+	if activityId < 1 {
+		br.Msg = "请输入活动ID"
+		return
+	}
+	resp := new(models.CygxActivityOfflineMeetingDetailResp)
+	activityInfo, err := models.GetAddActivityInfoById(activityId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取活动详情信息失败,Err:" + err.Error()
+		return
+	}
+	if !services.GetBelongingRai(user.Mobile) {
+		br.Msg = "你暂无查看权限"
+		br.ErrMsg = "你暂无查看权限,UserId:" + strconv.Itoa(user.UserId)
+		return
+	}
+	var condition string
+	var pars []interface{}
+	condition = ` AND do_fail_type = 0 AND activity_id  = ?`
+	pars = append(pars, activityId)
+
+	listSignup, err := models.GetActivitySignupList(condition, pars)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetOfflineMeetingListWithUser,UserId:" + strconv.Itoa(user.UserId)
+		return
+	}
+	//获取对应销售所能查看的用户手机号
+	UserMobileMap, err := services.GetAdminCheckUserMobileMap(user)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetAdminCheckUserMobileMap,UserId:" + strconv.Itoa(user.UserId)
+		return
+	}
+	//获取用户的签到时间
+	SigninTimeMap, err := services.GetUserActivitySigninTimeMap(activityId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetUserActivitySigninTimeMap,activityId:" + strconv.Itoa(activityId)
+		return
+	}
+	for _, v := range listSignup {
+		if _, ok := UserMobileMap[v.Mobile]; ok {
+			item := new(models.CygxActivitySignupResp)
+			item.RealName = v.RealName
+			item.CompanyName = v.CompanyName
+			if _, ok := SigninTimeMap[v.UserId]; ok {
+				item.IsMeeting = 1
+				item.SigninTime = SigninTimeMap[v.UserId]
+			}
+			resp.List = append(resp.List, item)
+		}
+	}
+	if len(resp.List) == 0 {
+		resp.List = make([]*models.CygxActivitySignupResp, 0)
+	}
+	resp.ActivityId = activityId
+	resp.ActivityName = activityInfo.ActivityName
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 1259 - 0
controllers/article.go

@@ -0,0 +1,1259 @@
+package controllers
+
+import (
+	"bufio"
+	"github.com/pdfcpu/pdfcpu/pkg/api"
+	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
+	"io"
+	//"bufio"
+	"encoding/json"
+	"fmt"
+	"github.com/medivhzhan/weapp/v2"
+	"os"
+
+	//"github.com/pdfcpu/pdfcpu/pkg/api"
+	//"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"html"
+
+	nhttp "net/http"
+
+	"strconv"
+	"strings"
+	"time"
+)
+
+type ArticleController struct {
+	BaseAuthController
+}
+
+type ArticleCommonController struct {
+	BaseCommonController
+}
+
+type ArticleControllerMobile struct {
+	BaseAuthMobileController
+}
+
+// @Title 获取报告详情
+// @Description 获取报告详情接口
+// @Param   ArticleId   query   int  true       "报告ID"
+// @Param   IsSendWx   query   int  false       "是否是通过微信模版进来的 1是,其它否"
+// @Success 200 {object} models.ArticleDetailResp
+// @router /detail [get]
+func (this *ArticleController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+
+	uid := user.UserId
+	articleId, err := this.GetInt("ArticleId")
+	isSendWx, _ := this.GetInt("IsSendWx")
+	if articleId <= 0 {
+		br.Msg = "文章不存在"
+		br.ErrMsg = "文章不存在,文章ID错误"
+		return
+	}
+	detail := new(models.ArticleDetail)
+	//detailInit := new(models.ArticleDetail) // 初始化的文章信息,用来处理body 内容回显
+	hasPermission := 0
+	var haveResearch bool
+	//判断是否已经申请过
+	applyCount, err := models.GetApplyRecordCount(uid)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ArticleDetailResp)
+	detail, err = models.GetArticleDetailById(articleId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+
+	detail.PublishDate = utils.TimeRemoveHms2(detail.PublishDate)
+	detail.Body = html.UnescapeString(detail.Body)
+	detail.Body = strings.Replace(detail.Body, "<p data-f-id=\"pbf\" style=\"text-align: center; font-size: 14px; margin-top: 30px; opacity: 0.65; font-family: sans-serif;\">Powered by <a href=\"https://www.froala.com/wysiwyg-editor?pb=1\" title=\"Froala Editor\">Froala Editor</a></p>", "", -1)
+	detail.Body = strings.Replace(detail.Body, "pre", "div", -1)
+	detail.Abstract = html.UnescapeString(detail.Abstract)
+	//detail.Abstract, _ = services.GetReportContentTextSubNew(detail.Abstract)
+	//作者头像
+	if detail.DepartmentId > 0 {
+		departmentDetail, err := models.GetArticleDepartmentDateilById(detail.DepartmentId)
+		if err == nil {
+			detail.DepartmentImgUrl = departmentDetail.ImgUrl
+		}
+	}
+	lyjhTypeMap, _ := services.GetLyjhTypeMap()
+	if _, ok := lyjhTypeMap[detail.CategoryId]; ok {
+		detail.IsRoadShow = true
+	}
+	// 判断是否属于研选类型的报告
+	if strings.Contains(detail.CategoryName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+		detail.IsResearch = true
+	}
+
+	// 高毅资产的联系人,有权限的行业也不能查看报告详情页。提示无权限页面
+	if detail.ArticleTypeId == 0 && user.CompanyId == utils.GAO_YI_ZI_CHAN_COMPANY_ID {
+		_, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionArticle(user)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+			return
+		}
+		resp.PopupMsg = popupMsg
+		resp.HasPermission = 3
+		resp.SellerName = sellerName
+		resp.SellerMobile = sellerMobile
+		detail.Body = ""
+		detail.Abstract = ""
+		detail.BodyText = ""
+		detail.SellerName = sellerName
+		detail.SellerMobile = sellerMobile
+		resp.Detail = detail
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+		return
+	}
+	articleCollectMap, _ := services.GetCygxArticleCollectMap(user.UserId)
+	detail.IsCollect = articleCollectMap[detail.ArticleId]
+	//detailInit = detail
+	if isSendWx == 1 {
+		var condition string
+		var pars []interface{}
+		pars = make([]interface{}, 0)
+		condition = ` AND article_id  = ? `
+		reportMappingMap, _ := services.GetReportMappingMap()
+
+		if reportMappingMap[detail.CategoryId] {
+			chooseCategoryMap, _ := services.GetChooseCategoryMap(user)
+			detail.IsShowFollowButton = true
+			detail.IsFollowButton = chooseCategoryMap[detail.CategoryId]
+		} else {
+			pars = append(pars, articleId)
+			industrialList, err := models.GetIndustrialArticleGroupManagementList(condition, pars)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取信息失败,Err:" + err.Error()
+				return
+			}
+			if len(industrialList) > 0 {
+				industryUserFollowMap, err := services.GetIndustryUserFollowMap(user)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "GetActivitySignupResp,Err:" + err.Error()
+					return
+				}
+				for _, v := range industrialList {
+					if industryUserFollowMap[v.IndustrialManagementId] {
+						detail.IsFollowButton = true
+					}
+				}
+				detail.IsShowFollowButton = true
+			}
+		}
+	}
+	//是否属于专项调研报告
+	if detail.SubCategoryName == "专项调研" {
+		detail.IsSpecialArticle = true
+		havePower, err := services.GetSpecialArticleDetailUserPower(user, detail)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+			return
+		}
+		resp.IsSpecialArticle = true
+		if !havePower {
+			hasPermission, sellerName, sellerMobile, popupMsg, err := services.GetUserHasPermissionArticle(user)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+				return
+			}
+			resp.PopupMsg = popupMsg
+			resp.HasPermission = hasPermission
+			resp.SellerName = sellerName
+			resp.SellerMobile = sellerMobile
+			detail.Body = ""
+			detail.Abstract = ""
+			detail.BodyText = ""
+			detail.SellerName = sellerName
+			detail.SellerMobile = sellerMobile
+			resp.Detail = detail
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "获取成功"
+			br.Data = resp
+			return
+		}
+	}
+	//`description:"1:有该行业权限,正常展示,2:无该行业权限,不存在权益客户下,3:无该品类权限,4:潜在客户,未提交过申请,5:潜在客户,已提交过申请"`
+	if user.CompanyId > 1 {
+		companyPermission, err := models.GetCompanyPermission(user.CompanyId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请访谈失败,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+
+		if companyPermission == "" {
+			if applyCount > 0 {
+				hasPermission = 5
+			} else {
+				hasPermission = 2
+			}
+			goto Loop
+		} else {
+			var articlePermissionName string
+			if detail.CategoryId > 0 {
+				articlePermission, err := models.GetArticlePermission(detail.CategoryId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取报告权限失败,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+					return
+				}
+				if articlePermission == nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "报告权限不存在,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+					return
+				}
+				articlePermissionName = articlePermission.PermissionName
+			} else {
+				articlePermissionName = detail.CategoryName
+			}
+
+			var hasPersion bool
+			slice := strings.Split(articlePermissionName, ",")
+			for _, v := range slice {
+				if strings.Contains(companyPermission, v) {
+					hasPersion = true
+				}
+			}
+			if strings.Contains(detail.CategoryName, "研选") {
+				detail.IsResearch = true
+			}
+			userType, _, err := services.GetUserType(user.CompanyId)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+				return
+			}
+			if userType == 1 && strings.Contains(detail.CategoryName, "研选") {
+				hasPersion = false
+			}
+			//if detail.IsReport == 1 {
+			//detailCategory, err := models.GetdetailByCategoryIdSando(detail.CategoryId)
+			//if err != nil && err.Error() != utils.ErrNoRow() {
+			//	br.Msg = "获取信息失败"
+			//	br.ErrMsg = "获取信息失败,Err:" + err.Error() + "categoryID 不存在:" + strconv.Itoa(detail.CategoryId)
+			//	return
+			//}
+			//permissionStr, err := models.GetCompanyPermissionByUser(user.CompanyId)
+			//if err != nil {
+			//	br.Msg = "获取信息失败"
+			//	br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+			//	return
+			//}
+			//if detailCategory != nil {
+			//	if detailCategory.PermissionType == 1 {
+			//		if !strings.Contains(permissionStr, detailCategory.ChartPermissionName+"(主观)") {
+			//			hasPersion = false
+			//		}
+			//	} else if detailCategory.PermissionType == 2 {
+			//		if !strings.Contains(permissionStr, detailCategory.ChartPermissionName+"(客观)") {
+			//			hasPersion = false
+			//		}
+			//	}
+			//}
+			//}
+
+			//大行业通过权限校验,再校验主客观权限。只有医药、消费、科技、智造,才会校验主客观权限
+			if hasPersion && utils.InArrayByStr([]string{utils.YI_YAO_NAME, utils.XIAO_FEI_NAME, utils.KE_JI_NAME, utils.ZHI_ZAO_NAME}, articlePermissionName) {
+				hasPersion = services.CheckArticlePermissionType(articleId, user)
+			}
+			if hasPersion {
+				hasPermission = 1
+				go services.ArticleHistory(articleId, user)
+				//30分钟之内阅读同一篇文章不错二次推送
+				key := "CYGX_ARTICLE_READ" + strconv.Itoa(articleId) + "_" + strconv.Itoa(uid)
+				if !utils.Rc.IsExist(key) {
+					go services.ArticleUserRemind(user, detail, 1)
+					utils.Rc.Put(key, 1, 30*time.Second)
+				}
+			} else { //无该行业权限
+				companyDetail, err := models.GetCompanyDetailById(user.CompanyId)
+				if err == nil && companyDetail.ProductId == 1 {
+					hasPermission = 2
+				} else {
+					hasPermission = 3
+				}
+			}
+		}
+
+		interviewApplyItem, err := models.GetArticleInterviewApply(uid, articleId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请访谈失败,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if interviewApplyItem != nil && interviewApplyItem.InterviewApplyId > 0 {
+			detail.IsInterviewApply = true
+			detail.InterviewApplyStatus = interviewApplyItem.Status
+		}
+		//获取销售手机号
+		sellerItem, err := models.GetSellerByCompanyId(user.CompanyId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取销售数据失败2,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if sellerItem != nil {
+			detail.SellerMobile = sellerItem.Mobile
+			detail.SellerName = sellerItem.RealName
+		}
+		sellerList, err := models.GetSellerList(articleId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取销售数据失败,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if detail.ArticleId >= utils.SummaryArticleId && strings.Contains(detail.SellerAndMobile, "-") {
+			strnum := strings.Index(detail.SellerAndMobile, "-")
+			detail.SellerAndMobile = detail.SellerAndMobile[0:strnum]
+			if strnum > 0 {
+				nickName := detail.SellerAndMobile[0:strnum]
+				sellerAndMobile := &models.SellerRep{
+					SellerMobile: "",
+					SellerName:   nickName,
+				}
+				sellerList = append(sellerList, sellerAndMobile)
+			}
+		}
+		detail.SellerList = sellerList
+
+	} else { //潜在客户
+		if applyCount > 0 {
+			hasPermission = 5
+		} else {
+			hasPermission = 4
+		}
+	}
+Loop:
+	if hasPermission != 1 && user.UserId > 0 {
+		detail.Body = ""
+		detail.BodyText = ""
+	} else {
+		articleFollowdetail, err := models.GetArticleFollowDetail(articleId, uid)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取关注信息失败,Err:" + err.Error()
+			return
+		}
+		detail.FollowNum = articleFollowdetail.DNum
+		detail.CollectionNum = articleFollowdetail.AcNum
+		if articleFollowdetail.MdNum > 0 {
+			detail.IsFollow = true
+		}
+		if detail.IsSummary == 1 {
+			detail.IsBelongSummary = true
+		}
+		if detail.IsReport == 1 {
+			detail.IsBelongReport = true
+		}
+		haveResearch = true
+	}
+	if hasPermission == 5 {
+		companyPermissionNoStatus, err := models.GetCompanyPermissionByUserNoStatus(user.CompanyId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请访谈失败,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if companyPermissionNoStatus != "" {
+			sellerItemQy, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取销售信息失败,Err:" + err.Error()
+				return
+			}
+			if sellerItemQy != nil {
+				hasPermission = 3
+				detail.SellerMobile = sellerItemQy.Mobile
+				detail.SellerName = sellerItemQy.RealName
+			}
+		}
+	}
+
+	if hasPermission == 2 || hasPermission == 4 {
+		//获取销售手机号
+		sellerItemQy, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取销售信息失败,Err:" + err.Error()
+			return
+		}
+		if sellerItemQy != nil {
+			hasPermission = 3
+			detail.SellerMobile = sellerItemQy.Mobile
+			detail.SellerName = sellerItemQy.RealName
+		}
+	}
+
+	if detail.ArticleId < utils.SummaryArticleId {
+		if user.Mobile != "" {
+
+			detail.HttpUrl = utils.StrategyPlatform + strconv.Itoa(articleId) + "?token="
+		} else {
+			detail.HttpUrl = utils.StrategyPlatform + strconv.Itoa(articleId)
+		}
+		detail.IsNeedJump = true
+	}
+
+	// 处理研选下面的路演精华 的报告链接是否跳转
+	if hasPermission == 1 && detail.ArticleId > utils.SummaryArticleId && detail.ArticleTypeId > 0 {
+		//detail.PublishDate = utils.TimeRemoveHms2(detail.PublishDate)
+		if detail.ReportLink != "" {
+
+			detail.ReportLink += "?token="
+		}
+	}
+	if articleId < utils.SummaryArticleId {
+		detail.Abstract, _ = services.GetReportContentTextSubNew(detail.Abstract)
+	}
+	if detail.ArticleTypeId == 14 {
+		detail.IsApplyAppointmentExpert = true //判断文章类型是否属于专家访谈  查研观向11.0
+	}
+	resp.HasPermission = hasPermission
+	resp.HaveResearch = haveResearch
+	if user.UserId == 0 {
+		resp.HasPermission = 1
+		if detail.UpdateFrequency == "daily" {
+			detail.Frequency = "日度"
+		} else if detail.UpdateFrequency == "weekly" {
+			detail.Frequency = "周度"
+		} else if detail.UpdateFrequency == "monthly" {
+			detail.Frequency = "月度"
+		} else if detail.UpdateFrequency == "quarterly" {
+			detail.Frequency = "季度"
+		} else if detail.UpdateFrequency == "yearly" {
+			detail.Frequency = "年度"
+		}
+	}
+	resp.Detail = detail
+	if user.Mobile != "" {
+		resp.Mobile = user.Mobile
+	} else {
+		resp.Mobile = user.Email
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 收藏
+// @Description 收藏
+// @Param	request	body models.ArticleCollectReq true "type json string"
+// @Success 200 {object} models.FontsCollectResp
+// @router /collect [post]
+func (this *ArticleController) ArticleCollect() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	var req models.ArticleCollectReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	articleId := req.ArticleId
+	detail, err := models.GetArticleDetailById(articleId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+	count, err := models.GetArticleCollectCount(uid, articleId)
+	if err != nil {
+		br.Msg = "获取数据失败!"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ArticleCollectResp)
+	if count <= 0 {
+		item := new(models.CygxArticleCollect)
+		item.ArticleId = req.ArticleId
+		item.UserId = uid
+		item.CreateTime = time.Now()
+		item.Mobile = user.Mobile
+		item.Email = user.Email
+		item.CompanyId = user.CompanyId
+		item.CompanyName = user.CompanyName
+		item.RealName = user.RealName
+		_, err = models.AddCygxArticleCollect(item)
+		if err != nil {
+			br.Msg = "收藏失败"
+			br.ErrMsg = "收藏失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "收藏成功"
+		resp.Status = 1
+		// 文章收藏消息发送
+		go services.ArticleUserRemind(user, detail, 2)
+		go services.ArticleHistoryUserLabelLogAdd(articleId, user.UserId)
+	} else {
+		err = models.RemoveArticleCollect(uid, articleId)
+		if err != nil {
+			br.Msg = "取消收藏失败"
+			br.ErrMsg = "取消收藏失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "已取消收藏"
+		resp.Status = 2
+	}
+	collectTotal, err := models.GetArticleCollectUsersCount(articleId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp.CollectCount = collectTotal
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 访谈申请
+// @Description 访谈申请
+// @Param	request	body models.ArticleInterviewApplyReq true "type json string"
+// @Success 200 {object} models.FontsCollectResp
+// @router /interview/apply [post]
+func (this *ArticleController) InterviewApply() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	var req models.ArticleInterviewApplyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	article, err := models.GetArticleDetailById(req.ArticleId)
+	if err != nil {
+		br.Msg = "获取纪要失败!"
+		br.ErrMsg = "获取纪要失败,Err:" + err.Error()
+		return
+	}
+
+	count, err := models.GetArticleInterviewApplyCount(uid, req.ArticleId)
+	if err != nil {
+		br.Msg = "获取数据失败!"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ArticleInterviewApplyResp)
+	if count <= 0 {
+		item := new(models.CygxInterviewApply)
+		item.ArticleId = req.ArticleId
+		item.UserId = uid
+		item.CompanyId = user.CompanyId
+		item.Status = "待邀请"
+		item.Sort = 1
+		item.ArticleTitle = article.Title
+		item.CreateTime = time.Now()
+		item.ModifyTime = time.Now()
+		item.ArticleIdMd5 = article.ArticleIdMd5
+		_, err = models.AddCygxInterviewApply(item)
+		if err != nil {
+			br.Msg = "申请失败"
+			br.ErrMsg = "申请失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "申请成功"
+		resp.Status = 1
+		//发送模板消息
+		if user.CompanyId > 1 {
+			mobile := user.Mobile
+			if mobile == "" {
+				mobile = user.Email
+			}
+			sellerItem, _ := models.GetSellerByCompanyId(user.CompanyId)
+			if sellerItem != nil && sellerItem.AdminId > 0 && user.Mobile != "" {
+				openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
+				if openIpItem != nil && openIpItem.OpenId != "" {
+					go services.SendInterviewApplyTemplateMsg(user.RealName, sellerItem.CompanyName, mobile, article.Title, openIpItem)
+				}
+			}
+		}
+	} else {
+		err = models.RemoveArticleInterviewApply(uid, req.ArticleId)
+		if err != nil {
+			br.Msg = "取消申请失败"
+			br.ErrMsg = "取消申请失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "已取消申请"
+		resp.Status = 2
+		if user.CompanyId > 1 {
+			mobile := user.Mobile
+			if mobile == "" {
+				mobile = user.Email
+			}
+			sellerItem, _ := models.GetSellerByCompanyId(user.CompanyId)
+			if sellerItem != nil && sellerItem.AdminId > 0 && user.Mobile != "" {
+				openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
+				if openIpItem != nil && openIpItem.OpenId != "" {
+					go services.SendInterviewApplyCancelTemplateMsg(user.RealName, sellerItem.CompanyName, mobile, article.Title, openIpItem)
+				}
+			}
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 获取报告详情
+// @Description 获取报告详情接口
+// @Param   ArticleIdMd5   query   int  true       "报告ID"
+// @Success 200 {object} models.ArticleDetailResp
+// @router /look/detail [get]
+func (this *ArticleControllerMobile) DetailMd5() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+
+	articleIdMd5 := this.GetString("ArticleIdMd5")
+	if articleIdMd5 == "" {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+	resp := new(models.ArticleDetailResp)
+	detail, err := models.GetArticleDetailByIdMd5(articleIdMd5)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+	articleId := detail.ArticleId
+	detail.Body = html.UnescapeString(detail.Body)
+
+	hasPermission := 2
+	//`description:"1:有该行业权限,正常展示,2:无该行业权限,不存在权益客户下,3:无该品类权限,4:潜在客户,未提交过申请,5:潜在客户,已提交过申请"`
+	if user.CompanyId > 1 {
+		companyPermission, err := models.GetCompanyPermission(user.CompanyId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取公司权限失败,Err:" + err.Error()
+			return
+		}
+		detail.Body = html.UnescapeString(detail.Body)
+		detail.Body = strings.Replace(detail.Body, "<p data-f-id=\"pbf\" style=\"text-align: center; font-size: 14px; margin-top: 30px; opacity: 0.65; font-family: sans-serif;\">Powered by <a href=\"https://www.froala.com/wysiwyg-editor?pb=1\" title=\"Froala Editor\">Froala Editor</a></p>", "", -1)
+		detail.Body = strings.Replace(detail.Body, "pre", "div", -1)
+		detail.Abstract, _ = services.GetReportContentTextSubNew(detail.Abstract)
+		if companyPermission == "" {
+			hasPermission = 2
+		} else {
+			var articlePermissionPermissionName string
+			if detail.CategoryId > 0 {
+				articlePermission, err := models.GetArticlePermission(detail.CategoryId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取报告权限失败,Err:" + err.Error() + articleIdMd5
+					return
+				}
+				if articlePermission == nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "报告权限不存在,Err:" + articleIdMd5
+					return
+				}
+				articlePermissionPermissionName = articlePermission.PermissionName
+			} else {
+				articlePermissionPermissionName = detail.CategoryName
+			}
+			var hasPersion bool
+			slice := strings.Split(articlePermissionPermissionName, ",")
+			for _, v := range slice {
+				if strings.Contains(companyPermission, v) {
+					hasPersion = true
+				}
+			}
+			userType, _, err := services.GetUserType(user.CompanyId)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+				return
+			}
+			if userType == 1 && strings.Contains(detail.CategoryName, "研选") {
+				hasPersion = false
+			}
+			if detail.IsReport == 1 {
+				detailCategory, err := models.GetdetailByCategoryIdSando(detail.CategoryId)
+				if err != nil && err.Error() != utils.ErrNoRow() {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取信息失败,Err:" + err.Error() + "categoryID 不存在:" + strconv.Itoa(detail.CategoryId)
+					return
+				}
+				permissionStr, err := models.GetCompanyPermissionByUser(user.CompanyId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+					return
+				}
+				if detailCategory != nil {
+					if detailCategory.PermissionType == 1 {
+						if !strings.Contains(permissionStr, detailCategory.ChartPermissionName+"(主观)") {
+							hasPersion = false
+						}
+					} else if detailCategory.PermissionType == 2 {
+						if !strings.Contains(permissionStr, detailCategory.ChartPermissionName+"(客观)") {
+							hasPersion = false
+						}
+					}
+				}
+			}
+			if hasPersion {
+				hasPermission = 1
+				record := new(models.CygxArticleHistoryRecordNewpv)
+				record.UserId = uid
+				record.ArticleId = articleId
+				record.CreateTime = time.Now()
+				record.ModifyTime = time.Now()
+				record.Mobile = user.Mobile
+				record.Email = user.Email
+				record.CompanyId = user.CompanyId
+				record.CompanyName = user.CompanyName
+				//新增浏览记录
+				go models.AddCygxArticleViewRecordNewpv(record)
+
+				//30分钟之内阅读同一篇文章不错二次推送
+				key := "CYGX_ARTICLE_READ" + strconv.Itoa(articleId) + "_" + strconv.Itoa(uid)
+				if !utils.Rc.IsExist(key) {
+					go services.ArticleUserRemind(user, detail, 1)
+					utils.Rc.Put(key, 1, 30*time.Second)
+				}
+			}
+			if hasPermission == 1 {
+				key := "CYGX_ARTICLE_" + strconv.Itoa(articleId) + "_" + strconv.Itoa(uid)
+				if !utils.Rc.IsExist(key) {
+					//新增浏览记录
+					record := new(models.CygxArticleViewRecord)
+					record.UserId = uid
+					record.ArticleId = articleId
+					record.CreateTime = time.Now()
+					record.Mobile = user.Mobile
+					record.Email = user.Email
+					record.CompanyId = user.CompanyId
+					record.CompanyName = user.CompanyName
+					go models.AddCygxArticleViewRecord(record)
+					utils.Rc.Put(key, 1, 5*time.Second)
+					models.ModifyReportLastViewTime(uid)
+				}
+			}
+		}
+		//作者头像
+		if detail.DepartmentId > 0 {
+			departmentDetail, err := models.GetArticleDepartmentDateilById(detail.DepartmentId)
+			if err == nil {
+				detail.DepartmentImgUrl = departmentDetail.ImgUrl
+				detail.NickName = departmentDetail.NickName
+			}
+		}
+	}
+	detail.SellerAndMobile = "" //业务需要强制处理为空
+	resp.HasPermission = hasPermission
+	if hasPermission == 1 {
+		detail.Abstract, _ = services.GetReportContentTextSub(detail.Abstract)
+		resp.Detail = detail
+	} else {
+		if user.Mobile != "" {
+			resp.Mobile = user.Mobile
+		} else {
+			resp.Mobile = user.Email
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 上传文章阅读时间
+// @Description 上传文章阅读时间接口
+// @Param  request	body models.AddStopTimeRep true "type json string"
+// @Success 200 {object} models.ArticleDetailResp
+// @router /addStopTime [post]
+func (this *ArticleController) AddStopTime() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.AddStopTimeRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	uid := user.UserId
+	articleId := req.ArticleId
+	stopTime := req.StopTime
+	outType := req.OutType
+	source := req.Source
+	if articleId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+	if stopTime == 0 {
+		stopTime = 1
+	}
+	if outType != 2 {
+		outType = 1
+	}
+	if source != "PC" {
+		source = "MOBILE"
+	}
+
+	detail := new(models.ArticleDetail)
+	hasPermission := 0
+	hasFree := 0
+
+	//判断是否已经申请过
+	applyCount, err := models.GetApplyRecordCount(uid)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+		return
+	}
+	//`description:"1:有该行业权限,正常展示,2:无该行业权限,不存在权益客户下,3:无该品类权限,4:潜在客户,未提交过申请,5:潜在客户,已提交过申请"`
+	if user.CompanyId > 1 {
+		companyPermission, err := models.GetCompanyPermission(user.CompanyId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请访谈失败,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		detail, err = models.GetArticleDetailById(articleId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取文章信息失败,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if companyPermission == "" {
+			if applyCount > 0 {
+				hasPermission = 5
+			} else {
+				hasPermission = 2
+			}
+			hasFree = 2
+			goto Loop
+		} else {
+			hasFree = 1
+			var articlePermissionPermissionName string
+			if detail.CategoryId > 0 {
+				articlePermission, err := models.GetArticlePermission(detail.CategoryId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取报告权限失败,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+					return
+				}
+				if articlePermission == nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "报告权限不存在,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+					return
+				}
+				articlePermissionPermissionName = articlePermission.PermissionName
+			} else {
+				articlePermissionPermissionName = detail.CategoryName
+			}
+			var hasPersion bool
+			slice := strings.Split(articlePermissionPermissionName, ",")
+			for _, v := range slice {
+				if strings.Contains(companyPermission, v) {
+					hasPersion = true
+				}
+			}
+			if hasPersion {
+				go services.ArticleHistoryStopTime(articleId, stopTime, outType, user)
+			} else { //无该行业权限
+				hasPermission = 3
+			}
+		}
+	} else { //潜在客户
+		if applyCount > 0 {
+			hasPermission = 5
+		} else {
+			hasPermission = 4
+		}
+	}
+Loop:
+	resp := new(models.ArticleDetailAddStopTimeRep)
+	resp.HasPermission = hasPermission
+	resp.HasFree = hasFree
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	br.Data = resp
+}
+
+// @Title 文章带问
+// @Description 新增文章带问接口
+// @Param	request	body models.AddArticleAskRep true "type json string"
+// @Success Ret=200 新增成功
+// @router /askAdd [post]
+func (this *ArticleController) AskAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.AddArticleAskRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.Content == "" {
+		br.Msg = "建议内容不可为空"
+		return
+	}
+
+	content := req.Content
+	itemToken, err := services.WxGetToken()
+	if err != nil {
+		br.Msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if itemToken.AccessToken == "" {
+		br.Msg = "accessToken is empty"
+		return
+	}
+	commerr, err := weapp.MSGSecCheck(itemToken.AccessToken, content)
+	if err != nil {
+		br.Msg = "内容校验失败!"
+		br.ErrMsg = "内容校验失败,Err:" + err.Error()
+
+		return
+	}
+	if commerr.ErrCode != 0 {
+		br.Msg = "内容违规,请重新提交!"
+		br.ErrMsg = "颜文字内容违规,Err:" + commerr.ErrMSG
+		return
+	}
+
+	articleId := req.ArticleId
+	count, _ := models.GetArticleCountById(articleId)
+	if count == 0 {
+		br.Msg = "操作失败"
+		br.ErrMsg = "文章ID错误,不存在 articleId:" + strconv.Itoa(articleId)
+		return
+	}
+	companyDetail, err := models.GetCompanyDetailById(user.CompanyId)
+	if err != nil {
+		br.Msg = "提交失败!"
+		br.ErrMsg = "获取客户详情失败,Err:" + err.Error()
+		return
+	}
+	if companyDetail == nil {
+		br.Msg = "提交失败!"
+		br.ErrMsg = "客户不存在,uid:" + strconv.Itoa(user.UserId)
+		return
+	}
+	item := new(models.CygxArticleAsk)
+	item.UserId = user.UserId
+	item.ArticleId = req.ArticleId
+	item.CompanyId = user.CompanyId
+	item.CompanyName = companyDetail.CompanyName
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.Content = content
+	_, err = models.AddArticleAsk(item)
+	if err != nil {
+		br.Msg = "提交失败"
+		br.ErrMsg = "提交失败,Err:" + err.Error()
+		return
+	}
+	companyItem, err := models.GetSellerDetailAllByCompanyId(user.CompanyId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取所属销售信息失败,Err:" + err.Error()
+		return
+	}
+	var mobile string
+	if utils.RunMode == "release" {
+		//mobile = utils.WxMsgTemplateIdAskMsgMobileAll + "," + companyItem.Mobile
+		mobile = utils.WxMsgTemplateIdAskMsgMobileAll
+	} else {
+		mobile = utils.WxMsgTemplateIdAskMsgMobile
+	}
+	openIdList, err := models.GetWxOpenIdByMobileList(mobile)
+	if err != nil {
+		br.Msg = "提交失败"
+		br.ErrMsg = "提交失败,Err:" + err.Error()
+		return
+	}
+	detail, err := models.GetArticleDetailById(articleId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+	companyName := user.CompanyName + "-" + user.RealName + "(" + companyItem.SellerName + ")"
+	go services.SendWxMsgWithAsk(companyName, time.Now().Format(utils.FormatDateTime), content, detail.Title, openIdList, req.ArticleId)
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "提交成功"
+}
+
+// @Title 下载PDF打水印
+// @Description 下载PDF打水印接口
+// @Param   ArticleId   query   int  true       "报告ID"
+// @Success 200 {object} models.ArticleDetailFileLink
+// @router /pdfwatermark [get]
+func (this *ArticleController) Pdfwatermark() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	articleId, err := this.GetInt("ArticleId")
+	if articleId <= 0 {
+		br.Msg = "文章不存在"
+		br.ErrMsg = "文章不存在,文章ID错误"
+		return
+	}
+	//缓存校验
+	cacheKey := fmt.Sprint("xygx:apply_record:add:", uid, "ArticleId_", articleId)
+	ttlTime := utils.Rc.GetRedisTTL(cacheKey)
+	if ttlTime > 0 && user.CompanyId != 16 {
+		br.Msg = "下载失败,下载过于频繁"
+		br.ErrMsg = "下载失败,下载过于频繁:mobile" + user.Mobile
+		return
+	}
+	resp := new(models.ArticleDetailFileLink)
+	detail := new(models.ArticleDetail)
+	detail, err = models.GetArticleDetailById(articleId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+	fileLink := detail.FileLink
+	if fileLink == "" {
+		br.Msg = "下载失败"
+		br.ErrMsg = "下载失败,报告链接不存在"
+		return
+	}
+	mobile := user.Mobile
+	if mobile == "" {
+		mobile = user.Email
+	}
+	sliceLink := strings.Split(fileLink, "/")
+	uploadDir := "static/pdf/"
+	//判断文件夹是否存在,不存在则创建
+	if !utils.FileIsExist(uploadDir) {
+		err = os.MkdirAll(uploadDir, 0755)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "存储目录创建失败,Err:" + err.Error()
+			return
+		}
+	}
+	var oldFile string
+	var newFile string
+	//获取PDF源文件名称
+	pdfName := sliceLink[len(sliceLink)-1]
+	pdfName = utils.MD5(pdfName) + ".pdf"
+	oldFile = uploadDir + pdfName
+	//判断PDF本地是否存在,不存在则保存到本地
+	if !utils.FileIsExist(oldFile) {
+		res, err := nhttp.Get(fileLink)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取源文件失败,Err:" + err.Error()
+			return
+		}
+		defer res.Body.Close()
+		// 获得get请求响应的reader对象
+		reader := bufio.NewReaderSize(res.Body, 32*1024)
+		file, err := os.Create(oldFile)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "保存源文件到本地失败,Err:" + err.Error()
+			return
+		}
+		defer file.Close()
+		//获得文件的writer对象
+		writer := bufio.NewWriter(file)
+		written, _ := io.Copy(writer, reader)
+		fmt.Printf("Total length: %d", written)
+	}
+	newFile = uploadDir + "new_" + pdfName
+	onTop := true
+	wm, err := pdfcpu.ParseTextWatermarkDetails(mobile, " op:.4, pos:c ,points:16 ", onTop, 1)
+	if err != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "生成水印文件失败,Err:" + err.Error()
+		return
+	}
+	err = api.AddWatermarksFile(oldFile, newFile, nil, wm, nil)
+	if err != nil {
+		//br.Msg = "下载失败"
+		//br.ErrMsg = "生成水印PDF失败,Err:" + err.Error()
+		resp.FileLink = fileLink
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+		return
+	}
+
+	randStr := utils.GetRandStringNoSpecialChar(28)
+	fileName := randStr + ".pdf"
+	savePath := uploadDir + time.Now().Format("200601/20060102/")
+	savePath += fileName
+	//上传到阿里云
+	err = services.UploadFileToAliyun(fileName, newFile, savePath)
+	if err != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "文件上传失败,Err:" + err.Error()
+		return
+	}
+	fileHost := "https://hzstatic.hzinsights.com/"
+	resourceUrl := fileHost + savePath
+	defer func() {
+		os.Remove(newFile)
+	}()
+
+	utils.Rc.SetNX(cacheKey, user.Mobile, time.Minute*5)
+	resp.FileLink = resourceUrl
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 约访专家
+// @Description 约访专家接口
+// @Param  request	body models.CygxArticleIdReq true "type json string"
+// @Success 200 {object}
+// @router /applyAppointmentExpert [post]
+func (this *ArticleController) ApplyAppointmentExpert() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.CygxArticleIdReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	articleId := req.ArticleId
+	var condition string
+	var pars []interface{}
+	condition += ` AND article_id =? AND user_id = ?  `
+	pars = append(pars, articleId, user.UserId)
+	total, err := models.GetCygxArticleApplyAppointmentExpertCount(condition, pars)
+	if err != nil {
+		br.Msg = "约访专家失败"
+		br.ErrMsg = "约访专家失败,Err:" + err.Error()
+		return
+	}
+	if total > 0 {
+		br.Msg = "您已提交申请,请勿重复提交。"
+		return
+	}
+	err = services.AddArticleApplyAppointmentExpert(user, articleId)
+	if err != nil {
+		br.Msg = "约访专家失败"
+		br.ErrMsg = "约访专家失败,Err:" + err.Error()
+		return
+	}
+	services.SendArticleApplyAppointmentExpertTemplateMsg(user, articleId)
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 182 - 0
controllers/banner.go

@@ -0,0 +1,182 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+)
+
+// Banner
+type BannerController struct {
+	BaseAuthController
+}
+
+// @Title 列表
+// @Description 列表接口
+// @Success Ret=200 {object} cygx.CygxBannerListResp
+// @router /list [get]
+func (this *BannerController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	resp := new(models.CygxBannerListResp)
+	var condition string
+	var pars []interface{}
+	condition += " AND art.show_type IN (0,1)	 AND art.status = 1 ORDER BY art.list_type ASC   , art.sort ASC  "
+	list, err := models.GetCygxBannerList(condition, pars, 0, 99999)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	bannerImgList, err := models.GetCygxBannerImgList()
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	mapImg := make(map[int]string)
+	for _, v := range bannerImgList {
+		mapImg[v.ImgId] = v.IndexImg
+	}
+	for _, v := range list {
+		v.IndexImg = mapImg[v.ImgId]
+		v.BannerUrlResp = services.GetBannerUrlBody(v.Link)
+	}
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 记录点击信息
+// @Description 记录点击信息
+// @Param	request	body cygx.CygxBannerIdReq true "type json string"
+// @Success 200 Ret=200 发布成功
+// @router /add/history [post]
+func (this *BannerController) History() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.CygxBannerIdReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	bannerId := req.BannerId
+	if bannerId == 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,id不可为空"
+		return
+	}
+	go services.AddCygxBannerHistory(user, bannerId)
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "记录成功"
+}
+
+// @Title 研选banner列表
+// @Description 研选banner列表接口
+// @Success Ret=200 {object} cygx.CygxBannerListResp
+// @router /listYx [get]
+func (this *BannerController) ListYx() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	resp := new(models.BannerUrlYxListResp)
+	var listA []*models.BannerUrlYxResp
+	var listB []*models.BannerUrlYxResp
+
+	if utils.RunMode == "release" {
+		listA = []*models.BannerUrlYxResp{
+			&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/1.png", Path: "pages-purchaser/leaflet/leaflet?leafletImage=https%3A%2F%2Fhzstatic.hzinsights.com%2Fcygx%2Fconfig%2Fresearch_11_0.png"},
+			&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/2.png", Path: "pages-purchaser/survey/surveySubmit"},
+			//&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/4.png", Path: "pages-purchaser/specialColumn/specialColumn"},
+			&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/3_long.png", Path: "pages-purchaser/researchList/researchList"},
+		}
+		listB = []*models.BannerUrlYxResp{
+			//&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/3.png", Path: "pages-purchaser/researchList/researchList"},
+			&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/4_short.png", Path: "pages-purchaser/specialColumn/specialColumn"},
+		}
+	} else {
+		listA = []*models.BannerUrlYxResp{
+			&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/1.png", Path: "pages-purchaser/leaflet/leaflet?leafletImage=https%3A%2F%2Fhzstatic.hzinsights.com%2Fcygx%2Fconfig%2Fresearch_11_0.png"},
+			&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/2.png", Path: "pages-purchaser/survey/surveySubmit"},
+		}
+		listB = []*models.BannerUrlYxResp{
+			//&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/4_short.png", Path: "pages-purchaser/specialColumn/specialColumn"},
+			&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/3.png", Path: "pages-purchaser/researchList/researchList"},
+		}
+	}
+
+	resp.ListA = listA
+	resp.ListB = listB
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 我要调研内容详情
+// @Description 我要调研内容详情接口
+// @Param   SuveryId   query   int  true       "ID"
+// @Success Ret=200 {object} cygx.CygxBannerListResp
+// @router /yxSurvey/detail [get]
+func (this *BannerController) YxSurveyDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	suveryId, _ := this.GetInt("SuveryId")
+	resp := new(models.CygxBannerYxSurveyRespDetailResp)
+	detail, err := models.GetCygxBannerYxSurveyDetail(suveryId)
+	if err != nil {
+		br.Msg = "详情不存在"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	resp.Detail = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 141 - 0
controllers/base_auth.go

@@ -0,0 +1,141 @@
+package controllers
+
+import (
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/adapter"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"net/http"
+	"net/url"
+	"strconv"
+
+	"github.com/rdlucklib/rdluck_tools/log"
+)
+
+var apiLog *log.Log
+
+func init() {
+	if utils.RunMode == "release" {
+		logDir := `/data/rdlucklog/hongze_mfyx`
+		apiLog = log.Init("20060102.api", logDir)
+	} else {
+		apiLog = log.Init("20060102.api")
+	}
+}
+
+type BaseAuthController struct {
+	beego.Controller
+	User  *models.WxUserItem
+	Token string
+}
+
+func (this *BaseAuthController) Prepare() {
+	//fmt.Println("enter prepare")
+	method := this.Ctx.Input.Method()
+	uri := this.Ctx.Input.URI()
+	fmt.Println("Url:", uri)
+	if method != "HEAD" {
+		if method == "POST" || method == "GET" {
+			authorization := this.Ctx.Input.Header("Authorization")
+			inviteCompany := this.Ctx.Input.Header("From")
+			if authorization == "" {
+				authorization = this.GetString("Authorization")
+			}
+			this.Token = authorization
+			if authorization == "" {
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "请重新授权!", ErrMsg: "请重新授权:Token is empty or account is empty"}, false, false)
+				this.StopRun()
+				return
+			}
+			session, err := models.GetSessionByToken(authorization)
+			if err != nil {
+				if err.Error() == utils.ErrNoRow() {
+					this.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "Token 信息已变更:Token: " + authorization}, false, false)
+					this.StopRun()
+					return
+				}
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
+				this.StopRun()
+				return
+			}
+			if session == nil {
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "sesson is empty "}, false, false)
+				this.StopRun()
+				return
+			}
+			//wxUser, err := models.GetWxUserItemByUserId(session.UserId)
+			wxUser, err := services.GetWxUserItemByOpenId(session.OpenId)
+			if err != nil && err != services.ERR_USER_NOT_BIND {
+				if err.Error() == utils.ErrNoRow() {
+					this.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "获取信息失败 " + strconv.Itoa(session.UserId)}, false, false)
+					this.StopRun()
+					return
+				}
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取wx_user信息异常,Eerr:" + err.Error()}, false, false)
+				this.StopRun()
+				return
+			}
+			if wxUser == nil {
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "admin is empty "}, false, false)
+				this.StopRun()
+				return
+			}
+			wxUser.InviteCompany = inviteCompany
+			this.User = wxUser
+			go services.AddCygxPageHistoryRecord(this.User, this.Ctx)
+		} else {
+			this.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
+			this.StopRun()
+			return
+		}
+	}
+}
+
+func (c *BaseAuthController) ServeJSON(encoding ...bool) {
+	var (
+		hasIndent   = false
+		hasEncoding = false
+	)
+	if beego.BConfig.RunMode == beego.PROD {
+		hasIndent = false
+	}
+	if len(encoding) > 0 && encoding[0] == true {
+		hasEncoding = true
+	}
+	if c.Data["json"] == nil {
+		go utils.SendEmail(utils.APPNAME+" "+utils.RunMode+"异常提醒:", "接口:"+"URI:"+c.Ctx.Input.URI()+";无返回值", utils.EmailSendToUsers)
+		return
+	}
+	baseRes := c.Data["json"].(*models.BaseResponse)
+	if baseRes != nil && baseRes.Ret != 200 && baseRes.Ret != 408 && baseRes.IsSendEmail {
+		body, _ := json.Marshal(baseRes)
+		msgBody := "URI:" + c.Ctx.Input.URI() + "<br/> ErrMsg:" + baseRes.ErrMsg + ";<br/>Msg:" + baseRes.Msg + ";<br/> Body:" + string(body) + ";<br/>" + c.Token
+		go utils.SendEmail(utils.APPNAME+" "+utils.RunMode+" 失败提醒", msgBody, utils.EmailSendToUsers)
+	}
+
+	c.JSON(c.Data["json"], hasIndent, hasEncoding)
+}
+
+func (c *BaseAuthController) JSON(data interface{}, hasIndent bool, coding bool) error {
+	c.Ctx.Output.Header("Content-Type", "application/json; charset=utf-8")
+	var content []byte
+	var err error
+	if hasIndent {
+		content, err = json.MarshalIndent(data, "", "  ")
+	} else {
+		content, err = json.Marshal(data)
+	}
+	if err != nil {
+		http.Error(c.Ctx.Output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
+		return err
+	}
+	ip := c.Ctx.Input.IP()
+	requestBody, _ := url.QueryUnescape(string(c.Ctx.Input.RequestBody))
+	apiLog.Println("请求地址:", c.Ctx.Input.URI(), "Authorization:", c.Ctx.Input.Header("Authorization"), "RequestBody:", requestBody, "ResponseBody", string(content), "IP:", ip)
+	if coding {
+		content = []byte(utils.StringsToJSON(string(content)))
+	}
+	return c.Ctx.Output.Body(content)
+}

+ 137 - 0
controllers/base_auth_mobile.go

@@ -0,0 +1,137 @@
+package controllers
+
+import (
+	"encoding/json"
+	"fmt"
+	beego "github.com/beego/beego/v2/adapter"
+	"hongze/hongze_mfyx/services"
+	"net/http"
+	"net/url"
+	"strconv"
+
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/utils"
+
+	"github.com/rdlucklib/rdluck_tools/log"
+)
+
+func init() {
+	if utils.RunMode == "release" {
+		logDir := `/data/rdlucklog/hongze_mfyx`
+		apiLog = log.Init("20060102.api", logDir)
+	} else {
+		apiLog = log.Init("20060102.api")
+	}
+}
+
+type BaseAuthMobileController struct {
+	beego.Controller
+	User  *models.WxUserItem
+	Token string
+}
+
+func (this *BaseAuthMobileController) Prepare() {
+	fmt.Println("enter prepare")
+	method := this.Ctx.Input.Method()
+	uri := this.Ctx.Input.URI()
+	fmt.Println("Url:", uri)
+	if method != "HEAD" {
+		if method == "POST" || method == "GET" {
+			authorization := this.Ctx.Input.Header("Authorization")
+			if authorization == "" {
+				authorization = this.GetString("Authorization")
+			}
+			this.Token = authorization
+			if authorization == "" {
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "请重新授权!", ErrMsg: "请重新授权:Token is empty or account is empty"}, false, false)
+				this.StopRun()
+				return
+			}
+			session, err := models.GetCygxSessionMobile(authorization)
+			if err != nil {
+				if err.Error() == utils.ErrNoRow() {
+					this.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "Token 信息已变更:Token: " + authorization}, false, false)
+					this.StopRun()
+					return
+				}
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
+				this.StopRun()
+				return
+			}
+			if session == nil {
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "sesson is empty "}, false, false)
+				this.StopRun()
+				return
+			}
+			//wxUser, err := models.GetWxUserItemByUserId(session.UserId)
+			wxUser, err := models.GetWxUserAouthByMobile(session.Mobile)
+			if err != nil && err != services.ERR_USER_NOT_BIND {
+				if err.Error() == utils.ErrNoRow() {
+					this.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "获取信息失败 " + strconv.Itoa(session.UserId)}, false, false)
+					this.StopRun()
+					return
+				}
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取wx_user信息异常,Eerr:" + err.Error()}, false, false)
+				this.StopRun()
+				return
+			}
+			if wxUser == nil {
+				this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "admin is empty "}, false, false)
+				this.StopRun()
+				return
+			}
+			this.User = wxUser
+		} else {
+			this.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
+			this.StopRun()
+			return
+		}
+	}
+}
+
+func (c *BaseAuthMobileController) ServeJSON(encoding ...bool) {
+	var (
+		hasIndent   = false
+		hasEncoding = false
+	)
+	if beego.BConfig.RunMode == beego.PROD {
+		hasIndent = false
+	}
+	if len(encoding) > 0 && encoding[0] == true {
+		hasEncoding = true
+	}
+	if c.Data["json"] == nil {
+		go utils.SendEmail(utils.APPNAME+" "+utils.RunMode+"异常提醒:", "接口:"+"URI:"+c.Ctx.Input.URI()+";无返回值", utils.EmailSendToUsers)
+		return
+	}
+	baseRes := c.Data["json"].(*models.BaseResponse)
+	if baseRes != nil && baseRes.Ret != 200 && baseRes.Ret != 408 && baseRes.IsSendEmail {
+		body, _ := json.Marshal(baseRes)
+		msgBody := "URI:" + c.Ctx.Input.URI() + "<br/> ErrMsg:" + baseRes.ErrMsg + ";<br/>Msg:" + baseRes.Msg + ";<br/> Body:" + string(body) + ";<br/>" + c.Token
+		go utils.SendEmail(utils.APPNAME+" "+utils.RunMode+" 失败提醒", msgBody, utils.EmailSendToUsers)
+	}
+
+	c.JSON(c.Data["json"], hasIndent, hasEncoding)
+}
+
+func (c *BaseAuthMobileController) JSON(data interface{}, hasIndent bool, coding bool) error {
+	c.Ctx.Output.Header("Content-Type", "application/json; charset=utf-8")
+	var content []byte
+	var err error
+	if hasIndent {
+		content, err = json.MarshalIndent(data, "", "  ")
+	} else {
+		content, err = json.Marshal(data)
+	}
+	if err != nil {
+		http.Error(c.Ctx.Output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
+		return err
+	}
+	ip := c.Ctx.Input.IP()
+	requestBody, _ := url.QueryUnescape(string(c.Ctx.Input.RequestBody))
+	apiLog.Println("请求地址:", c.Ctx.Input.URI(), "Authorization:", c.Ctx.Input.Header("Authorization"), "RequestBody:", requestBody, "ResponseBody", string(content), "IP:", ip)
+	if coding {
+		content = []byte(utils.StringsToJSON(string(content)))
+	}
+	return c.Ctx.Output.Body(content)
+}

+ 124 - 0
controllers/base_common.go

@@ -0,0 +1,124 @@
+package controllers
+
+import (
+	"encoding/json"
+	"net/http"
+	"net/url"
+	"strings"
+
+	beego "github.com/beego/beego/v2/adapter"
+
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/utils"
+)
+
+type BaseCommonController struct {
+	beego.Controller
+	//User  *models.WxUserItem
+	Token string
+}
+
+func (this *BaseCommonController) Prepare() {
+	var requestBody string
+	method := this.Ctx.Input.Method()
+	if method == "GET" {
+		requestBody = this.Ctx.Request.RequestURI
+	} else {
+		requestBody, _ = url.QueryUnescape(string(this.Ctx.Input.RequestBody))
+	}
+	ip := this.Ctx.Input.IP()
+	apiLog.Println("请求地址:", this.Ctx.Input.URI(), "RequestBody:", requestBody, "IP:", ip)
+
+	authorization := this.Ctx.Input.Header("Authorization")
+	if authorization == "" {
+		cookie := this.Ctx.GetCookie("rddp_access_token")
+		utils.FileLog.Info("authorization:%s,cookie:%s", authorization, cookie)
+		authorization = cookie
+	}
+	uri := this.Ctx.Input.URI()
+	utils.FileLog.Info("URI:%s", uri)
+	if strings.Contains(uri, "/api/wechat/login") {
+		authorization = ""
+	}
+	if authorization != "" {
+		//session, err := models.GetSessionByToken(authorization)
+		//if err != nil {
+		//	if err.Error() == utils.ErrNoRow() {
+		//		this.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "Token 信息已变更:Token: " + authorization}, false, false)
+		//		this.StopRun()
+		//		return
+		//	}
+		//	this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
+		//	this.StopRun()
+		//	return
+		//}
+		//if session == nil {
+		//	this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "sesson is empty "}, false, false)
+		//	this.StopRun()
+		//	return
+		//}
+		//wxUser, err := models.GetWxUserItemByUserId(session.UserId)
+		//if err != nil {
+		//	if err.Error() == utils.ErrNoRow() {
+		//		this.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "获取admin 信息失败 " + strconv.Itoa(session.UserId)}, false, false)
+		//		this.StopRun()
+		//		return
+		//	}
+		//	this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取wx_user信息异常,Eerr:" + err.Error()}, false, false)
+		//	this.StopRun()
+		//	return
+		//}
+		//if wxUser == nil {
+		//	this.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "admin is empty "}, false, false)
+		//	this.StopRun()
+		//	return
+		//}
+		//this.User = wxUser
+	}
+	//this.Token = authorization
+}
+
+func (c *BaseCommonController) ServeJSON(encoding ...bool) {
+	var (
+		hasIndent   = false
+		hasEncoding = false
+	)
+	if beego.BConfig.RunMode == beego.PROD {
+		hasIndent = false
+	}
+	if len(encoding) > 0 && encoding[0] == true {
+		hasEncoding = true
+	}
+	if c.Data["json"] == nil {
+		go utils.SendEmail(utils.APPNAME+" "+utils.RunMode+"异常提醒", "接口:"+"URI:"+c.Ctx.Input.URI()+";无返回值", utils.EmailSendToUsers)
+		return
+	}
+	baseRes := c.Data["json"].(*models.BaseResponse)
+	if baseRes != nil && !baseRes.Success && baseRes.IsSendEmail {
+		go utils.SendEmail(utils.APPNAME+" "+utils.RunMode+" 失败提醒", "URI:"+c.Ctx.Input.URI()+" ErrMsg:"+baseRes.ErrMsg+";Msg"+baseRes.Msg, utils.EmailSendToUsers)
+	}
+	c.JSON(c.Data["json"], hasIndent, hasEncoding)
+}
+
+func (c *BaseCommonController) JSON(data interface{}, hasIndent bool, coding bool) error {
+	c.Ctx.Output.Header("Content-Type", "application/json; charset=utf-8")
+	var content []byte
+	var err error
+	if hasIndent {
+		content, err = json.MarshalIndent(data, "", "  ")
+	} else {
+		content, err = json.Marshal(data)
+	}
+	if err != nil {
+		http.Error(c.Ctx.Output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
+		return err
+	}
+	ip := c.Ctx.Input.IP()
+	requestBody, _ := url.QueryUnescape(string(c.Ctx.Input.RequestBody))
+	apiLog.Println("请求地址:", c.Ctx.Input.URI(), "Authorization:", c.Ctx.Input.Header("Authorization"), "RequestBody:", requestBody, "ResponseBody", string(content), "IP:", ip)
+
+	if coding {
+		content = []byte(utils.StringsToJSON(string(content)))
+	}
+	return c.Ctx.Output.Body(content)
+}

+ 177 - 0
controllers/collection.go

@@ -0,0 +1,177 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+// Collection
+type CollectionController struct {
+	BaseAuthController
+}
+
+// @Title 精选看板、路演banner列表
+// @Description 精选看板、路演banner列表接口
+// @Success Ret=200 {object} cygx.CollectionBannerListResp
+// @router /banner/list [get]
+func (this *CollectionController) BannerList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	resp := new(models.CollectionBannerListResp)
+	var listA []*models.CollectionBannerResp
+	listB := new(models.CollectionBannerResp)
+	listA = []*models.CollectionBannerResp{
+		&models.CollectionBannerResp{Title: "", IndexImg: "https://hzstatic.hzinsights.com/cygx/banner/xcx/lyhf.png", Path: "/reportPages/trainVideoPages/trainVideoPages"},
+	}
+	listB.Title = ""
+	listB.IndexImg = "https://hzstatic.hzinsights.com/cygx/banner/xcx/jxkb.png"
+	listB.IsShowSustainable = true
+	resp.ListA = listA
+	resp.ListB = listB
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 精选看板跳转详情地址
+// @Description 精选看板跳转详情地址接口
+// @Success Ret=200 {object} cygx.CollectionBannerListResp
+// @router /detail [get]
+func (this *CollectionController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	resp := new(models.CollectionDetailResp)
+	if user.Mobile != "" {
+
+		resp.HttpUrl = utils.COLLECTIONS_INFO_HTTP_URL
+	} else {
+		resp.HttpUrl = utils.COLLECTIONS_INFO_HTTP_URL
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 提交精选看板申请接口
+// @Description 提交精选看板申请接口
+// @Param	request	body cygx.CygxBannerIdReq true "type json string"
+// @Success 200 Ret=200 提交成功
+// @router /apply/add [post]
+func (this *CollectionController) ApplyAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.ApplyCollectionReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	content := req.Content
+	if content == "" {
+		br.Msg = "内容不能为空"
+		br.ErrMsg = "内容不能为空"
+		return
+	}
+	item := new(models.CygxApplyCollection)
+	item.UserId = user.UserId
+	item.CreateTime = time.Now()
+	item.ModifyTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	item.Content = content
+	item.RegisterPlatform = utils.REGISTER_PLATFORM
+	sellerItem, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return
+	}
+	item.RealName = user.RealName
+	if sellerItem != nil {
+		item.SellerName = sellerItem.RealName
+	}
+	newId, err := models.AddCygxApplyCollection(item)
+	services.SendCygxApplyCollectionTemplateMsg(user, content, int(newId))
+	if err != nil {
+		br.Msg = "申请失败"
+		br.ErrMsg = "申请失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "记录成功"
+}
+
+// @Title  获取申请详情
+// @Description 获取申请详情接口
+// @Param   ApplyCollectionId   query   int  true       "ID"
+// @Success Ret=200 {object} cygx.CygxApplyCollectionDetailResp
+// @router /apply/detail [get]
+func (this *CollectionController) ApplyDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	resp := new(models.CygxApplyCollectionDetailResp)
+	applyCollectionId, _ := this.GetInt("ApplyCollectionId")
+	if applyCollectionId < 1 {
+		br.Msg = "请输入详情ID"
+		return
+	}
+	detail, err := models.GetCygxApplyCollectionDetail(applyCollectionId)
+	if err != nil {
+		br.Msg = "详情不存在"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	resp.Detail = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 331 - 0
controllers/config.go

@@ -0,0 +1,331 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"strings"
+	"time"
+)
+
+type ConfigController struct {
+	BaseAuthController
+}
+
+type BaseConfigController struct {
+	BaseCommonController
+}
+
+// @Title 获取搜索推荐词
+// @Description 获取搜索推荐词
+// @Success 200 {object} models.ConfigResp
+// @router /detail [get]
+func (this *ConfigController) BrowseHistoryList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	resp := new(models.ConfigResp)
+	detail := new(models.CygxConfig)
+	//configCode := "hot_search"
+	//detail, err := models.GetConfigByCode(configCode)
+	hotSearch, err := models.GetHotSearch()
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	var condition string
+	var pars []interface{}
+	currentTime := time.Now()
+	starTime := currentTime.AddDate(0, 0, -8).Format("2006-01-02") + " 00:00:00"
+	endTime := currentTime.AddDate(0, 0, -1).Format("2006-01-02") + " 23:59:59"
+	condition += ` AND create_time < ` + "'" + endTime + "'" + `AND create_time > ` + "'" + starTime + "'"
+	hotList, err := models.GetSearchKeyWordTop(condition, pars)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range hotList {
+		item := new(models.KeyWord)
+		item.KeyWord = v.KeyWord
+		resp.ListHot = append(resp.ListHot, item)
+	}
+	detail.ConfigValue = hotSearch
+	resp.Item = detail
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 页面访问统计
+// @Description 上传页面访问统计
+// @Param	request	body models.CygxPageHistoryRecordRep true "type json string"
+// @Success Ret=200 新增成功
+// @router /pageHistory [post]
+func (this *ConfigController) PageHistory() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.CygxPageHistoryRecordRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	pageType := req.PageType
+	var havePageType bool
+	PageType := []string{"Summary", "SummarySearch", "Report", "ReportSearch", "IndustryList", "Activit", "ActivitSearch", "ActivitParticulars", "ReportParticulars", "MySchedule", "LabelMore", "ArticleCopy"}
+	for _, v := range PageType {
+		if pageType == v {
+			havePageType = true
+		}
+	}
+	if !havePageType {
+		br.Msg = "新增失败"
+		br.ErrMsg = "PageType参数类型错误:" + pageType
+		return
+	}
+	item := new(models.CygxPageHistoryRecord)
+	item.UserId = user.UserId
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	item.DetailId = req.DetailId
+	item.ChartPermissionId = req.ChartPermissionId
+	item.IndustrialManagementId = req.IndustrialManagementId
+	item.PageType = req.PageType
+	_, err = models.AddCygxPageHistoryRecord(item)
+	if err != nil {
+		br.Msg = "新增访问记录失败"
+		br.ErrMsg = "新增访问记录失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+}
+
+// @Title 获取研选说明
+// @Description 获取研选说明接口
+// @Success 200 {object} models.ConfigResp
+// @router /descriptionOfResearch [get]
+func (this *ConfigController) DescriptionOfResearch() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	configCode := "description_of_research"
+	detail, err := models.GetConfigByCode(configCode)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ConfigResp)
+	resp.Item = detail
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 获取搜索推荐词(无需token)
+// @Description 获取搜索推荐词(无需token)
+// @Success 200 {object} models.ConfigResp
+// @router /detailPublic [get]
+func (this *BaseConfigController) HotDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	detail := new(models.CygxConfig)
+	hotSearch, err := models.GetHotSearch()
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	detail.ConfigValue = hotSearch
+	resp := new(models.ConfigResp)
+	resp.Item = detail
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 用户搜索记录统计
+// @Description 用户搜索记录统计
+// @Param   KeyWord   query   string  false       "搜索关键词"
+// @Success Ret=200 新增成功
+// @router /user/search/keyWordLog [post]
+func (this *ConfigController) KeyWordLog() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.CygxSearchKeyWordLogRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	keyWord := req.KeyWord
+	if keyWord == "" {
+		br.Msg = "搜索内容不能为空"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	if keyWord != "" {
+		go services.AddUserSearchLog(user, keyWord, 1)
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+}
+
+// @Title 关于我们浏览记录
+// @Description 关于我们浏览记录接口
+// @Success 200
+// @router /aboutUs/addHistory [post]
+func (this *ConfigController) AboutUsAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	go services.AddCygxAboutUsVideoHistory(user)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功!"
+}
+
+// @Title 买方研选产品介绍(无需token)
+// @Description 买方研选产品介绍接口(无需token)
+// @Success 200 {object} models.ConfigImgListResp
+// @router /research/introduce [get]
+func (this *BaseConfigController) ResearchIntroduce() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	conf, err := models.GetConfigByCode("research_introduce_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "买方研选产品介绍信息失败,Err:" + err.Error()
+		return
+	}
+	if conf.ConfigValue == "" {
+		br.Msg = "获取失败"
+		br.ErrMsg = "买方研选产品介绍信息失败"
+		return
+	}
+	list := new(*models.ConfigImgListResp)
+	if err = json.Unmarshal([]byte(conf.ConfigValue), &list); err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "买方研选产品介绍信配置值解析失败, Err: " + err.Error()
+		return
+	}
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = list
+}
+
+// @Title 买方研选报价单(无需token)
+// @Description 买方研选报价单(无需token)
+// @Success 200 {object} models.ConfigImgListResp
+// @router /research/quotation [get]
+func (this *BaseConfigController) ResearchQuotation() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	conf, err := models.GetConfigByCode("research_quotation_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "买方研选产品介绍信息失败,Err:" + err.Error()
+		return
+	}
+	if conf.ConfigValue == "" {
+		br.Msg = "获取失败"
+		br.ErrMsg = "买方研选产品介绍信息失败"
+		return
+	}
+	list := new(*models.ConfigImgListResp)
+	if err = json.Unmarshal([]byte(conf.ConfigValue), &list); err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "买方研选产品介绍信配置值解析失败, Err: " + err.Error()
+		return
+	}
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = list
+}
+
+// @Title 买方研选升级新资源海报(无需token)
+// @Description 买方研选升级新资源海报(无需token)
+// @Success 200 {object} models.ConfigImgListResp
+// @router /research/hb [get]
+func (this *BaseConfigController) ResearchHb() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	detail, err := models.GetConfigByCode("research_hb_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "买方研选升级新资源海报信息失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ConfigImgHbResp)
+	list := strings.Split(detail.ConfigValue, "{|}")
+	if len(list) == 0 {
+		list = make([]string, 0)
+	}
+	resp.HbImg = list[0]
+	resp.ButtonImg = list[len(list)-1]
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}

+ 524 - 0
controllers/home.go

@@ -0,0 +1,524 @@
+package controllers
+
+import (
+	"encoding/json"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"html"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type HomeController struct {
+	BaseAuthController
+}
+
+type BaseHomeController struct {
+	BaseCommonController
+}
+
+// @Title 首页列表接口
+// @Description 首页列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ChartPermissionId   query   int  true       "品类id,最新传0"
+// @Success 200 {object} models.HomeListResp
+// @router /list [get]
+func (this *HomeController) ListHome() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	chartPermissionId, _ := this.GetInt("ChartPermissionId")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+	var total int
+	resp := new(models.HomeListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.HaveResearch = true
+	userType, _, err := services.GetUserType(user.CompanyId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+		return
+	}
+	condition += ` AND is_summary = 1  `
+	if chartPermissionId > 0 {
+		categoryId, err := models.GetCategoryId(chartPermissionId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取分类权限信息失败,Err:" + err.Error()
+			return
+		}
+		categoryinfo, err := models.GetChartPermissionById(chartPermissionId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取信息失败,Err:" + err.Error()
+			return
+		}
+		if userType == 1 && categoryinfo.PermissionName == "研选" {
+			resp.HaveResearch = false
+			resp.Paging = page
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "获取成功"
+			br.Data = resp
+			return
+		}
+		page = paging.GetPaging(currentIndex, pageSize, total)
+		//if categoryId != "" {
+		//	condition += ` AND category_id IN(` + categoryId + `)`
+		//	condition += ` OR ( category_name LIKE '%研选%' AND publish_status = 1 AND is_summary = 1 )`
+		//} else {
+		//	condition += ` AND  category_name  LIKE '%研选%' `
+		//}
+		if categoryId != "" {
+			condition += ` AND category_id IN(` + categoryId + `)`
+			//condition += ` OR ( category_name  LIKE '%` + utils.CHART_PERMISSION_NAME_YANXUAN + `%' AND publish_status = 1 AND is_summary = 1 )`
+		} else {
+			condition += ` AND  category_name   LIKE '%` + utils.CHART_PERMISSION_NAME_YANXUAN + `%'`
+		}
+	}
+	//永续客户无法查看研选分类的内容
+	if userType == 1 {
+		condition += ` AND  category_name  NOT LIKE '%研选` + `%'`
+	}
+	total, err = models.GetHomeCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.Msg = "获取帖子总数失败,Err:" + err.Error()
+		return
+	}
+	page = paging.GetPaging(currentIndex, pageSize, total)
+	list, err := models.GetHomeList(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.Msg = "获取帖子数据失败,Err:" + err.Error()
+		return
+	}
+	//研选的五张图片
+	detailResearch, err := models.GetConfigByCode("category_research_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据研选分类图片失败,Err:" + err.Error()
+		return
+	}
+	researchList := strings.Split(detailResearch.ConfigValue, "{|}")
+	//对应分类的所图片
+	detailCategoryUrl, err := models.GetConfigByCode("category_map_img_url")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "行业配置信息失败,Err:" + err.Error()
+		return
+	}
+	categoryUrlList := strings.Split(detailCategoryUrl.ConfigValue, "{|}")
+	mapCategoryUrl := make(map[string]string)
+	var categoryId string
+	var imgUrlChart string
+	for _, v := range categoryUrlList {
+		vslice := strings.Split(v, "_")
+		categoryId = vslice[0]
+		imgUrlChart = vslice[len(vslice)-1]
+		mapCategoryUrl[categoryId] = imgUrlChart
+	}
+
+	for k, v := range list {
+		item := list[k]
+		//如果文章一开始的内容是图片,优先展示第一张图片
+		imgurl, _ := services.FixArticleImgUrl(html.UnescapeString(list[k].Body))
+		newBody, _ := services.GetReportContentTextSub(item.Body)
+		list[k].Body = newBody
+		if imgurl != "" {
+			list[k].BodyHtml = imgurl
+		}
+		list[k].PublishDate = utils.StrTimeToTime(item.PublishDate).Format(utils.FormatDateTimeNoSecond) //时间字符串格式转时间格式
+		if strings.Contains(item.CategoryName, "研选") {
+			list[k].IsResearch = true
+		}
+		if item.Pv > 999 {
+			list[k].Pv = 999
+		}
+		//如果是研选系列的任意取五张图片的中的一张
+		if v.CategoryId == "0" {
+			knum := v.ArticleId % 5
+			list[k].ImgUrlPc = researchList[knum]
+		} else {
+			list[k].ImgUrlPc = mapCategoryUrl[v.CategoryId]
+		}
+		if list[k].ArticleId < utils.SummaryArticleId {
+			list[k].HttpUrl = utils.StrategyPlatform + strconv.Itoa(v.ArticleId)
+			list[k].IsNeedJump = true
+		}
+	}
+	resp.List = list
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 首页/搜索头部导航接口
+// @Description 首页/搜索头部导航接口
+// @Param   SearchPage  query  int  false  "是否为搜索页面"
+// @Success 200 {object} models.HomeListResp
+// @router /header_tab [get]
+func (this *HomeController) HeaderTab() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	searchPage, _ := this.GetInt("SearchPage")
+
+	key := models.HomeHeaderTabConfigKey
+	conf, e := models.GetConfigByCode(key)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取首页头部导航失败, Err: " + e.Error()
+		return
+	}
+	if conf.ConfigValue == "" {
+		br.Msg = "获取失败"
+		br.ErrMsg = "首页头部导航配置值有误"
+		return
+	}
+
+	list := new(models.HomeHeaderTabList)
+	if e = json.Unmarshal([]byte(conf.ConfigValue), &list); e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "首页头部导航配置值解析失败, Err: " + e.Error()
+		return
+	}
+	resp := list.Home
+	if searchPage == 1 {
+		resp = list.SearchPage
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 首页列表接口v7.6版本
+// @Description 首页列表接口v7.6版本
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ChartPermissionId   query   int  true       "品类id,最新传0"
+// @Param   CtagId   query   int  true       "图表子类ID"
+// @Param   ListType   query   int  true       "列表类型,1最新,2 纪要 ,3图表 默认1"
+// @Success 200 {object} models.HomeArtAndChartListResp
+// @router /artAndChart/list [get]
+func (this *HomeController) ListHomeArtAndChart() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	chartPermissionId, _ := this.GetInt("ChartPermissionId")
+	listType, _ := this.GetInt("ListType")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	if listType <= 0 {
+		listType = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+	var total, chartTotal int
+	resp := new(models.HomeArtAndChartListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.HaveResearch = true
+
+	// 最新/纪要
+	if listType != 3 {
+		userType, _, err := services.GetUserType(user.CompanyId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+			return
+		}
+		condition = ` AND is_summary = 1  `
+		if chartPermissionId > 0 {
+			categoryId, err := models.GetCategoryId(chartPermissionId)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取分类权限信息失败,Err:" + err.Error()
+				return
+			}
+			categoryInfo, err := models.GetChartPermissionById(chartPermissionId)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取信息失败,Err:" + err.Error()
+				return
+			}
+			if userType == 1 && strings.Contains(categoryInfo.PermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+				resp.HaveResearch = false
+				resp.Paging = page
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				br.Data = resp
+				return
+			}
+			page = paging.GetPaging(currentIndex, pageSize, total)
+			if categoryId != "" {
+				condition += ` AND category_id IN(` + categoryId + `)`
+				//condition += ` OR ( category_name  LIKE '%` + utils.CHART_PERMISSION_NAME_YANXUAN + `%' AND publish_status = 1 AND is_summary = 1 )`
+			} else {
+				condition += ` AND  category_name   LIKE '%` + utils.CHART_PERMISSION_NAME_YANXUAN + `%'`
+			}
+		}
+		//永续客户无法查看研选分类的内容
+		if userType == 1 {
+			condition += ` AND  category_name  NOT LIKE '%` + utils.CHART_PERMISSION_NAME_YANXUAN + `%'`
+		}
+
+		list := make([]*models.HomeArticle, 0)
+		// 7.6-与音频作联合查询, 整体进行发布时间的排序(代码写的嘎嘎烂, 将就着用吧=_=!)
+		if listType == 1 {
+			var unionPars []interface{}
+			unionList, unionTotal, e := services.GetHomeNewestList(user.UserId, user.CompanyId, startSize, pageSize, condition, unionPars)
+			if e != nil {
+				br.Msg = "获取信息失败"
+				br.Msg = "获取纪要音频联合列表失败, Err: " + e.Error()
+				return
+			}
+			total = unionTotal
+			list = unionList
+		} else {
+			total, err = models.GetHomeCount(condition, pars)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.Msg = "获取帖子总数失败,Err:" + err.Error()
+				return
+			}
+
+			homeList, err := models.GetHomeList(condition, pars, startSize, pageSize)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.Msg = "获取帖子数据失败,Err:" + err.Error()
+				return
+			}
+			list = homeList
+		}
+
+		resp.List, err = services.HandleArticleCategoryImg(list)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.Msg = "处理封面图片失败,HandleArticleCategoryImg,Err:" + err.Error()
+			return
+		}
+		resp.List = list
+	}
+	if chartTotal > total {
+		total = chartTotal
+	}
+
+	page = paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 首页列表接口
+// @Description 首页列表接口
+// @Param   TagIds   query   string  true       "标签选择"
+// @Param   ChartPermissionId   query   int	  false     "行业id"
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Success 200 {object} models.HomeArtAndChartListResp
+// @router /new [get]
+func (this *HomeController) NewList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	tagIds := this.GetString("TagIds")
+	chartPermissionId, _ := this.GetInt("ChartPermissionId")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var conditionInit string
+	var pars []interface{}
+	//var total int
+	resp := new(models.HomeResourceDataListResp)
+	totalRai, err := models.GetCountCompanyProductCompanyId(user.CompanyId, utils.COMPANY_PRODUCT_RAI_ID)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "GetCountCompanyProductCompanyId,Err:" + err.Error()
+		return
+	}
+
+	if tagIds != "" {
+		conditionTagIdsInit, err := services.GetConditionInitByTagIds(tagIds, chartPermissionId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取活动权限数据失败,GetConditionInitByTagIds Err:" + err.Error()
+			return
+		}
+		conditionInit += conditionTagIdsInit
+	}
+	//行业筛选
+	if chartPermissionId > 0 {
+		conditionInit += " AND chart_permission_id  =  " + strconv.Itoa(chartPermissionId)
+	}
+
+	if tagIds == "" && chartPermissionId == 0 {
+		//查询近一个月的数据
+		conditionInit += " AND publish_date  >   '" + time.Now().AddDate(0, 0, -30).Format(utils.FormatDateTime) + "'"
+	}
+
+	//conditionInit += `  AND source IN ('newchart')`
+	if user.CompanyId <= 1 || totalRai == 0 {
+		//condition += " AND source IN ('roadshow','article') "
+		condition += " AND source NOT IN ('activityspecial') "
+		listActivityYiDong, err := models.GetActivityListHomeNew("  AND art.yidong_activity_id != '' ", 0, 1000)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取可见活动数据失败,Err:" + err.Error()
+			return
+		}
+		//易董的活动不查看  v12.2.1
+		var yiDongactivityIds []int
+		for _, v := range listActivityYiDong {
+			yiDongactivityIds = append(yiDongactivityIds, v.ActivityId)
+		}
+		lenyiDongactivityIds := len(yiDongactivityIds)
+		condition += `  AND IF ( source = 'activity' , source_id  NOT IN (` + utils.GetOrmInReplace(lenyiDongactivityIds) + `) ,1=1 ) `
+		pars = append(pars, yiDongactivityIds)
+	} else {
+		condition += ` AND source NOT IN ('activity','activityspecial','newchart') ` + conditionInit
+		//conditionActivity, err := services.GetActivityonditionList(user, "", "", "", "1,2,3", "", 0, 0, "", 0, 1)
+		conditionActivity, err := services.ActivityConditioninitSql(user, "", 0)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取活动权限数据失败,Err:" + err.Error()
+			return
+		}
+		conditionActivity += ` AND art.publish_status = 1 `
+		var conditionOrder string
+		conditionOrder = ` ORDER BY art.activity_time DESC ,  art.active_state ASC   `
+		conditionActivity += conditionOrder
+		actPageSize := 200
+		if tagIds != "" {
+			actPageSize = 2000
+		}
+		listActivity, err := models.GetActivityListHomeNew(conditionActivity, 0, actPageSize)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取可见活动数据失败,Err:" + err.Error()
+			return
+		}
+
+		var activityIds []int
+		for _, v := range listActivity {
+			activityIds = append(activityIds, v.ActivityId)
+		}
+		lenActivityIds := len(activityIds)
+
+		var activityspecialIds []int
+
+		lenActivityspecialIds := len(activityspecialIds)
+
+		if lenActivityIds > 0 {
+			condition += ` OR ( source = 'activity' AND source_id IN (` + utils.GetOrmInReplace(lenActivityIds) + `) ` + conditionInit + ` )    `
+			pars = append(pars, activityIds)
+		}
+
+		if lenActivityspecialIds > 0 {
+			condition += ` OR ( source = 'activityspecial' AND source_id IN (` + utils.GetOrmInReplace(lenActivityspecialIds) + `) ` + conditionInit + ` )   `
+			pars = append(pars, activityspecialIds)
+		}
+	}
+	total, err := models.GetResourceDataCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	//Source      string    `description:"资源类型 报告 :article 、图表 :newchart、微路演 :roadshow、活动 :activity、活动视频:activityvideo、活动音频:activityvoice、专项调研活动:activityspecial"`
+	list, err := services.GetResourceDataList(condition, pars, startSize, pageSize, user)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	page = paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 842 - 0
controllers/research.go

@@ -0,0 +1,842 @@
+package controllers
+
+import (
+	"encoding/json"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 研选
+type ResearchController struct {
+	BaseAuthController
+}
+
+// @Title 近期更新主题列表
+// @Description 近期更新主题列表接口
+// @Param   ChartPermissionId   query   int  true       "分类ID"
+// @Success 200 {object} models.IndustrialManagementNewList
+// @router /theme/newList [get]
+func (this *ResearchController) NewList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	articleTypeIds, err := services.GetYanXuanArticleTypeIds()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanArticleTypeIds,Err:" + err.Error()
+		return
+	}
+	if articleTypeIds == "" {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "研选分类ID不能为空"
+		return
+	}
+	var condition string
+	var conditionOrder string
+	condition = ` AND a.article_type_id IN (` + articleTypeIds + `)  `
+	list, err := models.GetIndustrialManagementNewList(condition)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	mapHot := make(map[string]int)
+
+	conditionOrder = ` ORDER BY sum_num DESC  `
+	listHot, err := models.GetThemeHeatList(user.UserId, condition, conditionOrder, 0, 3)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range listHot {
+		mapHot[v.IndustryName] = v.IndustrialManagementId
+	}
+	for k, v := range list {
+		if mapHot[v.IndustryName] > 0 {
+			list[k].IsHot = true
+		}
+	}
+	resp := new(models.IndustrialManagementNewList)
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 用户收藏列表
+// @Description 用户收藏列表接口
+// @Param   ChartPermissionId   query   int  true       "分类ID"
+// @Success 200 {object} models.ArticleCollectionLIstResp
+// @router /collectionList [get]
+func (this *ResearchController) CollectionList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize", 15)
+	var condition string
+	var pars []interface{}
+	articleTypeIds, err := services.GetYanXuanArticleTypeIds()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanArticleTypeIds,Err:" + err.Error()
+		return
+	}
+	if articleTypeIds != "" {
+		condition = ` AND a.article_type_id IN (` + articleTypeIds + `)  `
+	} else {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "研选分类ID不能为空"
+		return
+	}
+	// 根据关注时间一个月前至昨日的增量数据排序
+	nowTime := time.Now().Local()
+	startTime := nowTime.AddDate(0, -1, 0)
+	endTime := nowTime.AddDate(0, 0, -1)
+	condition += ` AND ac.create_time BETWEEN ? AND ? `
+	pars = append(pars, startTime, endTime)
+	list, err := models.GetReportCollectionBillboardListYx(pageSize, pars, condition)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取报告阅读增量排行榜失败, Err:" + err.Error()
+		return
+	}
+	for k, v := range list {
+		if v.MyCollectNum > 0 {
+			list[k].IsCollect = true
+		}
+	}
+	var articleIds []int
+	for k, v := range list {
+		if v.MyCollectNum > 0 {
+			list[k].IsCollect = true
+		}
+		articleIds = append(articleIds, v.ArticleId)
+	}
+	//处理关联的产业
+	industrialMap, err := services.GetArticleIndustrialByArticleId(articleIds)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取关联的产业信息失败,GetArticleIndustrialByArticleId Err:" + err.Error()
+		return
+	}
+	for k, v := range list {
+		if len(industrialMap[v.ArticleId]) > 0 {
+			list[k].List = industrialMap[v.ArticleId]
+		} else {
+			list[k].List = make([]*models.IndustrialManagementResp, 0)
+		}
+		list[k].PublishDate = utils.StrTimeToTime(v.PublishDate).Format(utils.FormatDate) //时间字符串格式转时间格式
+	}
+	resp := new(models.ArticleCollectionLIstResp)
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 主题热度/近期更新更多,列表
+// @Description 主题热度/近期更新更多,列表接口
+// @Param   ChartPermissionId   query   int  true       "分类ID"
+// @Param   ThemeType   query   int  true       "主题类型,1主题热度、2近期更新 默认1"
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Success 200 {object} models.IndustrialManagementHotListResp
+// @router /hotList [get]
+func (this *ResearchController) HotList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	themeType, _ := this.GetInt("ThemeType")
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize15
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+	var condition string
+	var conditionOrder string
+	articleTypeIds, err := services.GetYanXuanArticleTypeIds()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanArticleTypeIds,Err:" + err.Error()
+		return
+	}
+	if articleTypeIds == "" {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "研选分类ID不能为空"
+		return
+	}
+	condition = ` AND a.article_type_id IN (` + articleTypeIds + `)  `
+	if themeType == 2 {
+		conditionOrder = `ORDER BY publish_date DESC  `
+	} else {
+		conditionOrder = `ORDER BY sum_num DESC   `
+	}
+
+	total, err := models.GetThemeHeatListCount(condition)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	list, err := models.GetThemeHeatList(user.UserId, condition, conditionOrder, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	listSubjcet, err := models.GetThemeHeatSubjectList(condition)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取标的信息失败,Err:" + err.Error()
+		return
+	}
+	mapHot := make(map[int]bool)
+	mapNew, err := services.GetYanXuanIndustrialManagementIdNewMap(articleTypeIds)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanIndustrialManagementIdNewMap,Err:" + err.Error()
+		return
+	}
+	//if themeType == 2 {
+	mapHot, err = services.GetYanXuanIndustrialManagementIdHotMap(articleTypeIds)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanIndustrialManagementIdNewMap,Err:" + err.Error()
+		return
+	}
+	//}
+	for k, v := range list {
+		list[k].IsNew = mapNew[v.IndustrialManagementId]
+		list[k].IsHot = mapHot[v.IndustrialManagementId]
+		if v.FllowNum > 0 {
+			list[k].IsFollw = true
+		}
+		for _, v2 := range listSubjcet {
+			if v2.IndustrialManagementId == v.IndustrialManagementId {
+				list[k].IndustrialSubjectList = append(list[k].IndustrialSubjectList, v2)
+			}
+		}
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(models.IndustrialManagementHotListResp)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title KOL榜列表
+// @Description KOL榜列表接口
+// @Param   ChartPermissionId   query   int  true       "分类ID"
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ThemeType   query   int  true       "主题类型,1关注度、2更新时间 "
+// @Success 200 {object} models.DepartmentListResp
+// @router /kolList [get]
+func (this *ResearchController) KolList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	themeType, _ := this.GetInt("ThemeType")
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize15
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+	articleTypeIds, err := services.GetYanXuanArticleTypeIds()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanArticleTypeIds,Err:" + err.Error()
+		return
+	}
+	if articleTypeIds == "" {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "研选分类ID不能为空"
+		return
+	}
+	var condition string
+	var conditionOrder string
+	condition = ` AND a.article_type_id IN (` + articleTypeIds + `)  `
+
+	total, err := models.GetDepartmentlistCount(condition)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	if themeType == 2 {
+		conditionOrder = `ORDER BY publish_date DESC  `
+	} else {
+		conditionOrder = `ORDER BY sum_num DESC `
+	}
+	mapHot := make(map[int]bool)
+	//if themeType == 2 {
+	conditionHot := `ORDER BY sum_num DESC `
+	listhot, err := models.GetDepartmentList(condition, conditionHot, user.UserId, 0, 3)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range listhot {
+		mapHot[v.DepartmentId] = true
+	}
+	//}
+
+	list, err := models.GetDepartmentList(condition, conditionOrder, user.UserId, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+	listIndustrial, err := models.GetIndustrialDepartmentList()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	departmentMap := make(map[string]string)
+	for k, v := range list {
+		if v.FllowNum > 0 {
+			list[k].IsFollw = true
+		}
+		for _, v2 := range listIndustrial {
+			if v2.DepartmentId == v.DepartmentId {
+				if departmentMap["D"+strconv.Itoa(v2.DepartmentId)+"In"+strconv.Itoa(v2.IndustrialManagementId)] == "" && len(list[k].List) < 4 {
+					list[k].List = append(list[k].List, v2)
+					departmentMap["D"+strconv.Itoa(v2.DepartmentId)+"In"+strconv.Itoa(v2.IndustrialManagementId)] = v.NickName
+				}
+			}
+		}
+		//if themeType == 2 {
+		v.IsHot = mapHot[v.DepartmentId]
+		//}
+	}
+	resp := new(models.DepartmentListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 主题详情
+// @Description 主题详情接口
+// @Param   IndustrialManagementId   query   int  true       "分类ID"
+// @Param   Source   query   int  true       "来源 1:研选,2:报告 默认1"
+// @Success 200 {object} models.GetThemeDetailResp
+// @router /theme/detail [get]
+func (this *ResearchController) ThemeDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	industrialManagementId, _ := this.GetInt("IndustrialManagementId")
+	if industrialManagementId < 1 {
+		br.Msg = "请输入产业ID"
+		return
+	}
+	source, _ := this.GetInt("Source")
+	if source != 2 {
+		source = 1
+	}
+
+	articleTypeIds, err := services.GetYanXuanArticleTypeIds()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanArticleTypeIds,Err:" + err.Error()
+		return
+	}
+	if articleTypeIds == "" {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "研选分类ID不能为空"
+		return
+	}
+	var condition string
+	if source == 1 {
+		condition = ` AND a.article_type_id IN (` + articleTypeIds + `)  `
+	} else {
+		condition = ` AND a.article_type_id  NOT IN (` + articleTypeIds + `)  `
+	}
+	resp := new(models.GetThemeDetailResp)
+	list, err := models.GetThemeDetail(user.UserId, industrialManagementId, condition)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	var articleIds []int
+	for _, v := range list {
+		resp.IndustryName = v.IndustryName
+		resp.IndustrialManagementId = v.IndustrialManagementId
+		if v.FllowNum > 0 {
+			resp.IsFollw = true
+		}
+		articleIds = append(articleIds, v.ArticleId)
+	}
+	mapArticleSubjectName, subjectMap, err := services.GetArticleSubjectName(articleIds)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v2 := range list {
+		item := new(models.GetThemeAericleListResp)
+		item.ArticleId = v2.ArticleId
+		item.Title = v2.Title
+		item.PublishDate = v2.PublishDate
+		item.SubjectName = v2.SubjectName
+		item.IndustrialSubjectId = v2.IndustrialSubjectId
+		item.DepartmentId = v2.DepartmentId
+		item.NickName = v2.NickName
+		item.Pv = v2.Pv
+		item.CollectNum = v2.CollectNum
+		item.MyCollectNum = v2.MyCollectNum
+		if v2.MyCollectNum > 0 {
+			item.IsCollect = true
+		}
+		item.SubjectName = mapArticleSubjectName[v2.ArticleId]
+		resp.List = append(resp.List, item)
+	}
+
+	listSub, err := models.GetcygxIndustrialSubject(industrialManagementId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range listSub {
+		itemSubJect := new(models.IndustrialSubject)
+		itemSubJect.SubjectName = v.SubjectName
+		itemSubJect.IndustrialSubjectId = v.IndustrialSubjectId
+		if subjectMap[v.IndustrialSubjectId] != "" {
+			resp.ListSubject = append(resp.ListSubject, itemSubJect)
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 研选作者详情
+// @Description 研选作者详情接口
+// @Param   DepartmentId   query   int  true       "作者ID"
+// @Success 200 {object} models.DepartmentDetailResp
+// @router /departmentId/detail [get]
+func (this *ResearchController) DepartmentIdDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	departmentId, _ := this.GetInt("DepartmentId")
+	if departmentId < 1 {
+		br.Msg = "请输入作者ID"
+		return
+	}
+	articleTypeIds, err := services.GetYanXuanArticleTypeIds()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetYanXuanArticleTypeIds,Err:" + err.Error()
+		return
+	}
+	if articleTypeIds == "" {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "研选分类ID不能为空"
+		return
+	}
+	var condition string
+	condition = ` AND a.article_type_id IN (` + articleTypeIds + `)  `
+	resp := new(models.DepartmentDetailResp)
+	detail, err := models.GetDepartmentDetail(user.UserId, departmentId, condition)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取作者信息失败,Err:" + err.Error()
+		return
+	}
+	resp.DepartmentId = detail.DepartmentId
+	resp.NickName = detail.NickName
+	resp.ImgUrl = detail.ImgUrl
+	resp.FllowNum = detail.FllowNum
+	resp.ArticleNum = detail.ArticleNum
+	resp.CollectNum = detail.CollectNum
+	if detail.MyFllowNum > 0 {
+		resp.IsFllow = true
+	}
+	condition += `  AND a.department_id = ` + strconv.Itoa(departmentId) + `  GROUP BY a.article_id  ORDER BY a.publish_date DESC  `
+	list, err := models.GetArticleCollectionList(condition, user.UserId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取文章列表失败,Err:" + err.Error()
+		return
+	}
+	var articleIds []int
+	for k, v := range list {
+		if v.MyCollectNum > 0 {
+			list[k].IsCollect = true
+		}
+		articleIds = append(articleIds, v.ArticleId)
+	}
+	//处理关联的产业
+	industrialMap, err := services.GetArticleIndustrialByArticleId(articleIds)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取关联的产业信息失败,GetArticleIndustrialByArticleId Err:" + err.Error()
+		return
+	}
+	for k, v := range list {
+		if len(industrialMap[v.ArticleId]) > 0 {
+			list[k].List = industrialMap[v.ArticleId]
+		} else {
+			list[k].List = make([]*models.IndustrialManagementResp, 0)
+		}
+	}
+
+	condition = ` AND a.department_id =  ` + strconv.Itoa(departmentId)
+	listIndustrial, err := models.GetIndustrialManagementNewList(condition)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	resp.List = list
+	resp.ListIndustrial = listIndustrial
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 文章相关热门收藏
+// @Description 文章相关热门收藏接口
+// @Param   ArticleId   query   int  true       "文章ID"
+// @Success 200 {object} models.ArticleCollectionLIstResp
+// @router /article/hotList [get]
+func (this *ResearchController) ArticleHotList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	articleId, _ := this.GetInt("ArticleId")
+	if articleId < 1 {
+		br.Msg = "请输入分类ID"
+		return
+	}
+	var condition string
+	condition = ` AND a.article_id IN (SELECT article_id FROM cygx_industrial_article_group_management WHERE industrial_management_id IN (SELECT industrial_management_id  FROM cygx_industrial_article_group_management  WHERE  article_id = ` + strconv.Itoa(articleId) + ` ) ) AND a.article_id != ` + strconv.Itoa(articleId) + ` AND a.category_name LIKE '%研选%' AND publish_status = 1 GROUP BY a.article_id ORDER BY collect_num DESC, publish_date DESC LIMIT 3 `
+	list, err := models.GetArticleCollectionList(condition, user.UserId)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	for k, v := range list {
+		if v.MyCollectNum > 0 {
+			list[k].IsCollect = true
+		}
+	}
+	resp := new(models.ArticleCollectionLIstResp)
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 热搜关键词
+// @Description 热搜关键词接口
+// @Success 200 {object} models.UserSearchKeyWordListResp
+// @router /hotKeyWord [get]
+func (this *ResearchController) HotKeyWord() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	//本来应该放在config控制器下,与未上线的代码冲突,所以放在这里
+	list, err := models.GetUserSearchKeyWord()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.UserSearchKeyWordListResp)
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 研选文章类型列表
+// @Description 研选文章类型列表接口
+// @Success 200 {object} models.CygxArticleTypeListResp
+// @router /article/typeList [get]
+func (this *ResearchController) ArticleType() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	key := utils.YAN_XUAN_TAB_KEY
+	conf, e := models.GetConfigByCode(key)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取首页头部导航失败, Err: " + e.Error()
+		return
+	}
+	if conf.ConfigValue == "" {
+		br.Msg = "获取失败"
+		br.ErrMsg = "首页头部导航配置值有误"
+		return
+	}
+	list := new(models.CygxArticleTypeListResp)
+	if e = json.Unmarshal([]byte(conf.ConfigValue), &list); e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "首页头部导航配置值解析失败, Err: " + e.Error()
+		return
+	}
+	resp := new(models.CygxArticleTypeListResp)
+	resp = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 研选最新报告列表
+// @Description 研选最新报告列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ArticleTypeIds   query   array  true       "文章类型ID多个用  , 隔开"
+// @Success 200 {object} models.IndustrialManagementNewList
+// @router /article/newList [get]
+func (this *ResearchController) ArticleNewList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	articleTypeIds := this.GetString("ArticleTypeIds")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	var condition string
+	var conditiontype string
+	var pars []interface{}
+	condition = `    AND publish_status = 1  `
+	if articleTypeIds == "" || strings.Contains(articleTypeIds, "999") {
+		conditiontype = " AND is_show_yanx  = 1 "
+	} else {
+		conditiontype = ` AND   group_id IN  (` + articleTypeIds + `) `
+	}
+	listType, err := models.GetCygxArticleTypeListCondition(conditiontype)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	needYanxuanSpecial := true
+	if articleTypeIds != "" && !strings.Contains(articleTypeIds, "999") {
+		needYanxuanSpecial = false
+	}
+
+	//只勾选了研选专栏时去掉文章的统计
+	if articleTypeIds == "999" {
+		condition += ` AND 1<0 `
+	}
+	articleTypeIds = ""
+	for _, v := range listType {
+		articleTypeIds += strconv.Itoa(v.ArticleTypeId) + ","
+	}
+	articleTypeIds = strings.TrimRight(articleTypeIds, ",")
+	condition += `   AND a.article_type_id IN (` + articleTypeIds + `) `
+
+	total, err := models.GetArticleResearchCount(condition, pars, needYanxuanSpecial)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetArticleResearchCount,Err:" + err.Error()
+		return
+	}
+	list, err := models.GetArticleResearchList(condition, pars, startSize, pageSize, user.UserId, needYanxuanSpecial)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+	var articleIds []int
+	for k, v := range list {
+		if v.MyCollectNum > 0 {
+			list[k].IsCollect = true
+		}
+		articleIds = append(articleIds, v.ArticleId)
+	}
+	//处理关联的产业
+	industrialMap, err := services.GetArticleIndustrialByArticleId(articleIds)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取关联的产业信息失败,GetArticleIndustrialByArticleId Err:" + err.Error()
+		return
+	}
+	for k, v := range list {
+		if len(industrialMap[v.ArticleId]) > 0 {
+			list[k].List = industrialMap[v.ArticleId]
+		} else {
+			list[k].List = make([]*models.IndustrialManagementResp, 0)
+		}
+	}
+	//处理对应的文章类型标签按钮
+	nameMap, styleMap, err := services.GetArticleTypeMap()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "GetArticleTypeMap Err:" + err.Error()
+		return
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(models.ArticleResearchListResp)
+	for _, v := range list {
+		item := models.ArticleResearchResp{
+			ArticleId:       v.ArticleId,
+			Title:           v.Title,
+			PublishDate:     v.PublishTime.Format(utils.FormatDate),
+			DepartmentId:    v.DepartmentId,
+			NickName:        v.NickName,
+			IsCollect:       v.IsCollect,
+			Pv:              v.Pv,
+			CollectNum:      v.CollectNum,
+			IsSpecial:       v.IsSpecial,
+			ArticleTypeName: nameMap[v.ArticleTypeId],
+			ButtonStyle:     styleMap[v.ArticleTypeId],
+			SpecialTags:     v.SpecialTags,
+			UserId:          v.UserId,
+			List:            v.List,
+			TopTime:         v.TopTime,
+		}
+		if v.ArticleTypeId == -1 {
+			item.ArticleTypeName = utils.CYGX_YANXUAN_SPECIAL
+		}
+		if v.SpecialType == 1 {
+			item.Title = "【笔记】" + item.Title
+		} else if v.SpecialType == 2 {
+			item.Title = "【观点】" + item.Title
+		}
+		if v.CompanyTags != "" {
+			v.SpecialTags += v.CompanyTags
+		}
+		if v.IndustryTags != "" {
+			if v.SpecialTags != "" {
+				v.SpecialTags += ","
+			}
+			v.SpecialTags += v.IndustryTags
+		}
+		item.SpecialTags = v.SpecialTags
+		resp.List = append(resp.List, &item)
+	}
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 95 - 0
controllers/resource.go

@@ -0,0 +1,95 @@
+package controllers
+
+import (
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"os"
+	"path"
+	"time"
+)
+
+// 资源管理-图片上传,合同上传等
+type ResourceController struct {
+	BaseAuthController
+}
+
+// @Title 图片上传
+// @Description 图片上传接口
+// @Param   file   query   file  true       "文件"
+// @Success 200 新增成功
+// @router /image/upload [post]
+func (this *ResourceController) Upload() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	f, h, err := this.GetFile("file")
+	if err != nil {
+		br.Msg = "获取资源信息失败"
+		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
+		return
+	}
+	ext := path.Ext(h.Filename)
+	dateDir := time.Now().Format("20060102")
+	uploadDir := "static/temp/" + dateDir
+	err = os.MkdirAll(uploadDir, 777)
+	if err != nil {
+		br.Msg = "存储目录创建失败"
+		br.ErrMsg = "存储目录创建失败,Err:" + err.Error()
+		return
+	}
+	randStr := utils.GetRandStringNoSpecialChar(28)
+	fileName := randStr + ext
+	fpath := uploadDir + "/" + fileName
+	defer f.Close() //关闭上传文件
+	err = this.SaveToFile("file", fpath)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "文件上传失败,Err:" + err.Error()
+		return
+	}
+	//
+	////上传到阿里云
+	//resourceUrl, err := services.UploadAliyun(fileName, fpath)
+	//if err != nil {
+	//	br.Msg = "文件上传失败"
+	//	br.ErrMsg = "文件上传失败,Err:" + err.Error()
+	//	return
+	//}
+
+	savePath := uploadDir + time.Now().Format("200601/20060102/")
+	savePath += fileName
+	//上传到阿里云
+	err = services.UploadFileToAliyun("", fpath, savePath)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "文件上传失败,Err:" + err.Error()
+		return
+	}
+	fileHost := "https://hzstatic.hzinsights.com/"
+	resourceUrl := fileHost + savePath
+	defer func() {
+		os.Remove(fpath)
+	}()
+	item := new(models.Resource)
+	item.ResourceUrl = resourceUrl
+	item.ResourceType = 1
+	item.CreateTime = time.Now()
+	newId, err := models.AddResource(item)
+	if err != nil {
+		br.Msg = "资源上传失败"
+		br.ErrMsg = "资源上传失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ResourceResp)
+	resp.Id = newId
+	resp.ResourceUrl = resourceUrl
+
+	br.Msg = "上传成功"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	return
+}

+ 584 - 0
controllers/search.go

@@ -0,0 +1,584 @@
+package controllers
+
+import (
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"strings"
+)
+
+type SearchController struct {
+	BaseAuthController
+}
+
+type BaseSearchController struct {
+	BaseCommonController
+}
+
+// @Title 搜索接口
+// @Description 搜索接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Param   OrderColumn   query   int  true       "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
+// @Success 200 {object} models.SearchItem
+// @router /list [get]
+func (this *SearchController) SearchList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	keyWord := this.GetString("KeyWord")
+	orderColumn := this.GetString("OrderColumn")
+	if keyWord == "" {
+		br.Msg = "请输入搜索词"
+		br.ErrMsg = "请输入搜索词"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+
+	//研选的五张图片
+	detailResearch, errConfig := models.GetConfigByCode("category_research_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据研选分类图片失败,Err:" + errConfig.Error()
+		return
+	}
+	researchList := strings.Split(detailResearch.ConfigValue, "{|}")
+	//对应分类的所图片
+	detailCategoryUrl, errConfig := models.GetConfigByCode("category_map_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "行业配置信息失败,Err:" + errConfig.Error()
+		return
+	}
+	categoryUrlList := strings.Split(detailCategoryUrl.ConfigValue, "{|}")
+	mapCategoryUrl := make(map[string]string)
+	var categoryId string
+	var imgUrlChart string
+	for _, v := range categoryUrlList {
+		vslice := strings.Split(v, "_")
+		categoryId = vslice[0]
+		imgUrlChart = vslice[len(vslice)-1]
+		mapCategoryUrl[categoryId] = imgUrlChart
+	}
+	if orderColumn == "" {
+		orderColumn = "Matching"
+	}
+	indexName := utils.IndexName
+	pageSize = 20
+	var result []*models.SearchItem
+	var total int64
+	var err error
+	if orderColumn == "PublishDate" {
+		tmpResult, tmpTotal, tmpErr := services.EsMultiMatchFunctionScoreQueryTimeSort(indexName, keyWord, startSize, 100, user.UserId)
+		result = tmpResult
+		total = tmpTotal
+		err = tmpErr
+	} else {
+		tmpResult, tmpTotal, tmpErr := services.EsMultiMatchFunctionScoreQuerySort(indexName, keyWord, startSize, pageSize, user.UserId, orderColumn)
+		result = tmpResult
+		total = tmpTotal
+		err = tmpErr
+	}
+	if err != nil {
+		br.Msg = "检索失败"
+		br.ErrMsg = "检索失败,Err:" + err.Error()
+		return
+	}
+	if len(result) == 0 {
+		result = make([]*models.SearchItem, 0)
+	}
+	//记录用户搜索关键词
+	go services.AddSearchKeyWord(user, keyWord, 1)
+	for k, v := range result {
+		//如果是研选系列的任意取五张图片的中的一张
+		if v.CategoryId == "0" {
+			knum := v.ArticleId % 5
+			result[k].ImgUrlPc = researchList[knum]
+		} else {
+			result[k].ImgUrlPc = mapCategoryUrl[v.CategoryId]
+		}
+	}
+	resp := new(models.SearchResp)
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+	resp.Paging = page
+	resp.List = result
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+//https://blog.csdn.net/my_miuye/article/details/110496025
+//search
+
+// @Title 报告搜索接口
+// @Description 报告搜索接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Success 200 {object} models.SearchItem
+// @router /report/list [get]
+func (this *SearchController) SearchReport() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	keyWord := this.GetString("KeyWord")
+	if keyWord == "" {
+		br.Msg = "请输入搜索词"
+		br.ErrMsg = "请输入搜索词"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	//indexName := "article_list"
+	indexName := utils.IndexName
+	pageSize = 100
+	var result []*models.SearchItem
+	var total int64
+	var err error
+	tmpResult, tmpTotal, tmpErr := services.EsSearchReport(indexName, keyWord, startSize, pageSize, user.UserId)
+	result = tmpResult
+	total = tmpTotal
+	err = tmpErr
+	if err != nil {
+		br.Msg = "检索失败"
+		br.ErrMsg = "检索失败,Err:" + err.Error()
+		return
+	}
+	if len(result) == 0 {
+		result = make([]*models.SearchItem, 0)
+	}
+	//记录用户搜索关键词
+	go services.AddSearchKeyWord(user, keyWord, 1)
+	resp := new(models.SearchResp)
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+	resp.Paging = page
+	resp.List = result
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 搜索接口
+// @Description 搜索接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Param   OrderColumn   query   int  true       "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
+// @Param   ListType   query   int  true       "列表类型,1最新/全部,2 纪要 ,3图表 默认1"
+// @Success 200 {object} models.SearchItem
+// @router /artAndChart/list [get]
+func (this *SearchController) ListHomeArtAndChart() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	listType, _ := this.GetInt("ListType")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	keyWord := this.GetString("KeyWord")
+	orderColumn := this.GetString("OrderColumn")
+	if keyWord == "" {
+		br.Msg = "请输入搜索词"
+		br.ErrMsg = "请输入搜索词"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+
+	//研选的五张图片
+	detailResearch, errConfig := models.GetConfigByCode("category_research_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据研选分类图片失败,Err:" + errConfig.Error()
+		return
+	}
+	researchList := strings.Split(detailResearch.ConfigValue, "{|}")
+	//对应分类的所图片
+	detailCategoryUrl, errConfig := models.GetConfigByCode("category_map_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "行业配置信息失败,Err:" + errConfig.Error()
+		return
+	}
+	categoryUrlList := strings.Split(detailCategoryUrl.ConfigValue, "{|}")
+	mapCategoryUrl := make(map[string]string)
+	var categoryId string
+	var imgUrlChart string
+	for _, v := range categoryUrlList {
+		vslice := strings.Split(v, "_")
+		categoryId = vslice[0]
+		imgUrlChart = vslice[len(vslice)-1]
+		mapCategoryUrl[categoryId] = imgUrlChart
+	}
+	if orderColumn == "" {
+		orderColumn = "Matching"
+	}
+	indexName := utils.IndexName
+	pageSize = 20
+	var chartTotal int
+	resp := new(models.SearchResp)
+	//page := paging.GetPaging(currentIndex, pageSize, total)
+
+	var err error
+
+	var result []*models.SearchItem
+	var total int64
+	if listType == 1 || listType == 2 {
+		if orderColumn == "PublishDate" {
+			tmpResult, tmpTotal, tmpErr := services.EsMultiMatchFunctionScoreQueryTimeSort(indexName, keyWord, startSize, 100, user.UserId)
+			result = tmpResult
+			total = tmpTotal
+			err = tmpErr
+		} else {
+			tmpResult, tmpTotal, tmpErr := services.EsMultiMatchFunctionScoreQuerySort(indexName, keyWord, startSize, pageSize, user.UserId, orderColumn)
+			result = tmpResult
+			total = tmpTotal
+			err = tmpErr
+		}
+		if err != nil {
+			br.Msg = "检索失败"
+			br.ErrMsg = "检索失败,Err:" + err.Error()
+			return
+		}
+		if len(result) == 0 {
+			result = make([]*models.SearchItem, 0)
+		}
+
+		for k, v := range result {
+			//如果是研选系列的任意取五张图片的中的一张
+			if v.CategoryId == "0" {
+				knum := v.ArticleId % 5
+				result[k].ImgUrlPc = researchList[knum]
+			} else {
+				result[k].ImgUrlPc = mapCategoryUrl[v.CategoryId]
+			}
+			result[k].Source = 1
+			result[k].PublishDate = utils.StrTimeToTime(result[k].PublishDate).Format(utils.FormatDate)
+		}
+	}
+	// ListType   query   int  true       "列表类型,1最新/全部,2 纪要 ,3图表 默认1"
+	//记录用户搜索关键词
+	var source int
+	if listType == 1 {
+		source = 3
+	} else if listType == 2 {
+		source = 1
+	} else {
+		source = 2
+	}
+	go services.AddSearchKeyWord(user, keyWord, source)
+
+	if chartTotal > int(total) {
+		total = int64(chartTotal)
+	}
+	if listType == 1 {
+		total = total + int64(chartTotal)
+	}
+	if len(result) == 0 {
+		result = make([]*models.SearchItem, 0)
+	}
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+	resp.Paging = page
+	resp.List = result
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 搜索接口
+// @Description 搜索接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Param   OrderColumn   query   int  true       "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
+// @Success 200 {object} models.SearchItem
+// @router /artAndChart/listPage [get]
+func (this *SearchController) ListHomeArtAndChartPage() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	// @Param   ListType   query   int  true       "列表类型,1最新/全部,2 纪要 ,3图表 默认1"
+	listType, _ := this.GetInt("ListType")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	listType = 1
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	keyWord := this.GetString("KeyWord")
+	orderColumn := this.GetString("OrderColumn")
+	if keyWord == "" {
+		br.Msg = "请输入搜索词"
+		br.ErrMsg = "请输入搜索词"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+
+	//研选的五张图片
+	detailResearch, errConfig := models.GetConfigByCode("category_research_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据研选分类图片失败,Err:" + errConfig.Error()
+		return
+	}
+	researchList := strings.Split(detailResearch.ConfigValue, "{|}")
+	//对应分类的所图片
+	detailCategoryUrl, errConfig := models.GetConfigByCode("category_map_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "行业配置信息失败,Err:" + errConfig.Error()
+		return
+	}
+	categoryUrlList := strings.Split(detailCategoryUrl.ConfigValue, "{|}")
+	mapCategoryUrl := make(map[string]string)
+	var categoryId string
+	var imgUrlChart string
+	for _, v := range categoryUrlList {
+		vslice := strings.Split(v, "_")
+		categoryId = vslice[0]
+		imgUrlChart = vslice[len(vslice)-1]
+		mapCategoryUrl[categoryId] = imgUrlChart
+	}
+	if orderColumn == "" {
+		orderColumn = "Matching"
+	}
+	var chartTotal int
+	resp := new(models.SearchResp)
+	var result []*models.SearchItem
+	var total int64
+	var articleIds []int
+	if listType == 1 || listType == 2 {
+		//添加映射关系
+		keyWord = strings.ToUpper(keyWord)
+		keyWordDetail, _ := models.GetCygxCygxIkWordMapDetail(keyWord)
+		if keyWordDetail != nil {
+			keyWord = keyWordDetail.KeyWordMap
+		}
+		_, tmpTotal, err := services.EsArticleSearch(keyWord, startSize, pageSize, orderColumn, 0)
+		if err != nil {
+			br.Msg = "检索失败"
+			br.ErrMsg = "检索失败,Err:" + err.Error()
+			return
+		}
+		tmpResult, tmpTotalResult, err := services.EsArticleSearchBody(keyWord, startSize, pageSize, orderColumn, 1)
+		if err != nil {
+			br.Msg = "检索失败"
+			br.ErrMsg = "检索失败,Err:" + err.Error()
+			return
+		}
+		result = tmpResult
+		if int(tmpTotalResult) < currentIndex*pageSize {
+			startSizeBody := startSize - int(tmpTotalResult)
+			if startSizeBody < 0 {
+				startSizeBody = 0
+			}
+			var pageSizeBody int
+			pageSizeBody = pageSize - len(tmpResult)
+			tmpResultBody, tmpTotalBody, err := services.EsArticleSearchBody(keyWord, startSizeBody, pageSizeBody, orderColumn, 2)
+			if err != nil {
+				br.Msg = "检索失败"
+				br.ErrMsg = "检索失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpResultBody {
+				result = append(result, v)
+			}
+			tmpTotalResult += tmpTotalBody
+		}
+
+		if int(tmpTotalResult) < currentIndex*pageSize {
+			startSizeIk := startSize - int(tmpTotalResult)
+			if startSizeIk < 0 {
+				startSizeIk = 0
+			}
+			var pageSizeIk int
+			pageSizeIk = pageSize - len(result)
+			tmpResultIk, _, err := services.EsArticleSearch(keyWord, startSizeIk, pageSizeIk, orderColumn, 2)
+			if err != nil {
+				br.Msg = "检索失败"
+				br.ErrMsg = "检索失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpResultIk {
+				result = append(result, v)
+			}
+		}
+		total = tmpTotal
+		if len(result) == 0 {
+			result = make([]*models.SearchItem, 0)
+		}
+
+		for k, v := range result {
+			//如果是研选系列的任意取五张图片的中的一张
+			if v.CategoryId == "0" {
+				knum := v.ArticleId % 5
+				result[k].ImgUrlPc = researchList[knum]
+			} else {
+				result[k].ImgUrlPc = mapCategoryUrl[v.CategoryId]
+			}
+			result[k].Source = 1
+			v.PublishDate = utils.TimeRemoveHms(v.PublishDate)
+			articleIds = append(articleIds, v.ArticleId)
+		}
+	}
+	//记录用户搜索关键词
+	//var source int
+	//if listType == 1 {
+	//	source = 3
+	//} else if listType == 2 {
+	//	source = 1
+	//} else {
+	//	source = 2
+	//}
+
+	if chartTotal > int(total) {
+		total = int64(chartTotal)
+	}
+	if listType == 1 {
+		total = total + int64(chartTotal)
+	}
+	if len(result) == 0 {
+		result = make([]*models.SearchItem, 0)
+	} else {
+		yxArticleIdMap := services.GetYxArticleIdMap(articleIds)
+		articleMapPv := services.GetArticleHistoryByArticleId(articleIds) //文章Pv
+		for _, v := range result {
+			v.IsResearch = yxArticleIdMap[v.ArticleId] // 添加是否属于研选的标识
+			v.Pv = articleMapPv[v.ArticleId]           // Pv
+		}
+	}
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+	resp.Paging = page
+	resp.List = result
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 综合搜索接口
+// @Description 综合搜索接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Success 200 {object} models.SearchItem
+// @router /comprehensive/list [get]
+func (this *SearchController) ComprehensiveList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	keyWord := this.GetString("KeyWord")
+	if keyWord == "" {
+		br.Msg = "请输入搜索词"
+		br.ErrMsg = "请输入搜索词"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	resp := new(models.HomeResourceDataListResp)
+	tmpResult, tmpTotalResult, err := services.EsComprehensiveSearch(keyWord, startSize, pageSize)
+	if err != nil {
+		br.Msg = "检索失败"
+		br.ErrMsg = "检索失败,Err:" + err.Error()
+		return
+	}
+	//for _, v := range tmpResult {
+	//	fmt.Println(v.Title, "Title", v.IsSummary)
+	//}
+	list, err := services.GetResourceDataEsList(tmpResult, user)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	if currentIndex == 1 {
+		go services.AddSearchKeyWord(user, keyWord, 1)
+	}
+
+	resp.List = list
+	page := paging.GetPaging(currentIndex, pageSize, int(tmpTotalResult))
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 128 - 0
controllers/tag.go

@@ -0,0 +1,128 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+)
+
+type TagController struct {
+	BaseAuthController
+}
+
+// @Title 获取标签列表-自定义顺序
+// @Description 获取标签列表-自定义顺序接口
+// @Success 200 {object} cygx.ChartPermissionResp
+// @router /list/custom [get]
+func (this *TagController) TagCustomizeList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var condition string
+
+	hasPermission, err := services.GetUserHasPermissionSimple(sysUser)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+		return
+	}
+	if hasPermission > 1 {
+		list := make([]*models.CygxTagList, 0)
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = list
+		return
+	}
+
+	list, err := models.GetCygxTagList(condition)
+	for _, v := range list {
+		if v.ArticleTypes != "" {
+			v.CheckList = append(v.CheckList, "A")
+		}
+		if v.ActivityTypes != "" {
+			v.CheckList = append(v.CheckList, "B")
+		}
+		if v.Industries != "" {
+			v.CheckList = append(v.CheckList, "C")
+		}
+		if v.SubjectNames != "" {
+			v.CheckList = append(v.CheckList, "D")
+		}
+		//固定标签默认都属于,前端互斥使用
+		if v.TagType > 0 {
+			v.CheckList = []string{"A", "B", "C", "D"}
+		}
+	}
+	if err != nil {
+		br.Msg = "获取标签失败"
+		br.ErrMsg = "获取标签信息失败,Err:" + err.Error()
+		return
+	}
+
+	//var condition string
+	condition = ` AND permission_name IN ('医药1','消费','科技','智造','策略') `
+	listPermission, err := models.GetChartPermissionReportAll(condition)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
+		return
+	}
+
+	resp := new(models.CygxTagListResp)
+
+	resp.List = list
+	resp.ListPermission = listPermission
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 记录点击信息
+// @Description 记录点击信息
+// @Param	request	body cygx.CygxTagIdReq true "type json string"
+// @Success 200 Ret=200 发布成功
+// @router /add/history [post]
+func (this *TagController) History() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.CygxTagIdReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	tagId := req.TagId
+	if tagId == 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,id不可为空"
+		return
+	}
+	go services.AddCygxTagHistory(user, tagId)
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "记录成功"
+}

+ 1935 - 0
controllers/user.go

@@ -0,0 +1,1935 @@
+package controllers
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 用户
+type UserController struct {
+	BaseAuthController
+}
+
+type UserCommonController struct {
+	BaseCommonController
+}
+
+// @Title 登录
+// @Description 登录接口
+// @Param	request	body models.LoginReq true "type json string"
+// @Success 200 {object} models.LoginResp
+// @router /login [post]
+func (this *UserController) Login() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.LoginReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录"
+		br.Ret = 408
+		return
+	}
+
+	unionId := this.User.UnionId
+	openId := this.User.OpenId
+	if unionId == "" {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,unionId 为空"
+		return
+	}
+	if req.LoginType == 1 || req.LoginType == 3 {
+		if req.Mobile == "" {
+			br.Msg = "参数错误"
+			br.ErrMsg = "参数错误,手机号为空 为空"
+			return
+		}
+		if req.LoginType == 3 {
+			item, err := models.GetMsgCode(req.Mobile, req.VCode)
+			if err != nil {
+				if err.Error() == utils.ErrNoRow() {
+					br.Msg = "验证码错误,请重新输入"
+					br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+					return
+				} else {
+					br.Msg = "验证码错误,请重新输入"
+					br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+					return
+				}
+			}
+			if item == nil {
+				br.Msg = "验证码错误,请重新输入"
+				return
+			}
+		}
+		req.Mobile = strings.Trim(req.Mobile, " ")
+	} else if req.LoginType == 2 {
+		if req.Email == "" {
+			br.ErrMsg = "邮箱不能为空,请输入邮箱"
+			br.Msg = "邮箱不能为空,请输入邮箱"
+			return
+		}
+		if !utils.ValidateEmailFormatat(req.Email) {
+			br.ErrMsg = "邮箱格式错误,请重新输入"
+			br.Msg = "邮箱格式错误,请重新输入"
+			return
+		}
+		item, err := models.GetMsgCode(req.Email, req.VCode)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "验证码错误,请重新输入"
+				br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+				return
+			} else {
+				br.Msg = "验证码错误,请重新输入"
+				br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+				return
+			}
+		}
+		if item == nil {
+			br.Msg = "验证码错误,请重新输入"
+			return
+		}
+	} else {
+		br.Msg = "无效的登录方式"
+		br.ErrMsg = "无效的登录方式,Err:"
+		return
+	}
+	if len(req.Mobile) >= 11 && req.CountryCode == "" {
+		req.CountryCode = "86"
+	}
+	user, err = services.BindWxUser(openId, req.Mobile, req.Email, req.CountryCode)
+	if err != nil {
+		br.Msg = "登录失败"
+		br.ErrMsg = "绑定手机号失败:" + err.Error()
+		return
+	}
+	userId := user.UserId
+	var token string
+	tokenItem, err := models.GetTokenByOpenId(openId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "登录失败"
+		br.ErrMsg = "登录失败,获取token失败:" + err.Error()
+		return
+	}
+
+	if tokenItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
+		timeUnix := time.Now().Unix()
+		timeUnixStr := strconv.FormatInt(timeUnix, 10)
+		token = utils.MD5(openId) + utils.MD5(timeUnixStr)
+		//新增session
+		{
+			session := new(models.CygxSession)
+			session.OpenId = unionId
+			session.UnionId = unionId
+			session.UserId = userId
+			session.CreatedTime = time.Now()
+			session.LastUpdatedTime = time.Now()
+			session.ExpireTime = time.Now().AddDate(0, 1, 0)
+			session.AccessToken = token
+			err = models.AddSession(session)
+			if err != nil {
+				br.Msg = "登录失败"
+				br.ErrMsg = "登录失败,新增用户session信息失败:" + err.Error()
+				return
+			}
+		}
+	} else {
+		token = tokenItem.AccessToken
+	}
+
+	//新增登录日志
+	{
+		loginLog := new(models.WxUserLog)
+		loginLog.UserId = userId
+		loginLog.OpenId = openId
+		loginLog.Mobile = req.Mobile
+		loginLog.Email = req.Email
+		loginLog.CreateTime = time.Now()
+		loginLog.Handle = "wechat_user_login"
+		loginLog.Remark = token
+		go models.AddWxUserLog(loginLog)
+	}
+	//添加邀请绑定关系
+	{
+		if req.ShareUserCode != "" {
+			count, _ := models.GetUserInviteeCount(userId)
+			if count == 0 {
+				userItem := new(models.UserInvitee)
+				userItem.CreateTime = time.Now()
+				userItem.InviteedUserId = strconv.Itoa(userId)
+				userItem.InviteeUserId = req.ShareUserCode
+				shareUserId, _ := strconv.Atoi(req.ShareUserCode)
+				inviteeUser, _ := models.GetWxUserItemByUserId(shareUserId)
+				if inviteeUser != nil {
+					userItem.InviteeMobile = inviteeUser.Mobile
+					userItem.InviteeCompany = inviteeUser.CompanyName
+					userItem.InviteeCompanyId = inviteeUser.CompanyId
+					userItem.InviteeEmail = inviteeUser.Email
+				}
+				models.AddUserInvite(userItem)
+			}
+		}
+	}
+
+	//先关注后登录,更新用户是否关注过查研观向小助手公众号
+	{
+		services.UpdateCygxSubscribe(userId, unionId)
+	}
+
+	resp := new(models.LoginResp)
+	resp.UserId = userId
+	resp.Authorization = token
+	if user.CompanyId == 1 {
+		resp.IsPotential = true
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	br.Msg = "登录成功"
+}
+
+// @Title 获取用户详情
+// @Description 获取用户详情接口
+// @Success 200 {object} models.UserDetail
+// @router /detail [get]
+func (this *UserController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	var hasPermission int
+	detail := new(models.UserDetail)
+	if uid > 0 {
+		var err error
+		detail, err = models.GetUserDetailByUserId(uid)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取信息失败,Err:" + err.Error()
+			return
+		}
+		if detail == nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取信息失败,Err:用户不存在"
+			return
+		}
+
+		totalCollect, err := models.GetArticleUserCollectCount(uid) // 文章收藏数量
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "GetArticleUserCollectCount,Err:" + err.Error()
+			return
+		}
+
+		totalHistory, err := models.GetArticleUserHistoryNum(uid) // 足迹数量
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "GetArticleUserHistoryNum,Err:" + err.Error()
+			return
+		}
+
+		totalSchedule, err := models.GetArticleUserScheduleNum(uid) // 我的日程数量
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "GetArticleUserScheduleNum,Err:" + err.Error()
+			return
+		}
+
+		detail.ConNum = totalCollect
+		detail.HistoryNum = totalHistory
+		detail.ScheduleNum = totalSchedule
+
+		userRecord, _ := models.GetUserRecordByUserId(uid, utils.WxPlatform)
+		if userRecord != nil {
+			detail.NickName = userRecord.NickName
+			if detail.Headimgurl == "" {
+				detail.Headimgurl = userRecord.Headimgurl
+			}
+			if detail.Headimgurl == "" {
+				userRecord, _ = models.GetUserRecordByUserId(uid, 1)
+				if userRecord != nil {
+					detail.NickName = userRecord.NickName
+					detail.Headimgurl = userRecord.Headimgurl
+				}
+			}
+		}
+		if user.CompanyId > 1 {
+			companyItem, err := models.GetCompanyDetailById(user.CompanyId)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+				return
+			}
+			if companyItem != nil && companyItem.CompanyId > 0 {
+				detail.CompanyName = companyItem.CompanyName
+				//if companyItem.Status == "试用" || companyItem.Status == "永续" || companyItem.Status == "正式" {
+				//permissionStr, err := models.GetCompanyPermissionByUser(companyItem.CompanyId)
+				//if err != nil {
+				//	br.Msg = "获取信息失败"
+				//	br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+				//	return
+				//}
+				var permissionStr string
+				permissionList, err := models.GetCompanyPermissionList(companyItem.CompanyId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+					return
+				}
+
+				mapIsUpgrade := make(map[string]string)
+				mapZhukKeGuan := make(map[string]int)
+				for _, v := range permissionList {
+					mapZhukKeGuan[v.PermissionName] += 1
+					if v.IsUpgrade == 1 {
+						mapIsUpgrade[v.PermissionName] = v.PermissionName + "(升级)"
+					}
+				}
+				mapPermissionName := make(map[string]string)
+				//处理升级,并且合并主客观
+				for _, v := range permissionList {
+					if _, ok := mapPermissionName[v.PermissionName]; ok {
+						continue
+					}
+					if _, ok := mapIsUpgrade[v.PermissionName]; ok {
+						permissionStr += mapIsUpgrade[v.PermissionName] + ","
+					} else {
+						if mapZhukKeGuan[v.PermissionName] == 1 {
+							permissionStr += v.Remark + ","
+						} else {
+							permissionStr += v.PermissionName + ","
+						}
+					}
+					mapPermissionName[v.PermissionName] = v.PermissionName
+				}
+				permissionStr = strings.TrimRight(permissionStr, ",")
+				//permissionStrOld, err := models.GetCompanyPermission(companyItem.CompanyId)
+				//if err != nil {
+				//	br.Msg = "获取信息失败"
+				//	br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+				//	return
+				//}
+				//permissionStrListOld := strings.Split(permissionStrOld, ",")
+				//for _, v := range permissionStrListOld {
+				//	if strings.Count(permissionStr, v) > 1 {
+				//		permissionStr = strings.Replace(permissionStr, v+"(主观)", v, -1)
+				//		permissionStr = strings.Replace(permissionStr, v+"(客观),", "", -1)
+				//	}
+				//}
+
+				detail.PermissionName = permissionStr
+				//} else {
+				if permissionStr == "" {
+					hasPermission = 1
+				}
+				//}
+				detail.SellerName = companyItem.SellerName
+				detail.SellerMobile = companyItem.Mobile
+
+				microRoadshowCollectcount, err := models.GetUserMicroRoadshowCollectcount(user.UserId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取微路演收藏信息失败,GetUserMicroRoadshowCollectcount Err:" + err.Error()
+					return
+				}
+				detail.ConNum += microRoadshowCollectcount
+
+			} else {
+				hasPermission = 1
+			}
+		} else {
+			//判断是否已经申请过
+			applyCount, err := models.GetApplyRecordCount(uid)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+				return
+			}
+			if applyCount > 0 {
+				hasPermission = 3
+			} else {
+				hasPermission = 2
+			}
+			detail.CompanyName = detail.Note
+		}
+		detail.HasPermission = hasPermission
+
+	} else {
+		ur, _ := models.GetUserRecordByOpenId(user.OpenId)
+		if ur != nil {
+			detail.NickName = ur.NickName
+			detail.Email = ur.BindAccount
+			detail.Mobile = ur.BindAccount
+			detail.NickName = ur.NickName
+			detail.Headimgurl = ur.Headimgurl
+		}
+		hasPermission = 2
+		detail.HasPermission = hasPermission
+	}
+	if detail.Headimgurl == "" {
+		detail.Headimgurl = utils.DefaultHeadimgurl
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = detail
+}
+
+// @Title 校验用户状态信息
+// @Description 校验用户状态信息
+// @Success 200 {object} models.CheckStatusResp
+// @router /check/status [get]
+func (this *UserController) CheckLogin() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录"
+		br.Ret = 408
+		return
+	}
+
+	uid := user.UserId
+	resp := new(models.CheckStatusResp)
+	if uid > 0 {
+		//判断token是否过期
+		userRecord, err := models.GetUserRecordByUserId(uid, utils.WxPlatform)
+		if err != nil {
+			br.Msg = "获取用户信息失败"
+			br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+			return
+		}
+		permissionStr, err := models.GetCompanyPermission(user.CompanyId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+			return
+		}
+		resp.PermissionName = permissionStr
+
+		if user.Mobile == "" && user.Email == "" {
+			resp.IsBind = true
+		}
+		if userRecord.UnionId == "" {
+			resp.IsAuth = true
+		}
+	} else {
+		resp.IsBind = true
+		if user.UnionId == "" {
+			resp.IsAuth = true
+		}
+		resp.PermissionName = ""
+	}
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+	br.Ret = 200
+}
+
+// @Title 获取我的收藏
+// @Description 获取我的收藏列表
+// @Param   PageSize    query   int true       "PageSize"
+// @Param   CurrentIndex    query   int true       "CurrentIndex"
+// @Success 200 {object} models.ArticleCollectListResp
+// @router /collect/list [get]
+func (this *UserController) CollectList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	userId := this.User.UserId
+	var pageSize, currentIndex, startSize int
+	pageSize, _ = this.GetInt("PageSize")
+	currentIndex, _ = this.GetInt("CurrentIndex")
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	total, err := models.GetArticleUserCollectCount(userId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	list, err := models.GetArticleUserCollectList(startSize, pageSize, userId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ArticleReportBillboardLIstPageResp)
+	if len(list) == 0 {
+		page := paging.GetPaging(currentIndex, pageSize, total)
+		resp.List = list
+		resp.Paging = page
+		br.Msg = "获取成功!"
+		br.Ret = 200
+		br.Success = true
+		br.Data = resp
+		return
+	}
+	var condition string
+	var pars []interface{}
+	var articleIds []string
+	for _, v := range list {
+		articleIds = append(articleIds, strconv.Itoa(v.ArticleId))
+	}
+	articleIdStr := strings.Join(articleIds, ",")
+
+	//获取文章关联的产业
+	pars = make([]interface{}, 0)
+	condition = ` AND mg.article_id IN (  ` + utils.GetOrmInReplace(len(articleIds)) + ` )  `
+	pars = append(pars, articleIds)
+	industrialList, err := models.GetIndustrialListByarticleId(pars, condition)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,GetSubjectList Err:" + err.Error()
+		return
+	}
+	industrialMap := make(map[int][]*models.IndustrialManagementIdInt)
+	if len(industrialList) > 0 {
+		for _, v := range industrialList {
+			item := new(models.IndustrialManagementIdInt)
+			item.ArticleId = v.ArticleId
+			if v.ArticleId > utils.SummaryArticleId {
+				item.IsResearch = true
+			}
+			item.IndustrialManagementId = v.IndustrialManagementId
+			item.IndustryName = v.IndustryName
+			industrialMap[v.ArticleId] = append(industrialMap[v.ArticleId], item)
+		}
+	}
+	for k, v := range list {
+		if len(industrialMap[v.ArticleId]) > 0 {
+			list[k].List = industrialMap[v.ArticleId]
+		} else {
+			list[k].List = make([]*models.IndustrialManagementIdInt, 0)
+		}
+	}
+
+	articleMap := make(map[int]*models.ArticleDetail)
+	if articleIdStr != "" {
+		articleList, err := models.GetArticleDetailByIdStr(articleIdStr)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取报告详情信息失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range articleList {
+			if _, ok := articleMap[v.ArticleId]; !ok {
+				articleMap[v.ArticleId] = v
+			}
+		}
+	}
+
+	//处理文章PV收藏等数量
+	mapArticleCollectNum := make(map[int]*models.CygxArticleNum)
+	if len(articleIds) > 0 {
+		articleCollectNumList, err := models.GetArticleCollectNum(articleIds, userId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,GetArticleCollectNum Err:" + err.Error()
+			return
+		}
+		for _, v := range articleCollectNumList {
+			mapArticleCollectNum[v.ArticleId] = v
+		}
+	}
+
+	lyjhTypeMap, _ := services.GetLyjhTypeMap()
+
+	lenList := len(list)
+	for i := 0; i < lenList; i++ {
+		item := list[i]
+		article := articleMap[item.ArticleId]
+		if list[i].IsSpecial != 1 {
+			list[i].Title = article.Title
+			list[i].DepartmentId = article.DepartmentId
+			list[i].NickName = article.NickName
+			list[i].PublishDate = article.PublishDate
+			if article.ArticleTypeId == 0 {
+				list[i].Source = 1
+			} else {
+				list[i].Source = 2
+				list[i].IsResearch = true
+			}
+			if mapArticleCollectNum[article.ArticleId] != nil {
+				list[i].CollectNum = mapArticleCollectNum[article.ArticleId].CollectNum
+				list[i].Pv = mapArticleCollectNum[article.ArticleId].Pv
+				list[i].IsCollect = mapArticleCollectNum[article.ArticleId].IsCollect
+			}
+			if _, ok := lyjhTypeMap[item.CategoryId]; ok && list[i].ArticleId >= utils.SummaryArticleId {
+				list[i].IsRoadShow = true
+			}
+		}
+		if item.ArticleTypeId == -1 {
+			list[i].ArticleTypeName = utils.CYGX_YANXUAN_SPECIAL
+		} else if item.ArticleTypeId > 0 {
+			list[i].ArticleTypeName = utils.CYGX_YANXUAN_ARTICLE
+		}
+		if item.SpecialType == 1 {
+			list[i].Title = "【笔记】" + list[i].Title
+		} else if list[i].SpecialType == 2 {
+			list[i].Title = "【观点】" + list[i].Title
+		}
+		if item.MyCollectNum > 0 {
+			list[i].IsCollect = true
+		}
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.List = list
+	resp.Paging = page
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 获取申请访谈列表
+// @Description 获取申请访谈列表
+// @Param   PageSize    query   int true       "PageSize"
+// @Param   CurrentIndex    query   int true       "CurrentIndex"
+// @Success 200 {object} models.ArticleInterviewApplyListResp
+// @router /interview/apply/list [get]
+func (this *UserController) InterviewApplyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	userId := this.User.UserId
+	var pageSize, currentIndex, startSize int
+	pageSize, _ = this.GetInt("PageSize")
+	currentIndex, _ = this.GetInt("CurrentIndex")
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	total, err := models.GetArticleUserInterviewApplyCount(userId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	list, err := models.GetArticleUserInterviewApplyList(startSize, pageSize, userId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	var articleIds []string
+	for _, v := range list {
+		articleIds = append(articleIds, strconv.Itoa(v.ArticleId))
+	}
+	articleIdStr := strings.Join(articleIds, ",")
+	articleMap := make(map[int]*models.ArticleDetail)
+	if articleIdStr != "" {
+		articleList, err := models.GetArticleDetailByIdStr(articleIdStr)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取报告详情信息失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range articleList {
+			if _, ok := articleMap[v.ArticleId]; !ok {
+				articleMap[v.ArticleId] = v
+			}
+		}
+	}
+	lenList := len(list)
+	for i := 0; i < lenList; i++ {
+		item := list[i]
+		if articleMap[item.ArticleId] == nil {
+			continue
+		}
+		article := articleMap[item.ArticleId]
+		bodySub, _ := services.GetReportContentTextSub(article.Body)
+		list[i].Title = article.Title
+		list[i].TitleEn = article.TitleEn
+		list[i].UpdateFrequency = article.UpdateFrequency
+		list[i].CreateDate = article.CreateDate
+		list[i].PublishDate = article.PublishDate
+		list[i].Body = bodySub
+		list[i].Abstract = article.Abstract
+		list[i].CategoryName = article.CategoryName
+		list[i].SubCategoryName = article.SubCategoryName
+		list[i].ExpertBackground = article.ExpertBackground
+		list[i].ExpertNumber = article.ExpertNumber
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(models.ArticleInterviewApplyListResp)
+	resp.List = list
+	resp.Paging = page
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 获取浏览历史列表
+// @Description 获取浏览历史列表
+// @Param   PageSize    query   int true       "PageSize"
+// @Param   CurrentIndex    query   int true       "CurrentIndex"
+// @Success 200 {object} models.ArticleBrowseHistoryListResp
+// @router /browse/history/list [get]
+func (this *UserController) BrowseHistoryList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	userId := this.User.UserId
+	var pageSize, currentIndex, startSize int
+	pageSize, _ = this.GetInt("PageSize")
+	currentIndex, _ = this.GetInt("CurrentIndex")
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	endDate := time.Now().AddDate(0, -1, 0).Format(utils.FormatDate)
+	total, err := models.GetArticleUserBrowseHistoryCount(userId, endDate)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	list, err := models.GetArticleUserBrowseHistoryList(startSize, pageSize, userId, endDate)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.ArticleReportBillboardLIstPageResp)
+	if len(list) == 0 {
+		page := paging.GetPaging(currentIndex, pageSize, total)
+		resp.List = list
+		resp.Paging = page
+		br.Msg = "获取成功!"
+		br.Ret = 200
+		br.Success = true
+		br.Data = resp
+		return
+	}
+
+	var articleIds []string
+	var condition string
+	var pars []interface{}
+	for _, v := range list {
+		articleIds = append(articleIds, strconv.Itoa(v.ArticleId))
+	}
+	articleIdStr := strings.Join(articleIds, ",")
+
+	//获取文章关联的产业
+	pars = make([]interface{}, 0)
+	condition = ` AND mg.article_id IN (  ` + utils.GetOrmInReplace(len(articleIds)) + ` )  `
+	pars = append(pars, articleIds)
+	industrialList, err := models.GetIndustrialListByarticleId(pars, condition)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,GetSubjectList Err:" + err.Error()
+		return
+	}
+	industrialMap := make(map[int][]*models.IndustrialManagementIdInt)
+	if len(industrialList) > 0 {
+		for _, v := range industrialList {
+			item := new(models.IndustrialManagementIdInt)
+			item.ArticleId = v.ArticleId
+			if v.ArticleId > utils.SummaryArticleId {
+				item.IsResearch = true
+			}
+			item.IndustrialManagementId = v.IndustrialManagementId
+			item.IndustryName = v.IndustryName
+			industrialMap[v.ArticleId] = append(industrialMap[v.ArticleId], item)
+		}
+	}
+	for k, v := range list {
+		if len(industrialMap[v.ArticleId]) > 0 {
+			list[k].List = industrialMap[v.ArticleId]
+		} else {
+			list[k].List = make([]*models.IndustrialManagementIdInt, 0)
+		}
+	}
+
+	articleMap := make(map[int]*models.ArticleDetail)
+	if articleIdStr != "" {
+		articleList, err := models.GetArticleDetailByIdStr(articleIdStr)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取报告详情信息失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range articleList {
+			if _, ok := articleMap[v.ArticleId]; !ok {
+				articleMap[v.ArticleId] = v
+			}
+		}
+	}
+
+	//处理文章PV收藏等数量
+	mapArticleCollectNum := make(map[int]*models.CygxArticleNum)
+	if len(articleIds) > 0 {
+		articleCollectNumList, err := models.GetArticleCollectNum(articleIds, userId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,GetArticleCollectNum Err:" + err.Error()
+			return
+		}
+		for _, v := range articleCollectNumList {
+			mapArticleCollectNum[v.ArticleId] = v
+		}
+	}
+
+	lenList := len(list)
+	for i := 0; i < lenList; i++ {
+		item := list[i]
+		article := articleMap[item.ArticleId]
+		if article != nil {
+			list[i].Title = article.Title
+			list[i].PublishDate = utils.TimeRemoveHms2(article.PublishDate)
+			list[i].DepartmentId = article.DepartmentId
+			list[i].NickName = article.NickName
+			if article.ArticleId < utils.SummaryArticleId {
+				list[i].Source = 1
+			} else {
+				list[i].Source = 2
+			}
+
+			if mapArticleCollectNum[article.ArticleId] != nil {
+				list[i].CollectNum = mapArticleCollectNum[article.ArticleId].CollectNum
+				list[i].Pv = mapArticleCollectNum[article.ArticleId].Pv
+				list[i].IsCollect = mapArticleCollectNum[article.ArticleId].IsCollect
+			}
+			//list[i].TitleEn = article.TitleEn
+			//list[i].UpdateFrequency = article.UpdateFrequency
+			//list[i].CreateDate = article.CreateDate
+			//list[i].Body, _ = services.GetReportContentTextSub(article.Body)
+			//list[i].Abstract = article.Abstract
+			//list[i].CategoryName = article.CategoryName
+			//list[i].SubCategoryName = article.SubCategoryName
+		}
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	resp.List = list
+	resp.Paging = page
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 未付费申请试用
+// @Description 未付费申请试用
+// @Param	request	body models.ApplyTryReq true "type json string"
+// @Success 200
+// @router /apply/try [post]
+func (this *UserController) ApplyTryOut() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	mobile := user.Mobile
+	var req models.ApplyTryReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.RealName == "" {
+		req.RealName = user.RealName
+	}
+	if req.CompanyName == "" {
+		req.CompanyName = user.CompanyName
+	}
+	uid := user.UserId
+
+	var title string
+	var sourceId int
+	var source string
+	tryType := req.TryType
+	detailId := req.DetailId
+	sourceId = detailId
+	source = tryType
+	var isResearch bool // 是否属于研选
+	if tryType == "Article" {
+		detail, err := models.GetArticleDetailById(detailId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取信息失败,Err:" + err.Error()
+			return
+		}
+		title = detail.Title
+		if detail.ArticleTypeId > 0 {
+			isResearch = true
+		}
+	} else if tryType == "Activity" {
+		detail, err := models.GetAddActivityInfoById(detailId)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "活动ID错误,不存在activityId:" + strconv.Itoa(detailId)
+			return
+		}
+		title = detail.ActivityName
+		if strings.Contains(detail.ChartPermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+			isResearch = true
+		}
+	} else if tryType == "MicroAudio" {
+		// 微路演音频
+		microAudio, e := models.GetCygxActivityVoiceById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "微路演音频信息有误, 不存在的VoiceId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = microAudio.VoiceName
+		sourceId = microAudio.ActivityId
+		source = "activityvoice"
+	} else if tryType == "ActivityVideo" {
+		// 活动视频
+		activityVideo, e := models.GetCygxActivityVideoById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "微路演音频信息有误, 不存在的VoiceId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = activityVideo.VideoName
+		sourceId = activityVideo.ActivityId
+		source = "activityvideo"
+	} else if tryType == "MicroVideo" {
+		// 微路演视频
+		microVideo, e := models.GetMicroRoadshowVideoById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "微路演视频信息有误, 不存在的VideoId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = microVideo.VideoName
+		source = "roadshow"
+	} else if tryType == "Researchsummary" {
+		// 本周研究汇总
+		ResearchSummaryInfo, e := models.GetCygxResearchSummaryInfoById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "本周研究汇总信息有误, 不存在的detailId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = ResearchSummaryInfo.Title
+		source = "researchsummary"
+	} else if tryType == "Minutessummary" {
+		// 上周纪要汇总
+		MinutesSummaryInfo, e := models.GetCygxMinutesSummaryInfoById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "上周纪要汇总信息有误, 不存在的detailId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = MinutesSummaryInfo.Title
+		source = "minutessummary"
+	} else if tryType == "ReportSelection" {
+		// 报告精选
+		ReportSelectionInfo, e := models.GetCygxReportSelectionInfoById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "报告精选信息有误, 不存在的detailId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = ReportSelectionInfo.Title
+		source = "reportselection"
+	} else if tryType == "ProductInterior" {
+		// 产品内测
+		ProductInteriorDetail, e := models.GetCygxProductInteriorDetail(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "产品内测信息有误, 不存在的detailId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = ProductInteriorDetail.Title
+		source = "productinterior"
+	}
+
+	//缓存校验
+	cacheKey := fmt.Sprint("xygx:apply_record:add:", uid)
+	ttlTime := utils.Rc.GetRedisTTL(cacheKey)
+	if ttlTime > 0 {
+		br.Msg = "申请失败,申请过于频繁"
+		br.ErrMsg = "申请失败,申请过于频繁"
+		return
+	}
+	utils.Rc.SetNX(cacheKey, user.Mobile, time.Second*10)
+
+	//判断是否已经申请过
+	applyCount, err := models.GetApplyRecordCount(uid)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+		return
+	}
+
+	if applyCount > 0 {
+		br.Msg = "您已提交申请,请耐心等待。"
+		br.IsSendEmail = false
+		return
+	}
+
+	//判断是否存在申请
+	var sellerMobile string
+	if req.ApplyMethod == 2 {
+		if req.BusinessCardUrl == "" {
+			br.Msg = "请上传名片"
+			return
+		}
+
+		if req.RealName == "" {
+			br.Msg = "请输入姓名"
+			return
+		}
+
+		if req.CompanyName == "" {
+			br.Msg = "请输入公司名称"
+			return
+		}
+
+		if req.BusinessCardUrl != "" && utils.RunMode == "release" {
+			card, err := services.GetBusinessCard(req.BusinessCardUrl)
+			if err != nil {
+				br.Msg = "名片识别失败"
+				br.ErrMsg = "名片识别失败,Err:" + err.Error()
+				return
+			}
+			mobileStr := strings.Join(card.WordsResult.MOBILE, ",")
+			isFlag := true
+			if mobile != "" {
+				if strings.Contains(mobileStr, mobile) || mobileStr == "" {
+					isFlag = true
+				} else {
+					isFlag = false
+				}
+			}
+			if !isFlag {
+				//阿里云识别
+				if utils.RunMode == "release" {
+					aliyunResult, err := services.AliyunBusinessCard(req.BusinessCardUrl)
+					if err != nil {
+						br.Msg = "识别失败"
+						br.ErrMsg = "识别失败,Err:" + err.Error()
+						return
+					}
+					if !aliyunResult.Success {
+						br.Msg = "识别失败"
+						br.ErrMsg = "识别失败"
+						return
+					}
+
+					mobileStr := strings.Join(aliyunResult.TelCell, ",")
+					if mobile != "" {
+						if strings.Contains(mobileStr, mobile) {
+							isFlag = true
+						} else {
+							isFlag = false
+						}
+					}
+				}
+			}
+			if !isFlag {
+				br.Msg = "名片手机号与所填手机号不匹配,请重新填写"
+				br.ErrMsg = "mobile:" + mobile
+				return
+			}
+		}
+	}
+
+	//获取销售信息
+	sellerItem, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "申请失败"
+		br.ErrMsg = "获取销售信息失败,Err:" + err.Error()
+		return
+	}
+
+	//用户状态,1:潜在客户 、2:现有客户 、3:FICC客户 、4:现有客户(正式,无对应权限) 、5:现有客户(试用,无对应权限)  、6:现有客户(试用暂停) 、7:现有客户(冻结) 、8:现有客户(流失)?
+	CompanyIdType := 1
+	applyMethod := ""
+	if sellerItem != nil {
+		companyItem, err := models.GetCompanyDetailById(user.CompanyId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+			return
+		}
+		if companyItem != nil && companyItem.CompanyId > 0 {
+			companyProduct, err := models.GetCompanyProductDetail(user.CompanyId, 2)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+				return
+			}
+			if companyProduct != nil && companyProduct.IsSuspend == 1 {
+				CompanyIdType = 6
+			} else {
+				switch companyItem.Status {
+				case "正式":
+					CompanyIdType = 4
+				case "试用":
+					CompanyIdType = 5
+				case "冻结":
+					CompanyIdType = 7
+				case "流失":
+					CompanyIdType = 8
+				}
+			}
+			applyMethod = companyItem.Status + "客户申请"
+			if detailId > 0 {
+				if companyProduct != nil && companyProduct.IsSuspend == 1 {
+					applyMethod = "试用暂停客户"
+				} else {
+					if companyItem.Status == "正式" || companyItem.Status == "试用" {
+						applyMethod = companyItem.Status + "客户申请,无对应权限"
+					} else if companyItem.Status == "冻结" || companyItem.Status == "流失" {
+						applyMethod = companyItem.Status + "客户"
+					}
+				}
+				applyMethod = applyMethod + "," + title
+			}
+			openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
+			if openIpItem != nil && openIpItem.OpenId != "" {
+				if req.ApplyMethod != 2 {
+					req.RealName = user.RealName
+					req.CompanyName = user.CompanyName
+				}
+				//go services.SendPermissionApplyTemplateMsg(req.RealName, req.CompanyName, mobile, applyMethod, openIpItem)
+			}
+		}
+	} else {
+		//获取销售信息
+		sellerItem, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 1)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "申请失败"
+			br.ErrMsg = "获取销售信息失败,Err:" + err.Error()
+			return
+		}
+		if sellerItem != nil {
+			CompanyIdType = 3
+			applyMethod = "FICC客户"
+		} else {
+			CompanyIdType = 1
+			applyMethod = "潜在客户"
+		}
+		if detailId > 0 {
+			applyMethod = applyMethod + "," + title
+		}
+	}
+	item := new(models.CygxApplyRecord)
+	item.UserId = user.UserId
+	item.BusinessCardUrl = req.BusinessCardUrl
+	item.RealName = req.RealName
+	item.CompanyName = req.CompanyName
+	item.Mobile = user.Mobile
+	item.CreateTime = time.Now()
+	item.ApplyMethod = req.ApplyMethod
+	item.CompanyIdPay = user.CompanyId
+	item.CompanyNamePay = user.CompanyName
+	item.CompanyIdType = CompanyIdType
+	if user.InviteCompany == utils.LUODING_CODE && user.CompanyId == 1 {
+		//如果是潜在客户就标记来源
+		item.InviteCompanySource = 2
+	}
+	item.Title = title
+	item.SourceId = sourceId
+	item.Source = strings.ToLower(source)
+	item.RegisterPlatform = utils.REGISTER_PLATFORM
+	err = models.AddApplyRecord(item)
+	if err != nil {
+		br.Msg = "申请失败"
+		br.ErrMsg = "申请失败,Err:" + err.Error()
+		return
+	}
+	if sellerItem == nil {
+		go services.SendPermissionApplyTemplateMsgAdmin(req, mobile, applyMethod, isResearch)
+	} else {
+		openIpItem, _ := models.GetUserRecordByMobile(4, sellerItem.Mobile)
+		if openIpItem != nil && openIpItem.OpenId != "" {
+			go services.SendPermissionApplyTemplateMsg(req.RealName, req.CompanyName, mobile, applyMethod, openIpItem)
+		}
+	}
+	//添加成功后,设置5分钟缓存,不允许重复添加
+	//utils.Rc.SetNX(cacheKey, user.Mobile, time.Second*60)
+
+	br.Msg = "申请成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = sellerMobile
+}
+
+// @Title 是否需要填写区号
+// @Description 获取是否需要填写区号接口
+// @Success 200 {object} models.CountryCode
+// @router /countryCcode/isNeedAdd [get]
+func (this *UserController) CountryCcode() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	uid := user.UserId
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	//if uid == 0 {
+	//	br.Msg = "请登录"
+	//	br.ErrMsg = "请登录,用户信息为空"
+	//	br.Ret = 408
+	//	return
+	//}
+	resp := new(models.CountryCode)
+	if user.CountryCode == "" && len(user.Mobile) >= 11 {
+		err := models.ChangeUserOutboundMobileByMobile(uid)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + err.Error()
+			return
+		}
+	}
+	if user.CountryCode == "" && user.Mobile != "" && len(user.Mobile) < 11 {
+		resp.IsNeedAddCountryCode = true
+	}
+	if user.OutboundMobile != "" {
+		resp.IsNeedAddCountryCode = false
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 上传用户区号
+// @Description 上传用户区号接口
+// @Param	request	body models.CountryCodeItem true "type json string"
+// @Success Ret=200 新增成功
+// @router /countryCcode/Add [POST]
+func (this *UserController) AddCountryCcode() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.CountryCodeItem
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	err = models.AddCountryCode(req.CountryCode, user)
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取信息失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+}
+
+// @Title 用户修改外呼手机号以及区号
+// @Description 用户修改外呼手机号以及区号接口
+// @Param	request	body models.OutboundMobileItem true "type json string"
+// @Success Ret=200 操作成功
+// @router /countryCcode/addOutboundMobile [POST]
+func (this *UserController) AddOutboundMobile() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	uid := user.UserId
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.OutboundMobileItem
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if !utils.ValidateFixedTelephoneFormatatEasy(req.OutboundMobile) {
+		br.Msg = "号码格式有误,请重新填写!"
+		br.ErrMsg = "号码格式有误,请重新填写" + req.OutboundMobile
+		return
+	}
+	if req.OutboundMobile == "" {
+		br.Msg = "请填写区号!"
+		return
+	}
+	item := new(models.OutboundMobileItem)
+	item.OutboundMobile = req.OutboundMobile
+	item.OutboundCountryCode = req.OutboundCountryCode
+	item.ActivityId = req.ActivityId
+	if req.ActivityId == 0 {
+		err = models.AddOutboundMobile(item, uid)
+	} else {
+		if user.Mobile == "" && user.OutboundMobile == "" {
+			items := new(models.CygxActivitySignup)
+			items.UserId = uid
+			items.ActivityId = req.ActivityId
+			items.CreateTime = time.Now()
+			items.Mobile = user.Mobile
+			items.Email = user.Email
+			items.CompanyId = user.CompanyId
+			items.CompanyName = user.CompanyName
+			items.SignupType = 1
+			items.FailType = 0
+			items.DoFailType = 0
+			items.OutboundMobile = req.OutboundMobile
+			items.CountryCode = req.OutboundCountryCode
+			_, err = models.AddActivitySignupFromEmail(items)
+		} else {
+			total, err := models.GetActivityCountByIdWithUid(item.ActivityId, uid)
+			if total == 0 {
+				br.Msg = "报名信息不存在"
+				br.ErrMsg = "报名信息不存在,Err:" + "活动ActivityId:" + strconv.Itoa(item.ActivityId) + "用户Uid:" + strconv.Itoa(uid)
+				return
+			}
+			if err != nil {
+				br.Msg = "操作失败"
+				br.ErrMsg = "操作失败,Err:" + err.Error()
+				return
+			}
+			err = models.AddOutboundMobile(item, uid)
+		}
+	}
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// @Title 获取我的提问
+// @Description 获取我的提问列表
+// @Success 200 {object} models.CygxAskListResp
+// @router /ask/list [get]
+func (this *UserController) AskList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	userId := this.User.UserId
+	listActcivity, err := models.GetActivityAskList(userId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取活动问题失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range listActcivity {
+		v.AskType = "Activity"
+	}
+	listArticle, err := models.GetArticleAskList(userId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取文章问题失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range listArticle {
+		v.AskType = "Report"
+		listActcivity = append(listActcivity, v)
+	}
+	resp := new(models.CygxAskListResp)
+	resp.List = listActcivity
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 是否展示免费试用按钮
+// @Description 获取是否展示免费试用按钮接口
+// @Param	request	body models.IsShow true "type json string"
+// @Success 200
+// @router /isShow/freeButton [get]
+func (this *UserController) IsShow() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	var resp models.IsShow
+	detail, err := models.GetConfigByCode("free_trial_card")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "城市配置信息失败,Err:" + err.Error()
+		return
+	}
+	companyDetail, err := models.GetCompanyDetailByIdGroup(user.CompanyId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取数据失败!"
+		br.ErrMsg = "获取客户详情失败,Err:" + err.Error()
+		return
+	}
+	count, err := models.CountCygxUserFreeeButton(user.UserId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取数据失败!"
+		br.ErrMsg = "获取客户详情失败,Err:" + err.Error()
+		return
+	}
+	if companyDetail != nil && companyDetail.IsSuspend == 0 {
+		if detail.ConfigValue == "1" && (companyDetail.Status == "正式" || companyDetail.Status == "试用" || companyDetail.Status == "永续") && count == 0 {
+			resp.IsShow = true
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 隐藏当天的按钮
+// @Description 隐藏当天的按钮接口
+// @Success 200
+// @router /freeButton/update [post]
+func (this *UserController) FreeButtonUpdate() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	count, err := models.CountCygxUserFreeeButtonByUser(user.UserId)
+	if err != nil {
+		br.Msg = "获取数据失败!"
+		br.ErrMsg = "获取客户详情失败,Err:" + err.Error()
+		return
+	}
+	if count == 0 {
+		item := new(models.CygxUserFreeeButton)
+		item.UserId = user.UserId
+		item.CompanyId = user.CompanyId
+		item.CreateTime = time.Now()
+		item.ModifyTime = time.Now()
+		item.EffectiveTime = time.Now().Format(utils.FormatDate)
+		_, err := models.AddCygxUserFreeeButton(item)
+		if err != nil {
+			br.Msg = "操作失败!"
+			br.ErrMsg = "获取客户详情失败,Err:" + err.Error()
+			return
+		}
+	} else {
+		err := models.UpdateCygxUserFreeeButton(user.UserId)
+		if err != nil {
+			br.Msg = "操作失败!"
+			br.ErrMsg = "获取客户详情失败,Err:" + err.Error()
+			return
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功!"
+}
+
+// @Title 权限弹窗是否展示免费月卡
+// @Description 获取权限弹窗是否展示免费月卡接口
+// @Param	request	body models.IsShow true "type json string"
+// @Success 200
+// @router /isShow/alert [get]
+func (this *UserController) AlertIsShow() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	var resp models.IsShow
+	detail, err := models.GetConfigByCode("free_trial_card")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "城市配置信息失败,Err:" + err.Error()
+		return
+	}
+	if user.CompanyId == 1 && detail.ConfigValue == "1" {
+		resp.IsShow = true
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 分享的时候是否展示免费月卡
+// @Description 获取权限弹窗是否展示免费月卡接口
+// @Param	request	body models.IsShow true "type json string"
+// @Success 200
+// @router /isShow/share [get]
+func (this *UserController) ShareIsShow() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	var resp models.IsShow
+	detail, err := models.GetConfigByCode("free_trial_card")
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "城市配置信息失败,Err:" + err.Error()
+		return
+	}
+	if user.CompanyId != 16 && detail.ConfigValue == "1" {
+		resp.IsShow = true
+	}
+	resp.LinkWxExplain = utils.LINK_WX_EXPLAIN
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 更改用户微信头像
+// @Description 更改用户微信头像
+// @Param	request	body models.Headimgurl true "type json string"
+// @Success 200 {object} models.ArticleDetailFileLink
+// @router /headimgurl/update [post]
+func (this *UserController) HeadimgurlUpdate() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.Headimgurl
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	uid := user.UserId
+	headimgurl := req.Headimgurl
+	if headimgurl == "" {
+		br.Msg = "操作失败"
+		br.ErrMsg = "头像信息不能为空"
+		return
+	}
+	err = models.UpdateUserHeadimgurl(headimgurl, uid)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "头像信息不能为空"
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// @Title 登录 (无需token)
+// @Description 登录接口 (无需token)
+// @Param	request	body models.LoginReq true "type json string"
+// @Success 200 {object} models.LoginResp
+// @router /loginPublic [post]
+func (this *UserCommonController) LoginPublic() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.LoginReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	mobile := strings.Trim(req.Mobile, " ")
+	if req.Mobile == "" {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,手机号为空 为空"
+		return
+	}
+
+	item, err := models.GetMsgCode(req.Mobile, req.VCode)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "验证码错误,请重新输入"
+			br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+			return
+		} else {
+			br.Msg = "验证码错误,请重新输入"
+			br.ErrMsg = "校验验证码失败,Err:" + err.Error()
+			return
+		}
+	}
+	if item == nil {
+		br.Msg = "验证码错误,请重新输入"
+		return
+	}
+
+	if len(req.Mobile) >= 11 && req.CountryCode == "" {
+		req.CountryCode = "86"
+	}
+	var token string
+	tokenItem, err := models.GetSessionMobileTokenByOpenId(mobile)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "登录失败"
+		br.ErrMsg = "登录失败,获取token失败:" + err.Error()
+		return
+	}
+	if tokenItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
+		timeUnix := time.Now().Unix()
+		timeUnixStr := strconv.FormatInt(timeUnix, 10)
+		token = utils.MD5(mobile) + utils.MD5(timeUnixStr)
+		//新增session
+		{
+			session := new(models.CygxSessionMobile)
+			session.Mobile = mobile
+			session.CreatedTime = time.Now()
+			session.LastUpdatedTime = time.Now()
+			session.ExpireTime = time.Now().AddDate(0, 1, 0)
+			session.AccessToken = token
+			err = models.AddCygxSessionMobile(session)
+			if err != nil {
+				br.Msg = "登录失败"
+				br.ErrMsg = "登录失败,新增用户session信息失败:" + err.Error()
+				return
+			}
+		}
+	} else {
+		token = tokenItem.AccessToken
+	}
+	resp := new(models.LoginResp)
+	resp.Authorization = token
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	br.Msg = "登录成功"
+}
+
+// @Title 获取我的留言
+// @Description 获取我的留言列表
+// @Success 200 {object} models.CygxCommentListResp
+// @router /comment/list [get]
+func (this *UserController) CommnetList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+
+	userId := this.User.UserId
+	commentlist, err := models.GetCommentList(userId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取我的留言列表失败,Err:" + err.Error()
+		return
+	}
+	articleLyjhMap, _ := services.GetLyjhArticleMap()
+	articleCollectMap, _ := services.GetCygxArticleCollectMap(user.UserId)
+	resp := new(models.CygxCommentListResp)
+	for _, comment := range commentlist {
+		item := models.CygxArticleCommentResp{
+			Id:          comment.Id,
+			UserId:      comment.UserId,
+			ArticleId:   comment.ArticleId,
+			IndustryId:  comment.IndustryId,
+			ActivityId:  comment.ActivityId,
+			CreateTime:  comment.CreateTime,
+			Mobile:      comment.Mobile,
+			Email:       comment.Email,
+			CompanyId:   comment.CompanyId,
+			CompanyName: comment.CompanyName,
+			Content:     comment.Content,
+			Title:       comment.Title,
+		}
+		if comment.ArticleId > 0 {
+			item.RedirectType = 1
+		} else if comment.IndustryId > 0 {
+			item.RedirectType = 3
+		} else if comment.ActivityId > 0 {
+			item.RedirectType = 2
+		}
+		item.IsCollect = articleCollectMap[comment.ArticleId]
+		item.IsRoadShow = articleLyjhMap[comment.ArticleId]
+		resp.List = append(resp.List, &item)
+	}
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 获取我的收藏
+// @Description 获取我的收藏列表
+// @Success 200 {object} models.ArticleCollectListResp
+// @router /collect/list/microRoadshow [get]
+func (this *UserController) MicroRoadshowCollectList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	userId := this.User.UserId
+
+	list, err := models.GetUserMicroRoadshowCollectList(userId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	resp := new(models.MicroRoadshowCollectList)
+	var audioIds []string
+	var videoIds []string
+	var activityVideoIds []string
+	for _, item := range list {
+		if item.ActivityVoiceId > 0 {
+			audioIds = append(audioIds, strconv.Itoa(item.ActivityVoiceId))
+		} else if item.VideoId > 0 {
+			videoIds = append(videoIds, strconv.Itoa(item.VideoId))
+		} else if item.ActivityVideoId > 0 {
+			activityVideoIds = append(activityVideoIds, strconv.Itoa(item.ActivityVideoId))
+		}
+	}
+	resp.AudioIds = strings.Join(audioIds, ",")
+	resp.VideoIds = strings.Join(videoIds, ",")
+	resp.ActivityVideoIds = strings.Join(activityVideoIds, ",")
+
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 新增埋点
+// @Description 新增埋点接口
+// @Success 200 "新增成功!"
+// @router /tracking [get]
+func (this *UserController) Tracking() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+
+	//item := new(models.CygxPageHistoryRecord)
+	//item.UserId = user.UserId
+	//item.CreateTime = time.Now()
+	//item.Mobile = user.Mobile
+	//item.Email = user.Email
+	//item.CompanyId = user.CompanyId
+	//item.CompanyName = user.CompanyName
+	//item.Router = this.Ctx.Request.RequestURI
+	//item.PageRouter = this.Ctx.Input.Query("PageRouter")
+	//
+	//go models.AddCygxPageHistoryRecord(item)
+	//
+
+	br.Msg = "新增成功!"
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 未付费申请试用详情
+// @Description 未付费申请试用详情接口
+// @Param   ApplyRecordId    query   int true       "申请ID"
+// @Success 200 {object} models.ArticleCollectListResp
+// @Success 200
+// @router /apply/detail [get]
+func (this *UserController) ApplyDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	resp := new(models.CygxApplyRecordDetialResp)
+	applyRecordId, _ := this.GetInt("ApplyRecordId")
+	detail, err := models.GetCygxApplyRecordById(applyRecordId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	switch detail.RegisterPlatform {
+	case 1:
+		detail.ApplicationSource = "小程序"
+	case 2:
+		detail.ApplicationSource = "网页版"
+	}
+
+	switch detail.InviteCompanySource {
+	case 2:
+		detail.ApplicationSource += "(络町)"
+	}
+	resp.Detail = detail
+	br.Msg = "申请成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 更改绑定邮箱
+// @Description 更改绑定邮箱接口
+// @Param	request	body models.Headimgurl true "type json string"
+// @Success 200 {object} models.ArticleDetailFileLink
+// @router /email/binding [post]
+func (this *UserController) EmailBinding() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.UserEmail
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	uid := user.UserId
+	if user.Email != "" {
+		br.Msg = "邮箱号已存在,请勿重复绑定"
+		br.ErrMsg = "邮箱格式错误,请重新输入 Email:" + user.Email
+		return
+	}
+	email := req.Email
+	if !utils.ValidateEmailFormatat(req.Email) {
+		br.Msg = "邮箱格式错误,请重新输入"
+		br.ErrMsg = "邮箱格式错误,请重新输入"
+		return
+	}
+	err = models.UpdateUserEmail(email, uid)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "头像信息不能为空"
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 609 - 0
controllers/wechat.go

@@ -0,0 +1,609 @@
+package controllers
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/medivhzhan/weapp/v2"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type WechatController struct {
+	BaseAuthController
+}
+
+type WechatCommonController struct {
+	BaseCommonController
+}
+
+// @Title 微信登录接口
+// @Description 微信登录接口
+// @Param   Code   query   string  true       "微信唯一编码code"
+// @Success 200 {object} models.WxLoginResp
+// @router /login [get]
+func (this *WechatCommonController) WechatLogin() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	code := this.GetString("Code")
+	if code == "" {
+		br.Msg = "参数错误"
+		br.ErrMsg = "Code 为空"
+		return
+	}
+	wxInfo, err := weapp.Login(utils.WxAppId, utils.WxAppSecret, code)
+	if err != nil {
+		br.Msg = "获取用户信息失败"
+		br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+		return
+	}
+	if err = wxInfo.GetResponseError(); err != nil {
+		br.Msg = "获取用户信息失败"
+		br.ErrMsg = "获取用户信息失败,code:" + strconv.Itoa(wxInfo.ErrCode) + ",msg:" + wxInfo.ErrMSG
+		return
+	}
+
+	wxUserInfo := new(services.WxUserInfo)
+	wxUserInfo.Unionid = wxInfo.UnionID
+	wxUserInfo.Openid = wxInfo.OpenID
+	wxUserInfo.Errcode = wxInfo.ErrCode
+	wxUserInfo.Errmsg = wxInfo.ErrMSG
+	wxUserInfo.SessionKey = wxInfo.SessionKey
+	token, userId, firstLogin, _, err := services.WxLogin(code, wxInfo.OpenID, wxInfo.UnionID, wxUserInfo)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "微信登录失败"
+		br.ErrMsg = "微信登录失败,err:" + err.Error()
+		return
+	}
+	if token == "" {
+		br.Msg = "微信登录失败"
+		br.ErrMsg = "token:" + token + "" + code + " " + wxInfo.OpenID + " " + wxInfo.UnionID
+		return
+	}
+	//新增登录日志
+	{
+		loginLog := new(models.WxUserLog)
+		loginLog.UserId = userId
+		loginLog.OpenId = wxInfo.OpenID
+		loginLog.UnionId = wxInfo.UnionID
+		loginLog.CreateTime = time.Now()
+		loginLog.Handle = "wechat_login_cygx"
+		loginLog.Remark = token
+		go models.AddWxUserLog(loginLog)
+	}
+	{
+		codeLog := new(models.WxUserCode)
+		codeLog.WxCode = code
+		codeLog.UserId = userId
+		codeLog.Code = 0
+		codeLog.FirstLogin = firstLogin
+		codeLog.Authorization = token
+		codeLog.UserPermission = 1
+		codeLog.CreateTime = time.Now()
+		models.AddWxUserCode(codeLog)
+	}
+
+	resp := new(models.WxLoginResp)
+	resp.UserId = userId
+	resp.FirstLogin = firstLogin
+	resp.Authorization = token
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "登录成功"
+	br.Data = resp
+}
+
+// @Title 小程序获取用户信息
+// @Description 小程序获取用户信息接口(需要登录)
+// @Param	request	body models.WxGetUserInfoReq true "type json string"
+// @Success 200 {object} models.WxGetUserInfoResp
+// @router /getUserInfo [post]
+func (this *WechatController) GetUserInfo() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.WxGetUserInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.RawData == "" || req.EncryptedData == "" || req.Signature == "" || req.Iv == "" {
+		br.Msg = "参数错误"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请登陆"
+		br.Ret = 408
+		return
+	}
+	userId := user.UserId
+	sessionKey := user.SessionKey
+	fmt.Println("sessionKey:", sessionKey)
+	fmt.Println(sessionKey, req.RawData, req.EncryptedData, req.Signature, req.Iv)
+	userInfo, err := weapp.DecryptUserInfo(sessionKey, req.RawData, req.EncryptedData, req.Signature, req.Iv)
+	fmt.Println("weapp.DecryptUserInfo ", err)
+
+	if err != nil {
+		br.Msg = "解析用户信息失败"
+		br.ErrMsg = "解析用户信息失败,DecryptUserInfo Err:" + err.Error()
+		return
+	}
+	//修改用户微信信息
+	err = models.ModifyUserRecordByDetail(userInfo.OpenID, userInfo.UnionID, userInfo.Nickname, userInfo.Avatar, userInfo.City, userInfo.Province, userInfo.Country, userInfo.Gender, userId)
+	if err != nil {
+		br.Msg = "授权失败"
+		br.ErrMsg = "授权失败,修改用户信息失败:" + err.Error()
+		return
+	}
+	var token string
+	tokenItem, err := models.GetTokenByOpenId(userInfo.OpenID)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "授权失败"
+		br.ErrMsg = "授权失败,获取token失败:" + err.Error()
+		return
+	}
+
+	if tokenItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
+		timeUnix := time.Now().Unix()
+		timeUnixStr := strconv.FormatInt(timeUnix, 10)
+		token = utils.MD5(userInfo.OpenID) + utils.MD5(timeUnixStr)
+		//新增session
+		{
+			session := new(models.CygxSession)
+			session.OpenId = userInfo.OpenID
+			session.UnionId = userInfo.UnionID
+			session.UserId = userId
+			session.CreatedTime = time.Now()
+			session.LastUpdatedTime = time.Now()
+			session.ExpireTime = time.Now().AddDate(0, 3, 0)
+			session.AccessToken = token
+			err = models.AddSession(session)
+			if err != nil {
+				br.Msg = "授权失败"
+				br.ErrMsg = "授权失败,新增用户session信息失败:" + err.Error()
+				return
+			}
+		}
+	} else {
+		token = tokenItem.AccessToken
+	}
+	resp := new(models.WxGetUserInfoResp)
+	resp.Authorization = token
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 小程序获取用户绑定手机号
+// @Description 小程序获取用户绑定手机号接口(需要登录)
+// @Param	request	body models.WxGetPhoneNumberReq true "type json string"
+// @Success 200 {object} models.WxGetPhoneNumberResp
+// @router /getPhoneNumber [post]
+func (this *WechatController) GetPhoneNumber() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.WxGetPhoneNumberReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.EncryptedData == "" || req.Iv == "" {
+		br.Msg = "参数错误"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请登陆"
+		br.Ret = 408
+		return
+	}
+	sessionKey := user.SessionKey
+	wxMobile, err := weapp.DecryptMobile(sessionKey, req.EncryptedData, req.Iv)
+	if err != nil {
+		br.Msg = "解析用户手机号信息失败"
+		br.ErrMsg = "解析用户手机号信息失败,Err:" + err.Error()
+		return
+	}
+	err = models.ModifyUsersMobile(user.UserId, wxMobile.PurePhoneNumber)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	resp := new(models.WxGetPhoneNumberResp)
+	resp.PhoneNumber = wxMobile.PhoneNumber
+	resp.PurePhoneNumber = wxMobile.PurePhoneNumber
+	resp.CountryCode = wxMobile.CountryCode
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}
+
+// @Title 获取短信验证码
+// @Description 获取短信验证码接口
+// @Param   Mobile   query   string  true       "手机号码"
+// @Param   AreaNum   query   string  true       "地区编码"
+// @Success Ret=200 获取成功
+// @router /getSmsCode [get]
+func (this *WechatController) GetSmsCode() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	mobile := this.GetString("Mobile")
+	if mobile == "" {
+		br.Msg = "请输入手机号"
+		return
+	}
+	areaNum := this.GetString("AreaNum")
+	msgCode := utils.GetRandDigit(4)
+	var result bool
+	if areaNum == "86" || areaNum == "" || areaNum == "0" {
+		result = services.SendSmsCode(mobile, msgCode)
+	} else {
+		result = services.SendSmsCodeGj(mobile, msgCode, areaNum)
+	}
+	//发送成功
+	if result {
+		item := new(models.MsgCode)
+		item.OpenId = ""
+		item.Code = msgCode
+		item.Mobile = mobile
+		item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix()
+		item.Enabled = 1
+		item.CreatedTime = time.Now()
+		err := models.AddMsgCode(item)
+		if err != nil {
+			br.Msg = "发送失败"
+			br.ErrMsg = "发送失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "发送成功"
+	} else {
+		br.Msg = "发送失败"
+	}
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 获取邮件验证码
+// @Description 获取邮件验证码接口
+// @Param   Email   query   string  true       "邮箱"
+// @Success Ret=200 获取成功
+// @router /getEmailCode [get]
+func (this *WechatController) GetEmailCode() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	email := this.GetString("Email")
+	if email == "" {
+		br.Msg = "请输入邮箱地址"
+		return
+	}
+	if !utils.ValidateEmailFormatat(email) {
+		br.Msg = "邮箱格式错误,请重新输入"
+		return
+	}
+	msgCode := utils.GetRandDigit(4)
+	content := "尊敬的用户:</br>您好,感谢您使用弘则研究,您正在进行邮箱验证,本次请求的验证码为:" + msgCode + "(为了保障您账号的安全性,请在15分钟内完成验证。)</br>弘则研究团队 </br>2019年05月11日"
+	title := "弘则研究登陆验证"
+	//发送邮件
+	result, err := utils.SendEmailByHz(title, content, email)
+	if err != nil {
+		br.Msg = "发送失败"
+		br.ErrMsg = "发送失败,Err:" + err.Error()
+		return
+	}
+	if result {
+		item := new(models.MsgCode)
+		item.OpenId = ""
+		item.Code = msgCode
+		item.Mobile = email
+		item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix()
+		item.Enabled = 1
+		item.CreatedTime = time.Now()
+		err := models.AddMsgCode(item)
+		if err != nil {
+			br.Msg = "发送失败"
+			br.ErrMsg = "发送失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "发送成功"
+	} else {
+		br.Msg = "发送失败"
+	}
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 更新微信token
+// @Description 更新微信token
+// @Success Ret=200 更新成功
+// @router /updateWxAccesstoken [get]
+func (this *WechatController) UpdateWxAccesstoken() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	accessToken, err := models.GetWxAccessToken()
+	if err != nil {
+		utils.FileLog.Info("GetWxAccessToken Err:%s", err.Error())
+		return
+	}
+	br.Data = accessToken
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 微信登录小助手接口
+// @Description 微信登录小助手接口
+// @Param   Code   query   string  true       "微信唯一编码code"
+// @Success 200 {object} models.WxLoginResp
+// @router /loginByxzs [get]
+func (this *WechatCommonController) WechatLoginByxzs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	code := this.GetString("Code")
+	if code == "" {
+		br.Msg = "参数错误"
+		br.ErrMsg = "Code 为空"
+		return
+	}
+
+	item, err := services.WxGetUserOpenIdByCodeXzs(code)
+	if err != nil {
+		br.Msg = "获取用户信息失败"
+		br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+		return
+	}
+	if item.Errcode != 0 {
+		br.Msg = "获取用户信息失败"
+		br.ErrMsg = "获取access_token 失败 errcode:" + strconv.Itoa(item.Errcode) + " ;errmsg:" + item.Errmsg
+		return
+	}
+	openId := item.Openid
+	if openId == "" {
+		br.Msg = "获取用户信息失败"
+		br.ErrMsg = "获取openid失败,openid:" + item.Openid
+		return
+	}
+	unionId := item.Unionid
+	if unionId == "" {
+		br.Msg = "获取用户信息失败"
+		br.ErrMsg = "获取unionid失败,unionid:" + item.Openid
+		return
+	}
+	total, err := models.GetCygxUserRecordCount(openId)
+	if err != nil {
+		br.Msg = "获取用户信息失败"
+		br.ErrMsg = "查询数量失败,Err:" + err.Error()
+		return
+	}
+	if total == 0 {
+		items := new(models.CygxUserRecord)
+		items.OpenId = openId
+		items.UnionId = unionId
+		items.CreateTime = time.Now()
+		_, err = models.AddCygxUserRecord(items)
+		if err != nil {
+			br.Msg = "获取用户信息失败"
+			br.ErrMsg = "添加openid失败,Err:" + err.Error()
+			return
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = item
+}
+
+// @Title 获取小程序分享二维码
+// @Description 获取小程序分享二维码
+// @Success 200 {object} models.ArticleDetailFileLink
+// @router /shareImage [post]
+func (this *WechatController) ShareImage() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	itemToken, err := services.WxGetToken()
+	if err != nil {
+		br.Msg = "分享失败"
+		br.ErrMsg = "获取itemToken失败,Err:" + err.Error()
+		return
+	}
+	if itemToken.AccessToken == "" {
+		br.Msg = "accessToken is empty"
+		return
+	}
+	var envVersion string
+	var resourceUrl string
+	if utils.RunMode == "release" {
+		envVersion = "release"
+	} else {
+		envVersion = "develop"
+	}
+	url := "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + itemToken.AccessToken
+	method := "POST"
+	payload := strings.NewReader(`{
+		"page":"pageMy/excessivePages/excessivePages",
+		"scene":"` + strconv.Itoa(uid) + `",
+		"env_version":"` + envVersion + `",
+		"check_path":false,
+		"auto_color":true
+				}`)
+	client := &http.Client{}
+	req, err := http.NewRequest(method, url, payload)
+	if err != nil {
+		br.Msg = "分享失败"
+		br.ErrMsg = "获取微信二维码失败,Err:" + err.Error()
+		return
+	}
+	req.Header.Add("Content-Type", "application/json")
+	postBody, err := client.Do(req)
+	if err != nil {
+		br.Msg = "分享失败"
+		br.ErrMsg = "获取微信二维码失败,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 {
+			br.Msg = "分享失败"
+			br.ErrMsg = "生成文件夹失败,Err:" + err.Error()
+			return
+		}
+	}
+	imagePath := uploadDir + uuid + ".jpg"
+	switch header := postBody.Header.Get("Content-Type"); {
+	case strings.HasPrefix(header, "application/json"):
+		tokenResp := models.ReturnBodyRule{}
+		decoder := json.NewDecoder(postBody.Body)
+		if decodeErr := decoder.Decode(&tokenResp); decodeErr != nil {
+			br.Msg = "分享失败"
+			br.ErrMsg = "获取微信二维码失败,Err:" + decodeErr.Error()
+			return
+		}
+	case strings.HasPrefix(header, "image"):
+		reply, err := ioutil.ReadAll(postBody.Body)
+		if err != nil {
+			br.Msg = "分享失败"
+			br.ErrMsg = "获取微信二维码失败,Err:" + err.Error()
+			return
+		}
+		imageContent, createErr := os.Create(imagePath)
+		if createErr != nil {
+			br.Msg = "分享失败"
+			br.ErrMsg = "获取微信二维码失败,Err:" + createErr.Error()
+			return
+		}
+		writeStringRes, writeStringErr := io.WriteString(imageContent, string(reply))
+		if writeStringErr != nil {
+			fmt.Println(writeStringRes)
+			br.Msg = "分享失败"
+			br.ErrMsg = "获取微信二维码失败,Err:" + writeStringErr.Error()
+			return
+		}
+		closeErr := imageContent.Close()
+		if closeErr != nil {
+			br.Msg = "分享失败"
+			br.ErrMsg = "获取微信二维码失败,Err:" + closeErr.Error()
+			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:
+		br.Msg = "分享失败"
+		br.ErrMsg = "没有获取到分享二维码"
+		return
+	}
+	resp := new(models.ArticleDetailFileLink)
+	resp.FileLink = resourceUrl
+	resp.Scene = strconv.Itoa(uid)
+	br.Ret = 200
+	br.Data = resp
+	br.Success = true
+	br.Msg = "提交成功"
+}
+
+// @Title 获取短信验证码(无需token)
+// @Description 获取短信验证码接口(无需token)
+// @Param   Mobile   query   string  true       "手机号码"
+// @Param   AreaNum   query   string  true       "地区编码"
+// @Success Ret=200 获取成功
+// @router /getSmsCodePublic [get]
+func (this *WechatCommonController) GetSmsCode() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	mobile := this.GetString("Mobile")
+	if mobile == "" {
+		br.Msg = "请输入手机号"
+		return
+	}
+	areaNum := this.GetString("AreaNum")
+	msgCode := utils.GetRandDigit(4)
+	var result bool
+	if areaNum == "86" || areaNum == "" || areaNum == "0" {
+		result = services.SendSmsCode(mobile, msgCode)
+	} else {
+		result = services.SendSmsCodeGj(mobile, msgCode, areaNum)
+	}
+	//发送成功
+	if result {
+		item := new(models.MsgCode)
+		item.OpenId = ""
+		item.Code = msgCode
+		item.Mobile = mobile
+		item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix()
+		item.Enabled = 1
+		item.CreatedTime = time.Now()
+		err := models.AddMsgCode(item)
+		if err != nil {
+			br.Msg = "发送失败"
+			br.ErrMsg = "发送失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "发送成功"
+	} else {
+		br.Msg = "发送失败"
+	}
+	br.Ret = 200
+	br.Success = true
+}

+ 1295 - 0
controllers/yanxuan_special.go

@@ -0,0 +1,1295 @@
+package controllers
+
+import (
+	"encoding/json"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_mfyx/models"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type YanxuanSpecialController struct {
+	BaseAuthController
+}
+
+// @Title 专栏列表
+// @Description 专栏列表
+// @Param   UserId   query   int  true       "用户ID"
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   Status   query   int  false       "研选专栏装态"
+// @Success 200 {object} models.SpecialListResp
+// @router /list [get]
+func (this *YanxuanSpecialController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	userId, _ := this.GetInt("UserId", 0)
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	status, _ := this.GetInt("Status")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+	resp := new(models.SpecialListResp)
+	var condition string
+	var pars []interface{}
+
+	if userId > 0 {
+		condition += ` AND a.user_id = ? `
+		pars = append(pars, userId)
+	}
+	if status == 2 {
+		condition += ` AND a.status = 2 `
+	} else {
+		condition += ` AND a.status = 3 `
+	}
+
+	total, err := models.GetCygxYanxuanSpecialCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + err.Error()
+		return
+	}
+
+	list, err := models.GetYanxuanSpecialList(sysUser.UserId, condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + err.Error()
+		return
+	}
+	for _, v := range list {
+		hasImg, err := utils.ArticleHasImgUrl(v.Content)
+		if err != nil {
+			return
+		}
+		if hasImg {
+			v.ContentHasImg = 1
+		}
+		v.Content = utils.ArticleRemoveImgUrl(v.Content)
+
+		//v.Content, err = utils.ExtractText(v.Content)
+		//if err != nil {
+		//	return
+		//}
+		//v.Content, _ = services.GetReportContentTextSubNew(v.Content)
+		v.Content = services.AnnotationHtml(v.Content)
+		if v.DocUrl != "" {
+			var docs []models.Doc
+			err := json.Unmarshal([]byte(v.DocUrl), &docs)
+			if err != nil {
+				br.Msg = "参数解析异常!"
+				br.ErrMsg = "参数解析失败,Err:" + err.Error()
+				return
+			}
+			v.Docs = docs
+		}
+		if v.MyCollectNum > 0 {
+			v.IsCollect = 1
+		}
+		if v.CompanyTags != "" {
+			v.Tags += v.CompanyTags
+		}
+		if v.IndustryTags != "" {
+			if v.Tags != "" {
+				v.Tags += ","
+			}
+			v.Tags += v.IndustryTags
+		}
+	}
+
+	isAuthor, isImproveInformation := services.GetYanxuanSpecialAuthorInfo(sysUser) //用户是否没开通研选专栏以及,专栏信息是否完善
+	resp.IsAuthor = isAuthor
+	resp.IsImproveInformation = isImproveInformation
+	resp.List = list
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 专栏详情
+// @Description 专栏详情
+// @Param   IsSendWx   query   int  false       "是否是通过微信模版进来的 1是,其它否"
+// @Param   Id   query   int  true       "详情ID"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /detail [get]
+func (this *YanxuanSpecialController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	specialId, _ := this.GetInt("Id", 0)
+	isSendWx, _ := this.GetInt("IsSendWx", 0)
+
+	if specialId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+
+	item, tmpErr := models.GetYanxuanSpecialById(specialId, sysUser.UserId)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+	if item.MyCollectNum > 0 {
+		item.IsCollect = 1
+	}
+
+	var resp models.CygxYanxuanSpecialResp
+
+	resp.HasPermission = 1
+	resp.CygxYanxuanSpecialItem = *item
+	if item.DocUrl != "" {
+		var docs []models.Doc
+		err := json.Unmarshal([]byte(item.DocUrl), &docs)
+		if err != nil {
+			br.Msg = "参数解析异常!"
+			br.ErrMsg = "参数解析失败,Err:" + err.Error()
+			return
+		}
+		resp.Docs = docs
+	}
+	if item.CompanyTags != "" {
+		resp.Tags += item.CompanyTags
+		resp.CompanyTags = append(resp.CompanyTags, item.CompanyTags)
+	}
+	if item.IndustryTags != "" {
+		if resp.Tags != "" {
+			resp.Tags += ","
+		}
+		resp.Tags += item.IndustryTags
+		resp.IndustryTags = strings.Split(item.IndustryTags, ",")
+	}
+
+	//如果状态未审核通过,而且查看的不是本人,不是审核人员,就无法查看详情
+	var configCode string
+	configCode = utils.TPL_MSG_WANG_FANG_WANG_YANG
+	cnf, err := models.GetConfigByCode(configCode)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + err.Error()
+		return
+	}
+
+	if isSendWx == 1 && strings.Contains(cnf.ConfigValue, sysUser.Mobile) {
+		resp.IsShowExamine = true
+		resp.ExamineStatus = item.Status
+	}
+	resp.ExamineStatus = item.Status
+	if item.UserId != sysUser.UserId && item.Status != 3 && !strings.Contains(cnf.ConfigValue, sysUser.Mobile) {
+		resp.CygxYanxuanSpecialItem = *new(models.CygxYanxuanSpecialItem) // 如果内容不可见,就把内容置空
+		resp.HasPermission = 2
+	}
+
+	//如果在web端有样式或者上传了文件,小程序就禁止编辑修改内容
+	hasStyle, err := utils.ArticleHasStyle(item.Content)
+	if err != nil {
+		return
+	}
+	hasImg, err := utils.ArticleHasImgUrl(item.Content)
+	if err != nil {
+		return
+	}
+	if hasStyle || strings.Contains(item.DocUrl, "http") || hasImg {
+		resp.ContentHasStyle = true
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 新增保存专栏作者详情
+// @Description 新增保存专栏作者详情
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/save [post]
+func (this *YanxuanSpecialController) AuthorSave() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.SaveCygxYanxuanSpecialAuthorReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.UserId <= 0 {
+		br.Msg = "用户id有误"
+		return
+	}
+	if req.SpecialName == "" {
+		br.Msg = "请输入专栏名称"
+		return
+	}
+	if req.NickName == "" {
+		br.Msg = "请输入昵称"
+		return
+	}
+
+	item := models.CygxYanxuanSpecialAuthor{
+		UserId:       req.UserId,
+		SpecialName:  req.SpecialName,
+		Introduction: req.Introduction,
+		Label:        req.Label,
+		NickName:     req.NickName,
+		CreateTime:   time.Now(),
+		ModifyTime:   time.Now(),
+		BgImg:        "",
+		Status:       1,
+	}
+
+	//if req.Id == 0{
+	//	_, err = models.AddCygxYanxuanSpecialAuthor(&item)
+	//	if err != nil {
+	//		br.Msg = "新增失败"
+	//		br.ErrMsg = "新增失败,Err:" + err.Error()
+	//		return
+	//	}
+	//} else {
+	//	err = models.UpdateYanxuanSpecialAuthor(&item)
+	//	if err != nil {
+	//		br.Msg = "保存失败"
+	//		br.ErrMsg = "保存失败,Err:" + err.Error()
+	//		return
+	//	}
+	//}
+	err = models.UpdateYanxuanSpecialAuthor(&item)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// @Title 新增保存专栏
+// @Description 新增保存专栏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /save [post]
+func (this *YanxuanSpecialController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.CygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Content == "" && req.DoType == 2 {
+		br.Msg = "请输入内容"
+		return
+	}
+	if req.CompanyTags == "" && req.IndustryTags == "" && req.DoType == 2 {
+		br.Msg = "请至少输入一个标签"
+		return
+	}
+	isApprovalPersonnel := req.IsApprovalPersonnel
+	item := models.CygxYanxuanSpecial{
+		Id:           req.Id,
+		UserId:       sysUser.UserId,
+		CreateTime:   time.Now(),
+		ModifyTime:   time.Now(),
+		PublishTime:  time.Now(),
+		Content:      req.Content,
+		ImgUrl:       req.ImgUrl,
+		DocUrl:       req.DocUrl,
+		Title:        req.Title,
+		Type:         req.Type,
+		CompanyTags:  req.CompanyTags,
+		IndustryTags: req.IndustryTags,
+	}
+	if req.DoType == 1 {
+		item.Status = 1
+	} else {
+		item.Status = 2
+	}
+	var authorUserId int
+	// 如果是审批人员操作的那么就是修改内容,加审批通过
+	if isApprovalPersonnel {
+		item.Status = 3
+		//校验是否属于审核人员
+		if !services.CheckYxSpecialIsApprovalPersonnel(sysUser.Mobile) {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,该账号不属于审核人员:" + sysUser.Mobile
+			return
+		}
+
+		specialItem, err := models.GetYanxuanSpecialItemById(req.Id)
+		if err != nil {
+			br.Msg = "保存失败"
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
+		}
+		item.UserId = specialItem.UserId // 专栏userid还是原有userId
+		authorUserId = specialItem.UserId
+		item.AdminName = sysUser.RealName //审核人员姓名
+	}
+
+	specialId := 0
+
+	if req.Id == 0 {
+		id, err := models.AddCygxYanxuanSpecial(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+		specialId = int(id)
+	} else {
+		err = models.UpdateYanxuanSpecial(&item)
+		if err != nil {
+			br.Msg = "保存失败"
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
+		}
+		specialId = req.Id
+	}
+
+	if isApprovalPersonnel {
+		go services.UpdateYanxuanSpecialResourceData(specialId)        //  写入首页最新  cygx_resource_data 表
+		go services.EsAddYanxuanSpecial(specialId)                     //  写入es 综合搜索
+		go services.SendWxMsgSpecialFollow(req.Id)                     //研选专栏有新内容审核通过时,给关注此专栏的客户发送模板消息
+		go services.SendWxMsgSpecialAuthor(req.Id, 2)                  //研选专栏审核完成时,给提交人发送模板消息
+		go services.UdpateYanxuanSpecialauthorArticleNum(authorUserId) //  更新作者发布文章的数量
+	} else {
+		if req.DoType == 2 {
+			go services.SendReviewTemplateMsgAdmin(specialId)
+			go services.UpdateYanxuanSpecialResourceData(specialId) //  写入首页最新  cygx_resource_data 表
+			go services.EsAddYanxuanSpecial(specialId)              //  写入es 综合搜索
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// @Title 专栏作者详情
+// @Description 专栏作者详情
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/detail [get]
+func (this *YanxuanSpecialController) AuthorDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	userId, _ := this.GetInt("UserId", 0)
+	if userId == 0 {
+		userId = sysUser.UserId
+	}
+	item, tmpErr := models.GetYanxuanSpecialAuthor(userId, sysUser.UserId, "")
+	if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Data = item
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 审批研选专栏
+// @Description 审批研选专栏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /enable [post]
+func (this *YanxuanSpecialController) Enable() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.EnableCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+	if req.Status <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	status := 0
+	if req.Status == 1 {
+		status = 3
+	} else {
+		status = 4
+	}
+	detail, err := models.GetYanxuanSpecialItemById(req.Id)
+	if err != nil {
+		br.Msg = "审批失败"
+		br.ErrMsg = "审批失败, Err:" + err.Error()
+		return
+	}
+	if tmpErr := models.EnableYanxuanSpecial(req.Id, status, req.Reason, user.RealName); tmpErr != nil {
+		br.Msg = "审批失败"
+		br.ErrMsg = "审批失败, Err:" + tmpErr.Error()
+		return
+	}
+	if req.Status == 1 {
+		go services.SendWxMsgSpecialFollow(req.Id)
+	}
+	go services.SendWxMsgSpecialAuthor(req.Id, req.Status)
+	go services.UpdateYanxuanSpecialResourceData(req.Id)                                  //  写入首页最新  cygx_resource_data 表
+	go services.EsAddYanxuanSpecial(req.Id)                                               //  写入es 综合搜索
+	go services.AddAddCygxYanxuanSpecialApprovalLog(user, req.Id, req.Status, req.Reason) //  添加审核记录日志
+	go services.UdpateYanxuanSpecialauthorArticleNum(detail.UserId)                       //  更新作者发布文章的数量
+	br.Msg = "审批成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 研选专栏收藏
+// @Description 研选专栏收藏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /collect [post]
+func (this *YanxuanSpecialController) Collect() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.CollectCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+	if req.Status <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	var sellerName string
+	sellerItemQy, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil {
+		br.Msg = "查询栏目详情失败!"
+		br.ErrMsg = "获取销售信息失败,Err:" + err.Error()
+		return
+	}
+	sellerName = sellerItemQy.RealName
+	if req.Status == 1 {
+		item := models.CygxYanxuanSpecialCollect{
+			UserId:           user.UserId,
+			Mobile:           user.Mobile,
+			Email:            user.Email,
+			CompanyId:        user.CompanyId,
+			CompanyName:      user.CompanyName,
+			RealName:         user.RealName,
+			SellerName:       sellerName,
+			CreateTime:       time.Now(),
+			ModifyTime:       time.Now(),
+			RegisterPlatform: utils.REGISTER_PLATFORM,
+			YanxuanSpecialId: req.Id,
+		}
+		_, err = models.AddCygxYanxuanSpecialCollect(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "收藏成功"
+	} else {
+		err = models.DelCygxYanxuanSpecialCollect(user.UserId, req.Id)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "取消收藏成功"
+	}
+	go services.UdpateYanxuanSpecialCollect(req.Id)
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 专栏内容中心
+// @Description 专栏内容中心
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /center [get]
+func (this *YanxuanSpecialController) Center() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 1:未发布,2:审核中 3:已发布 4:驳回
+	status, _ := this.GetInt("Status", 0)
+
+	if status <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+
+	var condition string
+	var pars []interface{}
+
+	condition += ` AND a.user_id = ? `
+	pars = append(pars, sysUser.UserId)
+
+	condition += ` AND a.status = ? `
+	pars = append(pars, status)
+
+	list, tmpErr := models.GetYanxuanSpecialList(sysUser.UserId, condition, pars, 0, 0)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	for _, v := range list {
+		//如果在web端有样式或者上传了文件,小程序就禁止编辑修改内容
+		hasStyle, err := utils.ArticleHasStyle(v.Content)
+		if err != nil {
+			return
+		}
+		hasImg, err := utils.ArticleHasImgUrl(v.Content)
+		if err != nil {
+			return
+		}
+		if hasStyle || strings.Contains(v.DocUrl, "http") || hasImg {
+			v.ContentHasStyle = true
+		}
+	}
+
+	br.Data = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 专栏点击记录
+// @Description 专栏点击记录
+// @Param	request	body models.AddCygxYanxuanSpecialRecordReq true "type json string"
+// @router /record [post]
+func (this *YanxuanSpecialController) Record() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+	var req models.AddCygxYanxuanSpecialRecordReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	specialId := req.SpecialId
+	stopTime := req.StopTime
+	if req.SpecialId <= 0 {
+		br.Msg = "文章不存在"
+		br.ErrMsg = "文章不存在,文章ID错误"
+		return
+	}
+	err = services.AddSpecialRecord(this.User, specialId, stopTime)
+	if err != nil {
+		br.Msg = "记录失败"
+		br.ErrMsg = "记录失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "记录成功"
+}
+
+// @Title 研选专栏关注
+// @Description 研选专栏关注
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /follow [post]
+func (this *YanxuanSpecialController) Follow() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.FollowCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.FollowUserId <= 0 {
+		br.Msg = "被关注的用户id"
+		return
+	}
+	if req.Status <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	var sellerName string
+	sellerItemQy, err := models.GetSellerByCompanyIdCheckFicc(user.CompanyId, 2)
+	if err != nil {
+		br.Msg = "查询栏目详情失败!"
+		br.ErrMsg = "获取销售信息失败,Err:" + err.Error()
+		return
+	}
+	sellerName = sellerItemQy.RealName
+	if req.Status == 1 {
+		item := models.CygxYanxuanSpecialFollow{
+			UserId:           user.UserId,
+			FollowUserId:     req.FollowUserId,
+			Mobile:           user.Mobile,
+			Email:            user.Email,
+			CompanyId:        user.CompanyId,
+			CompanyName:      user.CompanyName,
+			RealName:         user.RealName,
+			SellerName:       sellerName,
+			CreateTime:       time.Now(),
+			ModifyTime:       time.Now(),
+			RegisterPlatform: utils.REGISTER_PLATFORM,
+			YanxuanSpecialId: req.SpecialId,
+		}
+		err = models.AddCygxYanxuanSpecialFollow(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "关注成功"
+	} else {
+		err = models.DelCygxYanxuanSpecialFollow(user.UserId, req.FollowUserId)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "取消关注成功"
+	}
+	go services.UdpateYanxuanSpecialFansNum(req.FollowUserId)
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 行业标签搜索
+// @Description 行业标签搜索
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /industrySearch [get]
+func (this *YanxuanSpecialController) IndustrySearch() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	keyword := this.GetString("Keyword")
+
+	list, tmpErr := models.GetYanxuanSpecialIndustry(keyword)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Data = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 公司标签搜索
+// @Description 公司标签搜索
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /companySearch [get]
+func (this *YanxuanSpecialController) CompanySearch() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	keyword := this.GetString("Keyword")
+
+	if keyword == "" {
+		br.Ret = 200
+		return
+	}
+
+	list, tmpErr := models.GetYanxuanSpecialCompany(keyword)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Data = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 专栏取消发布
+// @Description 专栏取消发布
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /cancel [post]
+func (this *YanxuanSpecialController) Cancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.CancelPublishCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+
+	specialItem, err := models.GetYanxuanSpecialItemById(req.Id)
+	if err != nil {
+		br.Msg = "专栏取消发布失败"
+		br.ErrMsg = "专栏取消发布失败,Err:" + err.Error()
+		return
+	}
+
+	if tmpErr := models.CancelPublishYanxuanSpecial(req.Id); tmpErr != nil {
+		br.Msg = "取消发布失败"
+		br.ErrMsg = "取消发布失败, Err:" + tmpErr.Error()
+		return
+	}
+	go services.UpdateYanxuanSpecialResourceData(req.Id)                 //  写入首页最新  cygx_resource_data 表
+	go services.EsAddYanxuanSpecial(req.Id)                              //  写入es 综合搜索
+	go services.UdpateYanxuanSpecialauthorArticleNum(specialItem.UserId) //  更新作者发布文章的数量
+	br.Msg = "取消发布成功"
+	br.Ret = 200
+	br.Success = true
+
+}
+
+// @Title 作者列表
+// @Description 作者列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/list [get]
+func (this *YanxuanSpecialController) AuthorList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+	var condition string
+	var pars []interface{}
+	condition += ` AND  a.nick_name <> ''   `
+
+	total, err := models.GetCygxYanxuanSpecialAuthorCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	condition += `	ORDER BY latest_publish_time DESC`
+	list, tmpErr := models.GetYanxuanSpecialAuthorList(condition, pars, startSize, pageSize)
+	if tmpErr != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	var userIds []int
+	for _, v := range list {
+		v.LatestPublishDate = v.LatestPublishTime.Format(utils.FormatDate) + "更新"
+		userIds = append(userIds, v.UserId)
+	}
+
+	bestNew := services.GetBestNewYanxuanSpecialByUserId(userIds)
+	for _, v := range list {
+		v.YanxuanSpecialCenter = bestNew[v.UserId]
+	}
+	resp := new(models.SpecialAuthorListResp)
+	isAuthor, _ := services.GetYanxuanSpecialAuthorInfo(sysUser) //用户是否没开通研选专栏以及,专栏信息是否完善
+	resp.IsAuthor = isAuthor
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.List = list
+	resp.Paging = page
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// @Title 更新作者头像
+// @Description 更新作者头像
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/head_img [post]
+func (this *YanxuanSpecialController) AuthorHeadImg() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.SaveCygxYanxuanSpecialAuthoHeadImgrReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.UserId <= 0 {
+		br.Msg = "用户id有误"
+		return
+	}
+	if req.HeadImg == "" {
+		br.Msg = "头像图片错误"
+		return
+	}
+
+	item := models.CygxYanxuanSpecialAuthor{
+		UserId:  req.UserId,
+		HeadImg: req.HeadImg,
+	}
+
+	err = models.UpdateYanxuanSpecialAuthorHeadImg(&item)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// @Title 删除专栏
+// @Description 删除专栏
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /del [post]
+func (this *YanxuanSpecialController) Delete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req models.EnableCygxYanxuanSpecialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Id <= 0 {
+		br.Msg = "文章id错误"
+		return
+	}
+
+	if tmpErr := models.DelYanxuanSpecial(req.Id); tmpErr != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败, Err:" + tmpErr.Error()
+		return
+	}
+
+	br.Msg = "删除成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// @Title 专栏文章敏感词检测
+// @Description 专栏文章敏感词检测
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /check [post]
+func (this *YanxuanSpecialController) Check() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.User
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req models.CygxYanxuanSpecialCheckReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Content == "" {
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "校验成功"
+	}
+	itemToken, err := services.WxGetToken()
+	if err != nil {
+		br.Msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if itemToken.AccessToken == "" {
+		br.Msg = "accessToken is empty"
+		return
+	}
+
+	suggest := models.WxCheckContent(itemToken.AccessToken, sysUser.OpenId, req.Content)
+	if suggest == "risky" {
+		br.Msg = "文章内容含有违法违规内容"
+		br.ErrMsg = "文章内容含有违法违规内容"
+		return
+	}
+	if len(req.ImgUrl) > 0 {
+		//for _, imgUrl := range req.ImgUrl {
+		//	imgBody, err := http.Get(imgUrl)
+		//	if err != nil {
+		//		br.Msg = "图片链接有误"
+		//		br.ErrMsg = "图片链接有误"
+		//		return
+		//	}
+		//	rnStr := utils.GetRandStringNoSpecialChar(5)
+		//	savePath := time.Now().Format(utils.FormatDateTimeUnSpace) + rnStr + ".jpg"
+		//	err = file.SaveFile(imgBody, savePath)
+		//	if err != nil {
+		//		br.Msg = "保存图片错误"
+		//		br.ErrMsg = "保存图片错误"
+		//		return
+		//	}
+		//	res, err := weapp.IMGSecCheck(itemToken.AccessToken, savePath)
+		//	if err != nil {
+		//		// 处理一般错误信息
+		//		br.Msg = "图片内容含有违法违规内容"
+		//		br.ErrMsg = "图片内容含有违法违规内容"
+		//		return
+		//	}
+		//	if err := res.GetResponseError(); err != nil {
+		//		// 处理微信返回错误信息
+		//		return
+		//	}
+		//	err = os.RemoveAll(savePath)
+		//	if err != nil {
+		//		return
+		//	}
+		//}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "校验成功"
+}
+
+// @Title 上传文章阅读时间
+// @Description 上传文章阅读时间接口
+// @Param  request	body models.AddStopTimeRep true "type json string"
+// @Success 200 {object} models.ArticleDetailResp
+// @router /addStopTimedel [post]
+func (this *YanxuanSpecialController) AddStopTime() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	var req models.AddStopTimeRep
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	uid := user.UserId
+	articleId := req.ArticleId
+	stopTime := req.StopTime
+	outType := req.OutType
+	source := req.Source
+	if articleId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+	if stopTime == 0 {
+		stopTime = 1
+	}
+	if outType != 2 {
+		outType = 1
+	}
+	if source != "PC" {
+		source = "MOBILE"
+	}
+
+	detail := new(models.ArticleDetail)
+	hasPermission := 0
+	hasFree := 0
+
+	//判断是否已经申请过
+	applyCount, err := models.GetApplyRecordCount(uid)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "判断是否已申请过试用失败,Err:" + err.Error()
+		return
+	}
+	//`description:"1:有该行业权限,正常展示,2:无该行业权限,不存在权益客户下,3:无该品类权限,4:潜在客户,未提交过申请,5:潜在客户,已提交过申请"`
+	if user.CompanyId > 1 {
+		companyPermission, err := models.GetCompanyPermission(user.CompanyId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "判断是否已申请访谈失败,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		detail, err = models.GetArticleDetailById(articleId)
+		if err != nil {
+			br.Msg = "获取信息失败"
+			br.ErrMsg = "获取文章信息失败,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+			return
+		}
+		if companyPermission == "" {
+			if applyCount > 0 {
+				hasPermission = 5
+			} else {
+				hasPermission = 2
+			}
+			hasFree = 2
+			goto Loop
+		} else {
+			hasFree = 1
+			var articlePermissionPermissionName string
+			if detail.CategoryId > 0 {
+				articlePermission, err := models.GetArticlePermission(detail.CategoryId)
+				if err != nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "获取报告权限失败,Err:" + err.Error() + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+					return
+				}
+				if articlePermission == nil {
+					br.Msg = "获取信息失败"
+					br.ErrMsg = "报告权限不存在,Err:" + strconv.Itoa(uid) + ";articleId" + strconv.Itoa(articleId)
+					return
+				}
+				articlePermissionPermissionName = articlePermission.PermissionName
+			} else {
+				articlePermissionPermissionName = detail.CategoryName
+			}
+			var hasPersion bool
+			slice := strings.Split(articlePermissionPermissionName, ",")
+			for _, v := range slice {
+				if strings.Contains(companyPermission, v) {
+					hasPersion = true
+				}
+			}
+			if hasPersion {
+				go services.ArticleHistoryStopTime(articleId, stopTime, outType, user)
+			} else { //无该行业权限
+				hasPermission = 3
+			}
+		}
+	} else { //潜在客户
+		if applyCount > 0 {
+			hasPermission = 5
+		} else {
+			hasPermission = 4
+		}
+	}
+Loop:
+	resp := new(models.ArticleDetailAddStopTimeRep)
+	resp.HasPermission = hasPermission
+	resp.HasFree = hasFree
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	br.Data = resp
+}

+ 57 - 0
main.go

@@ -0,0 +1,57 @@
+package main
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/adapter/logs"
+	_ "hongze/hongze_mfyx/routers"
+	"hongze/hongze_mfyx/services"
+	"hongze/hongze_mfyx/utils"
+	"runtime"
+	"time"
+
+	"github.com/beego/beego/v2/server/web"
+	"github.com/beego/beego/v2/server/web/context"
+)
+
+func main() {
+	if web.BConfig.RunMode == "dev" {
+		web.BConfig.WebConfig.DirectoryIndex = true
+		web.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
+	}
+	go services.Task()
+
+	web.BConfig.RecoverFunc = Recover
+	web.Run()
+}
+
+func Recover(ctx *context.Context, config *web.Config) {
+	if err := recover(); err != nil {
+		if err == web.ErrAbort {
+			return
+		}
+		if !web.BConfig.RecoverPanic {
+			panic(err)
+		}
+		stack := ""
+		msg := fmt.Sprintf("The request url is  %v", ctx.Input.URL())
+		stack += msg + "</br>"
+		logs.Critical(msg)
+		msg = fmt.Sprintf("The request data is %v", string(ctx.Input.RequestBody))
+		stack += msg + "</br>"
+		logs.Critical(msg)
+		msg = fmt.Sprintf("Handler crashed with error %v", err)
+		stack += msg + "</br>"
+		logs.Critical(msg)
+		for i := 1; ; i++ {
+			_, file, line, ok := runtime.Caller(i)
+			if !ok {
+				break
+			}
+			logs.Critical(fmt.Sprintf("%s:%d", file, line))
+			stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d</br>", file, line))
+		}
+		go utils.SendEmail(utils.APPNAME+"崩了"+time.Now().Format("2006-01-02 15:04:05"), stack, utils.EmailSendToUsers)
+		go utils.SendAlarmMsg(stack, 1)
+	}
+	return
+}

+ 28 - 0
models/about_us_video_history.go

@@ -0,0 +1,28 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxAboutUsVideoHistory struct {
+	Id               int `orm:"column(id);pk"`
+	UserId           int
+	CreateTime       time.Time
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	ModifyTime       time.Time `description:"修改时间"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+}
+
+// 添加历史信息
+func AddCygxAboutUsVideoHistory(item *CygxAboutUsVideoHistory) (lastId int64, err error) {
+	o := orm.NewOrm()
+	item.ModifyTime = time.Now()
+	lastId, err = o.Insert(item)
+	return
+}

+ 1295 - 0
models/activity.go

@@ -0,0 +1,1295 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_mfyx/utils"
+	"strings"
+	"time"
+)
+
+// 活动详情
+type CygxActivity struct {
+	ActivityId                int       `orm:"column(activity_id);pk";description:"活动ID 等于0新增活动,大于0修改活动"`
+	ActivityTypeId            int       `description:"活动类型id"`
+	ActivityTypeName          string    `description:"活动类型名称"`
+	ChartPermissionId         int       `description:"行业id"`
+	ChartPermissionName       string    `description:"行业名称"`
+	ChartPermissionNames      string    `description:"行业名称辅助字段,区分研选子分类"`
+	IsShowHz                  int       `description:"是否同时在弘则展示  1是,0否"`
+	ChartPermissionIdDeputy   int       `description:"行业id"`
+	ChartPermissionNameDeputy string    `description:"副行业名称"`
+	Body                      string    `description:"内容"`
+	CreateTime                time.Time `description:"创建时间"`
+	IsLimitPeople             int       `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum            int       `description:"限制的人数数量"`
+	CustomerTypeIds           string    `description:"活动可见的客户类型,多个ID用 , 隔开"`
+	PublishStatus             int       `description:"发布状态 1已发布,0未发布"`
+	LastUpdatedTime           time.Time `description:"更新时间"`
+	ActivityTime              string    `description:"活动时间"`
+	ActivityTimeText          string    `description:"活动时间带文字"`
+	DistinguishedGuest        string    `description:"嘉宾"`
+	Host                      string    `description:"主持人"`
+	MainlandTell              string    `description:"大陆拨入号"`
+	HongKongTell              string    `description:"香港拨入号"`
+	TaiwanTell                string    `description:"台湾拨入号"`
+	AmericaTell               string    `description:"美国拨入号"`
+	ParticipationCode         string    `description:"参会密码"`
+	Theme                     string    `description:"主题"`
+	Expert                    string    `description:"专家"`
+	ActivityName              string    `description:"活动名称"`
+	ActivityNameTask          string    `description:"活动名称定时任务同步的时候使用"`
+	OnlineParticipation       string    `description:"网络参会"`
+	ReportLink                string    `description:"报告链接"`
+	City                      string    `description:"城市"`
+	Address                   string    `description:"活动地址"`
+	Highlights                string    `description:"活动亮点"`
+	Remarks                   string    `description:"备注"`
+	Speaker                   string    `description:"主讲人"`
+	ArticleId                 int       `description:"关联报告id"`
+	Label                     string    `description:"标签"`
+	LinkParticipants          string    `description:"链接参会"`
+	AppAttendance             string    `description:"App参会"`
+	ConferencePassword        string    `description:"会议密码"`
+	TemporaryLabel            string    `description:"临时标签"`
+	IsMakerShow               int       `description:"是否仅决策人可见 0,否 、1,是"`
+	VisibleRange              int       `description:"可见范围 1,仅本组可见 、2,全部客户可见"`
+	Scale                     string    `description:"管理规模,空不填,1::50亿以下,2:50~100亿,3:100亿以上。多个用, 隔开"`
+	IsShowSubjectName         int       `description:"小程序内是否展示标的名称 1是 ,0 否 默认0 "`
+	IsHideAppointment         int       `description:"是否隐藏预约纪要按钮 1是 ,0 否 默认0 "`
+	AdminId                   int       `description:"销售/管理员ID"`
+	AdminName                 string    `description:"销售/管理员姓名"`
+	IsCanAppointmentMinutes   int       `description:"是否可预约纪要 1是 ,0 否 默认0 "`
+	YidongActivityId          string    `description:"易董活动ID"`
+	YidongActivityUrl         string    `description:"易董活动跳转地址"`
+	YidongActivityEndTime     string    `description:"易董活动截止时间"`
+	ActivityJoinType          string    `description:"活动入会类型01报名审核后可入会 02预约即可入会 03仅定向邀请人员可入会"`
+	YidongSignUpEnd           string    `description:"易董活动截止时间"` // 报名结束时间,适应于报名审核后可入会,为空表示不限制报名时间
+	YidongSignUpStart         string    `description:"易董活动截止时间"` // 报名开始时间,适应于报名审核后可入会,为空表示不限制报名时间
+	IsExternalLabel           int       `description:"是否为外部资源 1是,0否"`
+	YidongActivityIdByCygx    string    `description:"通过查研观向建会易董返回的活动ID"`
+	JmcjRoadshowTitle         string    `description:"进门财经的活动标题"`
+	JmcjActivityId            string    `description:"进门财经的活动ID"`
+}
+
+type ActivityCheck struct {
+	CheckPermission   bool   `description:"权限是否通过校验"`
+	HasPermission     int    `description:"操作方式,1:有该行业权限,正常展示,2:无该行业权限,3:潜在客户,未提交过申请,4:潜在客户,已提交过申请"`
+	PopupMsg          string `description:"权限弹窗信息"`
+	CancelPopupMsg    string `description:"取消报名时间弹窗信息"`
+	SellerMobile      string `description:"销售电话"`
+	SellerName        string `description:"销售姓名"`
+	Mobile            string `description:"手机号"`
+	IsResearch        bool   `description:"是否属于研选"`
+	IsResearchSpecial bool   `description:"是否属于特殊的研选"`
+	CheckTime         bool   `description:"时间是否通过校验"`
+	CheckEmail        bool   `description:"邮箱是否通过校验"`
+	CheckPoints       bool   `description:"扣点是否通过校验"`
+	CompanyPoints     string `description:"公司剩余点数"`
+	ActivityPoints    string `description:"本场活动要扣除的点数"`
+}
+
+type Activity struct {
+	ActivityTypeId   int    `description:"活动类型id"`
+	ActivityTypeName string `description:"活动名称"`
+	TemplateP        string `description:"活动模板,带P标签"`
+	Template         string `description:"活动模板"`
+	ShowType         string `description:"人数限制类型,1不展示限制,2可选限制,3强制限制"`
+}
+type ActivityIdRep struct {
+	ActivityId  int `description:"活动id"`
+	PlaySeconds int `description:"播放时长"`
+}
+
+type ActivitySingnupRep struct {
+	ActivityId int `description:"活动id"`
+	SignupType int `description:"报名方式,1预约外呼,2自主拨入,3我要报名"`
+}
+
+type ActivityCcustomerType struct {
+	CustomerTypeId  int    `description:"活动类型id"`
+	CustomerName    string `description:"活动名称"`
+	PermissionValue string `description:"用户权限对应的值"`
+}
+
+type ActivityCcustomerTypeList struct {
+	List []*ActivityCcustomerType
+}
+
+// 列表
+func GetActivityCcustomerTypeList() (items []*ActivityCcustomerType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_customer_type ORDER BY sort DESC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 活动添加、修改入参
+type ActivityRep struct {
+	ActivityTypeId    int    `description:"活动类型id"`
+	ChartPermissionId int    `description:"行业id"`
+	Body              string `description:"内容"`
+	LimitPeopleNum    int    `description:"限制的人数数量"`
+	CustomerTypeIds   string `description:"活动可见的客户类型,多个ID用 , 隔开"`
+	ActivityId        int    `description:"活动ID 等于0新增活动,大于0修改活动"`
+	DoType            int    `description:"操作类型 0,保存 、1,发布"`
+}
+
+type ActivityArticleResp struct {
+	ReportLink string `description:"报告链接"`
+	ArticleId  int    `description:"报告id(报告链接跳转使用)"`
+	Title      string `description:"报告id(报告链接跳转使用)"`
+}
+
+// 活动详情
+type ActivityDetail struct {
+	ActivityId                int                        `orm:"column(activity_id);pk";description:"活动ID "`
+	ActivityTypeId            int                        `description:"活动类型id"`
+	PublishStatus             int                        `description:"发布状态,0未发布,1已发布"`
+	ActivityTypeName          string                     `description:"活动类型名称"`
+	ChartPermissionId         int                        `description:"行业id"`
+	ChartPermissionName       string                     `description:"行业名称"`
+	ChartPermissionNames      string                     `description:"行业名称辅助字段,区分研选子分类"`
+	Body                      string                     `description:"内容"`
+	CreateTime                string                     `description:"创建时间"`
+	IsLimitPeople             int                        `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum            int                        `description:"限制的人数数量"`
+	LastUpdatedTime           string                     `description:"更新时间"`
+	ActivityTime              string                     `description:"活动时间"`
+	ActivityTimeText          string                     `description:"活动时间带文字"`
+	DistinguishedGuest        string                     `description:"嘉宾"`
+	Host                      string                     `description:"主持人"`
+	Speaker                   string                     `description:"主讲人"`
+	MainlandTell              string                     `description:"大陆拨入号"`
+	HongKongTell              string                     `description:"香港拨入号"`
+	TaiwanTell                string                     `description:"台湾拨入号"`
+	AmericaTell               string                     `description:"美国拨入号"`
+	ParticipationCode         string                     `description:"参会密码"`
+	Theme                     string                     `description:"主题"`
+	Expert                    string                     `description:"专家"`
+	ActivityName              string                     `description:"活动名称"`
+	OnlineParticipation       string                     `description:"网络参会"`
+	ReportLink                string                     `description:"报告链接"`
+	City                      string                     `description:"城市"`
+	Address                   string                     `description:"活动地址"`
+	Highlights                string                     `description:"活动亮点"`
+	Remarks                   string                     `description:"备注"`
+	ShowType                  string                     `description:"人数限制类型,1不展示限制,2可选限制,3强制限制"`
+	IsSignup                  int                        `description:"是否已报名 1是 ,0 否"`
+	IsAppointment             int                        `description:"是否已预约纪要 1是 ,0 否"`
+	SignupNum                 int                        `description:"已报名人数"`
+	SignupType                int                        `description:"报名方式,1预约外呼,2自主拨入,3我要报名"`
+	ActiveState               string                     `description:"活动进行状态 未开始:1、进行中2、已结束3"`
+	IsCancelMeetingReminder   int                        `description:"是否取消会议提醒 1展示取消会议提醒 ,0展示会议提醒"`
+	ArticleId                 int                        `description:"报告id(报告链接跳转使用)"`
+	CustomerTypeIds           string                     `description:"活动可见的客户类型,多个ID用 , 隔开"`
+	IsShowSustainable         bool                       `description:"是否展示限免标签"`
+	Description               string                     `description:"研选内容说明"`
+	IsResearch                bool                       `description:"是否属于研选"`
+	IsResearchSpecial         bool                       `description:"是否属于特殊的研选"`
+	LinkParticipants          string                     `description:"链接参会"`
+	AppAttendance             string                     `description:"App参会"`
+	ConferencePassword        string                     `description:"会议密码"`
+	Scale                     string                     `description:"管理规模,空不填,1::50亿以下,2:50~100亿,3:100亿以上。多个用, 隔开"`
+	IsShowAppointment         bool                       `description:"是否展示预约纪要"`
+	IsHideAppointment         int                        `description:"是否隐藏预约纪要按钮  1是,0 否"`
+	IsCClassMeeting           bool                       `description:"是否是c类电话会"`
+	ArticleList               []*ActivityArticleResp     // 下面是列表添加的部分结构体
+	IsBrackets                int                        `description:"是否有方括号 1是 ,0 否"`
+	Label                     string                     `description:"主题标签"`
+	ImgUrl                    string                     `description:"图片链接"`
+	ImgUrlText                string                     `description:"图片链接文字"`
+	ActivityType              int                        `description:"活动线上线下类型 1线上,0 线下"`
+	JmcjRoadshowTitle         string                     `description:"进门财经手动匹配的活动名称"`
+	Listndustrial             []*IndustrialManagementRep `description:"活动关联的产业信息"`
+	IsShowOutboundCall        bool                       `description:"是否展示预约外呼"`
+	IsShowMeetingReminder     bool                       `description:"是否展示会议提醒"`
+	IsShowHelpSsk             bool                       `description:"是否展示帮我带问"`
+	IsShowSignup              bool                       `description:"是否展示我要报名"`
+	IsShowDetails             bool                       `description:"是否展示查看详情按钮"`
+	TemporaryLabel            string                     `description:"临时标签"`
+	IsCanAppointmentMinutes   int                        `description:"是否可预约纪要 1是 ,0 否 默认0 "`
+	YidongActivityId          string                     `description:"易董活动ID"`
+	YidongActivityUrl         string                     `description:"易董活动跳转地址"`
+	AudioLink                 bool                       `description:"是否展示回放按钮"`
+	VoiceList                 *CygxActivityVoiceReq      `description:"音频数据"`
+	AdminId                   int                        `description:"管理员、销售ID "`
+	IsMakerShow               int                        `description:"是否仅决策人可见 0,否 、1,是"`
+	VisibleRange              int                        `description:"可见范围 1,仅本组可见 、2,全部客户可见"`
+	VideoDetail               *CygxActivityVideoListResp `description:"视频数据"`
+	FileType                  int                        `description:"类型: 1-音频; 2-视频"`
+	SourceType                int                        `description:"活动来源。 1:活动 、2:专项产业调研"`
+	TripImgLink               string                     `description:"专项产业调研行程链接"`
+	ActivityTimeEnd           string                     `description:"专项产业调研活动预期结束时间"`
+	IsCollect                 bool                       `description:"是否收藏"`
+	IsShowFollowButton        bool                       `description:"是否展示关注取关按钮"`
+	IsFollowButton            bool                       `description:"是否关注"`
+	IsYidongConduct           bool                       `description:"是否属于易董办会 1:是 、0:否"`
+	IsCanOutboundCall         int                        `description:"是否提供外呼 1:是 、0:否"`
+	TencentConferenceNumber   string                     `description:"腾讯会议号"`
+	YidongActivityIdByCygx    string                     `description:"通过查研观向建会易董返回的活动ID"`
+	IsShowSigninButton        bool                       `description:"是否展示签到码按钮"`
+	IsShowSignUpDetail        bool                       `description:"是否展示报名详情按钮"`
+	SigninImg                 string                     `description:"签到码图片"`
+	IsNeedEmail               int                        `description:"是否需要提供邮箱 1是,0否"`
+	SiginupDeadline           string                     `description:"报名截止时间"`
+	IsExternalLabel           bool                       `description:"是否为外部资源"`
+	IsResearchPoints          bool                       `description:"是否为研选扣点"`
+	CancelDeadline            string                     `description:"取消报名截止时间"`
+	ImgUrlBgYx                string                     `description:"研选背景图片"`
+	ChartPermissionNameDeputy string                     `description:"副行业名称"`
+	TopTime                   int                        `description:"置顶时间"`
+}
+type ListArticleActivity struct {
+	Title   string `description:"文章标题"`
+	ArtleId int    `description:"产业id"`
+}
+
+type CygxActivityResp struct {
+	HaqveJurisdiction bool   `description:"是否有权限"`
+	OperationMode     string `description:"操作方式 Apply:立即申请、Call:拨号 为空则为有权限"`
+	HasPermission     int    `description:"操作方式,1:有该行业权限,正常展示,2:无该行业权限,3:潜在客户,未提交过申请,4:潜在客户,已提交过申请,5:有IFCC、无权益"`
+	PopupMsg          string `description:"权限弹窗信息"`
+	MsgType           string `description:"Type : 类型 , Industry : 行业"`
+	SellerMobile      string `description:"销售电话"`
+	SellerName        string `description:"销售姓名"`
+	IsResearch        bool   `description:"是否属于研选"`
+	IsResearchSpecial bool   `description:"是否属于特殊的研选"`
+	Detail            *ActivityDetail
+}
+
+// 通过纪要ID获取活动详情
+func GetAddActivityInfoById(ActivityId int) (item *ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity  WHERE activity_id=? AND publish_status = 1 `
+	err = o.Raw(sql, ActivityId).QueryRow(&item)
+	return
+}
+
+// 通过纪要ID获取活动详情
+func GetAddActivityInfoByActivityId(ActivityId int) (item *ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity  WHERE activity_id=?  `
+	err = o.Raw(sql, ActivityId).QueryRow(&item)
+	return
+}
+
+// 通过活动名称获取活动详情
+func GetAddActivityInfoByTitle(title, startDate, endDate string) (item *ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity  WHERE  activity_time > '` + startDate + `' AND activity_time < '` + endDate + `' AND (activity_name_task LIKE '%` + title + `%' OR  jmcj_roadshow_title LIKE '%` + title + `%')   AND activity_id  NOT IN (1328)  LIMIT 1 `
+	err = o.Raw(sql).QueryRow(&item)
+	return
+}
+
+// 通过纪要ID获取活动详情
+func GetAddActivityInfoByIdShow(uid, ActivityId int) (item *ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *,( SELECT COUNT( 1 ) FROM cygx_activity_signup AS s WHERE s.activity_id = a.activity_id AND s.user_id = ?   AND s.is_cancel = 0  AND s.do_fail_type = 0) AS is_signup,
+			( SELECT COUNT( DISTINCT user_id ) FROM cygx_activity_signup AS s WHERE s.activity_id = a.activity_id  AND s.is_cancel = 0 AND s.do_fail_type = 0) AS signup_num,
+			( SELECT COUNT( 1 ) FROM cygx_activity_meeting_reminder AS m WHERE m.activity_id = a.activity_id AND m.user_id = ?  AND m.is_cancel = 0 ) AS is_cancel_meeting_reminder,
+			( SELECT COUNT( 1 ) FROM cygx_activity_appointment AS ap WHERE ap.activity_id = a.activity_id AND ap.user_id = ? ) AS is_appointment
+			FROM cygx_activity AS a  WHERE activity_id=? AND publish_status = 1 `
+	err = o.Raw(sql, uid, uid, uid, ActivityId).QueryRow(&item)
+	return
+}
+
+// 活动列表
+type CygxActivityList struct {
+	ActivityId              int    `orm:"column(activity_id);pk";description:"活动ID 等于0新增活动,大于0修改活动"`
+	ActivityTypeId          int    `description:"活动类型id"`
+	ActivityName            string `description:"活动名称"`
+	ActivityTypeName        string `description:"活动类型名称"`
+	Speaker                 string `description:"主讲人"`
+	SignupType              int    `description:"报名方式,1预约外呼,2我要报名"`
+	ChartPermissionId       int    `description:"行业id"`
+	ChartPermissionName     string `description:"行业名称"`
+	IsLimitPeople           int    `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum          int    `description:"限制的人数数量"`
+	ActivityTime            string `description:"活动时间"`
+	ActivityTimeText        string `description:"活动时间带文字"`
+	City                    string `description:"城市"`
+	Address                 string `description:"活动地址"`
+	DistinguishedGuest      string `description:"嘉宾"`
+	Expert                  string `description:"专家"`
+	IsSignup                int    `description:"是否已报名 1是 ,0 否"`
+	IsAppointment           int    `description:"是否已预约纪要 1是 ,0 否"`
+	IsShowAppointment       bool   `description:"是否展示预约纪要"`
+	SignupNum               int    `description:"已报名人数"`
+	ActiveState             string `description:"活动进行状态 未开始:1、进行中2、已结束3"`
+	IsCancelMeetingReminder int    `description:"是否取消会议提醒 1展示取消会议提醒 ,0展示会议提醒"`
+	IsBrackets              int    `description:"是否有方括号 1是 ,0 否"`
+	Label                   string `description:"主题标签"`
+	IsShowSustainable       bool   `description:"是否展示限免标签"`
+	ImgUrl                  string `description:"图片链接"`
+	ImgUrlText              string `description:"图片链接文字"`
+	ActivityType            int    `description:"活动线上线下类型 1线上,0 线下"`
+	IsHideAppointment       int    `description:"是否隐藏预约纪要按钮  1是,0 否"`
+	JmcjRoadshowTitle       string `description:"进门财经手动匹配的活动名称"`
+	IsCClassMeeting         bool   `description:"是否是c类电话会"`
+}
+
+type GetCygxActivityListRep struct {
+	Paging                 *paging.PagingItem `description:"分页数据"`
+	List                   []*ActivityDetail
+	Label                  string `description:"主题"`
+	ImgUrl                 string `description:"图片路径"`
+	IsResearch             bool   `description:"是否属于研选"`
+	IsJump                 bool   `description:"是否跳转"`
+	IndustrialManagementId int    `description:"产业ID"`
+	IndustryNewLabel       bool   `description:"产业是否新标签"`
+	IsShowResearchPoints   bool   `description:"是否展示研选扣点搜索"`
+}
+
+// 列表
+func GetActivityListAll(condition string, pars []interface{}, uid, startSize, pageSize, playBack int) (items []*ActivityDetail, err error) {
+	var sqlJiontable string
+	if playBack == 1 {
+		//sqlJiontable = ` INNER JOIN cygx_activity_voice AS ac ON ac.activity_id = art.activity_id `
+	}
+	o := orm.NewOrm()
+	sql := `SELECT art.* ,t.activity_type,t.img_url_text,
+		( SELECT COUNT( 1 ) FROM cygx_activity_signup AS s WHERE s.activity_id = art.activity_id AND s.user_id = ?   AND s.is_cancel = 0  AND s.do_fail_type = 0) AS is_signup,
+		( SELECT COUNT( DISTINCT user_id ) FROM cygx_activity_signup AS s WHERE s.activity_id = art.activity_id   AND s.is_cancel = 0  AND s.do_fail_type = 0) AS signup_num,
+		( SELECT COUNT( 1 ) FROM cygx_activity_meeting_reminder AS m WHERE m.activity_id = art.activity_id AND m.user_id = ?  AND m.is_cancel = 0  ) AS is_cancel_meeting_reminder,
+		( SELECT COUNT( 1 ) FROM cygx_activity_appointment AS ap WHERE ap.activity_id = art.activity_id AND ap.user_id = ? ) AS is_appointment
+		FROM cygx_activity as art
+		INNER JOIN cygx_activity_type  as t ON t.activity_type_id = art.activity_type_id` + sqlJiontable + ` WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, uid, uid, uid, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityListByDateTime(startDate, endDate, activityIds, activityIdsLongTime string) (items []*CygxActivityList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity WHERE activity_time > '` + startDate + `' AND activity_time < '` + endDate + `' `
+	activityIds = strings.TrimRight(activityIds, ",")
+	if activityIds != "" {
+		sql += ` AND activity_id  NOT IN (` + activityIds + `,1328 )  `
+	}
+	sql += `  OR activity_id IN (` + activityIdsLongTime + `)`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 获取我的日程数量
+func GetSpecialScheduleCount(uid int) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := `
+SELECT COUNT( 1 ) AS count FROM
+			cygx_activity_special AS art
+			INNER JOIN cygx_activity_special_trip AS my ON my.activity_id = art.activity_id 
+		WHERE
+			1 = 1 AND my.user_id = ? AND my.is_cancel = 0`
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+// 获取数量
+func GetActivityCount(condition string, playBack int, pars []interface{}, filter int) (count int, err error) {
+	var sqlJiontable string
+	if playBack == 1 {
+		//sqlJiontable = ` INNER JOIN cygx_activity_voice AS ac ON ac.activity_id = art.activity_id `
+	}
+
+	if filter == 1 {
+		sqlJiontable = ` INNER JOIN cygx_activity_video AS av ON av.activity_id = art.activity_id `
+	} else if filter == 2 {
+		sqlJiontable = ` INNER JOIN cygx_activity_voice AS ac ON ac.activity_id = art.activity_id `
+	}
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity as art ` + sqlJiontable + ` WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 获取我的日程数量
+func GetScheduleCount(condition string, uid int) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := `SELECT COUNT( 1 ) AS count 
+				FROM cygx_my_schedule AS m
+				INNER JOIN cygx_activity AS art ON art.activity_id = m.activity_id 
+				WHERE
+				user_id = ?`
+	if condition != "" {
+		sqlCount += condition
+	}
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+// 我的日程列表
+func GetScheduleList(condition string, pars []interface{}, uid, startSize, pageSize int) (items []*ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT art.*,t.activity_type,t.img_url_text,
+			( SELECT COUNT( 1 ) FROM cygx_activity_signup AS s WHERE s.activity_id = art.activity_id AND s.user_id = ? AND s.is_cancel = 0 AND s.do_fail_type = 0) AS is_signup,
+            ( SELECT COUNT( DISTINCT user_id ) FROM cygx_activity_signup AS s WHERE s.activity_id = art.activity_id AND  s.is_cancel = 0  AND s.do_fail_type = 0) AS signup_num ,
+			( SELECT COUNT( 1 ) FROM cygx_activity_appointment AS ap WHERE ap.activity_id = art.activity_id AND ap.user_id = ? ) AS is_appointment,
+			( SELECT COUNT( 1 ) FROM cygx_activity_meeting_reminder AS m WHERE m.activity_id = art.activity_id AND m.is_cancel = 0 AND m.user_id = ? ) AS is_cancel_meeting_reminder
+            FROM cygx_activity AS art
+			INNER JOIN cygx_my_schedule as my ON my.activity_id = art.activity_id 
+			INNER JOIN cygx_activity_type  as t ON t.activity_type_id = art.activity_type_id
+            WHERE 1=1 AND my.user_id = ? `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY art.active_state ASC,art.activity_time ASC  LIMIT ?,?`
+	_, err = o.Raw(sql, pars, uid, uid, uid, uid, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 我的日程列表 活动以及专项调研一起
+func GetScheduleAndSpecilList(condition string, pars []interface{}, conditionSpecil string, parsSpecil []interface{}, startSize, pageSize int) (items []*ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			art.activity_id,
+			art.activity_time_text,
+			art.activity_name,
+			art.chart_permission_id,
+			art.active_state,
+			t.activity_type,
+			art.chart_permission_name,
+			art.distinguished_guest,
+			art.expert,
+			art.speaker,
+			"" AS trip_img_link,
+			"" AS activity_time_end,
+			art.yidong_activity_id,
+			art.is_can_appointment_minutes,
+			art.activity_type_id,
+			art.limit_people_num,
+			art.is_limit_people,
+			1 AS source_type,
+			art.activity_time, 
+			art.city,
+			art.is_external_label,
+			art.siginup_deadline,
+			art.is_research_points,
+			art.cancel_deadline
+		FROM
+			cygx_activity AS art
+			INNER JOIN cygx_my_schedule AS my ON my.activity_id = art.activity_id
+			INNER JOIN cygx_activity_type AS t ON t.activity_type_id = art.activity_type_id
+		WHERE
+			1 = 1 `
+	if condition != `` {
+		sql += condition
+	}
+	sql += ` UNION ALL
+		SELECT
+			art.activity_id,
+			art.activity_time_text_by_day AS activity_time_text,
+			art.research_theme AS activity_name,
+			art.chart_permission_id,
+			"",
+			art.special_type AS activity_type,
+			art.chart_permission_name,
+			"",
+			"",
+			"",
+			art.trip_img_link_fix AS trip_img_link,
+			art.activity_time_end,
+			"",
+			"",
+			"",
+			"",
+			"",
+			2 AS source_type,
+			art.activity_time,
+			"",
+			"",
+			"",
+			"",
+			""
+		FROM
+			cygx_activity_special AS art
+			INNER JOIN cygx_activity_special_trip AS my ON my.activity_id = art.activity_id 
+		WHERE
+			1 = 1`
+	if conditionSpecil != "" {
+		sql += conditionSpecil
+	}
+	sql += ` ORDER BY activity_time DESC   LIMIT ?,?`
+	_, err = o.Raw(sql, pars, parsSpecil, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 获取数量
+func GetActivityCountById(activityId int) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := `SELECT COUNT(1) AS count  FROM cygx_activity WHERE activity_id = ?`
+	err = o.Raw(sqlCount, activityId).QueryRow(&count)
+	return
+}
+
+// 删除数据
+func DeleteActivity(activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_activity WHERE activity_id = ?`
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// 修改活动状态至进行中
+func UpdateActivitySattusToHaveInHand() (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg("修改活动状态至进行中失败"+err.Error(), 2)
+			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "修改活动状态至进行中失败 ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+		}
+	}()
+	o := orm.NewOrm()
+	resultTime_30 := time.Now().Add(-time.Minute * 60).Format("2006-01-02 15:04:05") // 线上活动也改成60分钟之后结束了 2023.5.8
+	resultTime_60 := time.Now().Add(-time.Minute * 60).Format("2006-01-02 15:04:05")
+	var sqlOr string
+	var condition string
+	condition += ` AND activity_time < NOW()`
+	sqlOr = condition
+	condition += ` AND (activity_type_id IN ( 1, 2, 3, 7 ) AND  activity_time > ` + "'" + resultTime_30 + "'" + ")"
+	condition += ` OR(activity_type_id IN ( 4, 5, 6, 8 ) AND  activity_time > ` + "'" + resultTime_60 + "'" + sqlOr + ")"
+	msql := " UPDATE cygx_activity SET active_state = 2, top_time = 0  WHERE 1 = 1 " + condition
+	_, err = o.Raw(msql).Exec()
+	return
+}
+
+// 修改活动状态至已结束
+func UpdateActivitySattusToComplete() (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg("修改活动状态至已结束"+err.Error(), 2)
+			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "修改活动状态至已结束 ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+		}
+	}()
+	o := orm.NewOrm()
+	resultTime_30 := time.Now().Add(-time.Minute * 60).Format("2006-01-02 15:04:05") // 线上活动也改成60分钟之后结束了 2023.5.8
+	resultTime_60 := time.Now().Add(-time.Minute * 60).Format("2006-01-02 15:04:05")
+	//var sqlOr string
+	var condition string
+	//condition += ` AND activity_time < NOW()`
+	//sqlOr = condition
+	condition += ` AND (activity_type_id IN ( 1, 2, 3, 7 ) AND  activity_time < ` + "'" + resultTime_30 + "'" + ")"
+	condition += ` OR(activity_type_id IN ( 4, 5, 6 ,8 ) AND  activity_time < ` + "'" + resultTime_60 + "'" + ")"
+	msql := " UPDATE cygx_activity SET active_state = 3 WHERE 1 = 1 " + condition
+	_, err = o.Raw(msql).Exec()
+	return
+}
+
+// 活动详情
+type WxMsgCygxActivityList struct {
+	Id                      int    `description:"报名ID"`
+	UserId                  int    `description:"用户ID"`
+	ActivityId              int    `description:"活动ID 等于0新增活动,大于0修改活动"`
+	ActivityTypeId          int    `description:"活动类型id"`
+	ActivityName            string `description:"活动名称"`
+	ActivityTypeName        string `description:"活动类型名称"`
+	Speaker                 string `description:"主讲人"`
+	SignupType              int    `description:"报名方式,1预约外呼,2我要报名"`
+	ChartPermissionId       int    `description:"行业id"`
+	ChartPermissionName     string `description:"行业名称"`
+	IsLimitPeople           int    `description:"是否限制人数 1是,0否"`
+	LimitPeopleNum          int    `description:"限制的人数数量"`
+	ActivityTime            string `description:"活动时间"`
+	ActivityTimeText        string `description:"活动时间带文字"`
+	City                    string `description:"城市"`
+	Address                 string `description:"活动地址"`
+	DistinguishedGuest      string `description:"嘉宾"`
+	Expert                  string `description:"专家"`
+	IsSignup                int    `description:"是否已报名 1是 ,0 否"`
+	SignupNum               int    `description:"已报名人数"`
+	ActiveState             string `description:"活动进行状态 未开始:1、进行中2、已结束3"`
+	IsCancelMeetingReminder int    `description:"是否取消会议提醒 1展示取消会议提醒 ,0展示会议提醒"`
+	IsBrackets              int    `description:"是否有方括号 1是 ,0 否"`
+	OpenId                  string `description:"OenId"`
+	FailType                int    `description:"失败原因,0,未失败,1总人数已满,2单机构超限制,3,爽约次数超限"`
+}
+
+// 列表 3o分钟
+func GetActivitySendMsgListAll(endDate string) (items []*WxMsgCygxActivityList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	s.id,
+	s.user_id,
+	s.fail_type,
+	cr.open_id,
+	a.*
+FROM
+	cygx_activity AS a
+	INNER JOIN cygx_activity_signup AS s ON s.activity_id = a.activity_id
+	INNER JOIN cygx_user_record AS cr ON cr.cygx_bind_account = s.mobile 
+WHERE
+	1 = 1 
+	AND s.is_send_wx_msg = 0 
+	AND s.do_fail_type = 0 
+	AND a.publish_status = 1
+	AND a.activity_time <= ? AND a.activity_time >= NOW() 
+	AND s.is_cancel = 0
+	AND( a.activity_type_id IN (4,5,6) OR (a.activity_type_id = 3 AND a.is_limit_people = 1 )) 	GROUP BY s.id`
+	_, err = o.Raw(sql, endDate).QueryRows(&items)
+	return
+}
+
+// 列表 15分钟提醒
+func GetActivitySendMsgListAllMeeting(endDate string) (items []*WxMsgCygxActivityList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	m.id,
+	cr.open_id,
+	a.* 
+FROM
+	cygx_activity AS a
+	INNER JOIN cygx_activity_meeting_reminder AS m ON m.activity_id = a.activity_id
+	INNER JOIN user_record AS c ON c.bind_account = m.mobile 
+	INNER JOIN cygx_user_record AS cr ON cr.union_id = c.union_id 
+WHERE
+	1 = 1 
+	AND m.is_send_wx_msg = 0 
+	AND a.publish_status = 1 
+	AND a.activity_time <= ? AND a.activity_time >= NOW() 
+	AND m.is_cancel = 0 
+	AND c.create_platform = 4
+	AND (
+	a.activity_type_id IN ( 1, 2 ) 
+	OR ( a.activity_type_id = 3 AND a.is_limit_people = 0 ))
+	GROUP BY m.id`
+	_, err = o.Raw(sql, endDate).QueryRows(&items)
+	return
+}
+
+// 修改是否推送消息状态
+func UPdateSendedMsgStatus(signupIds string) (err error) {
+	sql := ` UPDATE cygx_activity_signup SET  is_send_wx_msg= 1  WHERE id IN(` + signupIds + `)`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql).Exec()
+	return
+}
+
+// 修改是否推送消息状态
+func UPdateSendedYiDongSignUp(activityId int) (err error) {
+	sql := ` UPDATE cygx_activity SET  is_yidong_sign_up= 1  WHERE activity_id = ? `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// 修改是否推送消息状态
+func UPdateSendedMsgMeetingStatus(signupIds string) (err error) {
+	sql := ` UPDATE cygx_activity_meeting_reminder SET  is_send_wx_msg= 1  WHERE id IN(` + signupIds + `)`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql).Exec()
+	return
+}
+
+// 获取满足推送的活动ID数量
+func GetCountActivityIdToSendFile(endDate string) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	COUNT(1) count
+FROM
+	cygx_activity AS a
+	INNER JOIN cygx_activity_signup AS s ON s.activity_id = a.activity_id 
+WHERE
+	1 = 1 
+	AND s.signup_type = 1 
+	AND s.fail_type = 0 
+	AND a.is_send_file_toemail = 0 
+	AND a.activity_time <= ? AND a.activity_time >= NOW() 	GROUP BY a.activity_id `
+	err = o.Raw(sql, endDate).QueryRow(&count)
+	return
+}
+
+// 获取满足推送的活动ID
+func GetActivityIdToSendFile(endDate string) (items []*ActivityIdRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			* 
+		FROM
+			cygx_activity AS a
+			INNER JOIN cygx_activity_signup AS s ON s.activity_id = a.activity_id 
+			INNER JOIN cygx_activity_type AS t ON a.activity_type_id = t.activity_type_id
+		WHERE
+			1 = 1 
+			AND s.signup_type = 1 
+			AND a.yidong_activity_id = '' 
+			AND t.activity_type = 1
+			AND s.fail_type = 0 
+			AND a.is_send_file_toemail = 0 
+			AND a.activity_time <= ? AND a.activity_time >= NOW() 	GROUP BY a.activity_id `
+	_, err = o.Raw(sql, endDate).QueryRows(&items)
+	return
+}
+
+type SignupExportRep struct {
+	Mobile         string `description:"手机号"`
+	CompanyName    string `description:"公司名称"`
+	CompanyId      int    `description:"公司Id"`
+	RealName       string `description:"姓名"`
+	CountryCode    string `description:"区号"`
+	OutboundMobile string `description:"外呼手机号"`
+	SellerName     string `description:"销售姓名"`
+}
+
+type ActivityMsgExportRep struct {
+	AskId       int    `description:"活动带问ID"`
+	UserId      int    `description:"用户ID"`
+	RealName    string `description:"姓名"`
+	CompanyName string `description:"公司名称"`
+	CompanyId   int    `description:"公司ID"`
+	Content     string `description:"内容"`
+	CreateTime  string `description:"提交时间"`
+}
+
+func GetSignupExport(activityId int) (item []*SignupExportRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			s.outbound_mobile,
+			s.country_code,
+			a.is_limit_people,
+			s.real_name,
+			s.seller_name,
+			s.company_id,
+			s.company_name 
+		FROM
+			cygx_activity_signup AS s
+			JOIN cygx_activity AS a ON a.activity_id = s.activity_id 
+			WHERE a.activity_id = ?  AND s.do_fail_type = 0 AND s.signup_type = 1  GROUP BY s.id `
+	_, err = o.Raw(sql, activityId).QueryRows(&item)
+	return
+}
+
+// 修改文件是否推送状态
+func UPdateActivityIdToSendFile(activityId int) (err error) {
+	sql := ` UPDATE cygx_activity SET  is_send_file_toemail= 1  WHERE activity_id = ?`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// 活动详情
+type CygxActivityLabelList struct {
+	KeyWord           string `orm:"column(label)";description:"主题"`
+	Timesort          string `description:"最大时间"`
+	Mintimesort       string `description:"最小时间"`
+	ImgUrlBg          string `description:"背景图片"`
+	ActivityId        int    `description:"活动ID "`
+	IsShowSubjectName int    `description:"小程序内是否展示标的名称 1是 ,0否 默认0 "`
+	Resource          int    `description:"位置 ,1:活动 ,2:专项产业调研"`
+	TemporaryLabel    string `description:"临时标签"`
+	IsNew             bool   `description:"是否为新:活动存在关联的的产业所关联的报告均在3个月内/无报告则标记新"`
+	YidongActivityId  string `description:"易董活动ID"`
+	IsExternalLabel   bool   `description:"是否为外部资源"`
+	IsResearchPoints  bool   `description:"是否为研选扣点"`
+	TripStatus        int    `description:"行程进行状态 1:预报名,2:确定行程"`
+	City              string `description:"城市"`
+	Days              int    `description:"天数"`
+	ActivityTypeId    int    `description:"活动类型id"`
+	IsResearch        bool   `description:"是否属于研选"`
+	ChartPermissionId int    `description:"行业id"`
+}
+
+// 主题列表
+func GetActivityLabelListAll(condition, sortTime string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityLabelList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT	activity_id,activity_type_id, label,temporary_label,is_show_subject_name, MAX( art.activity_time ) AS timesort, MIn( art.activity_time ) AS mintimesort , yidong_activity_id,city,is_external_label,is_research_points,chart_permission_id
+		FROM cygx_activity as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY art.activity_id ORDER BY ` + sortTime + ` ,art.activity_id DESC  LIMIT ?,? `
+
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 主题列表
+func GetActivityLabelListCity() (items []*CygxActivity, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			activity_id,
+			activity_type_id,
+			activity_time,
+			label,
+			temporary_label,
+			is_show_subject_name,
+			yidong_activity_id,
+			city 
+		FROM
+			cygx_activity AS art 
+		WHERE
+			1 = 1 
+			AND art.active_state IN ( 1, 2 ) 
+			AND city != '' 
+		ORDER BY
+			activity_time ASC  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+type GetCygxActivityLabelListRep struct {
+	Label  string `description:"主题"`
+	ImgUrl string `description:"图片路径"`
+	List   []*CygxActivityLabelList
+}
+
+// 获取研选系列专家电话会,会前1小时,满足推送的活动ID数量
+func GetCountActivityResearchToSendFile(condition, endDate string) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	COUNT(1) count
+FROM
+	cygx_activity AS a
+	INNER JOIN cygx_activity_help_ask AS k ON k.activity_id = a.activity_id 
+WHERE
+	1 = 1 ` + condition + `
+	AND a.is_send_ask_msg = 0 
+	AND a.activity_time <= ? 
+	AND a.activity_time >= NOW()`
+	err = o.Raw(sql, endDate).QueryRow(&count)
+	return
+}
+
+// 获取研选系列专家电话会,会前1小时,满足推送的活动ID
+func GetActivityResearchToSendFile(condition, endDate string) (items []*ActivityIdRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	* 
+FROM
+	cygx_activity AS a
+	INNER JOIN cygx_activity_help_ask AS k ON k.activity_id = a.activity_id 
+WHERE
+	1 = 1 ` + condition + `
+	AND a.is_send_ask_msg = 0 
+	AND a.activity_time <= ? 
+	AND a.activity_time >= NOW() 
+GROUP BY
+	a.activity_id `
+	_, err = o.Raw(sql, endDate).QueryRows(&items)
+	return
+}
+
+func GetActivityMsgExport(activityId int) (item []*ActivityMsgExportRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			k.*
+			FROM
+			cygx_activity_help_ask AS k
+			WHERE
+			k.activity_id = ? 
+			GROUP BY
+			k.ask_id`
+	_, err = o.Raw(sql, activityId).QueryRows(&item)
+	return
+}
+
+// 修改文件带问消息是否推送状态
+func UPdateActivityMsgToSendFile(activityId int) (err error) {
+	sql := ` UPDATE cygx_activity SET  is_send_ask_msg= 1  WHERE activity_id = ?`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+type AskEmailRep struct {
+	Name   string `description:"姓名"`
+	Email  string `description:"邮箱"`
+	Mobile string `description:"手机号"`
+}
+
+func GetAskEmail() (item []*AskEmailRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_ask_email`
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+// 主题列表
+func GetActivityLabelSpecialListAll(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityLabelList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT	label,activity_id,is_show_subject_name,days
+		FROM cygx_activity_special as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += `  LIMIT ?,? `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+type GetCygxActivitySpecialDetailListResp struct {
+	IsFollow        bool               `description:"是否关注新调研通知"`
+	IsBindingMobile bool               `description:"是否绑定了手机号"`
+	Paging          *paging.PagingItem `description:"分页数据"`
+	List            []*CygxActivitySpecialDetail
+}
+
+type CygxActivitySpecialResp struct {
+	HaqveJurisdiction bool   `description:"是否有权限"`
+	OperationMode     string `description:"操作方式 Apply:立即申请、Call:拨号 为空则为有权限"`
+	HasPermission     int    `description:"操作方式,1:有该行业权限,正常展示,2:无该行业权限,3:潜在客户,未提交过申请,4:潜在客户,已提交过申请,5:有IFCC、无权益"`
+	PopupMsg          string `description:"权限弹窗信息"`
+	MsgType           string `description:"Type : 类型 , Industry : 行业"`
+	SellerMobile      string `description:"销售电话"`
+	SellerName        string `description:"销售姓名"`
+	IsFollow          bool   `description:"是否关注新调研通知"`
+	Detail            *CygxActivitySpecialDetail
+}
+
+// 获取专项调研活动列表
+func GetCygxActivitySpecialDetailList(condition string, pars []interface{}, uid, startSize, pageSize int) (items []*CygxActivitySpecialDetail, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+	art.*,
+	(
+	SELECT
+		COUNT( 1 ) 
+	FROM
+		cygx_activity_special_signup AS s 
+	WHERE
+		s.activity_id = art.activity_id 
+		AND s.user_id = ?
+	) AS is_signup
+FROM
+	cygx_activity_special AS art
+WHERE
+	1 = 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += `  LIMIT ?,? `
+	_, err = o.Raw(sql, uid, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 通过活动ID获取活动详情
+func GetCygxActivitySpecialDetailById(uid, ActivityId int) (item *CygxActivitySpecialDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *,( SELECT COUNT( 1 ) FROM cygx_activity_special_signup AS s WHERE s.activity_id = a.activity_id AND s.user_id = ? ) AS is_signup 
+FROM
+	cygx_activity_special AS a 
+WHERE
+	activity_id = ?
+	AND publish_status = 1 	AND is_offline = 0  `
+	err = o.Raw(sql, uid, ActivityId).QueryRow(&item)
+	return
+}
+
+// 通过活动ID获取活动详情
+func GetCygxActivitySpecialDetail(ActivityId int) (item *CygxActivitySpecialDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_special  WHERE activity_id=? AND publish_status = 1 `
+	err = o.Raw(sql, ActivityId).QueryRow(&item)
+	return
+}
+
+func UpdateCygxActivityName(activityId int, Name string) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_activity SET activity_name_task = ? WHERE activity_id=?  `
+	_, err = o.Raw(sql, Name, activityId).Exec()
+	return
+}
+
+// 获取已发布但是为开始活动的权限
+func GetActivityWeekPermission() (permission string, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+			GROUP_CONCAT( DISTINCT chart_permission_name SEPARATOR ',' ) AS permission 
+		FROM
+			cygx_activity 
+		WHERE
+			active_state = 1`
+	err = o.Raw(sql).QueryRow(&permission)
+	return
+}
+
+// 列表
+func GetIndustrialActivityGroupManagementList(activityId int) (items []*IndustrialManagementRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			m.chart_permission_id,
+			m.industrial_management_id,
+			m.industry_name 
+			FROM
+			cygx_industrial_activity_group_management AS am
+			INNER JOIN cygx_industrial_management AS m ON m.industrial_management_id = am.industrial_management_id
+			WHERE
+			am.activity_id = ? AND am.source = 1`
+	_, err = o.Raw(sql, activityId).QueryRows(&items)
+	return
+}
+
+// GetActivityListByYiDong 获取易董同步过来的活动列表
+func GetActivityListByYiDong() (items []*CygxActivity, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity WHERE yidong_activity_id != '' `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// GetActivityListByYiDong 获取易董同步过来的活动列表
+func GetActivityListByYiDongByCygx() (items []*CygxActivity, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity WHERE yidong_activity_id_by_cygx != '' `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// AddCygxActivity 添加活动
+func AddCygxActivity(item *CygxActivity) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 列表
+func GetActivityListByYidong(condition string) (items []*ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity WHERE 1 = 1 
+	AND ( yidong_activity_id != '' OR yidong_activity_id_by_cygx != '' )  AND publish_status = 1  `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityListByCondition(condition string, pars []interface{}) (items []*CygxActivity, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity WHERE  1 =1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// UpdateCygxActivitySubmitMeetingByActivityId  ,修改活动提交到会状态
+func UpdateCygxActivitySubmitMeetingByActivityId(activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_activity SET is_submit_meeting = 1 WHERE activity_id  = ? `
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// UpdateCygxActivitySubmitMeetingByYidong  ,跟易董返回的用户状态修改活动以提交到会状态
+func UpdateCygxActivitySubmitMeetingByYidong(yidongActivityId string) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_activity SET is_submit_meeting = 1 WHERE yidong_activity_id=? OR  yidong_activity_id_by_cygx = ? `
+	_, err = o.Raw(sql, yidongActivityId, yidongActivityId).Exec()
+	return
+}
+
+// UpdateActivityshowSubject 根据易董推过来的匹配信息,判断临时标签是否展示
+func UpdateActivityshowSubject(activityId int) (err error) {
+	sql := ` UPDATE cygx_activity SET  is_show_subject_name= 1 , temporary_label = ''  WHERE activity_id = ?`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// GetActivitySpecialSearcheList 活动与专项调研的搜索
+func GetActivitySpecialSearcheList(condition string, pars []interface{}, conditionSpecil string, parsSpecil []interface{}, startSize, pageSize int) (items []*ActivityDetail, total int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			art.activity_id,
+			art.activity_time_text,
+			art.activity_name,
+			art.chart_permission_id,
+			art.active_state,
+			t.activity_type,
+			t.img_url_text,
+			art.chart_permission_name,
+			art.distinguished_guest,
+			art.expert,
+			art.speaker,
+			"" AS trip_img_link,
+			"" AS activity_time_end,
+			art.yidong_activity_id,
+			art.is_can_appointment_minutes,
+			art.activity_type_id,
+			art.limit_people_num,
+			art.is_limit_people,
+			art.city,
+			1 AS source_type,
+			art.is_yidong_conduct,
+			art.activity_time,
+			art.is_external_label,
+			art.siginup_deadline,
+			art.is_research_points,
+			art.cancel_deadline
+		FROM
+			cygx_activity AS art
+			INNER JOIN cygx_activity_type AS t ON t.activity_type_id = art.activity_type_id
+		WHERE
+			1 = 1 `
+	if condition != `` {
+		sql += condition
+	}
+	sql += ` UNION ALL
+		SELECT
+			art.activity_id,
+			art.activity_time_text_by_day AS activity_time_text,
+			art.research_theme AS activity_name,
+			art.chart_permission_id,
+			"",
+			art.special_type AS activity_type,
+			"",
+			art.chart_permission_name,
+			"",
+			"",
+			"",
+			art.trip_img_link_fix AS trip_img_link,
+			art.activity_time_end,
+			"",
+			"",
+			"",
+			"",
+			"",
+			"",
+			2 AS source_type,
+			"",
+			art.activity_time,
+			"",
+			"",
+			"",
+			""
+		FROM
+			cygx_activity_special AS art
+		WHERE
+			1 = 1 `
+	if conditionSpecil != "" {
+		sql += conditionSpecil
+	}
+	totalSql := `SELECT COUNT(1) total FROM (` + sql + `) z `
+	err = o.Raw(totalSql, pars, parsSpecil).QueryRow(&total)
+	if err != nil {
+		return
+	}
+	sql += ` ORDER BY activity_time DESC   LIMIT ?,?`
+	_, err = o.Raw(sql, pars, parsSpecil, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityListNew(condition string, pars []interface{}, uid, startSize, pageSize, playBack, filter int, typeName string) (items []*ActivityDetail, err error) {
+	var sqlJiontable string
+	if playBack == 1 {
+		//sqlJiontable = ` INNER JOIN cygx_activity_voice AS ac ON ac.activity_id = art.activity_id `
+	}
+	if filter == 1 {
+		sqlJiontable = ` INNER JOIN cygx_activity_video AS av ON av.activity_id = art.activity_id `
+	} else if filter == 2 {
+		sqlJiontable = ` INNER JOIN cygx_activity_voice AS ac ON ac.activity_id = art.activity_id `
+	}
+
+	o := orm.NewOrm()
+	sql := `SELECT art.* ,t.activity_type,t.img_url_text,t.img_url_bg_yx,
+		( SELECT COUNT( 1 ) FROM cygx_activity_signup AS s WHERE s.activity_id = art.activity_id AND s.user_id = ?   AND s.is_cancel = 0  AND s.do_fail_type = 0) AS is_signup,
+		( SELECT COUNT( DISTINCT user_id ) FROM cygx_activity_signup AS s WHERE s.activity_id = art.activity_id   AND s.is_cancel = 0  AND s.do_fail_type = 0) AS signup_num,
+		( SELECT COUNT( 1 ) FROM cygx_activity_meeting_reminder AS m WHERE m.activity_id = art.activity_id AND m.user_id = ?  AND m.is_cancel = 0  ) AS is_cancel_meeting_reminder,
+		( SELECT COUNT( 1 ) FROM cygx_activity_appointment AS ap WHERE ap.activity_id = art.activity_id AND ap.user_id = ? ) AS is_appointment
+		FROM cygx_activity as art
+		INNER JOIN cygx_activity_type  as t ON t.activity_type_id = art.activity_type_id ` + sqlJiontable + ` WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?`
+
+	if typeName != "" {
+		typeSlice := strings.Split(typeName, ",")
+		tempCondition := ""
+		for _, s := range typeSlice {
+			if s == "1" {
+				tempCondition += "'专家电话会',"
+			} else if s == "2" {
+				tempCondition += "'分析师电话会',"
+			} else if s == "1,2" {
+				tempCondition += "'专家电话会','分析师电话会',"
+			}
+		}
+		tempCondition = strings.TrimRight(tempCondition, ",")
+		sql = `SELECT * FROM(` + sql + `) AS t WHERE t.activity_type_name IN (` + tempCondition + `)`
+	}
+	_, err = o.Raw(sql, uid, uid, uid, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityListHomeNew(condition string, startSize, pageSize int) (items []*ActivityDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT activity_id
+		FROM cygx_activity as art
+		INNER JOIN cygx_activity_type  as t ON t.activity_type_id = art.activity_type_id WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 主题列表
+func GetActivityLabelListAllNoLimit(condition, sortTime string, pars []interface{}, conditionSpecial string) (items []*CygxActivityLabelList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT	activity_id, label,temporary_label,is_show_subject_name, art.activity_time,	1 AS resource, yidong_activity_id 
+		FROM cygx_activity as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += `  UNION ALL `
+	sql += ` SELECT
+			art.activity_id,
+			art.label,
+			art.temporary_label,
+			is_show_subject_name,
+			art.activity_time,
+			2 AS resource,
+			'' AS yidong_activity_id 
+		FROM
+			cygx_activity_special AS art   WHERE 1= 1 ` + conditionSpecial
+
+	sql += ` GROUP BY label,resource  ORDER BY ` + sortTime + ` , activity_id DESC `
+
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetCygxActivityList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivity, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?  `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 批量修改弘则活动与进门财经的一个活动关联
+func UpdateJmcjActivityIdGroup(items map[int]string) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw("UPDATE cygx_activity SET jmcj_activity_id = ? WHERE activity_id = ? AND jmcj_activity_id= '' ").Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for k, v := range items {
+		_, err = p.Exec(v, k)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 237 - 0
models/activity_appointment.go

@@ -0,0 +1,237 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivityAppointment struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	RealName    string    `description:"用户实际名称"`
+	SellerName  string    `description:"所属销售"`
+}
+
+type AppointmentResp struct {
+	ActivityId    int    `description:"活动ID"`
+	HasPermission int    `description:"操作方式,1:有该行业权限,正常展示,2:无该行业权限,3:潜在客户,未提交过申请,4:潜在客户,已提交过申请"`
+	PopupMsg      string `description:"权限弹窗信息"`
+	SellerMobile  string `description:"销售电话"`
+	SellerName    string `description:"销售姓名"`
+	GoFollow      bool   `description:"是否去关注"`
+}
+
+//添加
+func AddCygxActivityAppointment(item *CygxActivityAppointment) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	var countMySchedule int
+	sql := `SELECT COUNT(1) AS count FROM cygx_my_schedule WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countMySchedule)
+	if err != nil {
+		return
+	}
+	if countMySchedule == 0 {
+		itemMy := new(CygxMySchedule)
+		itemMy.UserId = item.UserId
+		itemMy.ActivityId = item.ActivityId
+		itemMy.CreateTime = time.Now()
+		itemMy.Mobile = item.Mobile
+		itemMy.Email = item.Email
+		itemMy.CompanyId = item.CompanyId
+		itemMy.CompanyName = item.CompanyName
+		_, err = o.Insert(itemMy)
+		if err != nil {
+			return
+		}
+	}
+	_, err = o.Insert(item)
+	return
+}
+
+//获取某一用户的报名的数量
+func GetUserCygxActivityAppointmentCount(uid, activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_appointment  WHERE  user_id=?  AND   activity_id =? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, activityId).QueryRow(&count)
+	return
+}
+
+//获取某一用户的报名的数量
+func GetUserCygxActivityAppointmentCountByUid(uid int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_appointment  WHERE  user_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+//删除
+func DeleteCygxActivityAppointment(uid, activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE  FROM cygx_activity_special_signup   WHERE   user_id=?   AND  activity_id=?    `
+	_, err = o.Raw(sql, uid, activityId).Exec()
+	return
+}
+
+//取消纪要预约
+func CancelcygxActivityAppointment(item *CygxActivityAppointment) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	//判断是否删除我的日程
+	var countSingup int
+	var countReminder int
+	sql := `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE  is_cancel = 0  AND user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countSingup)
+	sql = `SELECT COUNT(1) AS count FROM cygx_activity_meeting_reminder WHERE   user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countReminder)
+	if err != nil {
+		return
+	}
+	if countSingup == 0 && countReminder == 0 {
+		sql = `DELETE  FROM cygx_my_schedule   WHERE user_id=?  AND activity_id=? `
+		_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+		if err != nil {
+			return
+		}
+	}
+	//删除预约的纪要
+	sql = `DELETE  FROM cygx_activity_appointment   WHERE user_id=?  AND activity_id=? `
+	_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+	if err != nil {
+		return
+	}
+	return
+}
+
+type CygxAppointmentAndActivity struct {
+	Mobile         string `description:"手机号"`
+	ActivityName   string `description:"所属销售"`
+	ActivityTypeId int    `description:"活动类型"`
+}
+
+//通过活动ID获取预约列表
+func GetAppointmentListByActivityId(activityIds, activityTypeIds string) (items []*CygxAppointmentAndActivity, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			m.*,a.activity_name,
+			a.activity_type_id
+		FROM
+			cygx_activity_appointment AS m
+			INNER JOIN cygx_activity AS a ON a.activity_id = m.activity_id 
+		WHERE
+			a.activity_id IN ( ` + activityIds + ` ) 
+			AND a.activity_type_id IN (` + activityTypeIds + `) 
+			AND DATE_SUB( CURDATE(), INTERVAL 14 DAY ) <= date( a.activity_time ) 
+			AND a.active_state = 3 	GROUP BY m.mobile`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+//通过活动ID、手机号获取预约列表
+func GetAppointmentListByActivityIdAndMobile(activityIds, mobile string) (items []*CygxAppointmentAndActivity, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			m.*,a.activity_name
+		FROM
+			cygx_activity_appointment AS m
+			INNER JOIN cygx_activity AS a ON a.activity_id = m.activity_id 
+		WHERE
+			a.activity_id IN ( ` + activityIds + ` ) 
+			AND a.activity_type_id IN ( 1, 2, 5 ) 
+			AND DATE_SUB( CURDATE(), INTERVAL 14 DAY ) <= date( a.activity_time ) 
+			AND a.active_state = 3
+			AND  m.mobile= ?`
+	_, err = o.Raw(sql, mobile).QueryRows(&items)
+	return
+}
+
+//通过活动ID获取预约纪要的人数列表
+func GetCygxAppointmentSummaryListBySubjectId(subjectIds string) (item []*CygxAppointmentAndActivity, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			ap.mobile,
+			ap.activity_id,
+			a.activity_name 
+		FROM
+			cygx_activity_appointment AS ap
+			INNER JOIN cygx_activity AS a ON a.activity_id = ap.activity_id
+			INNER JOIN cygx_industrial_activity_group_subject AS sg ON sg.activity_id = a.activity_id 
+		WHERE
+			a.active_state = 3 
+			AND a.chart_permission_id = 31 
+			AND DATE_SUB( CURDATE(), INTERVAL 14 DAY ) <= date( a.activity_time ) 
+			AND a.activity_type_id = 1 
+			AND sg.industrial_subject_id IN (` + subjectIds + `) 
+		GROUP BY
+			ap.mobile,
+			ap.activity_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+type CygxAppointment struct {
+	Mobile         string `description:"手机号"`
+	UserId         int    `description:"userId"`
+	ActivityName   string `description:"所属销售"`
+	ActivityTypeId int    `description:"活动类型"`
+}
+
+//通过活动ID获取预约纪要的人数列表
+func GetCygxAppointmentSummaryBySubjectId(subjectIds string) (item []*CygxAppointment, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			ap.user_id,
+			ap.mobile,
+			ap.activity_id,
+			a.activity_name 
+		FROM
+			cygx_activity_appointment AS ap
+			INNER JOIN cygx_activity AS a ON a.activity_id = ap.activity_id
+			INNER JOIN cygx_industrial_activity_group_subject AS sg ON sg.activity_id = a.activity_id 
+		WHERE
+			a.active_state = 3
+			AND sg.industrial_subject_id IN (` + subjectIds + `) 
+		GROUP BY
+			ap.mobile,
+			ap.activity_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+//GetCygxAppointmentListByUser 获取预约纪要的人
+func GetCygxAppointmentListByUser(condition string, pars []interface{}) (item []*CygxActivityAppointment, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_activity_appointment  
+			WHERE 1 = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}

+ 203 - 0
models/activity_attendance_detail.go

@@ -0,0 +1,203 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+type CygxActivityAttendanceDetail struct {
+	AttendanceId          int       `orm:"column(attendance_id);pk;"description:"主键ID"`
+	ActivityId            int       `description:"活动ID"`
+	RealName              string    `description:"姓名"`
+	Mobile                string    `description:"手机号"`
+	CompanyName           string    `description:"公司名称"`
+	CompanyId             int       `description:"公司id 不在数据库的用户为0"`
+	SellerName            string    `description:"销售姓名"`
+	FirstMeetingTime      string    `description:"首次入会时间"`
+	LastMeetingTime       string    `description:"最后退出时间"`
+	Duration              string    `description:"参会时长"`
+	MeetingTypeStr        string    `description:"参会方式"`
+	MeetingAuthentication string    `description:"参会权鉴"`
+	MeetingStatusStr      string    `description:"参会状态"`
+	CreateTime            time.Time `description:"创建时间"`
+	Position              string    `description:"职位"`
+	IsMeetingStr          int       `description:"是否到会,1到会,0未到会"`
+	UseridEntity          int       `description:"参会者身份. 1:主讲人, 2:主持人, 3:嘉宾, 4:普通参会者, 5:联席主讲人, 6:会议助理"`
+	ActivityTime          string    `description:"活动时间"`
+	CrmCompanyMapStatusId int       `description:"转换后的对应状态信息:1=正式客户, 2=曾使用客户, 3=其他"`
+}
+
+// 添加会议提醒信息
+func AddCygxActivityAttendanceDetail(item *CygxActivityAttendanceDetail) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	var count int
+	var countMySchedule int
+	sql := `SELECT COUNT(1) AS count FROM cygx_my_schedule WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item, item.ActivityId).QueryRow(&countMySchedule)
+	if err != nil {
+		return
+	}
+	if countMySchedule == 0 {
+		itemMy := new(CygxMySchedule)
+		itemMy.ActivityId = item.ActivityId
+		itemMy.CreateTime = time.Now()
+		itemMy.Mobile = item.Mobile
+
+		itemMy.CompanyId = item.CompanyId
+		itemMy.CompanyName = item.CompanyName
+		lastId, err = o.Insert(itemMy)
+		if err != nil {
+			return
+		}
+	}
+	sql = `SELECT COUNT(1) AS count FROM cygx_activity_meeting_reminder WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item, item.ActivityId).QueryRow(&count)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		sql := `UPDATE cygx_activity_meeting_reminder SET is_cancel = 0  WHERE user_id=?  AND activity_id=? `
+		_, err = o.Raw(sql, item, item.ActivityId).Exec()
+	} else {
+		lastId, err = o.Insert(item)
+	}
+	itemLog := new(CygxActivityMeetingReminderLog)
+	//itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	//itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 1
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+func AddAttendancDetail(items []*CygxActivityAttendanceDetail, activityId int, mobileStr string) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	//修改活动是否上传到会信息字段
+	sql := `UPDATE cygx_activity SET  is_submit_meeting=1   WHERE activity_id=? `
+	_, err = o.Raw(sql, activityId).Exec()
+	if err != nil {
+		return
+	}
+	//修改单个报名信息是否到会
+	sql = `UPDATE cygx_activity_signup SET  is_meeting=0   WHERE activity_id=? `
+	_, err = o.Raw(sql, activityId).Exec()
+	if err != nil {
+		return
+	}
+	sql = `UPDATE cygx_activity_signup SET  is_meeting=1   WHERE  activity_id=? AND ( outbound_mobile IN (` + mobileStr + `)  OR mobile IN (` + mobileStr + `) )`
+	_, err = o.Raw(sql, activityId).Exec()
+	if err != nil {
+		return
+	}
+	//二次上传时删除原有数据
+	sql = ` DELETE FROM cygx_activity_attendance_detail WHERE activity_id = ?`
+	_, err = o.Raw(sql, activityId).Exec()
+	if err != nil {
+		return
+	}
+
+	//
+	////插入提交信息
+	//for _, v := range items {
+	//	_, err = o.Insert(v)
+	//	if err != nil {
+	//		return
+	//	}
+	//}
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+// 获取用户参会列表
+func GetRoadshowDataList(title, findStartDate, findEndDate string) (list []*RoadshowData, err error) {
+	o := orm.NewOrmUsingDB("comein_data")
+	sql := `SELECT * FROM roadshow_data WHERE roadshow_title LIKE '%` + title + `%' AND  roadshow_begin_time >= '` + findStartDate + `' AND roadshow_begin_time <= '` + findEndDate + `'`
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
+// 获取这个时段内的进门财经参会活动
+func GetRoadshowDataListByDateTime(findStartDate, findEndDate string) (list []*RoadshowData, err error) {
+	o := orm.NewOrmUsingDB("comein_data")
+	sql := `SELECT * FROM roadshow_data WHERE   roadshow_begin_time >= '` + findStartDate + `' AND roadshow_begin_time <= '` + findEndDate + `'   GROUP BY roadshow_title `
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
+type WxUserOutboundMobile struct {
+	RealName       string `description:"姓名"`
+	Mobile         string `description:"手机号"`
+	OutboundMobile string `description:"外呼手机号"`
+	CompanyId      int    `description:"公司ID"`
+	CompanyName    string `description:"公司名称"`
+	SellerName     string `description:"所属销售"`
+}
+
+func GetWxUserOutboundMobile(mobileStr string) (item []*WxUserOutboundMobile, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT u.real_name,u.mobile,u.outbound_mobile,u.company_id,p.company_name ,GROUP_CONCAT( DISTINCT p.seller_name SEPARATOR '/' ) AS seller_name
+			FROM wx_user as u 
+			INNER JOIN company_product AS p ON p.company_id = u.company_id 
+			WHERE outbound_mobile IN (` + mobileStr + `) OR mobile IN (` + mobileStr + `)  GROUP BY u.user_id`
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+// 我的日程列表
+func GetActivityAttendanceDetailList(activityIds string) (items []*CygxActivityAttendanceDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_attendance_detail WHERE activity_id IN (` + activityIds + `) `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 我的日程列表
+func GetActivityAttendanceDetailListAll() (items []*CygxActivityAttendanceDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_attendance_detail WHERE  activity_id >= 1000 ORDER BY activity_id  ASC  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityAttendanceDetailListCondition(condition string, pars []interface{}) (items []*CygxActivityAttendanceDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_attendance_detail WHERE   1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func AddAttendancDetailNew(items []*CygxActivityAttendanceDetail, activityIds []int) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	//修改活动是否上传到会信息字段
+	sql := `UPDATE cygx_activity SET  is_submit_meeting=1   WHERE activity_id IN  (` + utils.GetOrmInReplace(len(activityIds)) + `)  `
+	_, err = o.Raw(sql, activityIds).Exec()
+	if err != nil {
+		return
+	}
+	_, err = o.InsertMulti(len(items), items)
+	return
+}

+ 22 - 0
models/activity_fastsearch_keywords.go

@@ -0,0 +1,22 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type ActivityFastsearchKeywords struct {
+	Id      int    `description:"活动类型id"`
+	KeyWord string `description:"关键词"`
+}
+
+type ActivityFastsearchKeywordsListResp struct {
+	List []*ActivityFastsearchKeywords
+}
+
+//列表
+func GetActivityFastsearchKeywordsList() (items []*ActivityFastsearchKeywords, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_fastsearch_keywords ORDER BY sort DESC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 78 - 0
models/activity_help_ask.go

@@ -0,0 +1,78 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivityHelpAsk struct {
+	AskId       int       `orm:"column(ask_id);pk" description:"带问id"`
+	UserId      int       `description:"用户id"`
+	ActivityId  int       `description:"活动id"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	Content     string    `description:"内容"`
+}
+
+// 添加优化建议
+func AddActivityHelpAsk(item *CygxActivityHelpAsk) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type AddCygxActivityHelpAsk struct {
+	ActivityId int    `description:"活动id"`
+	Content    string `description:"内容"`
+}
+
+type CygxAskList struct {
+	ReportOrActivityId int    ` description:"对应的文章或者活动Id"`
+	Title              string `description:"标题"`
+	Content            string `description:"内容"`
+	AskType            string `description:"类型 Activity 活动 、Report 文章报告"`
+	CreateTime         string `description:"创建时间"`
+}
+
+type CygxAskListResp struct {
+	List []*CygxAskList
+}
+
+//report_or_activity_id
+
+// 主题列表
+func GetActivityAskList(userId int) (items []*CygxAskList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			k.activity_id as report_or_activity_id,
+			k.content,
+			k.create_time,
+			a.activity_name as title
+		FROM
+			cygx_activity_help_ask AS k
+			INNER JOIN cygx_activity AS a ON a.activity_id = k.activity_id 
+		WHERE
+			user_id = ? AND a.publish_status = 1 ORDER BY k.ask_id DESC`
+	_, err = o.Raw(sql, userId).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetArticleAskList(userId int) (items []*CygxAskList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			k.article_id as report_or_activity_id,
+			k.content,
+			k.create_time,
+			a.title as title
+		FROM
+			cygx_article_ask AS k
+			INNER JOIN cygx_article AS a ON a.article_id = k.article_id 
+		WHERE
+			user_id = ? AND a.publish_status = 1 ORDER BY k.ask_id DESC`
+	_, err = o.Raw(sql, userId).QueryRows(&items)
+	return
+}

+ 202 - 0
models/activity_meeting_reminder.go

@@ -0,0 +1,202 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+type CygxActivityMeetingReminder struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+}
+
+// 记录日志
+type CygxActivityMeetingReminderLog struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	Type        int       `description:"操作方式,1报名,2取消报名"`
+}
+
+// 添加会议提醒信息
+func AddActivityMeetingReminder(item *CygxActivityMeetingReminder) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	var count int
+	var countMySchedule int
+	sql := `SELECT COUNT(1) AS count FROM cygx_my_schedule WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countMySchedule)
+	if err != nil {
+		return
+	}
+	if countMySchedule == 0 {
+		itemMy := new(CygxMySchedule)
+		itemMy.UserId = item.UserId
+		itemMy.ActivityId = item.ActivityId
+		itemMy.CreateTime = time.Now()
+		itemMy.Mobile = item.Mobile
+		itemMy.Email = item.Email
+		itemMy.CompanyId = item.CompanyId
+		itemMy.CompanyName = item.CompanyName
+		lastId, err = o.Insert(itemMy)
+		if err != nil {
+			return
+		}
+	}
+	sql = `SELECT COUNT(1) AS count FROM cygx_activity_meeting_reminder WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&count)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		sql := `UPDATE cygx_activity_meeting_reminder SET is_cancel = 0  WHERE user_id=?  AND activity_id=? `
+		_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+	} else {
+		lastId, err = o.Insert(item)
+	}
+	itemLog := new(CygxActivityMeetingReminderLog)
+	itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 1
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+// 获取用户报名数量
+func GetActivityMeetingReminderCount(uid, activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_meeting_reminder WHERE is_cancel=0 AND user_id=? AND activity_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, activityId).QueryRow(&count)
+	return
+}
+
+// 取消会议提醒
+func CancelActivityMeetingReminder(item *CygxActivityMeetingReminder) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	//判断是否删除我的日程
+	var countSignup int
+	var countAppointment int
+	sql := `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE  is_cancel = 0  AND user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countSignup)
+
+	sql = `SELECT COUNT(1) AS count FROM cygx_activity_appointment WHERE  user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countAppointment)
+	if err != nil {
+		return
+	}
+	if countSignup == 0 && countAppointment == 0 {
+		sql = `DELETE  FROM cygx_my_schedule   WHERE user_id=?  AND activity_id=? `
+		_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+		if err != nil {
+			return
+		}
+	}
+	sql = `DELETE  FROM cygx_activity_meeting_reminder   WHERE user_id=?  AND activity_id=? `
+	_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+	if err != nil {
+		return
+	}
+	itemLog := new(CygxActivityMeetingReminderLog)
+	itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 2
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+// 获取某一用户的日程数量
+func GetUserActivityMeetingReminderCount(uid int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_meeting_reminder_log WHERE  user_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+// GetCygxReminderListByUser 获取设置会议提醒的人
+func GetCygxReminderListByUser(condition string, pars []interface{}) (item []*CygxActivityMeetingReminder, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_activity_meeting_reminder  
+			WHERE 1 = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+// 修改是否推送消息状态
+func UpdateSendedMsgMeetingSendWxMsg(activityIds []int) (err error) {
+	lenarr := len(activityIds)
+	if lenarr == 0 {
+		return
+	}
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	condition = ` AND activity_id IN (` + utils.GetOrmInReplace(lenarr) + `)`
+	pars = append(pars, activityIds)
+	//修改设置消息提醒微信模版消息推送状态
+	sql := ` UPDATE cygx_activity_meeting_reminder SET  is_send_wx_msg= 1  WHERE  1=1   ` + condition
+	_, err = o.Raw(sql, pars).Exec()
+	if err != nil {
+		return
+	}
+
+	//修改设置预约外呼微信模版消息推送状态
+	sql = ` UPDATE cygx_activity_signup SET  is_send_wx_msg= 1  WHERE  1=1   ` + condition
+	_, err = o.Raw(sql, pars).Exec()
+	return
+}

+ 41 - 0
models/activity_mirror_word.go

@@ -0,0 +1,41 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type CygxActivityMirrorWord struct {
+	Id            int    `description:"id"`
+	KeyWord       string `description:"关键词"`
+	MirrorKeyWord string `description:"关键词"`
+}
+
+type ActivityMirrorWordListResp struct {
+	List []*CygxActivityMirrorWord
+}
+
+//列表
+func GetActivityMirrorWordList() (items []*ActivityFastsearchKeywords, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_mirror_word ORDER BY sort DESC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+//获取镜像词数量
+func GetActivityMirrorWordCount(keyWord string) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT( 1 ) AS count  FROM cygx_activity_mirror_word WHERE key_word IN (` + keyWord + `) `
+	err = o.Raw(sqlCount).QueryRow(&count)
+	return
+}
+
+func GetMirrorWord(keyWord string) (mirrorword string, err error) {
+	sql := ` SELECT GROUP_CONCAT( DISTINCT m.mirror_key_word SEPARATOR ',' ) AS mirrorword 
+				FROM
+				cygx_activity_mirror_word AS m 
+				WHERE m.key_word IN (` + keyWord + `)`
+	o := orm.NewOrm()
+	err = o.Raw(sql).QueryRow(&mirrorword)
+	return
+}

+ 91 - 0
models/activity_offline_meeting_detail.go

@@ -0,0 +1,91 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// 报名
+type CygxActivityOfflineMeetingDetail struct {
+	Id          int       `orm:"column(id);pk"`
+	UserId      int       `description:"用户id"`
+	ActivityId  int       `description:"活动ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱号"`
+	CompanyId   int       `description:"公司ID"`
+	CompanyName string    `description:"公司名称"`
+	IsMeeting   int       `description:"是否到会  1.是 ,0否"`
+	SigninTime  string    `description:"签到时间"`
+}
+
+// 列表
+func GetOfflineMeetingList(condition string, pars []interface{}) (items []*CygxActivitySignupList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT  *
+			FROM cygx_activity_offline_meeting_detail   WHERE 1 =1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 批量添加
+func AddCygxActivityOfflineMeetingDetailList(items []*CygxActivityOfflineMeetingDetail) (lastId int64, err error) {
+	lenitems := len(items)
+	if lenitems == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(1, items)
+	return
+}
+
+// 添加
+func AddCygxActivityOfflineMeetingDetail(item *CygxActivityOfflineMeetingDetail) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+// 获取数量
+func GetCygxActivityOfflineMeetingDetailCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity_offline_meeting_detail as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// UpdateCygxActivityOfflineMeetingDetailSigninTime  修改签到时间
+func UpdateCygxActivityOfflineMeetingDetailSigninTime(activityId, userId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_activity_offline_meeting_detail SET signin_time = NOW() ,is_meeting = 1  WHERE activity_id  = ? AND  user_id = ? `
+	_, err = o.Raw(sql, activityId, userId).Exec()
+	return
+}
+
+// 预约外呼列表
+func GetOfflineMeetingListByUser(meetingUids string, activityId int) (items []*CygxActivityOfflineMeetingDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT s.* FROM cygx_activity_offline_meeting_detail  as s  WHERE activity_id = ? AND user_id IN  (` + meetingUids + `)`
+	_, err = o.Raw(sql, activityId).QueryRows(&items)
+	return
+}
+
+// 报名
+type CygxActivityOfflineMeetingDetailResp struct {
+	ActivityId   int    `description:"活动ID "`
+	ActivityName string `description:"活动名称"`
+	List         []*CygxActivitySignupResp
+}
+
+// 预约外呼列表
+func GetOfflineMeetingListWithUser(condition string, pars []interface{}) (items []*CygxActivitySignupList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT s.* 
+			FROM cygx_activity_offline_meeting_detail  as s 
+			  WHERE 1 =1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}

+ 179 - 0
models/activity_points_bill.go

@@ -0,0 +1,179 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// CygxActivityPointsBill 活动扣点流水表
+type CygxActivityPointsBill struct {
+	Id                int       `gorm:"column:id;primary_key;AUTO_INCREMENT" json:""`
+	UserId            int       `gorm:"column:user_id;NOT NULL" json:""`                     // 用户ID
+	ActivityId        int       `gorm:"column:activity_id;default:0;NOT NULL" json:""`       // 活动ID
+	CreateTime        time.Time `gorm:"column:create_time" json:""`                          // 创建时间
+	Mobile            string    `gorm:"column:mobile" json:""`                               // 手机号
+	Email             string    `gorm:"column:email" json:""`                                // 邮箱
+	CompanyId         int       `gorm:"column:company_id;default:0" json:""`                 // 公司ID
+	CompanyName       string    `gorm:"column:company_name" json:""`                         // 公司名称
+	RealName          string    `gorm:"column:real_name" json:""`                            // 用户实际名称
+	AdminId           int       `gorm:"column:admin_id;NOT NULL" json:""`                    // 管理员、销售ID
+	Source            int       `gorm:"column:source;default:1;NOT NULL" json:""`            // 来源,1客户端,2后台添加, 3开发人员手动添加、4定时任务
+	BillDetailed      float64   `gorm:"column:bill_detailed;default:0;NOT NULL" json:""`     // 流水明细,判断是进账还是出账
+	RegisterPlatform  int       `gorm:"column:register_platform;default:0;NOT NULL" json:""` // 来源 1小程序,2:网页
+	ChartPermissionId int       `gorm:"column:chart_permission_id;default:0" json:""`        // 表chart_permission中id
+	DoType            int       `gorm:"column:do_type;default:1;NOT NULL" json:""`           // 操作方式,1减少,2增加
+	Content           string    `gorm:"column:content" json:""`                              // 内容说明
+	Points            float64   `gorm:"column:points;default:0;NOT NULL" json:""`            // 公司剩余点数
+}
+
+// 获取列表
+func GetCygxActivityPointsBillList(condition string, pars []interface{}) (list []*CygxActivityPointsBill, err error) {
+	sql := `SELECT * FROM cygx_activity_points_bill  WHERE  1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = orm.NewOrm().Raw(sql, pars).QueryRows(&list)
+	return
+}
+
+// CompanyTryOutDayListResp 客户累计试用天数
+type CygxActivityPointsBillListResp struct {
+	List []*CygxActivityPointsBillResp
+}
+
+type CygxActivityPointsBillResp struct {
+	Id           int     `gorm:"column:id;primary_key;AUTO_INCREMENT"`
+	Content      string  `gorm:"column:content" `                                 // 内容说明
+	Points       float64 `gorm:"column:points;default:0;NOT NULL" `               // 公司剩余点数
+	CreateTime   string  `gorm:"column:create_time" `                             // 创建时间
+	CompanyId    int     `gorm:"column:company_id;default:0" `                    // 公司ID
+	CompanyName  string  `gorm:"column:company_name" `                            // 公司名称
+	RealName     string  `gorm:"column:real_name"`                                // 用户实际名称
+	BillDetailed float64 `gorm:"column:bill_detailed;default:0;NOT NULL" json:""` // 流水明细,判断是进账还是出账
+}
+
+// 获取数量
+func GetCygxActivityPointsBillCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity_points_bill as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 通过查询条件获取详情
+func GetCygxActivityPointsBillDetailByCondition(condition string, pars []interface{}) (item *CygxActivityPointsBill, err error) {
+	if condition == "" {
+		return
+	}
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_points_bill  WHERE 1 = 1  ` + condition
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// AddCygxActivityPointsBillMulti 批量添加
+func AddCygxActivityPointsBillMulti(items []*CygxActivityPointsBill, itemsUpdate []*CygxActivityPointsCompany) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	if len(items) > 0 {
+		//批量添加流水信息
+		_, err = o.InsertMulti(len(items), items)
+	}
+	//批量修改公司剩余点数
+	p, err := o.Raw("UPDATE cygx_activity_points_company SET points = ?, modify_time = ? WHERE company_id = ?").Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range itemsUpdate {
+		_, err = p.Exec(v.Points, v.ModifyTime, v.CompanyId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// AddCygxActivityPointsBillAndCompanyMulti 批量添加
+func AddCygxActivityPointsBillAndCompanyMulti(items []*CygxActivityPointsBill, itemsCompany []*CygxActivityPointsCompany) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	if len(items) > 0 {
+		//批量添加流水信息
+		_, err = o.InsertMulti(len(items), items)
+	}
+	if len(itemsCompany) > 0 {
+		//批量添加流水信息
+		_, err = o.InsertMulti(len(itemsCompany), itemsCompany)
+	}
+	return
+}
+
+// UpdateCygxActivityPointsBillMulti 批量修改
+func UpdateCygxActivityPointsBillMulti(items []*CygxActivityPointsBill, itemsUpdate []*CygxActivityPointsCompany) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+
+	//批量修改公司剩余点数
+	p, err := o.Raw("UPDATE cygx_activity_points_bill SET points = ?, bill_detailed = ? WHERE id = ?").Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		_, err = p.Exec(v.Points, v.BillDetailed, v.Id)
+		if err != nil {
+			return
+		}
+	}
+
+	//批量修改公司剩余点数
+	p, err = o.Raw("UPDATE cygx_activity_points_company SET points = ?, modify_time = ? WHERE company_id = ?").Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range itemsUpdate {
+		_, err = p.Exec(v.Points, v.ModifyTime, v.CompanyId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 42 - 0
models/activity_points_company.go

@@ -0,0 +1,42 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivityPointsCompany struct {
+	Id          int       `gorm:"column:id;primary_key;AUTO_INCREMENT" json:"id"`
+	CompanyId   int       `gorm:"column:company_id;default:0" json:"company_id"`  // 公司ID
+	CompanyName string    `gorm:"column:company_name" json:"company_name"`        // 公司名称
+	Points      float64   `gorm:"column:points;default:0;NOT NULL" json:"points"` // 公司剩余点数
+	CreateTime  time.Time `gorm:"column:create_time;NOT NULL" json:"create_time"` // 创建时间
+	ModifyTime  time.Time `gorm:"column:modify_time;NOT NULL" json:"modify_time"` // 更新时间
+}
+
+// 获取公司剩余点数
+func GetCompanyPoints(companyId int) (comapnyPointsNum float64, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT points FROM cygx_activity_points_company  WHERE company_id=? `
+	err = o.Raw(sql, companyId).QueryRow(&comapnyPointsNum)
+	return
+}
+
+// 列表
+func GetCygxActivityPointsCompanyList(condition string, pars []interface{}) (items []*CygxActivityPointsCompany, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_points_company as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 获取数量
+func GetCygxActivityPointsCompanyCountByCompanyId(companyId int) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity_points_company WHERE company_id=?  `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, companyId).QueryRow(&count)
+	return
+}

+ 90 - 0
models/activity_points_set.go

@@ -0,0 +1,90 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type YanXuanActivityPointsRedis struct {
+	UserId           int       `description:"用户ID"`
+	ComapnyId        int       `description:"公司ID"`
+	ActivityId       int       `description:"活动ID"`
+	PublishStatus    int       `description:"发布状态 1已发布,0未发布"`
+	SourceType       int       `description:"1:报名、 2:取消报名、3:活动编辑、4:活动发布,取消发布、5:活动到会。"`
+	AdminId          int       `description:"管理员、销售ID"`
+	Source           int       `description:" 来源,1客户端,2后台添加, 3开发人员手动添加、4定时任务"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+	CreateTime       time.Time `description:"创建时间"`
+}
+
+type CygxActivityPointsSet struct {
+	Id                 int       `gorm:"column:id;primary_key;AUTO_INCREMENT" json:"id"`
+	ActivityId         int       `gorm:"column:activity_id;NOT NULL" json:"activity_id"`                         // 活动ID
+	PointsObject       int       `gorm:"column:points_object;default:1;NOT NULL" json:"points_object"`           // 扣点对象,1:参会人、2:办会人、3:办会人和参会人
+	CompanyId          int       `gorm:"column:company_id;default:0;NOT NULL" json:"company_id"`                 // 公司ID
+	CompanyName        float64   `gorm:"column:company_name;NOT NULL" json:"company_name"`                       // 公司名称
+	UserPointsNum      float64   `gorm:"column:user_points_num;default:0;NOT NULL" json:"user_points_num"`       // 参会人扣点数量
+	PointsType         int       `gorm:"column:points_type;default:0;NOT NULL" json:"points_type"`               // 扣点形式,1:报名即扣点,2:到会即扣点
+	CompanyPointsNum   float64   `gorm:"column:company_points_num;default:0;NOT NULL" json:"company_points_num"` // 办会人扣点数量
+	CancelDeadlineType int       `description:"取消报名截止时间类型,0:不设置,1:同报名截止时间, 2:24小时之前、3:48小时之前"`
+	CreateTime         time.Time `gorm:"column:create_time;NOT NULL" json:"create_time"` // 创建时间
+	ModifyTime         time.Time `gorm:"column:modify_time;NOT NULL" json:"modify_time"` // 更新时间
+}
+
+type CygxActivityPointsSetRsq struct {
+	ActivityId       int    `gorm:"column:activity_id;NOT NULL" json:"ActivityId"`                        // 活动ID
+	PointsObject     int    `gorm:"column:points_object;default:1;NOT NULL" json:"PointsObject"`          // 扣点对象,1:参会人、2:办会人、3:办会人和参会人
+	CompanyId        int    `gorm:"column:company_id;default:0;NOT NULL" json:"CompanyId"`                // 公司ID
+	CompanyName      string `gorm:"column:company_name;NOT NULL" json:"CompanyName"`                      // 公司名称
+	UserPointsNum    string `gorm:"column:user_points_num;default:0;NOT NULL" json:"UserPointsNum"`       // 参会人扣点数量
+	PointsType       int    `gorm:"column:points_type;default:0;NOT NULL" json:"PointsType"`              // 扣点形式,1:报名即扣点,2:到会即扣点
+	CompanyPointsNum string `gorm:"column:company_points_num;default:0;NOT NULL" json:"CompanyPointsNum"` // 办会人扣点数量
+}
+
+type CygxActivityPointsSetConfigListResp struct {
+	List []*CygxActivityPointsSetConfigResp
+}
+
+type CygxActivityPointsSetConfigResp struct {
+	PointsNum string `gorm:"column:user_points_num;default:0;NOT NULL" json:"PointsNum"` // 扣点数量
+}
+
+// 通过活动ID获取详情
+func GetCygxActivityPointsSetDetail(activityId int) (item *CygxActivityPointsSet, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_points_set  WHERE activity_id=? `
+	err = o.Raw(sql, activityId).QueryRow(&item)
+	return
+}
+
+// 通过活动ID获取详情
+func GetCygxActivityPointsSetUserNum(activityId int) (userPointsNum float64, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT user_points_num FROM cygx_activity_points_set  WHERE activity_id=? `
+	err = o.Raw(sql, activityId).QueryRow(&userPointsNum)
+	return
+}
+
+// 通过互动ID获取数量
+func GetCygxActivityPointsSetCountByActivityId(ActivityId int) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity_points_set  WHERE activity_id=?   `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, ActivityId).QueryRow(&count)
+	return
+}
+
+// 列表
+func GetCygxActivityPointsSetList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityPointsSet, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_points_set as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	if startSize+pageSize == 0 {
+		_, err = o.Raw(sql, pars).QueryRows(&items)
+	} else {
+		sql += ` LIMIT ?,?  `
+		_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	}
+	return
+}

+ 40 - 0
models/activity_restrict_signup.go

@@ -0,0 +1,40 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+)
+
+// 批量添加
+func AddCygxActivityRestrictSignupList(items []*CygxActivityRestrictSignup) (lastId int64, err error) {
+	lenitems := len(items)
+	if lenitems == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(1, items)
+	return
+}
+
+// 删除
+func DeleteCygxActivityRestrictSignupByUserIds(userIdDelArr []int) (err error) {
+	if len(userIdDelArr) == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_activity_restrict_signup  WHERE  1= 1  AND user_id IN (` + utils.GetOrmInReplace(len(userIdDelArr)) + `)`
+	_, err = o.Raw(sql, userIdDelArr).Exec()
+	return
+}
+
+// 列表
+func GetCygxActivityRestrictSignupList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityRestrictSignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_restrict_signup as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?  `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}

+ 25 - 0
models/activity_seaarch_history.go

@@ -0,0 +1,25 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySearchHistory struct {
+	Id                 int `orm:"column(id);pk"`
+	UserId             int
+	CreateTime         time.Time
+	Mobile             string `description:"手机号"`
+	CompanyId          int    `description:"公司id"`
+	CompanyName        string `description:"公司名称"`
+	ChartPermissionIds string `description:"表chart_permission中id"`
+	WhichDay           string `description:"是否属于新标签,1是,0否"`
+	IsPower            int    `description:"是否属于深标签,1是,0否"`
+}
+
+//添加
+func AddCygxActivitySearchHistory(item *CygxActivitySearchHistory) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}

+ 142 - 0
models/activity_signin.go

@@ -0,0 +1,142 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySignin struct {
+	Id           int       `orm:"column(id);pk"`
+	ActivityId   int       `description:"活动ID"`
+	UserId       int       `description:"用户ID"`
+	CreateTime   time.Time `description:"创建时间"`
+	Mobile       string    `description:"手机号"`
+	Email        string    `description:"邮箱"`
+	CompanyId    int       `description:"公司id"`
+	CompanyName  string    `description:"公司名称"`
+	BusinessCard string    `description:"名片"`
+	RealName     string    `description:"用户实际名称"`
+	IsSignup     int       `description:"是否报名了"`
+	CountryCode  string    `description:"手机国家区号"`
+	OpenId       string    `description:"Openid"`
+}
+
+type CygxActivitySigninLog struct {
+	Id           int       `orm:"column(id);pk"`
+	ActivityId   int       `description:"活动ID"`
+	UserId       int       `description:"用户ID"`
+	CreateTime   time.Time `description:"创建时间"`
+	Mobile       string    `description:"手机号"`
+	Email        string    `description:"邮箱"`
+	CompanyId    int       `description:"公司id"`
+	CompanyName  string    `description:"公司名称"`
+	BusinessCard string    `description:"名片"`
+	RealName     string    `description:"用户实际名称"`
+	IsSignup     int       `description:"是否报名了"`
+	CountryCode  string    `description:"手机国家区号"`
+	OpenId       string    `description:"Openid"`
+}
+
+type CygxActivitySigninResp struct {
+	ActivityId   int    `description:"活动ID"`
+	ActivityName string `description:"活动名称"`
+	RealName     string `description:"用户实际名称"`
+	Mobile       string `description:"手机号"`
+	CompanyName  string `description:"公司名称"`
+	BusinessCard string `description:"名片"`
+	IsNewUser    bool   `description:"是否属于新客户"`
+	IsSignup     bool   `description:"是否报名了"`
+}
+
+type CygxActivitySigninDetailResp struct {
+	Detail          *CygxActivitySigninResp
+	IsBindingMobile bool `description:"是否绑定手机号"`
+}
+
+// 获取数量
+func GetCygxActivitySigninCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_activity_signin as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// GetCygxActivitySigninList 获取签到列表信息
+func GetCygxActivitySigninList(condition string, pars []interface{}) (items []*CygxActivitySignin, err error) {
+	sql := `SELECT
+			*
+		FROM
+			cygx_activity_signin AS art
+		WHERE
+			1 = 1 	` + condition
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func GetCygxActivitySigninDetail(condition string, pars []interface{}) (item *CygxActivitySignin, err error) {
+	sql := `SELECT *  FROM cygx_activity_signin as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = orm.NewOrm().Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// 修改创建时间,做签到时间使用
+func UpdatedateCygxActivitySignin(item *CygxActivitySignin) (err error) {
+	sql := ` UPDATE cygx_activity_signin SET  create_time= NOW()   WHERE   open_id = ?  AND activity_id = ? `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, item.OpenId, item.ActivityId).Exec()
+	return
+}
+
+// 添加
+func AddCygxActivitySignin(item *CygxActivitySignin) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+// 修改
+func UpdateCygxActivitySignin(item *CygxActivitySignin) (err error) {
+	o := orm.NewOrm()
+	updateParams := make(map[string]interface{})
+	updateParams["UserId"] = item.UserId
+	updateParams["Mobile"] = item.Mobile
+	updateParams["Email"] = item.Email
+	updateParams["CompanyId"] = item.CompanyId
+	updateParams["CompanyName"] = item.CompanyName
+	updateParams["BusinessCard"] = item.BusinessCard
+	updateParams["RealName"] = item.RealName
+	updateParams["CountryCode"] = item.CountryCode
+	ptrStructOrTableName := "cygx_activity_signin"
+	whereParam := map[string]interface{}{"id": item.Id}
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams)
+	return
+}
+
+// 添加日志
+func AddCygxActivitySigninLog(item *CygxActivitySigninLog) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+type CygxActivitySigninReq struct {
+	ActivityId   int    `description:"活动id"`
+	CountryCode  string `description:"手机国家区号"`
+	Mobile       string `description:"手机号"`
+	VCode        string `description:"验证码"`
+	CompanyName  string `description:"公司名称"`
+	BusinessCard string `description:"名片"`
+	RealName     string `description:"用户实际名称"`
+	SigninType   int    `description:"签到方式,1:填写手机号/机构名称;2:上传名片"`
+}

+ 677 - 0
models/activity_signup.go

@@ -0,0 +1,677 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySignup struct {
+	Id             int       `orm:"column(id);pk"`
+	ActivityId     int       `description:"活动ID"`
+	UserId         int       `description:"用户ID"`
+	CreateTime     time.Time `description:"创建时间"`
+	Mobile         string    `description:"手机号"`
+	Email          string    `description:"邮箱"`
+	CompanyId      int       `description:"公司id"`
+	CompanyName    string    `description:"公司名称"`
+	FailType       int       `description:"失败原因,0,未失败,1总人数已满,2单机构超限制,3,爽约次数超限"`
+	SignupType     int       `description:"报名方式,1预约外呼,2自主拨入,3我要报名"`
+	DoFailType     int       `description:"失败原因,0,未失败,1总人数已满,2单机构超限制,3,爽约次数超限"`
+	OutboundMobile string    `description:"外呼手机号"`
+	CountryCode    string    `description:"手机国家区号"`
+	RealName       string    `description:"用户实际名称"`
+	SellerName     string    `description:"所属销售"`
+}
+
+type SignupStatus struct {
+	SignupStatus      string `description:"返回状态:人数已满:FullStarffed、单机构超过两人:TwoPeople、爽约次数过多:BreakPromise、超时:Overtime 、成功:Success"`
+	GoFollow          bool   `description:"是否去关注"`
+	SignupType        int    `description:"报名方式,1预约外呼,2我要报名"`
+	ActivityId        int    `description:"活动ID"`
+	HaqveJurisdiction bool   `description:"是否有权限"`
+	OperationMode     string `description:"操作方式 Apply:立即申请、Call:拨号 为空则为有权限"`
+	HasPermission     int    `description:"操作方式,1:有该行业权限,正常展示,2:无该行业权限,3:潜在客户,未提交过申请,4:潜在客户,已提交过申请"`
+	PopupMsg          string `description:"权限弹窗信息"`
+	SellerMobile      string `description:"销售电话"`
+	MsgType           string `description:"Type : 类型 , Industry : 行业"`
+	SellerName        string `description:"销售姓名"`
+	Mobile            string `description:"外呼手机号"`
+	CountryCode       string `description:"外呼手机号区号"`
+	GoOutboundMobile  bool   `description:"是否去绑定手机号"`
+	GoBindEmail       bool   `description:"是否去绑定邮箱"`
+	IsResearch        bool   `description:"是否属于研选"`
+	IsResearchSpecial bool   `description:"是否属于特殊的研选"`
+	ActivityTypeName  string `description:"活动类型名称"`
+	ActivityTime      string `description:"活动时间"`
+	ActivityType      int    `description:"活动线上线下类型 1线上,0 线下"`
+}
+
+// 我的日程
+type CygxMySchedule struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+}
+
+// 报名记录日志
+type CygxActivitySignupLog struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	Type        int       `description:"操作方式,1报名,2取消报名"`
+}
+
+// 添加报名信息
+func AddActivitySignup(item *CygxActivitySignup) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	var count int
+	var countMySchedule int
+	sql := `SELECT COUNT(1) AS count FROM cygx_my_schedule WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countMySchedule)
+	if err != nil {
+		return
+	}
+	if countMySchedule == 0 {
+		itemMy := new(CygxMySchedule)
+		itemMy.UserId = item.UserId
+		itemMy.ActivityId = item.ActivityId
+		itemMy.CreateTime = time.Now()
+		itemMy.Mobile = item.Mobile
+		itemMy.Email = item.Email
+		itemMy.CompanyId = item.CompanyId
+		itemMy.CompanyName = item.CompanyName
+		lastId, err = o.Insert(itemMy)
+		if err != nil {
+			return
+		}
+	}
+	sql = `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&count)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		sql := `UPDATE cygx_activity_signup SET is_cancel = 0 ,do_fail_type = 0, signup_type=? WHERE user_id=?  AND activity_id=? `
+		_, err = o.Raw(sql, item.SignupType, item.UserId, item.ActivityId).Exec()
+	} else {
+		lastId, err = o.Insert(item)
+	}
+	if err != nil {
+		return
+	}
+	itemLog := new(CygxActivitySignupLog)
+	itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 1
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+// 仅绑定邮箱的用户修改报名后,添加报名信息
+func AddActivitySignupFromEmail(item *CygxActivitySignup) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	var count int
+	var countMySchedule int
+	ow := orm.NewOrmUsingDB("weekly_report")
+	sql := `UPDATE wx_user SET outbound_mobile=? ,outbound_country_code = ? ,is_msg_outbound_mobile = 1   WHERE user_id=? `
+	_, err = ow.Raw(sql, item.OutboundMobile, item.CountryCode, item.UserId).Exec()
+	if err != nil {
+		return
+	}
+	sql = `SELECT COUNT(1) AS count FROM cygx_my_schedule WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countMySchedule)
+	if err != nil {
+		return
+	}
+	if countMySchedule == 0 {
+		itemMy := new(CygxMySchedule)
+		itemMy.UserId = item.UserId
+		itemMy.ActivityId = item.ActivityId
+		itemMy.CreateTime = time.Now()
+		itemMy.Mobile = item.Mobile
+		itemMy.Email = item.Email
+		itemMy.CompanyId = item.CompanyId
+		itemMy.CompanyName = item.CompanyName
+		lastId, err = o.Insert(itemMy)
+		if err != nil {
+			return
+		}
+	}
+	sql = `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&count)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		sql := `UPDATE cygx_activity_signup SET is_cancel = 0 ,do_fail_type = 0, signup_type=? WHERE user_id=?  AND activity_id=? `
+		_, err = o.Raw(sql, item.SignupType, item.UserId, item.ActivityId).Exec()
+	} else {
+		lastId, err = o.Insert(item)
+	}
+	if err != nil {
+		return
+	}
+	itemLog := new(CygxActivitySignupLog)
+	itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 1
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+// 添加报名信息
+func AddActivitySignupNoSchedule(item *CygxActivitySignup) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	lastId, err = o.Insert(item)
+	if err != nil {
+		return
+	}
+	itemLog := new(CygxActivitySignupLog)
+	itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 1
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+// 获取用户报名成功数量
+func GetActivitySignupCount(uid, activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE is_cancel=0  AND do_fail_type = 0 AND user_id=? AND activity_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, activityId).QueryRow(&count)
+	return
+}
+
+// 获取用户报名数量
+func GetActivitySignupByUserCount(uid, activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE is_cancel=0 AND user_id=? AND activity_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, activityId).QueryRow(&count)
+	return
+}
+
+// 获取除弘则以外所有成功报名的用户数量
+func GetActivitySignupSuccessByUserCountNoHz(activityId int) (count int, err error) {
+	sqlCount := `SELECT
+	COUNT( 1 ) AS count 
+FROM
+	cygx_activity_signup 
+WHERE
+	is_cancel = 0 
+	AND company_id != 16 
+	AND do_fail_type = 0 
+	AND activity_id =  ? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, activityId).QueryRow(&count)
+	return
+}
+
+// 获取用户报名禁止数量
+func GetActivitySignupByUserRestrictCount(uid, activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE do_fail_type=3 AND user_id=? AND activity_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, activityId).QueryRow(&count)
+	return
+}
+
+// 获取某一活动已经报名的数量
+func GetActivitySignupSuccessCount(activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE is_cancel=0 AND do_fail_type = 0 AND activity_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, activityId).QueryRow(&count)
+	return
+}
+
+// 获取某一活动某个机构已经报名的数量
+func GetActivitySignupCompanyCount(activityId, companyId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_signup WHERE is_cancel=0 AND fail_type = 0 AND activity_id=? AND company_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, activityId, companyId).QueryRow(&count)
+	return
+}
+
+// 获取某一用户是否被限制报名
+func GetUserRestrictCount(mobile string) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_restrict_signup WHERE is_restrict=1  AND mobile=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, mobile).QueryRow(&count)
+	return
+}
+
+// 获取某一用户的日程数量
+func GetUserMeetingReminderCount(uid int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_my_schedule WHERE  user_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+// 获取某一用户的报名的数量
+func GetUserSignupCount(uid int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_signup_log WHERE  user_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+// 取消报名
+func CancelActivitySignup(item *CygxActivitySignup) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	//判断是否删除我的日程
+	var countReminder int
+	var countAppointment int
+	sql := `SELECT COUNT(1) AS count FROM cygx_activity_meeting_reminder WHERE is_cancel = 0  AND  user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countReminder)
+
+	sql = `SELECT COUNT(1) AS count FROM cygx_activity_appointment WHERE  user_id=? AND activity_id=? `
+	err = o.Raw(sql, item.UserId, item.ActivityId).QueryRow(&countAppointment)
+	if err != nil {
+		return
+	}
+	if countReminder == 0 && countAppointment == 0 {
+		sql = `DELETE  FROM cygx_my_schedule   WHERE user_id=?  AND activity_id=? `
+		_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+		if err != nil {
+			return
+		}
+	}
+	sql = `DELETE  FROM cygx_activity_signup   WHERE user_id=?  AND activity_id=? `
+	_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+	if err != nil {
+		return
+	}
+	itemLog := new(CygxActivitySignupLog)
+	itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 2
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+// 详情
+func GetActivitySignupDetail(activityId, uid int) (item *CygxActivitySignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_signup WHERE  activity_id = ? AND user_id =? `
+	err = o.Raw(sql, activityId, uid).QueryRow(&item)
+	return
+}
+
+func GetActivitySignuListByUser(condition string, pars []interface{}) (item []*CygxActivitySignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_activity_signup  
+			WHERE 1 = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+// 解除报名限制之后二次报名
+func AddActivitySignupByRestrict(item *CygxActivitySignup) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	itemMy := new(CygxMySchedule)
+	itemMy.UserId = item.UserId
+	itemMy.ActivityId = item.ActivityId
+	itemMy.CreateTime = time.Now()
+	itemMy.Mobile = item.Mobile
+	itemMy.Email = item.Email
+	itemMy.CompanyId = item.CompanyId
+	itemMy.CompanyName = item.CompanyName
+	lastId, err = o.Insert(itemMy)
+	if err != nil {
+		return
+	}
+	sql := `UPDATE cygx_activity_signup SET do_fail_type = 0 , fail_type=0 WHERE user_id=?  AND activity_id=? `
+	_, err = o.Raw(sql, item.UserId, item.ActivityId).Exec()
+	itemLog := new(CygxActivitySignupLog)
+	itemLog.UserId = item.UserId
+	itemLog.ActivityId = item.ActivityId
+	itemLog.CreateTime = time.Now()
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.Type = 1
+	lastId, err = o.Insert(itemLog)
+	return
+}
+
+// 列表
+func GetActivitySignupListAll() (items []*CygxActivitySignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_signup `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 修改是否推送消息状态
+func UPdateSignup(item *CygxActivitySignup) (err error) {
+	sql := ` UPDATE cygx_activity_signup SET  outbound_mobile= ? , country_code=86  WHERE id = ?`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, item.Mobile, item.Id).Exec()
+	return
+}
+
+// 获取数量
+func GetActivityCountByIdWithUid(activityId, Uid int) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := `SELECT COUNT(1) AS count  FROM cygx_activity_signup WHERE activity_id = ? AND user_id = ?`
+	err = o.Raw(sqlCount, activityId, Uid).QueryRow(&count)
+	return
+}
+
+// 获取用户报名数量
+func GetActivitySignupNomeetingCount(activityId int) (count int, err error) {
+	sqlCount := `SELECT
+	COUNT( 1 ) count 
+FROM
+	cygx_activity_signup AS s
+	INNER JOIN cygx_activity AS a ON a.activity_id = s.activity_id 
+WHERE
+	1 = 1 
+	AND a.is_limit_people > 0 
+	AND s.is_meeting = 0 
+	AND a.is_submit_meeting = 1
+	AND a.activity_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, activityId).QueryRow(&count)
+	return
+}
+
+func GetUserMeetingMobile(activityId int) (items []*CygxActivitySignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+FROM
+	cygx_activity_signup AS s 
+WHERE
+	s.is_meeting = 1 
+	AND s.activity_id = ?`
+	_, err = o.Raw(sql, activityId).QueryRows(&items)
+	return
+}
+
+// 获取用户是否被限制报名
+func GetRestrictSignupCountByUid(uid int) (count int, err error) {
+	sqlCount := `SELECT COUNT( 1 ) count FROM cygx_activity_restrict_signup  WHERE user_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+// 获取用户爽约次数
+func GetActivitySignupNomeetingCountByUid(uid int) (count int, err error) {
+	sqlCount := `SELECT
+	COUNT( 1 ) count 
+FROM
+	cygx_activity_signup AS s
+	INNER JOIN cygx_activity AS a ON a.activity_id = s.activity_id 
+WHERE
+	1 = 1 
+	AND a.is_limit_people > 0 
+	AND s.is_meeting = 0 
+	AND a.is_submit_meeting = 1
+	AND s.do_fail_type = 0
+	AND s.user_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid).QueryRow(&count)
+	return
+}
+
+// 删除
+func DeleteCygxActivityRestrictSignup(uid int) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_activity_restrict_signup  WHERE user_id=?`
+	_, err = o.Raw(sql, uid).Exec()
+	return
+}
+
+type CygxActivitySignupList struct {
+	Id          int    `orm:"column(id);pk"`
+	UserId      int    `description:"用户id"`
+	ActivityId  int    `description:"活动ID"`
+	CompanyName string `description:"公司名称"`
+	RealName    string `description:"姓名"`
+	CreateTime  string `description:"创建时间"`
+	IsMeeting   int    `description:"是否到会 ,1是, 0否"`
+	Operation   bool   `description:"操作按钮,true,到会,false 未到会"`
+	Channel     int    `description:"报名渠道,0 空降、 1小程序报名"`
+	SellerName  string `description:"所属销售"`
+	Mobile      string `description:"手机号"`
+	Email       string `description:"邮箱"`
+	CompanyId   int    `description:"公司id"`
+	SigninTime  string `description:"签到时间"`
+}
+
+type CygxActivitySignupResp struct {
+	CompanyName string `description:"公司名称"`
+	RealName    string `description:"姓名"`
+	IsMeeting   int    `description:"是否到会 ,1是, 0否"`
+	SigninTime  string `description:"签到时间"`
+}
+
+// 获取用户报名列表
+func GetActivitySignupNomeetingCountList(activityId int) (items []*CygxActivitySignupList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	s.*
+FROM
+	cygx_activity_signup AS s
+	INNER JOIN cygx_activity AS a ON a.activity_id = s.activity_id 
+WHERE
+	1 = 1
+	AND s.is_meeting = 0 
+	AND a.is_submit_meeting = 1
+	AND a.activity_id = ?`
+	_, err = o.Raw(sql, activityId).QueryRows(&items)
+	return
+}
+
+type UserAndCompanyName struct {
+	UserId              int `orm:"column(user_id);pk"`
+	Mobile              string
+	Email               string
+	CompanyId           int
+	CompanyName         string `description:"公司名称"`
+	CountryCode         string `description:"手机国家区号"`
+	OutboundMobile      string `description:"外呼手机号"`
+	OutboundCountryCode string `description:"外呼手机号区号"`
+}
+
+func GetUserAndCompanyNameList(uid int) (item *UserAndCompanyName, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT u.*,c.company_name 
+			FROM wx_user AS u
+	INNER JOIN company AS c ON c.company_id = u.company_id
+	WHERE user_id =?`
+	err = o.Raw(sql, uid).QueryRow(&item)
+	return
+}
+
+type CygxActivityRestrictSignup struct {
+	Id          int       `orm:"column(id);pk"`
+	UserId      int       `description:"用户id,多个用,隔开"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱号"`
+	CompanyId   int       `description:"公司ID"`
+	CompanyName string    `description:"公司名称"`
+	IsRestrict  int       `description:"是否限制报名,1是,0否"`
+}
+
+// 添加
+func AddCygxActivityRestrictSignup(item *CygxActivityRestrictSignup) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+// 获取列表信息根据手机号分组
+func GetCygxActivitySignupByMobileList(condition string) (items []*CygxActivitySignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_signup_detail  WHERE  1= 1 ` + condition + `  GROUP BY mobile  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 修改用户报名的相关信息
+func UpdateCygxActivitySignup(wxUser *WxUserItem) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_activity_signup_detail SET email=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE  mobile=? `
+	_, err = o.Raw(sql, wxUser.Email, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Mobile).Exec()
+	return
+}
+
+// UpdateCygxActivitySignupisMeet 修改易董的活动,用户已到会
+func UpdateCygxActivitySignupisMeet(activityId int, mobile string) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_activity_signup SET is_meeting=1 WHERE activity_id=?  AND mobile = ? `
+	_, err = o.Raw(sql, activityId, mobile).Exec()
+	return
+}
+
+// UpdateCygxActivitySignupisMeetList 批量修改易董的活动,用户已到会
+func UpdateCygxActivitySignupisMeetList(condition string, pars []interface{}) (err error) {
+	if condition == "" {
+		return
+	}
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_activity_signup SET is_meeting=1 WHERE  1= 1 ` + condition
+	_, err = o.Raw(sql, pars).Exec()
+	return
+}
+
+// GetCygxCygxActivitySignupList 获取报名列表信息
+func GetActivitySignupList(condition string, pars []interface{}) (items []*CygxActivitySignup, err error) {
+	sql := `SELECT
+			*
+		FROM
+			cygx_activity_signup AS v
+		WHERE
+			1 = 1 	` + condition
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// GetCygxCygxActivitySignupList 获取报名列表信息
+func GetActivitySignupInnerActivityList(condition string, pars []interface{}) (items []*CygxActivitySignup, err error) {
+	sql := `SELECT
+			*
+		FROM
+			cygx_activity_signup AS v
+			INNER JOIN cygx_activity as a  ON a.activity_id = v.activity_id
+		WHERE
+			1 = 1 	` + condition
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// UpdateCygxActivitySignupIsMeeting 批量标记用户的到会信息
+func UpdateCygxActivitySignupIsMeeting(items []*CygxActivityAttendanceDetail) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw(` UPDATE cygx_activity_signup SET
+							is_meeting = 1
+							WHERE outbound_mobile = ? AND activity_id = ? `).Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		_, err = p.Exec(
+			v.Mobile,
+			v.ActivityId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 66 - 0
models/activity_signup_break.go

@@ -0,0 +1,66 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+type CygxActivitySignupBreak struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	RealName    string    `description:"用户实际名称"`
+	SellerName  string    `description:"所属销售"`
+}
+
+// 添加爽约记录
+func AddCygxActivitySignupBreak(item *CygxActivitySignupBreak) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 批量添加
+func AddCygxActivitySignupBreakList(items []*CygxActivitySignupBreak) (lastId int64, err error) {
+	lenitems := len(items)
+	if lenitems == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(1, items)
+	return
+}
+
+// 删除
+func DeleteCygxActivitySignupBreak(uid, activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_activity_signup_break  WHERE user_id=? AND activity_id =? `
+	_, err = o.Raw(sql, uid, activityId).Exec()
+	return
+}
+
+// 删除
+func DeleteCygxActivitySignupBreakById(activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_activity_signup_break  WHERE  activity_id =? `
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// 批量删除
+func DeleteCygxActivitySignupBreakByIds(activityIds []int) (err error) {
+	lenactivityIds := len(activityIds)
+	if lenactivityIds == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_activity_signup_break  WHERE  activity_id IN (` + utils.GetOrmInReplace(lenactivityIds) + `)`
+	_, err = o.Raw(sql, activityIds).Exec()
+	return
+}

+ 203 - 0
models/activity_signup_detail.go

@@ -0,0 +1,203 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+type CygxActivitySignupDetail struct {
+	Id                    int       `orm:"column(id);pk"`
+	ActivityId            int       `description:"活动ID"`
+	UserId                int       `description:"用户ID"`
+	CreateTime            time.Time `description:"创建时间"`
+	Mobile                string    `description:"手机号"`
+	Email                 string    `description:"邮箱"`
+	CompanyId             int       `description:"公司id"`
+	CompanyName           string    `description:"公司名称"`
+	FailType              int       `description:"失败原因,0,未失败,1总人数已满,2单机构超限制,3,爽约次数超限"`
+	SignupType            int       `description:"报名方式,1预约外呼,2自主拨入,3我要报名"`
+	DoFailType            int       `description:"失败原因,0,未失败,1总人数已满,2单机构超限制,3,爽约次数超限"`
+	OutboundMobile        string    `description:"外呼手机号"`
+	CountryCode           string    `description:"手机国家区号"`
+	RealName              string    `description:"用户实际名称"`
+	SellerName            string    `description:"所属销售"`
+	FirstMeetingTime      string    `description:"首次入会时间"`
+	LastMeetingTime       string    `description:"最后退出时间"`
+	Duration              string    `description:"参会时长"`
+	MeetingTypeStr        string    `description:"参会方式"`
+	MeetingAuthentication string    `description:"参会权鉴"`
+	MeetingStatusStr      string    `description:"参会状态"`
+	Position              string    `description:"职位"`
+	IsMeeting             int       `description:"是否到会,1到会,0未到会"`
+	UseridEntity          int       `description:"参会者身份. 1:主讲人, 2:主持人, 3:嘉宾, 4:普通参会者, 5:联席主讲人, 6:会议助理"`
+	ActivityTime          string    `description:"活动时间"`
+	CrmCompanyMapStatusId int       `description:"转换后的对应状态信息:1=正式客户, 2=曾使用客户, 3=其他"`
+}
+
+// 获取当天已结束的活动
+func GetActivitySattusToComplete() (items []*CygxActivity, err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg("修改活动状态至已结束"+err.Error(), 2)
+		}
+	}()
+	o := orm.NewOrm()
+	//resultTime_30 := time.Now().Add(-time.Minute * 30).Format(utils.FormatDateTime)
+	//resultTime_60 := time.Now().Add(-time.Minute * 60).Format(utils.FormatDateTime)
+	startTime := time.Now().Format(utils.FormatDate)
+	var condition string
+	condition += `  AND  activity_time > '` + startTime + `'`
+	//condition += ` AND (activity_type_id IN ( 1, 2, 3, 7 ) AND  activity_time < '` + resultTime_30 + `')`
+	//condition += ` OR(activity_type_id IN ( 4, 5, 6 ) AND  activity_time < '` + resultTime_60 + `')`
+	//condition += ` OR(activity_type_id IN ( 4, 5, 6 ) AND  activity_time < '` + resultTime_60 + `'  AND  activity_time > '` + startTime + `')`
+	sql := " SELECT * FROM cygx_activity   WHERE 1 = 1  AND active_state = 3 " + condition
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 获取今天报名的用户信息,存入到参会记录表中
+func GetSignupDetailBySignup(condition string, pars []interface{}) (list []*CygxActivitySignupDetail, err error) {
+	sql := `SELECT * FROM cygx_activity_signup  WHERE  1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = orm.NewOrm().Raw(sql, pars).QueryRows(&list)
+	return
+}
+
+// 获取参会记录表列表
+func GetSignupDetailList(condition string, pars []interface{}) (list []*CygxActivitySignupDetail, err error) {
+	sql := `SELECT * FROM cygx_activity_signup_detail  WHERE  1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = orm.NewOrm().Raw(sql, pars).QueryRows(&list)
+	return
+}
+
+// 添加
+func AddCygxActivitySignupDetail(items []*CygxActivitySignupDetail) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	if len(items) > 0 {
+		//批量添加
+		_, err = o.InsertMulti(len(items), items)
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+// UpdateActivitySignupDetailMulti 批量修改用户报名信息且报名的人
+func UpdateActivitySignupDetailMulti(items []*CygxActivitySignupDetail) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw(` UPDATE cygx_activity_signup_detail SET 
+							first_meeting_time = ?,
+							last_meeting_time = ?,
+							duration = ?,
+							meeting_type_str = ?,
+							meeting_authentication = ?,
+							meeting_status_str = ?,
+							position = ?,
+							is_meeting = ?,
+							userid_entity = ?,
+							activity_time = ?,
+							crm_company_map_status_id = ?
+							WHERE mobile = ? AND activity_id = ? `).Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		_, err = p.Exec(
+			v.FirstMeetingTime,
+			v.LastMeetingTime,
+			v.Duration,
+			v.MeetingTypeStr,
+			v.MeetingAuthentication,
+			v.MeetingStatusStr,
+			v.Position,
+			v.IsMeeting,
+			v.UseridEntity,
+			v.ActivityTime,
+			v.CrmCompanyMapStatusId,
+			v.Mobile, v.ActivityId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// UpdateActivitySignupDetailMultiByYiDong 易董批量修改用户报名信息且报名的人
+func UpdateActivitySignupDetailMultiByYiDong(items []*CygxActivitySignupDetail) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw(` UPDATE cygx_activity_signup_detail SET 
+							first_meeting_time = ?,
+							last_meeting_time = ?,
+							meeting_status_str = ?,
+							position = ?,
+							real_name = ?,
+							duration = ?,
+							is_meeting = ?
+							WHERE mobile = ? AND activity_id = ? `).Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		_, err = p.Exec(
+			v.FirstMeetingTime,
+			v.LastMeetingTime,
+			v.MeetingStatusStr,
+			v.Position,
+			v.RealName,
+			v.Duration,
+			v.IsMeeting,
+			v.Mobile, v.ActivityId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// UpdateActivitySignupDetailMultiByYiDong 易董批量修改用户报名信息且报名的人
+func UpdateActivitySignupDetailMultiMobileAndUserId(items []*CygxActivitySignupDetail) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw(` UPDATE cygx_activity_signup_detail SET
+							user_id = ?
+							WHERE mobile = ? AND user_id = 0 `).Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		fmt.Println(v.Mobile)
+		_, err = p.Exec(
+			v.UserId,
+			v.Mobile)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 75 - 0
models/activity_special.go

@@ -0,0 +1,75 @@
+package models
+
+import (
+	//"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// 专项调研活动列表
+type CygxActivitySpecialDetail struct {
+	ActivityId            int       `description:"活动ID "`
+	ActivityTypeName      string    `description:"活动名称"`
+	SpecialType           int       `description:"调研形式、 1 线上 , 2 线下"`
+	City                  string    `description:"调研城市"`
+	ChartPermissionName   string    `description:"行业名称"`
+	ChartPermissionId     int       `description:"行业Id"`
+	ResearchTheme         string    `description:"调研主题"`
+	ActivityTimeText      string    `description:"活动预期时间带文字"`
+	TripImgLink           string    `description:"行程图片链接"`
+	IsSignup              int       `description:"是否感兴趣 1是 ,0 否"`
+	Label                 string    `description:"主题标签"`
+	ImgUrl                string    `description:"图片链接"`
+	ImgUrlText            string    `description:"图片链接文字"`
+	IndustrialName        string    `description:"产业名称"`
+	IndustrialSubjectName string    `description:"标的名称(相关公司)"`
+	Scale                 string    `description:"管理规模,空不填,1::50亿以下,2:50~100亿,3:100亿以上。多个用, 隔开"`
+	CustomerTypeIds       string    `description:"活动可见的客户类型,多个ID用 , 隔开"`
+	IsTrip                int       `description:"是否报名 1是 ,0 否"`
+	TripNum               int       `description:"已报名人数"`
+	Days                  int       `description:"调研天数"`
+	Host                  string    `description:"主持人"`
+	PersonInCharge        string    `description:"纪要负责人"`
+	LimitPeopleNum        int       `description:"限制人数数量"`
+	TripImgLinkFix        string    `description:"确定行程之后的图片链接"`
+	ActivityTimeTextByDay string    `description:"活动预期时间带周日"`
+	ActivityTime          string    `description:"活动预期时间"`
+	ActivityTimeEnd       string    `description:"活动预期结束时间"`
+	ActiveState           int       `description:"活动进行状态 未开始:1、进行中2、已结束3"`
+	TripStatus            int       `description:"行程进行状态 1:预报名,2:确定行程"`
+	Explain               string    `description:"说明"`
+	AdminId               int       `description:"管理员ID"`
+	LastUpdatedTime       time.Time `description:"更新时间"`
+}
+
+// 获取数量
+func GetActivitySpecialCount(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.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 主题列表
+func GetActivitySpecialListAll(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivitySpecialDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT	*
+		FROM cygx_activity_special as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY art.last_updated_time DESC  LIMIT ?,? `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 修改发布状态
+func UpdateActivitySpecialPublishStatus(publishStatus, activityId int) (err error) {
+	sql := ` UPDATE cygx_activity_special SET  publish_status= ?  WHERE activity_id = ?`
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, publishStatus, activityId).Exec()
+	return
+}

+ 35 - 0
models/activity_special_meeting_detail.go

@@ -0,0 +1,35 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySpecialMeetingDetail struct {
+	Id          int       `orm:"column(id);pk"`
+	UserId      int       `description:"用户id"`
+	ActivityId  int       `description:"活动ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱号"`
+	CompanyId   int       `description:"公司ID"`
+	CompanyName string    `description:"公司名称"`
+	IsMeeting   int       `description:"是否到会  1.是 ,0否"`
+	IsAirborne  int       `description:"是否属于空降  1.是 ,0否"`
+	RealName    string    `description:"真实姓名"`
+}
+
+// 添加
+func AddCygxActivitySpecialMeetingDetail(item *CygxActivitySpecialMeetingDetail) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+// 取消
+func CancelCygxActivitySpecialMeetingDetail(uid, activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE  FROM cygx_activity_special_meeting_detail   WHERE user_id=?  AND activity_id=? `
+	_, err = o.Raw(sql, uid, activityId).Exec()
+	return
+}

+ 158 - 0
models/activity_special_signup.go

@@ -0,0 +1,158 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySpecialSignup struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	RealName    string    `description:"用户实际名称"`
+	SellerName  string    `description:"所属销售"`
+}
+
+type SignupSpecialStatus struct {
+	ActivityId    int    `description:"活动ID"`
+	HasPermission int    `description:"操作方式,1:有该行业权限,正常展示,2:无该行业权限,3:潜在客户,未提交过申请,4:潜在客户,已提交过申请"`
+	PopupMsg      string `description:"权限弹窗信息"`
+	PopupMsg2     string `description:"权限弹窗信息"`
+	Status        int    `description:"返回类型,1:添加,2:取消"`
+	SellerMobile  string `description:"销售电话"`
+	SellerName    string `description:"销售姓名"`
+	SignupStatus  int    `description:"返回状态:1:成功 、2 :人数已满 、3:调研次数已用完、 4:超时"`
+}
+
+// 添加
+func AddCygxActivitySpecialSignup(item *CygxActivitySpecialSignup) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+// 获取某一用户的报名的数量
+func GetUserCygxActivitySpecialSignup(uid, activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_special_signup  WHERE  user_id=?  AND   activity_id =? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, activityId).QueryRow(&count)
+	return
+}
+
+// 删除
+func DeleteCygxActivitySpecialSignup(uid, activityId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE  FROM cygx_activity_special_signup   WHERE   user_id=?   AND  activity_id=?    `
+	_, err = o.Raw(sql, uid, activityId).Exec()
+	return
+}
+
+// 列表
+func GetActivityListSpecialAll(activityId int) (items []*CygxActivitySpecialSignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT art.*  FROM cygx_activity_special_signup as art WHERE 1= 1 AND  activity_id = ?  GROUP BY company_id`
+	_, err = o.Raw(sql, activityId).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityListSpecialByActivityId(activityId int) (items []*CygxActivitySpecialSignup, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT art.*  FROM cygx_activity_special_signup as art WHERE 1= 1 AND  activity_id = ? `
+	_, err = o.Raw(sql, activityId).QueryRows(&items)
+	return
+}
+
+type CygxActivitySpecialSignupResp struct {
+	Id          int       `orm:"column(id);pk"`
+	ActivityId  int       `description:"活动ID"`
+	UserId      int       `description:"用户ID"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	RealName    string    `description:"用户实际名称"`
+	SellerName  string    `description:"所属销售"`
+	Count       string    `description:"所属销售"`
+}
+
+// 列表
+func GetActivityListSpecialGroupByMobile(condition string, pars []interface{}) (items []*CygxActivitySpecialSignupResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT s.*,	COUNT( 1 ) AS count   FROM cygx_activity_special_signup as s INNER JOIN cygx_activity_special AS a ON a.activity_id = s.activity_id
+			` + condition + `  GROUP BY s.mobile`
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityListSpecialGroupByCompanyId(condition string, pars []interface{}) (items []*CygxActivitySpecialSignupResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *,	COUNT( 1 ) AS count   FROM cygx_activity_special_signup   as s INNER JOIN cygx_activity_special AS a ON a.activity_id = s.activity_id
+			 ` + condition + `  GROUP BY s.company_id`
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// UpdateActivitySpecialSignupNumMulti 批量修改专项调研感兴趣的人数排名
+func UpdateActivitySpecialSignupNumMulti(items []*CygxActivitySpecialSignupResp) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw("UPDATE cygx_activity_special_signup SET user_num = ? WHERE mobile = ?").Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		_, err = p.Exec(v.Count, v.Mobile)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// UpdateActivitySpecialSignupCompanyIdMulti 批量修改专项调研感兴趣的用户的对应公司ID
+func UpdateActivitySpecialSignupCompanyIdMulti(items []*WxUser) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw("UPDATE cygx_activity_special_signup SET company_id = ? WHERE mobile = ?").Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		_, err = p.Exec(v.CompanyId, v.Mobile)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// UpdateActivitySpecialSignupCompanyNumMulti 批量修改专项调研感兴趣的公司对应的数量
+func UpdateActivitySpecialSignupCompanyNumMulti(items []*CygxActivitySpecialSignupResp) (err error) {
+	o := orm.NewOrm()
+	p, err := o.Raw("UPDATE cygx_activity_special_signup SET company_num = ? WHERE company_id = ?").Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		_ = p.Close() // 别忘记关闭 statement
+	}()
+	for _, v := range items {
+		_, err = p.Exec(v.Count, v.CompanyId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 195 - 0
models/activity_special_trip.go

@@ -0,0 +1,195 @@
+package models
+
+import (
+	"fmt"
+	//"hongze/hongze_admin/models"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySpecialTrip struct {
+	Id             int       `orm:"column(id);pk"`
+	UserId         int       `description:"用户id,多个用,隔开"`
+	ActivityId     int       `description:"活动ID"`
+	CreateTime     time.Time `description:"创建时间"`
+	Mobile         string    `description:"手机号"`
+	Email          string    `description:"邮箱号"`
+	CompanyId      int       `description:"公司ID"`
+	CompanyName    string    `description:"公司名称"`
+	RealName       string    `description:"用户实际名称"`
+	SellerName     string    `description:"所属销售"`
+	AdminId        int       `description:"销售/管理员ID"`
+	Source         int       `description:"来源,1小程序,2后台添加"`
+	OutboundMobile string    `description:"外呼手机号"`
+	CountryCode    string    `description:"手机国家区号"`
+	IsCancel       string    `description:"是否取消,1是,0否"`
+	IsValid        int       `description:"参会报名是否有效 1:是,0"`
+}
+
+type CygxActivitySpecialTripResp struct {
+	Id             int    `description:"ID"`
+	UserId         int    `description:"用户id"`
+	ActivityId     int    `description:"活动ID"`
+	CreateTime     string `description:"创建时间"`
+	Mobile         string `description:"手机号"`
+	Email          string `description:"邮箱号"`
+	CompanyId      int    `description:"公司ID"`
+	CompanyName    string `description:"公司名称"`
+	RealName       string `description:"用户实际名称"`
+	SellerName     string `description:"所属销售"`
+	OutboundMobile string `description:"外呼手机号"`
+	CountryCode    string `description:"手机国家区号"`
+}
+
+func GetCygxActivitySpecialTripList(condition string, pars []interface{}) (item []*CygxActivitySpecialTripResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_activity_special_trip  
+			WHERE 1 = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+func GetCygxActivitySpecialmeetingDetailList(condition string, pars []interface{}) (item []*CygxActivitySpecialTripResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_activity_special_meeting_detail  
+			WHERE 1 = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+// 获取某一用户的报名的数量
+func GetUserActivitySpecialTripCount(uid, activityId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_special_trip  WHERE  user_id=?  AND   activity_id =? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, activityId).QueryRow(&count)
+	return
+}
+
+// 获取某一活动的报名的数量
+func GetActivitySpecialTripCountByActivityId(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_activity_special_trip as t  WHERE    1 = 1 ` + condition
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 获取某一活动的报名的数量 (同时关联活动类型进行获取)
+func GetActivitySpecialTripCountByActivitySpecial(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count
+		FROM
+			cygx_activity_special_trip AS t
+			INNER JOIN cygx_activity_special AS a ON a.activity_id = t.activity_id 
+		WHERE
+			 1= 1 ` + condition
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 获取空降的公司报名的记录
+func GetActivitySpecialTripAirborneCountByActivitySpecial(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count
+		FROM
+			cygx_activity_special_meeting_detail AS t
+			INNER JOIN cygx_activity_special AS a ON a.activity_id = t.activity_id 
+		WHERE
+			 1= 1  	AND YEAR ( t.create_time )= YEAR (NOW()) ` + condition
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 添加
+func AddCygxActivitySpecialTrip(item *CygxActivitySpecialTrip) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	_, err = o.Insert(item)
+	if err != nil {
+		return
+	}
+	//itemBill := new(CygxActivitySpecialTripBill)
+	//itemBill.UserId = item.UserId
+	//itemBill.ActivityId = item.ActivityId
+	//itemBill.CreateTime = time.Now()
+	//itemBill.Mobile = item.Mobile
+	//itemBill.Email = item.Email
+	//itemBill.CompanyId = item.CompanyId
+	//itemBill.CompanyName = item.CompanyName
+	//itemBill.RealName = item.RealName
+	//itemBill.Source = 1
+	//itemBill.BillDetailed = -1 // 流水减一
+	//itemBill.DoType = 1
+	//itemBill.RegisterPlatform = 1
+	//itemBill.ChartPermissionId = itemActivity.ChartPermissionId
+	//
+	//_, err = o.Insert(itemBill)
+	//if err != nil {
+	//	return
+	//}
+	return
+}
+
+// 取消
+func CancelActivitySpecialTrip(uid int, item *CygxActivitySpecialDetail) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE  FROM cygx_activity_special_trip   WHERE user_id=?  AND activity_id=? `
+	_, err = o.Raw(sql, uid, item.ActivityId).Exec()
+	return
+}
+
+// CancelActivitySpecialTripIsValid  处理活动报名是否有效
+func CancelActivitySpecialTripIsValid(isValid, activityId, userId int) (err error) {
+	sql := ` UPDATE cygx_activity_special_trip SET  is_valid= ?,is_cancel = 1  WHERE activity_id = ? AND  user_id = ? `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, isValid, activityId, userId).Exec()
+	return
+}
+
+type CygxActivitySpecialTripInit struct {
+	Id                int       `orm:"column(id);pk"`
+	UserId            int       `description:"用户id,多个用,隔开"`
+	ActivityId        int       `description:"活动ID"`
+	CreateTime        time.Time `description:"创建时间"`
+	Mobile            string    `description:"手机号"`
+	Email             string    `description:"邮箱号"`
+	CompanyId         int       `description:"公司ID"`
+	CompanyName       string    `description:"公司名称"`
+	RealName          string    `description:"用户实际名称"`
+	SellerName        string    `description:"所属销售"`
+	AdminId           int       `description:"销售/管理员ID"`
+	Source            int       `description:"来源,1小程序,2后台添加"`
+	OutboundMobile    string    `description:"外呼手机号"`
+	CountryCode       string    `description:"手机国家区号"`
+	IsCancel          string    `description:"是否取消,1是,0否"`
+	IsValid           int       `description:"参会报名是否有效 1:是,0"`
+	ChartPermissionId int       `description:"行业Id"`
+}
+
+func GetCygxActivitySpecialTripListinit(condition string, pars []interface{}) (item []*CygxActivitySpecialTripInit, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	t.*,
+	a.chart_permission_id 
+FROM
+	cygx_activity_special_trip AS t
+	INNER JOIN cygx_activity_special AS a ON a.activity_id = t.activity_id 
+WHERE
+	1 = 1 
+	AND is_valid = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}

+ 189 - 0
models/activity_special_trip_bill.go

@@ -0,0 +1,189 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySpecialTripBill struct {
+	Id                  int       `orm:"column(id);pk"`
+	UserId              int       `description:"用户id,多个用,隔开"`
+	ActivityId          int       `description:"活动ID"`
+	CreateTime          time.Time `description:"创建时间"`
+	Mobile              string    `description:"手机号"`
+	Email               string    `description:"邮箱号"`
+	CompanyId           int       `description:"公司ID"`
+	CompanyName         string    `description:"公司名称"`
+	RealName            string    `description:"用户实际名称"`
+	AdminId             int       `description:"销售/管理员ID"`
+	Source              int       `description:"来源,1小程序,2后台添加, 3开发人员手动添加"`
+	BillDetailed        int       `description:"流水明细,判断是进账还是出账"`
+	DoType              int       `description:"操作方式,1报名,2取消报名"`
+	RegisterPlatform    int       `description:"来源 1小程序,2:网页"`
+	ChartPermissionId   int       `description:"行业id"`
+	ChartPermissionName string    `description:"行业名称"`
+	Way                 int       `description:"1报名,取消报名。2到会取消到会 3转正或清零 4取消活动"`
+	Content             string    `description:"内容"`
+	Total               string    `description:"总和"`
+}
+
+// 添加
+func AddCygxActivitySpecialTripBill(item *CygxActivitySpecialTripBill) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	if err != nil {
+		return
+	}
+	return
+}
+
+func GetCygxActivitySpecialTripBill(condition string, pars []interface{}) (item []*CygxActivitySpecialTripBill, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_activity_special_trip_bill  
+			WHERE 1 = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+type CygxActivitySpecialTripBillList struct {
+	Id                  int       `orm:"column(id);pk"`
+	UserId              int       `description:"用户id,多个用,隔开"`
+	ActivityId          int       `description:"活动ID"`
+	CreateTime          time.Time `description:"创建时间"`
+	Mobile              string    `description:"手机号"`
+	Email               string    `description:"邮箱号"`
+	CompanyId           int       `description:"公司ID"`
+	CompanyName         string    `description:"公司名称"`
+	RealName            string    `description:"用户实际名称"`
+	AdminId             int       `description:"销售/管理员ID"`
+	Source              int       `description:"来源,1小程序,2后台添加, 3开发人员手动添加"`
+	BillDetailed        int       `description:"流水明细,判断是进账还是出账"`
+	DoType              int       `description:"操作方式,1报名,2取消报名"`
+	RegisterPlatform    int       `description:"来源 1小程序,2:网页"`
+	ChartPermissionId   int       `description:"行业id"`
+	ChartPermissionName string    `description:"行业名称"`
+	Way                 int       `description:"1报名,取消报名。2到会取消到会 3转正或清零 4取消活动"`
+	Content             string    `description:"内容"`
+}
+
+func GetCygxActivitySpecialTripBillList(condition string, pars []interface{}) (item []*CygxActivitySpecialTripBillList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			b.*
+		FROM
+			cygx_activity_special_trip_bill AS b
+		WHERE
+			1 = 1` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+type SpecialBillInitBig struct {
+	ApprovalTime time.Time
+	CompanyId    int
+	CompanyName  string
+}
+
+func GetActivitySecialTirpBillForInit(packageType int) (item []*SpecialBillInitBig, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+	a.approve_time,d.company_id,c.company_name 
+FROM
+	company_approval a
+	INNER JOIN company_contract b ON a.company_contract_id = b.company_contract_id
+	INNER JOIN company c ON a.company_id = c.company_id
+	INNER JOIN cygx_company_user_type d ON a.company_id = d.company_id
+WHERE
+	a.apply_method = 1 
+	AND a.product_id = 2 
+	AND a.approve_status = '已审批' 
+	AND b.product_id = 2 
+	AND d.package_type = ?
+	GROUP BY d.company_id `
+	_, err = o.Raw(sql, packageType).QueryRows(&item)
+	return
+}
+
+type SpecialBillInitNotBig struct {
+	ApprovalTime       time.Time
+	CompanyId          int
+	CompanyName        string
+	ChartPermissionIds string
+}
+
+func GetActivitySecialTirpBillForInitNotBig() (item []*SpecialBillInitNotBig, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+	a.approve_time,d.company_id,d.company_name,GROUP_CONCAT(DISTINCT c.chart_permission_id) AS chart_permission_ids
+FROM
+	company_approval a
+	INNER JOIN company_contract b ON a.company_contract_id = b.company_contract_id
+	INNER JOIN company_report_permission c ON a.company_id = c.company_id 
+	INNER JOIN company d ON a.company_id = d.company_id
+WHERE
+	a.apply_method = 1 
+	AND a.product_id = 2 
+	AND a.approve_status = '已审批' 
+	AND b.product_id = 2 
+	AND c.product_id = 2
+	AND c.is_upgrade = 1
+	GROUP BY d.company_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+// 批量添加
+func AddCygxActivitySpecialTripBillMulti(items []*CygxActivitySpecialTripBill) (err error) {
+	o := orm.NewOrm()
+	if len(items) > 0 {
+		//批量添加
+		_, err = o.InsertMulti(len(items), items)
+	}
+	return
+}
+
+type SpecialBillInitReduce struct {
+	CreateTime  time.Time
+	CompanyId   int
+	CompanyName string
+}
+
+func GetActivitySecialTirpBillForReduce() (item []*SpecialBillInitReduce, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+	a.create_time,a.company_id,c.company_name 
+FROM
+	company_operation_record a
+	INNER JOIN company c ON a.company_id = c.company_id
+	INNER JOIN company_report_permission e ON a.company_id = e.company_id 
+WHERE
+	a.operation = 'try_out' 
+	AND a.product_id = 2 
+	AND e.status NOT IN ('正式','永续')
+	GROUP BY a.company_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+func GetCygxActivitySpecialTripBillForInit() (item []*CygxActivitySpecialTripBill, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity_special_trip_bill GROUP BY company_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+func GetCygxActivitySpecialTripBillByCompanyIdForInit(companyId int) (item []*CygxActivitySpecialTripBill, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity_special_trip_bill WHERE company_id = ? ORDER BY create_time DESC  `
+	_, err = o.Raw(sql, companyId).QueryRows(&item)
+	return
+}
+
+func UpdateCygxActivitySpecialTripBillByCompanyIdForInit(total string, id int) (err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_activity_special_trip_bill SET total=? WHERE id = ?  `
+	_, err = o.Raw(sql, total, id).Exec()
+	return
+}

+ 82 - 0
models/activity_type.go

@@ -0,0 +1,82 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type ActivityType struct {
+	ActivityTypeId   int    `description:"活动类型id"`
+	ActivityTypeName string `description:"活动类型名称"`
+	//TemplateP        string `description:"活动模板,带P标签"`
+	//Template         string `description:"活动模板"`
+	ShowType     string `description:"人数限制类型,1不展示限制,2可选限制,3强制限制"`
+	IsChoose     bool   `description:"是否选择"`
+	OnlineIco    string `description:"线上线下Ico图标"`
+	ActivityType int    `description:"活动线上线下类型 1线上,0 线下"`
+}
+
+type ActivityTypeListResp struct {
+	List []*ActivityType
+}
+
+// 列表
+func GetActivityTypeList(condition string) (items []*ActivityType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_type WHERE 1= 1  ` + condition + `  ORDER BY sort DESC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetActivityTypeDetailById(activityTypeId int) (item *ActivityType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_type WHERE activity_type_id = ? `
+	err = o.Raw(sql, activityTypeId).QueryRow(&item)
+	return
+}
+
+type ActivityTypeListHomeResp struct {
+	List []*ActivityTypeHome
+}
+
+type ActivityTypeListHomeRespPc struct {
+	List []*ActivityTypeHomePc
+}
+
+type ActivityTypeHome struct {
+	ActivityTypeId   int    `description:"活动类型id"`
+	ActivityTypeName string `description:"活动名称"`
+	ImgUrl           string `description:"图片"`
+	ImgUrlBg         string `description:"背景图片"`
+	ImgUrlBgs        string `description:"背景图片"`
+	Position         int    `description:"位置 ,1:左 ,2:右边"`
+	Resource         int    `description:"位置 ,1:活动 ,2:专项产业调研"`
+	List             []*CygxActivityLabelList
+}
+
+type ActivityTypeHomePc struct {
+	ActivityTypeId   int    `description:"活动类型id"`
+	Resource         int    `description:"位置 ,1:活动 ,2:专项产业调研"`
+	ActivityTypeName string `description:"活动名称"`
+	OnlineIco        string `description:"线上线下Ico图标"`
+	ImgUrlBgPc       string `description:"Pc端背景图片"`
+	List             []*CygxActivityLabelList
+}
+
+// 列表
+func GetActivityTypeHomeList(condition string, pars []interface{}) (items []*ActivityTypeHome, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_type  WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetActivityTypeHomeListPc() (items []*ActivityTypeHomePc, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_type WHERE activity_type_id != 7   ORDER BY sort DESC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 78 - 0
models/activity_user_search_content.go

@@ -0,0 +1,78 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivityUserSearchContent struct {
+	Id                 int       `orm:"column(id);pk"`
+	UserId             int       `description:"用户ID"`
+	CreateTime         time.Time `description:"创建时间"`
+	Mobile             string    `description:"手机号"`
+	Email              string    `description:"邮箱"`
+	CompanyId          int       `description:"公司id"`
+	CompanyName        string    `description:"公司名称"`
+	ModifyTime         time.Time `description:"更新时间"`
+	ChartPermissionids string    `description:"行业id"`
+	ActivityTypeids    string    `description:"活动类型id"`
+	ActiveState        string    `description:"活动进行状态 未开始:1、进行中2、已结束3"`
+	IsShowJurisdiction int       `description:"是否仅展示有权限的,1是,0否"`
+}
+
+//更新搜索信息
+func AddUserSearchContent(item *CygxActivityUserSearchContent, ttlTime time.Duration) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	var count int
+	sql := `SELECT COUNT(1) AS count FROM cygx_activity_user_search_content WHERE user_id=? `
+	err = o.Raw(sql, item.UserId).QueryRow(&count)
+	if err != nil {
+		return
+	}
+	if count > 0 || ttlTime > 0 {
+		sql := `UPDATE cygx_activity_user_search_content SET chart_permissionids = ?,activity_typeids = ?,active_state = ?,is_show_jurisdiction = ? ,modify_time=NOW() WHERE user_id=? `
+		_, err = o.Raw(sql, item.ChartPermissionids, item.ActivityTypeids, item.ActiveState, item.IsShowJurisdiction, item.UserId).Exec()
+		return
+	} else {
+		lastId, err = o.Insert(item)
+	}
+	return
+}
+
+//通过用户ID获取用户搜索条件详情
+func GetUserSearchContentByUid(uid int) (item *CygxActivityUserSearchContent, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_user_search_content WHERE user_id = ? `
+	err = o.Raw(sql, uid).QueryRow(&item)
+	return
+}
+
+type ActivityUserSearchContentList struct {
+	IsShowJurisdiction   bool `description:"是否仅展示有权限的,1是,0否"`
+	ListActivityStaus    []ActivityStaus
+	ListChartPermission  []*ActivityChartPermission
+	ListChartPermission2 []*ActivityChartPermission
+	ListActivityType     []*ActivityType
+}
+
+type ActivityStaus struct {
+	Id         int
+	IsChoose   bool `description:"是否选择"`
+	StatusName string
+}
+
+type Arrayse struct {
+	IsChoose bool
+}

+ 178 - 0
models/activity_video.go

@@ -0,0 +1,178 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type CygxActivityVideo struct {
+	VideoId       int    `orm:"column(video_id);pk"description:"视频id"`
+	VideoName     string `description:"视频名称"`
+	ActivityId    int    ` description:"活动ID"`
+	ModifyDate    string `description:"更新时间"`
+	VideoDuration string `description:"视频时长"`
+	VideoCounts   int    `description:"播放量"`
+	VideoUrl      string `description:"视频地址"`
+	CreateTime    string `description:"创建时间"`
+	BackgroundImg string `description:"封面图片"`
+	ShareImg      string `description:"分享图片"`
+}
+
+type CygxActivityVideoResp struct {
+	VideoId           int    `orm:"column(video_id);pk"description:"视频id"`
+	ChartPermissionId int    `description:"权限id"`
+	VideoName         string `description:"视频名称"`
+	ActivityId        int    ` description:"活动ID"`
+	ModifyDate        string `description:"更新时间"`
+	VideoDuration     string `description:"视频时长"`
+	VideoCounts       int    `description:"播放量"`
+	VideoUrl          string `description:"视频地址"`
+	CreateTime        string `description:"创建时间"`
+	BackgroundImg     string `description:"封面图片"`
+	ShareImg          string `description:"分享图片"`
+}
+
+type CygxActivityVideoReq struct {
+	VideoName     string `description:"视频名称"`
+	VideoDuration string `description:"视频时长"`
+	VideoUrl      string `description:"视频地址"`
+	ActivityId    int    ` description:"活动ID"`
+}
+
+// string `orm:"column(label)";description:"主题"`
+// 活动详情
+type CygxActivityVideoListResp struct {
+	ActivityId    int    `description:"活动ID 等于0新增活动,大于0修改活动"`
+	Id            int    `orm:"column(video_id)";description:"视频id"`
+	Title         string `orm:"column(video_name)";description:"视频名称"`
+	ResourceUrl   string `orm:"column(video_url)";description:"视频地址"`
+	VideoDuration string `description:"视频时长"`
+	ActivityTime  string `description:"活动时间"`
+}
+
+type CygxActivityVideoListRep struct {
+	Paging *paging.PagingItem `description:"分页数据"`
+	List   []*CygxActivityVideoListResp
+}
+
+// 列表
+func GetActivityVideoListAll(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityVideoListResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT art.*,v.video_id,v.video_name,v.video_url,video_duration FROM cygx_activity as art  INNER JOIN cygx_activity_video AS v ON v.activity_id = art.activity_id   WHERE 1= 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+func UpdateActivityVideoCounts(activityId int) (err error) {
+	sql := `UPDATE cygx_activity_video SET video_counts = video_counts+1 WHERE activity_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// GetCygxActivityVideoByActivityId 获取活动视频
+func GetCygxActivityVideoByActivityId(activityId int) (item *CygxActivityVideo, err error) {
+	sql := `SELECT * FROM cygx_activity_video WHERE activity_id = ? LIMIT 1 `
+	err = orm.NewOrm().Raw(sql, activityId).QueryRow(&item)
+	return
+}
+
+// GetCygxActivityVideoByActivityId 获取活动视频
+func GetCygxActivityVideoReqByActivityId(activityId int) (item *CygxActivityVideoReq, err error) {
+	sql := `SELECT * FROM cygx_activity_video WHERE video_id = ? LIMIT 1 `
+	err = orm.NewOrm().Raw(sql, activityId).QueryRow(&item)
+	return
+}
+
+// GetCygxActivityVideoById 获取活动视频
+func GetCygxActivityVideoById(videoId int) (item *CygxActivityVideo, err error) {
+	sql := `SELECT * FROM cygx_activity_video WHERE video_id = ? LIMIT 1 `
+	err = orm.NewOrm().Raw(sql, videoId).QueryRow(&item)
+	return
+}
+
+// 列表
+func GetActivityVideoList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityVideoResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	v.*,art.chart_permission_id
+FROM
+	cygx_activity_video AS v 
+	INNER JOIN cygx_activity as art ON art.activity_id = v.activity_id    WHERE 1= 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 获取所有活动视频ID
+func GetActivityVideoActivityIds() (activityIds string, err error) {
+	sql := `SELECT
+				GROUP_CONCAT( DISTINCT a.activity_id SEPARATOR ',' ) AS activityids 
+			FROM
+				cygx_activity_video AS a `
+	o := orm.NewOrm()
+	err = o.Raw(sql).QueryRow(&activityIds)
+	return
+}
+
+type CygxActivityVideoDetailResp struct {
+	ActivityId          int    ` description:"活动ID"`
+	Id                  int    `description:"视频ID"`
+	Title               string `description:"标题"`
+	ResourceUrl         string `description:"链接"`
+	BackgroundImg       string `description:"背景图"`
+	PlaySeconds         int    `description:"音视频时长"`
+	ChartPermissionId   int    `description:"行业ID"`
+	ChartPermissionName string `description:"行业名称"`
+	Type                int    `description:"类型: 1-音频; 2-活动视频; 3-产业视频 、 4-系列问答视频"`
+}
+
+// GetCygxActivityVideoById 获取活动视频
+func GetCygxActivityVideoByActivityIdInfo(activityId int) (item *CygxActivityVideoDetailResp, err error) {
+	sql := `SELECT
+			v.video_id AS id,
+			v.video_name AS title,
+			v.video_url AS resource_url,
+			v.video_duration AS play_seconds,
+			v.activity_id,
+			a.chart_permission_id,
+			a.chart_permission_name
+		FROM
+			cygx_activity_video AS v
+			INNER JOIN cygx_activity AS a  ON  v.activity_id = a.activity_id
+		WHERE
+			 v.activity_id = ? 
+			LIMIT 1 `
+	err = orm.NewOrm().Raw(sql, activityId).QueryRow(&item)
+	return
+}
+
+func UpdateActivityVideoCommentNum(activityId int) (err error) {
+	sql := `UPDATE cygx_activity_video SET comment_num = comment_num+1 WHERE activity_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// 修改
+func UpdateCygxActivityVideo(item *CygxActivityVideo) (err error) {
+	to := orm.NewOrm()
+	updateParams := make(map[string]interface{})
+	updateParams["BackgroundImg"] = item.BackgroundImg
+	updateParams["ShareImg"] = item.ShareImg
+	ptrStructOrTableName := "cygx_activity_video"
+	whereParam := map[string]interface{}{"activity_id": item.ActivityId}
+	qs := to.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams)
+	return
+}

+ 73 - 0
models/activity_video_history.go

@@ -0,0 +1,73 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivityVideoHistory struct {
+	Id               int       `orm:"column(id);pk"description:"音频id"`
+	VideoId          int       `description:"微路演音频id"`
+	ActivityId       int       `description:"活动id"`
+	UserId           int       `description:"用户id"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司Id"`
+	CompanyName      string    `description:"公司名称"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	PlaySeconds      string    `description:"播放时间 单位s"`
+	CreateTime       time.Time `description:"视频创建时间"`
+	ModifyTime       time.Time `description:"视频修改时间"`
+	RegisterPlatform int       // 来源 1小程序,2:网页
+}
+
+// 添加
+func AddCygxActivityVideoHistory(item *CygxActivityVideoHistory) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+// 获取列表信息根据手机号分组
+func GetActivityVideoHistoryByMobileList(condition string) (items []*CygxActivityVideoHistory, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_video_history  WHERE 1 =1  ` + condition + `  GROUP BY user_id  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 修改用户浏览活动视频的相关信息
+func UpdateCygxActivityVideoHistory(wxUser *WxUserItem) (err error) {
+	o := orm.NewOrm()
+	var sql string
+	if wxUser.Mobile != "" {
+		sql = `UPDATE cygx_activity_video_history SET email=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE mobile=? `
+		_, err = o.Raw(sql, wxUser.Email, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Mobile).Exec()
+	} else if wxUser.Email != "" {
+		sql = `UPDATE cygx_activity_video_history SET mobile=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE email=? `
+		_, err = o.Raw(sql, wxUser.Mobile, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Email).Exec()
+	}
+	return
+}
+
+func GetLastCygxActivityVideoHistory(activityId, userId int) (item *CygxActivityVoiceHistory, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity_video_history WHERE activity_id=?  AND user_id=? AND register_platform = 1 ORDER BY create_time DESC limit 1 `
+	err = o.Raw(sql, activityId, userId).QueryRow(&item)
+	return
+}
+
+//func UpdateLastCygxActivityVideoHistory(playSeconds string, lastId int) (err error) {
+//	o := orm.NewOrm()
+//	sql := ` UPDATE cygx_micro_roadshow_video_history SET play_seconds =? WHERE id=? `
+//	_, err = o.Raw(sql, playSeconds, lastId).Exec()
+//	return
+//}
+
+func UpdateLastCygxActivityVideoHistory(playSeconds string, lastId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_activity_video_history SET play_seconds = play_seconds +? WHERE id=? `
+	_, err = o.Raw(sql, playSeconds, lastId).Exec()
+	return
+}

+ 154 - 0
models/activity_voice.go

@@ -0,0 +1,154 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+// ActivityVoice 活动语音表结构体
+type CygxActivityVoice struct {
+	ActivityVoiceId  int       `orm:"column(activity_voice_id);pk" description:"活动音频ID"`
+	ActivityId       int       ` description:"活动ID"`
+	VoiceUrl         string    `description:"音频地址"`
+	VoiceName        string    `description:"音频名称"`
+	VoicePlaySeconds string    `description:"音频时长"`
+	VoiceCounts      int       `description:"播放量"`
+	ModifyTime       string    `description:"更新时间"`
+	CreateTime       time.Time `description:"创建时间"`
+	BackgroundImg    string    `description:"封面图片"`
+	ShareImg         string    `description:"分享图片"`
+}
+
+// ActivityVoice 活动语音表结构体
+type CygxActivityVoiceResp struct {
+	ActivityVoiceId     int    `orm:"column(activity_voice_id);pk" description:"活动音频ID"`
+	ActivityId          int    ` description:"活动ID"`
+	VoiceUrl            string `description:"音频地址"`
+	VoiceName           string `description:"音频名称"`
+	VoicePlaySeconds    string `description:"音频时长"`
+	VoiceCounts         int    `description:"播放量"`
+	ModifyTime          string `description:"更新时间"`
+	CreateTime          string `description:"创建时间"`
+	ChartPermissionId   int    `description:"权限id"`
+	ChartPermissionName string `description:"行业名称"`
+	ActivityTime        string `description:"活动时间"`
+	BackgroundImg       string `description:"封面图片"`
+	ShareImg            string `description:"分享图片"`
+}
+
+// ActivityVoiceReq 音频数据
+type CygxActivityVoiceReq struct {
+	ActivityId      int    ` description:"活动ID"`
+	ActivityVoiceId int    ` description:"音频ID"`
+	Url             string `description:"音频资源url地址"`
+	Name            string `description:"音频名称"`
+	PlaySeconds     int    `description:"音频时长"`
+}
+
+// GetCygxActivityVoiceReqList 获取活动ID的音频
+func GetCygxActivityVoiceReqList(activityIds []int) (items []*CygxActivityVoiceReq, err error) {
+	lenactivityIds := len(activityIds)
+	if lenactivityIds == 0 {
+		return
+	}
+	//活动音频,设置有效时间为30天,失效后该活动就不再支持音频回放。有效期起始时间为活动的开始时间
+	//endTime := time.Now().AddDate(0, 0, -30).Format("2006-01-02 15:04:05")
+	sql := `SELECT
+			v.activity_id,
+			v.activity_voice_id,
+			v.voice_url AS url,
+			v.voice_name AS name,
+			v.voice_play_seconds AS play_seconds 
+		FROM
+			cygx_activity_voice AS v
+			INNER JOIN cygx_activity AS a ON a.activity_id = v.activity_id 
+		WHERE
+			1 = 1 	 AND  v.activity_id IN (` + utils.GetOrmInReplace(lenactivityIds) + `)  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityIds).QueryRows(&items)
+	return
+}
+
+func UpdateCygxActivityVoiceCounts(activityId int) (err error) {
+	sql := `UPDATE cygx_activity_voice SET voice_counts = voice_counts+1 WHERE activity_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// GetCygxActivityVoiceById 主键获取活动音频
+func GetCygxActivityVoiceById(videoId int) (item *CygxActivityVoice, err error) {
+	sql := `SELECT * FROM cygx_activity_voice WHERE activity_voice_id = ? LIMIT 1`
+	err = orm.NewOrm().Raw(sql, videoId).QueryRow(&item)
+	return
+}
+
+// 列表
+func GetActivityVoiceListAll(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityVideoListResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT art.*  FROM cygx_activity as art  INNER JOIN cygx_activity_voice AS v ON v.activity_id = art.activity_id   WHERE 1= 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// GetCygxActivityVoiceByActivityId 主键获取活动音频
+func GetCygxActivityVoiceByActivityId(activityId int) (item *CygxActivityVoice, err error) {
+	sql := `SELECT * FROM cygx_activity_voice WHERE activity_id = ? LIMIT 1`
+	err = orm.NewOrm().Raw(sql, activityId).QueryRow(&item)
+	return
+}
+
+// 列表
+func GetActivityVoiceList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxActivityVoiceResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	v.*,art.chart_permission_id,art.activity_time
+FROM
+	cygx_activity_voice AS v 
+	INNER JOIN cygx_activity as art ON art.activity_id = v.activity_id    WHERE 1= 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 获取所有活动音频ID
+func GetActivityVoiceActivityIds() (activityIds string, err error) {
+	sql := `SELECT
+				GROUP_CONCAT( DISTINCT a.activity_id SEPARATOR ',' ) AS activityids 
+			FROM
+				cygx_activity_voice AS a `
+	o := orm.NewOrm()
+	err = o.Raw(sql).QueryRow(&activityIds)
+	return
+}
+
+func UpdateActivityVoiceCommentNum(activityId int) (err error) {
+	sql := `UPDATE cygx_activity_voice SET comment_num = comment_num+1 WHERE activity_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// 修改
+func UpdateCygxActivityVoice(item *CygxActivityVoice) (err error) {
+	to := orm.NewOrm()
+	updateParams := make(map[string]interface{})
+	updateParams["BackgroundImg"] = item.BackgroundImg
+	updateParams["ShareImg"] = item.ShareImg
+	ptrStructOrTableName := "cygx_activity_voice"
+	whereParam := map[string]interface{}{"activity_id": item.ActivityId}
+	qs := to.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams)
+	return
+}

+ 65 - 0
models/activity_voice_history.go

@@ -0,0 +1,65 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivityVoiceHistory struct {
+	Id               int       `orm:"column(id);pk"`
+	ActivityId       int       `description:"活动ID"`
+	UserId           int       `description:"用户ID"`
+	CreateTime       time.Time `description:"创建时间"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	PlaySeconds      string    `description:"播放时间 单位s"`
+	ModifyTime       time.Time `description:"视频修改时间"`
+	RegisterPlatform int       // 来源 1小程序,2:网页
+}
+
+// 添加
+func AddCygxActivityVoiceHistory(item *CygxActivityVoiceHistory) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+func GetLastCygxActivityVoiceHistory(activityId, userId int) (item *CygxActivityVoiceHistory, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity_voice_history WHERE activity_id=?  AND user_id=? AND register_platform = 1 ORDER BY create_time DESC limit 1 `
+	err = o.Raw(sql, activityId, userId).QueryRow(&item)
+	return
+}
+
+func UpdateLastCygxActivityVoiceHistory(playSeconds string, lastId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_activity_voice_history SET play_seconds = play_seconds +? WHERE id=? `
+	_, err = o.Raw(sql, playSeconds, lastId).Exec()
+	return
+}
+
+// 获取列表信息根据手机号分组
+func GetActivityVoiceHistoryByMobileList(condition string) (items []*CygxActivityVoiceHistory, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_activity_voice_history  WHERE 1 =1  ` + condition + `  GROUP BY user_id  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 修改用户浏览活动音频的相关信息
+func UpdateCygxActivityVoiceHistory(wxUser *WxUserItem) (err error) {
+	o := orm.NewOrm()
+	var sql string
+	if wxUser.Mobile != "" {
+		sql = `UPDATE cygx_activity_voice_history SET email=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE mobile=? `
+		_, err = o.Raw(sql, wxUser.Email, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Mobile).Exec()
+	} else if wxUser.Email != "" {
+		sql = `UPDATE cygx_activity_voice_history SET mobile=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE email=? `
+		_, err = o.Raw(sql, wxUser.Mobile, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Email).Exec()
+	}
+	return
+}

+ 113 - 0
models/admin.go

@@ -0,0 +1,113 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type AdminMobileResp struct {
+	Mobile string `description:"手机号"`
+}
+
+// 获取销售所能查看到的手机号
+func GetAdminByRole() (items []*AdminMobileResp, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT mobile  FROM admin  WHERE role = 'admin' `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+type Admin struct {
+	AdminId                   int    `orm:"column(admin_id);pk" description:"系统用户id"`
+	AdminName                 string `description:"系统用户名称"`
+	AdminAvatar               string `description:"用户头像"`
+	RealName                  string `description:"系统用户姓名"`
+	Password                  string `json:"-"`
+	LastUpdatedPasswordTime   string `json:"-"`
+	Enabled                   int
+	Email                     string `description:"系统用户邮箱"`
+	LastLoginTime             string
+	CreatedTime               time.Time
+	LastUpdatedTime           string
+	Role                      string    `description:"系统用户角色"`
+	Mobile                    string    `description:"手机号"`
+	RoleType                  int       `description:"角色类型:1需要录入指标,0:不需要"`
+	RoleId                    int       `description:"角色ID"`
+	RoleName                  string    `description:"角色名称"`
+	RoleTypeCode              string    `description:"角色类型编码"`
+	DepartmentId              int       `description:"部门id"`
+	DepartmentName            string    `description:"部门名称"`
+	GroupId                   int       `description:"分组id"`
+	GroupName                 string    `description:"分组名称"`
+	Authority                 int       `description:"管理权限,0:无,1:部门负责人,2:小组负责人,或者ficc销售主管,4:ficc销售组长"`
+	Position                  string    `description:"职位"`
+	DisableTime               time.Time `description:"禁用时间"`
+	ChartPermission           int8      `description:"图表权限id"`
+	OpenId                    string    `description:"弘则部门公众号的openid"`
+	UnionId                   string    `description:"微信公众平台唯一标识"`
+	EdbPermission             int8      `description:"指标库操作权限,0:只能操作 自己的,1:所有指标可操作"`
+	MysteelChemicalPermission int8      `description:"钢联化工指标操作权限,0:只能操作 自己的,1:所有指标可操作"`
+	PredictEdbPermission      int8      `description:"预测指标库操作权限,0:只能操作 自己的,1:所有预测指标可操作"`
+	Province                  string    `description:"省"`
+	ProvinceCode              string    `description:"省编码"`
+	City                      string    `description:"市"`
+	CityCode                  string    `description:"市编码"`
+}
+
+func GetSysAdminById(adminId int) (item *Admin, err error) {
+	sql := `SELECT * FROM admin WHERE admin_id=? `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, adminId).QueryRow(&item)
+	return
+}
+
+func GetSysAdminByMobile(mobile string) (item *Admin, err error) {
+	sql := `SELECT * FROM admin WHERE mobile=? LIMIT 1 `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, mobile).QueryRow(&item)
+	return
+}
+
+// 获取权益内部人员手机号
+func GetRaiAdmin() (items []*AdminMobileResp, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT
+	mobile
+FROM
+	admin 
+WHERE
+	role_type_code LIKE '%rai%' 
+	AND group_id NOT IN ( 19, 10 ) 
+	AND enabled = 1 
+	OR (
+	department_name = '产品技术部' 
+	AND enabled = 1) `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+type GetSellerUserMobileResp struct {
+	Mobile string `description:"手机号"`
+	UserId int    `description:"用户ID"`
+}
+
+// 获取销售所能查看到的手机号
+func GetSellerUserMobile(adminId int) (items []*GetSellerUserMobileResp, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT mobile FROM user_seller_relation WHERE seller_id  = ? `
+	_, err = o.Raw(sql, adminId).QueryRows(&items)
+	return
+}
+
+// GetUserSellerRelationUserList 获取跟销售绑定了关系的权益用户
+func GetUserSellerRelationUserList() (items []*GetSellerUserMobileResp, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT
+			a.user_id 
+		FROM
+			user_seller_relation AS a
+			INNER JOIN company_product AS b ON b.company_id = a.company_id 
+			AND b.product_id = 2 `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 32 - 0
models/advice.go

@@ -0,0 +1,32 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxAdvice struct {
+	AdviceId      int       `orm:"column(advice_id);pk" description:"优化建议id"`
+	UserId        int       `description:"用户id"`
+	UserRealName  string    `description:"姓名"`
+	CompanyId     int       `description:"公司id"`
+	CompanyName   string    `description:"公司名称"`
+	SalesRealName string    `description:"所属销售"`
+	Advice        string    `description:"优化建议"`
+	AdviceImgUrl  string    `description:"图片,多张用#分割"`
+	CreateTime    time.Time `description:"提交建议时间"`
+	Mobile        string    `description:"手机号"`
+	Email         string    `description:"邮箱"`
+}
+
+//添加优化建议
+func AddCygxAdvice(item *CygxAdvice) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type AddCygxAdviceReq struct {
+	Advice       string `description:"优化建议"`
+	AdviceImgUrl string `description:"图片,多张用#分割"`
+}

+ 77 - 0
models/apply_collection.go

@@ -0,0 +1,77 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CollectionBannerResp struct {
+	Title             string `description:"标题"`
+	IndexImg          string `description:"小程序封面图"`
+	Path              string `description:"小程序路径"`
+	IsShowSustainable bool   `description:"是否展示限免标签"`
+}
+
+type CollectionBannerListResp struct {
+	ListA []*CollectionBannerResp
+	ListB *CollectionBannerResp
+}
+
+type CollectionDetailResp struct {
+	HttpUrl string `description:"跳转地址"`
+}
+
+type ApplyCollectionReq struct {
+	Content string `description:"内容"`
+}
+
+// 精选看板申请表
+type CygxApplyCollection struct {
+	ApplyCollectionId int       `orm:"column(apply_collection_id);pk" description:"主键ID"`
+	UserId            int       `description:"用户ID"`         // 用户ID
+	Mobile            string    `description:"手机号"`          // 手机号
+	Email             string    `description:"邮箱"`           // 邮箱
+	CompanyId         int       `description:"公司ID"`         // 公司ID
+	CompanyName       string    `description:"公司名称"`         // 公司名称
+	RealName          string    `description:"用户实际名称"`       // 用户实际名称
+	SellerName        string    `description:"所属销售"`         // 所属销售
+	CreateTime        time.Time `description:"创建时间"`         // 创建时间
+	ModifyTime        time.Time `description:"修改时间"`         // 修改时间
+	RegisterPlatform  int       `description:"来源 1小程序,2:网页"` // 来源 1小程序,2:网页
+	Content           string    `description:" 内容"`          // 内容
+}
+
+// 精选看板申请表
+type CygxApplyCollectionResp struct {
+	ApplyCollectionId int       `gorm:"column:"`
+	UserId            int       `gorm:"column:"`                    // 用户ID
+	Mobile            string    `gorm:"column:"`                    // 手机号
+	Email             string    `gorm:"column:"`                    // 邮箱
+	CompanyId         int       `gorm:"column:;default:0"`          // 公司ID
+	CompanyName       string    `gorm:"column:"`                    // 公司名称
+	RealName          string    `gorm:"column:"`                    // 用户实际名称
+	SellerName        string    `gorm:"column:"`                    // 所属销售
+	CreateTime        time.Time `gorm:"column:"`                    // 创建时间
+	ModifyTime        time.Time `gorm:"column:"`                    // 修改时间
+	RegisterPlatform  int       `gorm:"column:;default:1;NOT NULL"` // 来源 1小程序,2:网页
+	Content           string    `gorm:"column:;NOT NULL"`           // 内容
+}
+
+// 添加信息
+func AddCygxApplyCollection(item *CygxApplyCollection) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 通过ID获取详情
+func GetCygxApplyCollectionDetail(applyCollectionId int) (item *CygxApplyCollectionResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_apply_collection  WHERE apply_collection_id=?  `
+	err = o.Raw(sql, applyCollectionId).QueryRow(&item)
+	return
+}
+
+type CygxApplyCollectionDetailResp struct {
+	Detail *CygxApplyCollectionResp
+}

+ 99 - 0
models/apply_record.go

@@ -0,0 +1,99 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxApplyRecord struct {
+	ApplyRecordId       int       `orm:"column(apply_record_id);pk" description:"申请试用id"`
+	UserId              int       `description:"用户ID"`
+	BusinessCardUrl     string    `description:"名片地址"`
+	RealName            string    `description:"姓名"`
+	CompanyName         string    `description:"公司名称"`
+	CompanyIdPay        int       `description:"已付费客户公司id"`
+	CompanyIdType       int       `description:"用户状态,1:潜在客户 、2:现有客户 、3:FICC客户 、4:现有客户(正式,无对应权限) 、5:现有客户(试用,无对应权限)  、6:现有客户(试用暂停) 、7:现有客户(冻结) 、8:现有客户(流失) "`
+	CompanyNamePay      string    `description:"公司名称"`
+	Mobile              string    `description:"手机号"`
+	CreateTime          time.Time `description:"创建时间"`
+	ApplyMethod         int       `description:"1:已付费客户申请试用,2:非客户申请试用"`
+	RegisterPlatform    int       `description:"来源 1小程序,2:网页"`
+	InviteCompanySource int       `description:"来源 1小程序,2:网页"`
+	SourceId            int       `description:"资源ID"`
+	Source              string    `description:"资源类型 报告 :article 、图表 :newchart、微路演 :roadshow、活动 :activity、活动视频:activityvideo、活动音频:activityvoice、专项调研活动:activityspecial"`
+	Title               string    `description:"标题"`
+}
+
+type CygxApplyRecordResp struct {
+	ApplyRecordId       int       `orm:"column(apply_record_id);pk" description:"申请试用id"`
+	UserId              int       `description:"用户ID"`
+	BusinessCardUrl     string    `description:"名片地址"`
+	RealName            string    `description:"姓名"`
+	CompanyName         string    `description:"公司名称"`
+	CompanyIdPay        int       `description:"已付费客户公司id"`
+	CompanyIdType       int       `description:"用户状态,1:潜在客户 、2:现有客户 、3:FICC客户 、4:现有客户(正式,无对应权限) 、5:现有客户(试用,无对应权限)  、6:现有客户(试用暂停) 、7:现有客户(冻结) 、8:现有客户(流失) "`
+	CompanyNamePay      string    `description:"公司名称"`
+	Mobile              string    `description:"手机号"`
+	CreateTime          time.Time `description:"创建时间"`
+	ApplyMethod         int       `description:"1:已付费客户申请试用,2:非客户申请试用"`
+	RegisterPlatform    int       `description:"来源 1小程序,2:网页"`
+	InviteCompanySource int       `description:"三方来源 ,1:弘则本身,2:络町"`
+	ApplicationSource   string    `description:"申请来源"`
+}
+
+func AddApplyRecord(item *CygxApplyRecord) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			o.Rollback()
+		} else {
+			o.Commit()
+		}
+	}()
+	_, err = o.Insert(item)
+	if err != nil {
+		return
+	}
+
+	ow := orm.NewOrmUsingDB("weekly_report")
+	msql := `UPDATE  wx_user
+		SET
+		  note = ?,
+		  is_note = 1,
+		  apply_method = ?,
+          real_name=?,
+		  mobile=?
+		WHERE user_id = ? `
+	_, err = ow.Raw(msql, item.CompanyName, item.ApplyMethod, item.RealName, item.Mobile, item.UserId).Exec()
+	return
+}
+
+func GetApplyRecordCount(userId int) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM cygx_apply_record WHERE user_id=? AND status=0 `
+	err = o.Raw(sql, userId).QueryRow(&count)
+	return
+}
+
+// 通过手机号获取详情
+func GetCygxApplyRecordByMobile(mobile string) (item *CygxApplyRecord, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_apply_record   WHERE mobile=? AND status=0   ORDER BY apply_record_id DESC   LIMIT 1 `
+	err = o.Raw(sql, mobile).QueryRow(&item)
+	return
+}
+
+// 通过ID获取详情
+func GetCygxApplyRecordById(applyRecordId int) (item *CygxApplyRecordResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_apply_record  WHERE apply_record_id=?  `
+	err = o.Raw(sql, applyRecordId).QueryRow(&item)
+	return
+}
+
+type CygxApplyRecordDetialResp struct {
+	Detail *CygxApplyRecordResp
+}

+ 959 - 0
models/article.go

@@ -0,0 +1,959 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+type CygxArticle struct {
+	Id               int    `orm:"column(id);pk"`
+	ArticleId        int    `description:"文章id"`
+	Title            string `description:"标题"`
+	TitleEn          string `description:"英文标题 "`
+	UpdateFrequency  string `description:"更新周期"`
+	CreateDate       string `description:"创建时间"`
+	PublishDate      string `description:"发布时间"`
+	Body             string `description:"内容"`
+	BodyText         string `description:"内容"`
+	Abstract         string `description:"摘要"`
+	CategoryName     string `description:"一级分类"`
+	SubCategoryName  string `description:"二级分类"`
+	PublishStatus    int    `description:"发布状态"`
+	CategoryId       int    `description:"分类id"`
+	CategoryIdTwo    int    `description:"分类id用作修改匹配类型使用"`
+	ExpertBackground string `description:"专家背景"`
+	ExpertNumber     string `description:"专家编号"`
+	InterviewDate    string `description:"访谈日期"`
+	Department       string `description:"作者"`
+	ArticleIdMd5     string `description:"ID,md5值"`
+	IsClass          int    `description:"是否归类,1是,0否"`
+	IsSummary        int    `description:"是否是纪要库,1是,0否"`
+	IsReport         int    `description:"是否属于报告,1是,0否"`
+	ReportType       int    `description:"报告类型,1行业报告,2产业报告,0无"`
+	FileLink         string `description:"下载预览链接"`
+	MatchTypeName    string `description:"匹配类型"`
+	Periods          string `description:"期数"`
+	ReportLink       string `description:"报告链接"`
+	ArticleType      string `description:"文章类型 文章类型,lyjh:路演精华 "`
+	HavePublish      int    `description:"是否发布过,1是 ,0 否"`
+	Source           int    `description:"来源 0策略平台同步,1小程序后台添加"`
+	SellerAndMobile  string `description:"销售和手机号"`
+	VideoUrl         string `description:"音频文件URL"`
+	VideoName        string `description:"音频文件名称"`
+	VideoPlaySeconds string `description:"音频播放时长"`
+	Stock            string `description:"个股标签"`
+	FieldName        string `description:"产业标签"`
+	Annotation       string `description:"核心观点"`
+	TypeName         string `description:"策略平台报告类型"`
+	ModifyTimeByCl   string `description:"策略平台报告更新时间"`
+	CeLueFieldId     int    `description:"策略平台领域ID"`
+	Cover            string `description:"封面图片"`
+}
+
+type CygxArticleEs struct {
+	Id               int    `orm:"column(id);pk"`
+	ArticleId        int    `description:"文章id"`
+	Title            string `description:"标题"`
+	TitleEn          string `description:"英文标题 "`
+	UpdateFrequency  string `description:"更新周期"`
+	CreateDate       string `description:"创建时间"`
+	PublishDate      string `description:"发布时间"`
+	Body             string `description:"内容"`
+	BodyText         string `description:"内容"`
+	Abstract         string `description:"摘要"`
+	CategoryName     string `description:"一级分类"`
+	SubCategoryName  string `description:"二级分类"`
+	PublishStatus    int    `description:"发布状态"`
+	CategoryId       string `description:"分类id"`
+	ExpertBackground string `description:"专家背景"`
+	ExpertNumber     string `description:"专家编号"`
+	InterviewDate    string `description:"访谈日期"`
+	Department       string `description:"作者"`
+	ArticleIdMd5     string `description:"ID,md5值"`
+	IsClass          int    `description:"是否归类,1是,0否"`
+	IsSummary        bool   `description:"是否是纪要库,1是,0否"`
+	IsReport         bool   `description:"是否属于报告,1是,0否"`
+	ReportType       int    `description:"报告类型,1行业报告,2产业报告,0无"`
+	FileLink         string `description:"下载预览链接"`
+	MatchTypeName    string `description:"匹配类型"`
+}
+
+type CygxArticleIdReq struct {
+	ArticleId int `description:"文章id"`
+}
+
+// 新增文章
+func AddCygxArticle(item *CygxArticle) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type HomeArticle struct {
+	ArticleId           int                  `description:"文章id"`
+	Title               string               `description:"标题"`
+	TitleEn             string               `description:"英文标题 "`
+	UpdateFrequency     string               `description:"更新周期"`
+	CreateDate          string               `description:"创建时间"`
+	PublishDate         string               `description:"发布时间"`
+	Body                string               `description:"内容"`
+	BodyHtml            string               `description:"内容带有HTML标签"`
+	Abstract            string               `description:"摘要"`
+	CategoryName        string               `description:"一级分类"`
+	SubCategoryName     string               `description:"二级分类"`
+	ExpertBackground    string               `description:"专家背景"`
+	IsResearch          bool                 `description:"是否属于研选"`
+	Pv                  int                  `description:"PV"`
+	ImgUrlPc            string               `description:"图片链接"`
+	CategoryId          string               `description:"文章分类"`
+	HttpUrl             string               `description:"文章链接跳转地址"`
+	IsNeedJump          bool                 `description:"是否需要跳转链接地址"`
+	Source              int                  `description:"来源  1:文章, 2:图表"`
+	Annotation          string               `description:"核心观点"`
+	HomeType            int                  `description:"数据类型:0-纪要(默认); 1-微路演音频"`
+	MicroAudio          *MicroAudioUnionList `description:"微路演音频"`
+	ChartPermissionName string               `description:"权限名称"`
+	ArticleTypeName     string               `description:"权限名称"`
+	IsReport            int                  `description:"是否属于报告,1是,0否"`
+	ArticleResponse     int                  `description:"报告类型 0:啥也不是,1研选报告,2:研选纪要,3:研选沙龙,4;研选观点"`
+	Readnum             int                  `description:"阅读数量"`
+	Cover               string               `description:"封面图片"`
+	BodyHighlight       []string             `description:"搜索高亮展示结果"`
+	ArticleTypeId       int                  `description:"文章类型ID"`
+	List                []*IndustrialManagementIdInt
+}
+
+type ArticleDetail struct {
+	ArticleId                int    `description:"报告id"`
+	Title                    string `description:"标题"`
+	TitleEn                  string `description:"英文标题 "`
+	UpdateFrequency          string `description:"更新周期"`
+	CreateDate               string `description:"创建时间"`
+	PublishDate              string `description:"发布时间"`
+	Body                     string `description:"内容"`
+	Abstract                 string `description:"摘要"`
+	CategoryName             string `description:"一级分类"`
+	SubCategoryName          string `description:"二级分类"`
+	IsCollect                bool   `description:"是否收藏:true,已收藏,false:未收藏"`
+	IsInterviewApply         bool   `description:"是否申请访谈:true,已申请,false:未申请"`
+	BodyText                 string `description:"内容"`
+	InterviewApplyStatus     string `description:"当前访谈申请状态:'待邀请','待访谈','已完成','已取消'"`
+	InterviewDate            string `description:"访谈时间"`
+	ExpertBackground         string `description:"专家背景"`
+	ExpertNumber             string `description:"专家编号"`
+	Department               string `description:"作者"`
+	SellerMobile             string `description:"销售手机号"`
+	SellerName               string `description:"销售名称"`
+	ArticleIdMd5             string `description:"纪要id"`
+	IsClass                  int    `description:"是否归类,1是,0否"`
+	CategoryId               int    `description:"分类ID"`
+	IsSummary                int    `description:"是否是纪要库,1是,0否"`
+	IsReport                 int    `description:"是否属于报告,1是,0否"`
+	IsResearch               bool   `description:"是否属于研选"`
+	FileLink                 string `description:"下载预览链接"`
+	SellerAndMobile          string `description:"销售和手机号"`
+	IsFollow                 bool   `description:"是否关注,1是,0否"`
+	IsBelongSummary          bool   `description:"是否属于纪要库"`
+	IsBelongReport           bool   `description:"是否属于报告"`
+	FollowNum                int    `description:"关注数量"`
+	CollectionNum            int    `description:"收藏数量"`
+	DepartmentId             int    `description:"作者ID"`
+	DepartmentImgUrl         string `description:"作者头像"`
+	NickName                 string `description:"作者昵称"`
+	SubjectIds               string `description:"文章关联标的的ID字符串"`
+	IndustrialAndSubjectIds  string `description:"文章关联产业和标的的ID字符串"`
+	IndustrialManagementId   int    `description:"文章关联产业ID"`
+	SellerList               []*SellerRep
+	HttpUrl                  string `description:"文章链接跳转地址"`
+	IsNeedJump               bool   `description:"是否需要跳转链接地址"`
+	ReportLink               string `description:"报告链接"`
+	IsShowLinkButton         int    `description:"这种报告类型是否展示查看报告链接"`
+	ArticleTypeId            int    `description:"文章类型ID"`
+	IsSpecialArticle         bool   `description:"是否属于专项调研报告"`
+	Annotation               string `description:"核心观点"`
+	IsShowFollowButton       bool   `description:"是否展示关注取关按钮"`
+	IsFollowButton           bool   `description:"是否关注"`
+	IsRoadShow               bool   `description:"是否是路演精华"`
+	ReportType               int    `description:"报告类型,1行业报告,2产业报告,0无"`
+	FieldName                string `description:"策略平台的领域字段名称"`
+	TypeName                 string `description:"策略平台类型字段名称"`
+	IsApplyAppointmentExpert bool   `description:"是否属于专家访谈"`
+	ArticleTypeName          string `description:"权限名称"`
+	MatchTypeName            string `description:"匹配类型"`
+	Stock                    string `description:"个股标签"`
+	Frequency                string `description:"更新周期(策略平台字段)"`
+}
+
+type ArticleDetailFileLink struct {
+	FileLink string `description:"下载预览链接"`
+	Scene    string `description:"资源参数"`
+}
+type SellerRep struct {
+	SellerMobile string `description:"销售手机号"`
+	SellerName   string `description:"销售名称"`
+}
+
+func GetArticleDetailById(articleId int) (item *ArticleDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article WHERE article_id = ?  AND publish_status = 1  `
+	err = o.Raw(sql, articleId).QueryRow(&item)
+	return
+}
+
+func GetSellerList(articleId int) (items []*SellerRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+		au.mobile as  seller_mobile,
+		au.name as  seller_name
+		FROM
+		cygx_article_author AS au
+		WHERE article_id = ?`
+	_, err = o.Raw(sql, articleId).QueryRows(&items)
+	return
+}
+
+func GetArticleDetailByIdMd5(articleIdMd5 string) (item *ArticleDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article WHERE article_id_md5 = ? `
+	err = o.Raw(sql, articleIdMd5).QueryRow(&item)
+	return
+}
+
+func GetArticleDetailByIdStr(articleIdStr string) (items []*ArticleDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT 	art.*,d.nick_name FROM
+			cygx_article AS art
+			LEFT JOIN cygx_article_department AS d ON d.department_id = art.department_id  WHERE article_id IN(` + articleIdStr + `) `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetArticlePermission(companyId int) (item *ChartPermission, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			a.chart_permission_name as  permission_name
+			FROM
+			cygx_report_mapping AS a
+			WHERE
+			a.category_id = ? LIMIT  1 `
+	err = o.Raw(sql, companyId).QueryRow(&item)
+	//_, err = o.Raw(sql, companyId).QueryRows(&item)
+	return
+}
+
+type ArticleDetailResp struct {
+	Detail           *ArticleDetail
+	HasPermission    int    `description:"1:有该行业权限,正常展示,2:无该行业权限,不存在权益客户下,3:无该品类权限,已提交过申请,4:无该行业权限,未提交过申请,5:潜在客户,未提交过申请,6:潜在客户,已提交过申请"`
+	HasFree          int    `description:"1:已付费(至少包含一个品类的权限),2:未付费(没有任何品类权限)"`
+	HaveResearch     bool   `description:"是否有研选权限"`
+	Mobile           string `description:"用户手机号"`
+	PopupMsg         string `description:"权限弹窗信息"`
+	SellerMobile     string `description:"销售电话"`
+	SellerName       string `description:"销售姓名"`
+	IsSpecialArticle bool   `description:"是否属于专项调研报告"`
+	IsResearch       bool   `description:"是否属于研选"`
+}
+
+type ArticleDetailHtgjResp struct {
+	HasPermission int    `description:"1:有该行业权限,正常展示,0:试用期已过期"`
+	CompanyName   string `description:"公司名称"`
+	Detail        *ArticleDetail
+}
+
+func ModifyArticleExpert(articleId int, expertNumStr, expertContentStr, interviewDateStr, bodyText string) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_article SET expert_background=?,expert_number=?,interview_date=?,body_text=? WHERE article_id=? `
+	_, err = o.Raw(sql, expertContentStr, expertNumStr, interviewDateStr, bodyText, articleId).Exec()
+	return
+}
+
+// 更改文章发布状态
+func UpdateArticlePublish(articleId, publishStatus int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_article SET publish_status=? WHERE article_id=? `
+	_, err = o.Raw(sql, publishStatus, articleId).Exec()
+	return
+}
+
+type ArticleDetailTest struct {
+	ArticleId int    `description:"报告id"`
+	Title     string `description:"标题"`
+	BodyText  string `description:"内容"`
+	Body      string `json:"-" description:"内容"`
+}
+
+func GetArticleDetailTestById(articleId int) (item *ArticleDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article WHERE article_id = ? `
+	err = o.Raw(sql, articleId).QueryRow(&item)
+	return
+}
+
+func GetArticleAll() (item []*ArticleDetail, err error) {
+	o := orm.NewOrm()
+	//sql := `SELECT * FROM cygx_article WHERE 1=1  is_summary=1`
+	sql := `SELECT * FROM cygx_article WHERE 1=1   AND publish_status = 1 `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+func GetArticleAllDate(endDate string) (item []*ArticleDetail, err error) {
+	o := orm.NewOrm()
+	//sql := `SELECT * FROM cygx_article WHERE is_summary=1 AND publish_date >= ?   `
+	sql := `SELECT * FROM cygx_article WHERE 1=1 AND publish_date >= ?   `
+	_, err = o.Raw(sql, endDate).QueryRows(&item)
+	return
+}
+
+func GetArticleAll2() (item []*ArticleDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article  `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+// 获取文章列表
+func GetArticleList(condition string, pars []interface{}) (items []*ArticleDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT 	*  FROM cygx_article  WHERE 1= 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func ModifyArticleContent(articleId int, content, expertNumStr, expertContentStr, interviewDateStr string) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_article SET body=?,expert_background=?,expert_number=?,interview_date=? WHERE article_id=? `
+	_, err = o.Raw(sql, content, expertContentStr, expertNumStr, interviewDateStr, articleId).Exec()
+	return
+}
+
+type ElasticArticleDetail struct {
+	ArticleId            int    `description:"报告id"`
+	Title                string `description:"标题"`
+	TitleEn              string `description:"英文标题 "`
+	UpdateFrequency      string `description:"更新周期"`
+	CreateDate           string `description:"创建时间"`
+	PublishDate          string `description:"发布时间"`
+	Abstract             string `description:"摘要"`
+	CategoryName         string `description:"一级分类"`
+	SubCategoryName      string `description:"二级分类"`
+	IsCollect            bool   `description:"是否收藏:true,已收藏,false:未收藏"`
+	IsInterviewApply     bool   `description:"是否申请访谈:true,已申请,false:未申请"`
+	BodyText             string `description:"内容"`
+	InterviewApplyStatus string `description:"当前访谈申请状态:'待邀请','待访谈','已完成','已取消'"`
+	InterviewDate        string `description:"访谈时间"`
+	ExpertBackground     string `description:"专家背景"`
+	ExpertNumber         string `description:"专家编号"`
+	Department           string `description:"作者"`
+	SellerMobile         string `description:"销售手机号"`
+	SellerName           string `description:"销售名称"`
+	ArticleIdMd5         string `description:"纪要id"`
+}
+
+func GetArticleCountById(articleId int) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM cygx_article WHERE article_id = ? `
+	err = o.Raw(sql, articleId).QueryRow(&count)
+	return
+}
+
+type CygxArticles struct {
+	Id               int    `orm:"column(id);pk"`
+	ArticleId        int    `description:"文章id"`
+	Title            string `description:"标题"`
+	TitleEn          string `description:"英文标题 "`
+	UpdateFrequency  string `description:"更新周期"`
+	CreateDate       string `description:"创建时间"`
+	PublishDate      string `description:"发布时间"`
+	Body             string `description:"内容"`
+	BodyText         string `description:"内容"`
+	Abstract         string `description:"摘要"`
+	CategoryName     string `description:"一级分类"`
+	SubCategoryName  string `description:"二级分类"`
+	PublishStatus    int    `description:"发布状态"`
+	CategoryId       int    `description:"分类id"`
+	ExpertBackground string `description:"专家背景"`
+	ExpertNumber     string `description:"专家编号"`
+	InterviewDate    string `description:"访谈日期"`
+	Department       string `description:"作者"`
+	ArticleIdMd5     string `description:"ID,md5值"`
+	IsClass          int    `description:"是否归类,1是,0否"`
+	IsSummary        int    `description:"是否是纪要库,1是,0否"`
+	IsReport         int    `description:"是否属于报告,1是,0否"`
+	ReportType       int    `description:"报告类型,1行业报告,2产业报告,0无"`
+}
+
+// 新增文章
+func AddCygxArticles(item *CygxArticle) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+func GetPermissionMappingById(categoryId int) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM cygx_permission_mapping WHERE category_id = ? `
+	err = o.Raw(sql, categoryId).QueryRow(&count)
+	return
+}
+
+func GetReportMappingById(categoryId int) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM cygx_report_mapping WHERE category_id = ? `
+	err = o.Raw(sql, categoryId).QueryRow(&count)
+	return
+}
+
+type ReportArticle struct {
+	ArticleId        int    `description:"文章id"`
+	Title            string `description:"标题"`
+	TitleEn          string `description:"英文标题 "`
+	UpdateFrequency  string `description:"更新周期"`
+	CreateDate       string `description:"创建时间"`
+	PublishDate      string `description:"发布时间"`
+	Body             string `description:"内容"`
+	Abstract         string `description:"摘要"`
+	CategoryName     string `description:"一级分类"`
+	SubCategoryName  string `description:"二级分类"`
+	ExpertBackground string `description:"专家背景"`
+	IsRed            bool   `description:"是否标记红点"`
+	Readnum          int    `description:"阅读数量"`
+	VideoUrl         string `description:"链接"`
+	IsHaveVideo      bool   `description:"是否含有音频文件"`
+	ImgUrlPc         string `description:"图片链接"`
+	CategoryId       string `description:"文章分类"`
+	Annotation       string `description:"核心观点"`
+	Resource         int    `description:"来源类型,1:文章、2:产品内测"`
+	MyCollectNum     int    `description:"本人是否收藏"`
+	IsCollect        bool   `description:"本人是否收藏"`
+	Pv               int    `description:"PV"`
+	CollectNum       int    `description:"收藏人数"`
+}
+
+type ReportMappingCategoryRep struct {
+	CategoryId int `description:"文章分类id"`
+}
+
+func GetReportMappingCategoryID() (item []*ReportMappingCategoryRep, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT category_id FROM cygx_permission_mapping  GROUP BY category_id  `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+type PermissionMappingCategoryRep struct {
+	CategoryId int `description:"文章分类id"`
+}
+
+func GetPermissionMappingCategoryID() (item []*PermissionMappingCategoryRep, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT category_id FROM cygx_report_mapping  GROUP BY category_id `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+// 检查用户是否阅读某一分类最新文章
+func GetUserIsReadThisNewCategoryArticleCount(categoryId, uid int) (count int, err error) {
+	sqlCount := `SELECT
+	COUNT( 1 ) AS count 
+FROM
+	cygx_article_history_record 
+WHERE
+	article_id = ( SELECT article_id FROM cygx_article WHERE category_id IN ( SELECT category_id_celue FROM cygx_report_mapping_group WHERE id_cygx = ? ) ORDER BY publish_date DESC LIMIT 0, 1 ) 
+	AND user_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, categoryId, uid).QueryRow(&count)
+	return
+}
+
+type ArticleId struct {
+	ArticleId int `description:"文章id"`
+}
+
+type ArticleIdAndTitle struct {
+	Title     string `description:"标题"`
+	ArticleId int    `description:"文章id"`
+}
+
+// 获取自定义分类的文章ID
+func GetCustomArticleId() (item []*ArticleId, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT article_id  FROM cygx_article WHERE is_custom = 1 `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+type ArticleFollowDetail struct {
+	DNum   int `description:"作者被关注的数量"`
+	MdNum  int `description:"本人是否关注这个作者"`
+	AcNum  int `description:"文章被收藏的数量"`
+	MacNum int `description:"本人是否收藏这个文章"`
+}
+
+// 获取文章被关注被收藏的详情
+func GetArticleFollowDetail(articleId, uid int) (item *ArticleFollowDetail, err error) {
+	//d_num 作者被关注的数量 、 md_num 本人是否关注这个作者 、ac_num 文章被收藏的数量 、 mac_num 本人是否收藏这个文章
+	o := orm.NewOrm()
+	sql := ` SELECT
+	( SELECT count( 1 ) FROM cygx_article_department_follow AS af  WHERE af.department_id = art.department_id AND af.type = 1 ) AS d_num,
+	( SELECT count( 1 ) FROM cygx_article_department_follow AS af WHERE af.department_id = art.department_id AND af.type = 1 AND af.user_id = ? ) AS md_num,
+	( SELECT count( 1 ) FROM cygx_article_collect AS ac   WHERE ac.article_id = art.article_id  ) AS ac_num,
+	( SELECT count( 1 ) FROM cygx_article_collect AS ac WHERE ac.article_id = art.article_id  AND ac.user_id = ? ) AS mac_num
+FROM
+	cygx_article AS art
+	LEFT JOIN cygx_article_department_follow AS af ON af.department_id = art.department_id
+	LEFT JOIN cygx_article_collect AS ac ON ac.article_id = art.article_id 
+WHERE
+	art.article_id = ?
+	GROUP BY art.article_id `
+	err = o.Raw(sql, uid, uid, articleId).QueryRow(&item)
+	return
+}
+
+// 日度点评的数据同步
+type ReportDetail struct {
+	Id                 int    `orm:"column(id)" description:"报告Id"`
+	AddType            int    `description:"新增方式:1:新增报告,2:继承报告"`
+	ClassifyIdFirst    int    `description:"一级分类id"`
+	ClassifyNameFirst  string `description:"一级分类名称"`
+	ClassifyIdSecond   int    `description:"二级分类id"`
+	ClassifyNameSecond string `description:"二级分类名称"`
+	Title              string `description:"标题"`
+	Abstract           string `description:"摘要"`
+	Author             string `description:"作者"`
+	Frequency          string `description:"频度"`
+	CreateTime         string `description:"创建时间"`
+	ModifyTime         string `description:"修改时间"`
+	State              int    `description:"1:未发布,2:已发布"`
+	PublishTime        string `description:"发布时间"`
+	Stage              int    `description:"期数"`
+	MsgIsSend          int    `description:"消息是否已发送,0:否,1:是"`
+	Content            string `description:"内容"`
+	VideoUrl           string `description:"音频文件URL"`
+	VideoName          string `description:"音频文件名称"`
+	VideoPlaySeconds   string `description:"音频播放时长"`
+	ContentSub         string `description:"内容前两个章节"`
+}
+
+func GetReportList() (items []*ReportDetail, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM report WHERE  classify_id_second = '57'`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetMaxArticleIdInfo() (item *ArticleDetail, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article   ORDER BY article_id desc  LIMIT 1`
+	err = o.Raw(sql).QueryRow(&item)
+	return
+}
+
+type ArticleResultApi struct {
+	Data []ArticleResultApidate `json:"data"`
+	Code int                    `json:"code"`
+	Msg  string                 `json:"msg"`
+}
+
+type ArticleDetailResultApi struct {
+	Data ArticleResultApidate `json:"data"`
+	Code int                  `json:"code"`
+	Msg  string               `json:"msg"`
+}
+
+type ArticleResultApidate struct {
+	ArticleId     int                      `json:"id"`
+	Title         string                   `json:"title"`
+	File          string                   `json:"file"`
+	TitleEn       string                   `json:"title_en"`
+	Frequency     string                   `json:"frequency"`
+	CreateDate    string                   `json:"create_date"`
+	UpdateDate    string                   `json:"update_date"`
+	PublishDate   time.Time                `json:"publish_date"`
+	PublishStatus int                      `json:"publish_status"`
+	IndustrId     int                      `json:"industry_id"`
+	SeriesId      int                      `json:"series_id"`
+	Series        ArticleSeries            `json:"series"`
+	Content       ArticleResultApiContent  `json:"content"`
+	Author        ArticleResultApiAuthor   `json:"author"`
+	Industry      ArticleResultApiIndustry `json:"industry"`
+	Type          ArticleResultApiType     `json:"type"`
+	Stock         []string                 `json:"stock"`
+	Field         ArticleField             `json:"field"`
+	Corpus        Corpus                   `json:"corpus"`
+	Cover         string                   `json:"cover"`
+	TypeId        int                      `json:"type_id"`
+	IsActive      bool                     `json:"is_active"`
+}
+
+type ArticleField struct {
+	Id          int    `json:"id"`
+	Name        string `json:"name"`
+	Description string `json:"description"`
+	IndustryId  int    `json:"industry_id"`
+}
+
+type Corpus struct {
+	Id        int    `json:"id"`
+	ArticleId int    `json:"article_id"`
+	Corpus    string `json:"corpus"`
+}
+
+type ArticleSeries struct {
+	Name string `json:"name"`
+}
+type ArticleResultApiContent struct {
+	ArticleId  int    `json:"id"`
+	Body       string `json:"body"`
+	Abstract   string `json:"abstract"`
+	Annotation string `json:"annotation"`
+}
+
+type ArticleResultApiAuthor struct {
+	PhoneNumber string `json:"phone_number"`
+	Name        string `json:"name"`
+}
+
+type ArticleResultApiIndustry struct {
+	Name string `json:"name"`
+}
+
+type ArticleResultApiType struct {
+	Name string `json:"name"`
+}
+
+type ArticleIndustryApi struct {
+	Data []ArticleResultApiIndustrdate `json:"data"`
+	Code int                           `json:"code"`
+	Msg  string                        `json:"msg"`
+}
+
+type ArticleResultApiIndustrdate struct {
+	Id     int                          `json:"id"`
+	Name   string                       `json:"name"`
+	Series []ArticleResultApiSeriesdate `json:"series"`
+}
+
+type ArticleResultApiSeriesdate struct {
+	Id   int    `json:"id"`
+	Name string `json:"name"`
+}
+
+type ArticleApiMap struct {
+	Id        int `description:"新ID"`
+	OldId     int `description:"旧Id"`
+	IsClass   int `description:"是否自动归类,1是,0否"`
+	IsReport  int `description:"是否属于报告,1是,0否"`
+	IsSummary int `description:"是否属于纪要,1是,0否"`
+}
+
+func GetArticleApiMap() (item []*ArticleApiMap, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT *  FROM	cygx_article_api_map WHERE	old_id > 0  AND is_update = 1 ORDER BY old_id ASC  `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+func GetArticleIdSubjectGroup(keyWord string) (articleid string, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+	GROUP_CONCAT(DISTINCT art.article_id   SEPARATOR ',') AS articleid
+FROM
+	cygx_article AS art
+	INNER JOIN cygx_industrial_article_group_subject AS sg ON sg.article_id = art.article_id
+	INNER JOIN cygx_industrial_subject AS s ON s.industrial_subject_id = sg.industrial_subject_id 
+WHERE
+	s.subject_name  LIKE '%` + keyWord + `%'  `
+	err = o.Raw(sql).QueryRow(&articleid)
+	return
+}
+
+func GetArticleIndustrialIdGroup(keyWord string) (articleid string, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+	GROUP_CONCAT(DISTINCT art.article_id   SEPARATOR ',') AS article_id
+FROM
+	cygx_article AS art
+	INNER JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = art.article_id
+	INNER JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id 
+WHERE
+	m.industry_name LIKE  '%` + keyWord + `%'  `
+	err = o.Raw(sql).QueryRow(&articleid)
+	return
+}
+
+// 通过文章ID获取文章所关联的标的ID
+func GetSubjectIds(articleId int) (subjects string, err error) {
+	sql := ` SELECT
+			GROUP_CONCAT( DISTINCT industrial_subject_id ORDER BY id ASC SEPARATOR ',' ) AS subjects 
+			FROM
+			cygx_industrial_article_group_subject WHERE article_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sql, articleId).QueryRow(&subjects)
+	return
+}
+
+// 修改发布状态
+func UpdateIsClassFail(articleId int) (err error) {
+	sql := `UPDATE cygx_article SET  is_class_fail=1  WHERE article_id=? `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, articleId).Exec()
+	return
+}
+
+type SummaryArticleStock struct {
+	Id        int    `description:"新ID"`
+	ArticleId int    `description:"文章id"`
+	Stock     string `description:"个股标签"`
+}
+
+// 综述报告
+func GetSummaryArticle(chartPermissionId int) (items []*SummaryArticleStock, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	* 
+FROM
+	cygx_article AS c
+	INNER JOIN cygx_report_mapping AS m 
+WHERE
+	c.type_name = '综述报告' 
+	AND m.category_id = c.category_id_two 
+	AND m.chart_permission_id = ? ORDER BY modify_time_by_cl DESC `
+
+	_, err = o.Raw(sql, chartPermissionId).QueryRows(&items)
+	return
+}
+
+type SummaryArticleStockResp struct {
+	List []*SummaryArticleStock
+}
+
+// 综述报告
+func GetArticleStock() (items []*SummaryArticleStock, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			stock,article_id
+		FROM
+			cygx_article AS art 
+		WHERE
+			1 = 1 
+			AND type_name = '综述报告' `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetCygxCygxArticleList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxArticle, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?  `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// 获取数量
+func GetCygxArticleCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 列表
+func GetCygxCygxArticleListByCondition(articleTypesCond, activityTypesCond, industryStr, subjectNameStr, articleTypeStr string) (artIds, actIds, mmIds string, err error) {
+	o := orm.NewOrm()
+	artSql := `SELECT GROUP_CONCAT(DISTINCT art.article_id SEPARATOR ',') AS art_ids FROM cygx_article as art `
+
+	actSql := ` SELECT GROUP_CONCAT(DISTINCT act.activity_id SEPARATOR ',') AS act_ids FROM cygx_activity as act `
+
+	mmSql := ` SELECT GROUP_CONCAT(DISTINCT mmc.id SEPARATOR ',') AS mm_ids FROM cygx_morning_meeting_review_chapter as mmc `
+
+	if industryStr != "" {
+		artSql += ` INNER JOIN cygx_industrial_article_group_management  AS iam ON iam.article_id = art.article_id 
+				INNER JOIN cygx_industrial_management AS im ON im.industrial_management_id=iam.industrial_management_id  `
+		actSql += ` INNER JOIN cygx_industrial_activity_group_management  AS iam ON iam.activity_id = act.activity_id 
+				INNER JOIN cygx_industrial_management AS im ON im.industrial_management_id=iam.industrial_management_id  `
+		mmSql += ` INNER JOIN cygx_morning_meeting_reviews  AS mm ON mmc.meeting_id = mm.id 
+				INNER JOIN cygx_industrial_management AS im ON im.industrial_management_id=mmc.industry_id  `
+	}
+	if subjectNameStr != "" {
+		artSql += ` INNER JOIN cygx_industrial_article_group_subject  AS ias ON ias.article_id = art.article_id 
+				INNER JOIN cygx_industrial_subject AS cis ON cis.industrial_subject_id=ias.industrial_subject_id  `
+		actSql += ` INNER JOIN cygx_industrial_activity_group_subject  AS ias ON ias.activity_id = act.activity_id 
+				INNER JOIN cygx_industrial_subject AS cis ON cis.industrial_subject_id=ias.industrial_subject_id  `
+		mmSql += ` IINNER JOIN cygx_morning_meeting_reviews  AS mm ON mmc.meeting_id = mm.id 
+				INNER JOIN cygx_industrial_subject AS cis ON cis.industrial_subject_id=mmc.industrial_subject_ids  `
+	}
+	artSql += ` WHERE 1=1 `
+	if articleTypesCond != "" || (articleTypesCond == "" && activityTypesCond == "") {
+		if industryStr != "" && subjectNameStr != "" {
+			artSql += articleTypesCond + ` AND (im.industry_name In (` + industryStr + `) OR cis.subject_name In (` + subjectNameStr + `) )`
+		} else if industryStr == "" && subjectNameStr != "" {
+			artSql += articleTypesCond + ` AND  cis.subject_name In (` + subjectNameStr + `) `
+		} else if industryStr != "" && subjectNameStr == "" {
+			artSql += articleTypesCond + ` AND im.industry_name In (` + industryStr + `) `
+		} else {
+			artSql += articleTypesCond
+		}
+		err = o.Raw(artSql).QueryRow(&artIds)
+	}
+
+	actSql += ` WHERE 1=1 `
+	if activityTypesCond != "" || (articleTypesCond == "" && activityTypesCond == "") {
+		if industryStr != "" && subjectNameStr != "" {
+			actSql += activityTypesCond + ` AND (im.industry_name In (` + industryStr + `) OR cis.subject_name In (` + subjectNameStr + `) )`
+		} else if industryStr == "" && subjectNameStr != "" {
+			actSql += activityTypesCond + ` AND  cis.subject_name In (` + subjectNameStr + `) `
+		} else if industryStr != "" && subjectNameStr == "" {
+			actSql += activityTypesCond + ` AND im.industry_name In (` + industryStr + `) `
+		} else {
+			actSql += activityTypesCond
+		}
+		err = o.Raw(actSql).QueryRow(&actIds)
+	}
+
+	if strings.Contains(articleTypeStr, "晨会精华") {
+		mmSql += ` WHERE 1=1 `
+		if industryStr != "" && subjectNameStr != "" {
+			mmSql += ` AND (im.industry_name In (` + industryStr + `) OR cis.subject_name In (` + subjectNameStr + `) )`
+		} else if industryStr == "" && subjectNameStr != "" {
+			mmSql += ` AND  cis.subject_name In (` + subjectNameStr + `) `
+		} else if industryStr != "" && subjectNameStr == "" {
+			mmSql += ` AND im.industry_name In (` + industryStr + `) `
+		}
+		err = o.Raw(mmSql).QueryRow(&mmIds)
+	}
+
+	return
+}
+
+// 单个tag时用,取合集
+func GetCygxCygxArticleListByConditionSoloTag(articleTypeCondSlice, activityTypesCondSlice, industriesCondSlice, subjectNamesSlice, articleTypeSlice []string) (artIds, actIds, mmIds string, err error) {
+	o := orm.NewOrm()
+	artSql := `SELECT GROUP_CONCAT(DISTINCT art.article_id SEPARATOR ',') AS art_ids FROM cygx_article as art `
+
+	actSql := ` SELECT GROUP_CONCAT(DISTINCT act.activity_id SEPARATOR ',') AS act_ids FROM cygx_activity as act `
+
+	mmSql := ` SELECT GROUP_CONCAT(DISTINCT mmc.id SEPARATOR ',') AS mm_ids FROM cygx_morning_meeting_review_chapter as mmc `
+
+	for _, s := range industriesCondSlice {
+		if s != "" {
+			artSql += ` INNER JOIN cygx_industrial_article_group_management  AS iam ON iam.article_id = art.article_id 
+				INNER JOIN cygx_industrial_management AS im ON im.industrial_management_id=iam.industrial_management_id  `
+			actSql += ` INNER JOIN cygx_industrial_activity_group_management  AS iam ON iam.activity_id = act.activity_id 
+				INNER JOIN cygx_industrial_management AS im ON im.industrial_management_id=iam.industrial_management_id  `
+			mmSql += ` INNER JOIN cygx_morning_meeting_reviews  AS mm ON mmc.meeting_id = mm.id 
+				INNER JOIN cygx_industrial_management AS im ON im.industrial_management_id=mmc.industry_id  `
+
+			break
+		}
+	}
+	for _, s := range subjectNamesSlice {
+		if s != "" {
+			artSql += ` INNER JOIN cygx_industrial_article_group_subject  AS ias ON ias.article_id = art.article_id 
+				INNER JOIN cygx_industrial_subject AS cis ON cis.industrial_subject_id=ias.industrial_subject_id  `
+			actSql += ` INNER JOIN cygx_industrial_activity_group_subject  AS ias ON ias.activity_id = act.activity_id 
+				INNER JOIN cygx_industrial_subject AS cis ON cis.industrial_subject_id=ias.industrial_subject_id  `
+			mmSql += ` IINNER JOIN cygx_morning_meeting_reviews  AS mm ON mmc.meeting_id = mm.id 
+				INNER JOIN cygx_industrial_subject AS cis ON cis.industrial_subject_id=mmc.industrial_subject_ids  `
+
+			break
+		}
+	}
+	artSql += ` WHERE 1=1 AND ((1=1 `
+	actSql += ` WHERE 1=1 AND ((1=1 `
+	mmSql += ` WHERE 1=1 AND ((1=1 `
+	var isNeedArt, isNeedAct, isNeedMm bool
+	for i, _ := range articleTypeCondSlice {
+		articleTypesCond := articleTypeCondSlice[i]
+		activityTypesCond := activityTypesCondSlice[i]
+		industryStr := industriesCondSlice[i]
+		subjectNameStr := subjectNamesSlice[i]
+		articleTypeStr := articleTypeSlice[i]
+
+		if articleTypesCond != "" || (articleTypesCond == "" && activityTypesCond == "") {
+			if industryStr != "" && subjectNameStr != "" {
+				artSql += articleTypesCond + ` AND (im.industry_name In (` + industryStr + `) OR cis.subject_name In (` + subjectNameStr + `) )`
+			} else if industryStr == "" && subjectNameStr != "" {
+				artSql += articleTypesCond + ` AND  cis.subject_name In (` + subjectNameStr + `) `
+			} else if industryStr != "" && subjectNameStr == "" {
+				artSql += articleTypesCond + ` AND im.industry_name In (` + industryStr + `) `
+			} else {
+				artSql += articleTypesCond
+			}
+
+			if i == len(articleTypeCondSlice)-1 {
+				artSql += `)) `
+			} else {
+				artSql += `) OR (1=1 `
+			}
+
+			isNeedArt = true
+		}
+
+		if activityTypesCond != "" || (articleTypesCond == "" && activityTypesCond == "") {
+			if industryStr != "" && subjectNameStr != "" {
+				actSql += activityTypesCond + ` AND (im.industry_name In (` + industryStr + `) OR cis.subject_name In (` + subjectNameStr + `) )`
+			} else if industryStr == "" && subjectNameStr != "" {
+				actSql += activityTypesCond + ` AND  cis.subject_name In (` + subjectNameStr + `) `
+			} else if industryStr != "" && subjectNameStr == "" {
+				actSql += activityTypesCond + ` AND im.industry_name In (` + industryStr + `) `
+			} else {
+				actSql += activityTypesCond
+			}
+
+			if i == len(articleTypeCondSlice)-1 {
+				actSql += `)) `
+			} else {
+				actSql += `) OR (1=1 `
+			}
+
+			isNeedAct = true
+		}
+
+		if strings.Contains(articleTypeStr, "晨会精华") {
+			if industryStr != "" && subjectNameStr != "" {
+				mmSql += ` AND (im.industry_name In (` + industryStr + `) OR cis.subject_name In (` + subjectNameStr + `) )`
+			} else if industryStr == "" && subjectNameStr != "" {
+				mmSql += ` AND  cis.subject_name In (` + subjectNameStr + `) `
+			} else if industryStr != "" && subjectNameStr == "" {
+				mmSql += ` AND im.industry_name In (` + industryStr + `) `
+			}
+
+			if i == len(articleTypeCondSlice)-1 {
+				mmSql += `)) `
+			} else {
+				mmSql += `) OR (1=1 `
+			}
+
+			isNeedMm = true
+		}
+	}
+
+	if isNeedArt {
+		err = o.Raw(artSql).QueryRow(&artIds)
+		if err != nil {
+			return
+		}
+	}
+	if isNeedAct {
+		err = o.Raw(actSql).QueryRow(&actIds)
+		if err != nil {
+			return
+		}
+	}
+	if isNeedMm {
+		err = o.Raw(mmSql).QueryRow(&mmIds)
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}

+ 33 - 0
models/article_and_yanxuan_record.go

@@ -0,0 +1,33 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleAndYanxuanRecord struct {
+	Id               int       `orm:"column(id);pk"`
+	SourceId         int       `description:"资源ID"`
+	Source           string    `description:"资源I类型  文章、研选专栏"`
+	UserId           int       `description:"用户ID"`
+	CreateTime       string    `description:"创建时间"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	ModifyTime       time.Time `description:"修改时间"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	StopTime         int       `description:"停留时间"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+}
+
+// 批量添加
+func AddCygxArticleAndYanxuanRecordMulti(items []*CygxArticleAndYanxuanRecord) (err error) {
+	o := orm.NewOrm()
+	if len(items) > 0 {
+		//批量添加
+		_, err = o.InsertMulti(len(items), items)
+	}
+	return
+}

+ 39 - 0
models/article_apply_appointment_expert.go

@@ -0,0 +1,39 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleApplyAppointmentExpert struct {
+	Id               int       `gorm:"column:id;primary_key;AUTO_INCREMENT" json:"id"`
+	ArticleId        int       `gorm:"column:article_id" json:"article_id"`                                  // cygx_article表article_id
+	UserId           int       `gorm:"column:user_id" json:"user_id"`                                        // 用户ID
+	Mobile           string    `gorm:"column:mobile" json:"mobile"`                                          // 手机号
+	Email            string    `gorm:"column:email" json:"email"`                                            // 邮箱
+	CompanyId        int       `gorm:"column:company_id;default:0" json:"company_id"`                        // 公司ID
+	CompanyName      string    `gorm:"column:company_name" json:"company_name"`                              // 公司名称
+	RealName         string    `gorm:"column:real_name" json:"real_name"`                                    // 用户实际名称
+	SellerName       string    `gorm:"column:seller_name" json:"seller_name"`                                // 所属销售
+	CreateTime       time.Time `gorm:"column:create_time" json:"create_time"`                                // 创建时间
+	ModifyTime       time.Time `gorm:"column:modify_time" json:"modify_time"`                                // 修改时间
+	RegisterPlatform int       `gorm:"column:register_platform;default:1;NOT NULL" json:"register_platform"` // 来源 1小程序,2:网页
+}
+
+// 添加历史信息
+func AddCygxArticleApplyAppointmentExpert(item *CygxArticleApplyAppointmentExpert) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 获取数量
+func GetCygxArticleApplyAppointmentExpertCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_apply_appointment_expert WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}

+ 30 - 0
models/article_ask.go

@@ -0,0 +1,30 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleAsk struct {
+	AskId       int       `orm:"column(ask_id);pk" description:"带问id"`
+	UserId      int       `description:"用户id"`
+	ArticleId   int       `description:"文章id"`
+	CreateTime  time.Time `description:"创建时间"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司id"`
+	CompanyName string    `description:"公司名称"`
+	Content     string    `description:"内容"`
+}
+
+//添加优化建议
+func AddArticleAsk(item *CygxArticleAsk) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type AddArticleAskRep struct {
+	ArticleId int    `description:"文章id"`
+	Content   string `description:"内容"`
+}

+ 27 - 0
models/article_author.go

@@ -0,0 +1,27 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type CygxArticleAuthor struct {
+	Id        int    `orm:"column(id);pk;"description:"主键ID"`
+	ArticleId int    `description:"文章ID"`
+	Mobile    string `description:"手机号"`
+	Name      string `description:"姓名"`
+}
+
+//获取数量
+func GetActivityAuthorCount(articcleId int, mobile string) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_author WHERE article_id=? AND mobile = ? `
+	err = o.Raw(sqlCount, articcleId, mobile).QueryRow(&count)
+	return
+}
+
+//添加优化建议
+func AddCygxActivityAuthor(item *CygxArticleAuthor) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}

+ 106 - 0
models/article_category_mapping.go

@@ -0,0 +1,106 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+	//"time"
+)
+
+type CygxArticleCategoryMapping struct {
+	Id                  int    `orm:"column(id);pk" description:"id"`
+	ChartPermissionId   int    `description:"行业ID"`
+	CategoryId          int    `description:"分类ID"`
+	ChartPermissionName string `description:"行业名称"`
+	MatchTypeName       string `description:"分类名称"`
+	ReportType          int    `description:"报告类型,2产业报告,1行业报告"`
+	SubCategoryName     string `description:"主题"`
+	Sort                int    `description:"排序"`
+	IsCustom            int    `description:"是否属于自定义的匹配类型 ,1是,0否"`
+	IsSummary           int    `description:"是否是纪要库,1是,0否"`
+	IsReport            int    `description:"是否是报告,1是,0否"`
+	PermissionType      int    `description:"1主观,2客观"`
+	CygxId              int    `description:"分类聚合ID"`
+	CeLueId             int    `description:"策略平台领域ID"`
+}
+
+// 添加
+func AddCygxArticleCategoryMapping(item *CygxArticleCategoryMapping) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 添加
+func AddCygxReportMappingCygx(item *CygxReportMappingCygx) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 获取数量
+func GetCygxReportMappingCygxCount(condition string) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_report_mapping_cygx as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount).QueryRow(&count)
+	return
+}
+
+// 获取所有的报告分类 查研观向
+func GetCygxReportMappingCygx() (items []*CygxReportMappingCygx, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				* 
+			FROM
+				cygx_report_mapping_cygx `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 获取所有的报告分类 策略
+func GetCygxReportMappingcelue(condition string) (items []*CygxReportMapping, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				* 
+			FROM
+				cygx_report_mapping_celue WHERE 1= 1  `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 通过分类ID获取详情
+func GetCygxReportMappingCygxByCategoryId(categoryId int) (item *CygxReportMappingCygx, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_report_mapping_cygx WHERE  id=? `
+	err = o.Raw(sql, categoryId).QueryRow(&item)
+	return
+}
+
+type CygxReportMappingCelue struct {
+	Id                  int       `orm:"column(id);pk" description:"id"`
+	ChartPermissionId   int       `description:"行业ID"`
+	CategoryId          int       `description:"分类ID"`
+	ChartPermissionName string    `description:"行业名称"`
+	SubCategoryName     string    `description:"主题"`
+	ReportType          int       `description:"报告类型,2产业报告,1行业报告"`
+	Sort                int       `description:"排序"`
+	IsCustom            int       `description:"是否属于自定义的匹配类型 ,1是,0否"`
+	IsSummary           int       `description:"是否是纪要库,1是,0否"`
+	IsReport            int       `description:"是否是报告,1是,0否"`
+	PermissionType      int       `description:"1主观,2客观"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"更新时间"`
+}
+
+// 通过 categoryId 获取详情
+func GetCygxReportMappingCelueMaxDetailByCategoryId(categoryId int) (item *CygxReportMappingCelue, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT  * FROM cygx_report_mapping_celue  WHERE  category_id = ?  LIMIT 1 `
+	err = o.Raw(sql, categoryId).QueryRow(&item)
+	return
+}

+ 29 - 0
models/article_celue_push.go

@@ -0,0 +1,29 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type CygxArticleCeluePush struct {
+	Id         int    `description:"新ID"`
+	ArticleId  int    `description:"文章ID"`
+	IsHandle   int    `description:"文章ID"`
+	Action     string `description:"日志类型:add,edit,move"`
+	ModifyTime string `description:"修改时间"`
+	CreateTime string `description:"创建时间"`
+}
+
+func GetArticleCeluePushList() (item []*CygxArticleCeluePush, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT *  FROM	cygx_article_celue_push WHERE	is_handle = 0  AND create_time >DATE_SUB(NOW(), INTERVAL 10 MINUTE)  GROUP BY article_id   `
+	_, err = o.Raw(sql).QueryRows(&item)
+	return
+}
+
+// 更改推送内容是否处理状态
+func UpdateCygxArticleCeluePush(articleId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_article_celue_push SET is_handle=1 WHERE article_id=? `
+	_, err = o.Raw(sql, articleId).Exec()
+	return
+}

+ 266 - 0
models/article_collect.go

@@ -0,0 +1,266 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+type CygxArticleCollect struct {
+	Id              int `orm:"column(id);pk"`
+	ArticleId       int
+	ActivityVoiceId int
+	ActivityVideoId int
+	VideoId         int
+	UserId          int
+	CreateTime      time.Time
+	ModifyTime      time.Time `description:"更新时间"`
+	Mobile          string    `description:"手机号"`
+	Email           string    `description:"邮箱"`
+	CompanyId       int       `description:"公司id"`
+	CompanyName     string    `description:"公司名称"`
+	RealName        string    `description:"用户实际名称"`
+}
+
+// 添加收藏信息
+func AddCygxArticleCollect(item *CygxArticleCollect) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type ArticleCollectReq struct {
+	ArticleId int `description:"报告id"`
+}
+
+type ArticleCollectResp struct {
+	Status       int `description:"1:收藏,2:取消收藏"`
+	CollectCount int `description:"收藏总数"`
+}
+
+func RemoveArticleCollect(userId, articleId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_article_collect WHERE user_id=? AND article_id=? `
+	_, err = o.Raw(sql, userId, articleId).Exec()
+	return
+}
+
+func GetArticleCollectUsersCount(articleId int) (count int, err error) {
+	sql := `SELECT COUNT(user_id) AS count FROM cygx_article_collect WHERE article_id=? `
+	err = orm.NewOrm().Raw(sql, articleId).QueryRow(&count)
+	return
+}
+
+func GetArticleCollectCount(userId, articleId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_article_collect WHERE user_id=? AND article_id=? `
+	err = orm.NewOrm().Raw(sql, userId, articleId).QueryRow(&count)
+	return
+}
+
+type ArticleCollectList struct {
+	Id              int `orm:"column(id);pk"`
+	ArticleId       int
+	UserId          int
+	CreateTime      time.Time
+	Title           string `description:"标题"`
+	TitleEn         string `description:"英文标题 "`
+	UpdateFrequency string `description:"更新周期"`
+	CreateDate      string `description:"创建时间"`
+	PublishDate     string `description:"发布时间"`
+	Body            string `description:"内容"`
+	Abstract        string `description:"摘要"`
+	CategoryName    string `description:"一级分类"`
+	SubCategoryName string `description:"二级分类"`
+}
+
+func GetCygxArticleCollectList(condition string) (items []*CygxArticleCollect, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_collect  WHERE 1 =1  AND article_id > 0  ` + condition + ` GROUP BY user_id  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// GetCygxArticleCollectByUser 根据用户ID获取所有文章收藏
+func GetCygxArticleCollectByUser(userId int) (items []*CygxArticleCollect, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_collect  WHERE 1 =1  AND article_id > 0 AND  user_id =?  `
+	_, err = o.Raw(sql, userId).QueryRows(&items)
+	return
+}
+
+// 修改用户收藏文章的相关信息
+func UpdateCygxArticleCollect(wxUser *WxUserItem) (err error) {
+	o := orm.NewOrm()
+	var sql string
+	if wxUser.Mobile != "" {
+		sql = `UPDATE cygx_article_collect SET email=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE mobile=? `
+		_, err = o.Raw(sql, wxUser.Email, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Mobile).Exec()
+	} else if wxUser.Email != "" {
+		sql = `UPDATE cygx_article_collect SET user_id=?,company_id=?,company_name=?,mobile=?,real_name=? WHERE email=? `
+		_, err = o.Raw(sql, wxUser.UserId, wxUser.CompanyId, wxUser.CompanyName, wxUser.Mobile, wxUser.RealName, wxUser.Email).Exec()
+	}
+	return
+}
+
+type CygxArticleCollectCountRep struct {
+	ArticleId int `description:"文章ID"`
+	Num       int `description:"数量"`
+}
+
+// 获取文章被收藏的数量
+func GetUserArticleCollectList() (items []*CygxArticleCollectCountRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			COUNT( 1 ) AS num,
+			f.article_id 
+		FROM
+			cygx_article_collect AS f
+			INNER JOIN cygx_article AS a ON a.article_id = f.article_id 
+		WHERE
+			1 = 1 
+		GROUP BY
+			f.article_id 
+		ORDER BY
+			num DESC 
+			LIMIT 30 `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 修改文章收藏的数量
+func UpdateArticleCollectCountNum(num, articleId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_article SET user_collection_num = ? WHERE article_id = ?`
+	_, err = o.Raw(sql, num, articleId).Exec()
+	return
+}
+
+type CygxArticleNum struct {
+	ArticleId  int  `description:"文章ID"`
+	IsCollect  bool `description:"本人是否收藏"`
+	Pv         int  `description:"PV"`
+	CollectNum int  `description:"收藏人数"`
+}
+
+// GetArticleCollectNum 根据文章ID获取收藏数量的列表
+func GetArticleCollectNum(articleId []string, uid int) (items []*CygxArticleNum, err error) {
+	lenarticleId := len(articleId)
+	if lenarticleId == 0 {
+		return
+	}
+	sql := `SELECT
+			a.article_id,
+			( SELECT count( 1 ) FROM cygx_article_history_record_newpv AS h WHERE h.article_id = a.article_id ) AS pv,
+			( SELECT count( 1 ) FROM cygx_article_collect AS ac   WHERE ac.article_id = a.article_id  ) AS collect_num, 
+			( SELECT count( 1 ) FROM cygx_article_collect AS ac   WHERE ac.article_id = a.article_id AND DATE_SUB( CURDATE(), INTERVAL 30 DAY ) <= date( ac.create_time )  ) AS collect_num_order, 
+			( SELECT count( 1 ) FROM cygx_article_collect AS ac WHERE ac.article_id = a.article_id  AND user_id = ? ) AS is_collect
+		FROM
+			cygx_article AS a WHERE  1 = 1  AND  article_id IN  (` + utils.GetOrmInReplace(lenarticleId) + `) `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, uid, articleId).QueryRows(&items)
+	return
+}
+
+// GetArticleCollectNum 根据文章ID获取收藏数量的列表
+func GetArticleCollectListNum(articleIds []int) (items []*CygxArticleNum, err error) {
+	lenArr := len(articleIds)
+	if lenArr == 0 {
+		return
+	}
+	sql := `SELECT  COUNT(1) as collect_num , article_id  FROM cygx_article_collect  WHERE   article_id IN  (` + utils.GetOrmInReplace(lenArr) + `)   GROUP BY article_id `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, articleIds).QueryRows(&items)
+	return
+}
+
+type MicroRoadshowCollectList struct {
+	AudioIds         string
+	VideoIds         string
+	ActivityVideoIds string
+}
+
+func GetVideoCollectCount(userId, videoId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_article_collect WHERE user_id=? AND video_id=? `
+	err = orm.NewOrm().Raw(sql, userId, videoId).QueryRow(&count)
+	return
+}
+
+func RemoveVideoCollect(userId, videoId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_article_collect WHERE user_id=? AND video_id=? `
+	_, err = o.Raw(sql, userId, videoId).Exec()
+	return
+}
+
+func GetVideoCollectUsersCount(videoId int) (count int, err error) {
+	sql := `SELECT COUNT(user_id) AS count FROM cygx_article_collect WHERE video_id=? `
+	err = orm.NewOrm().Raw(sql, videoId).QueryRow(&count)
+	return
+}
+
+func GetVoiceCollectCount(userId, voiceId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_article_collect WHERE user_id=? AND activity_voice_id=? `
+	err = orm.NewOrm().Raw(sql, userId, voiceId).QueryRow(&count)
+	return
+}
+
+func RemoveVoiceCollect(userId, voiceId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_article_collect WHERE user_id=? AND activity_voice_id=? `
+	_, err = o.Raw(sql, userId, voiceId).Exec()
+	return
+}
+
+func GetVoiceCollectUsersCount(voiceId int) (count int, err error) {
+	sql := `SELECT COUNT(user_id) AS count FROM cygx_article_collect WHERE activity_voice_id=? `
+	err = orm.NewOrm().Raw(sql, voiceId).QueryRow(&count)
+	return
+}
+
+func GetActivityVideoCollectCount(userId, activityVideoId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_article_collect WHERE user_id=? AND activity_video_id=? `
+	err = orm.NewOrm().Raw(sql, userId, activityVideoId).QueryRow(&count)
+	return
+}
+
+func RemoveActivityVideoCollect(userId, activityVideoId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_article_collect WHERE user_id=? AND activity_video_id=? `
+	_, err = o.Raw(sql, userId, activityVideoId).Exec()
+	return
+}
+
+func GetActivityVideoCollectUsersCount(videoId int) (count int, err error) {
+	sql := `SELECT COUNT(user_id) AS count FROM cygx_article_collect WHERE activity_video_id=? `
+	err = orm.NewOrm().Raw(sql, videoId).QueryRow(&count)
+	return
+}
+
+func GetActivityVoiceCollectCount(userId, activityId int) (count int, err error) {
+	sql := `SELECT
+	COUNT( 1 ) AS count 
+FROM
+	cygx_article_collect AS c
+	INNER JOIN cygx_activity_voice AS vc 
+WHERE
+	c.user_id =? 
+	AND vc.activity_id =? 
+	AND c.activity_voice_id = vc.activity_voice_id`
+	err = orm.NewOrm().Raw(sql, userId, activityId).QueryRow(&count)
+
+	return
+}
+
+func GetActivityVideoCollectCountByActivityId(userId, activityId int) (count int, err error) {
+	sql := `SELECT
+	COUNT( 1 ) AS count 
+FROM
+	cygx_article_collect AS c
+	INNER JOIN cygx_activity_video AS vd 
+WHERE
+	c.user_id =? 
+	AND vd.activity_id =? 
+	AND c.activity_video_id = vd.video_id`
+	err = orm.NewOrm().Raw(sql, userId, activityId).QueryRow(&count)
+	return
+}

+ 86 - 0
models/article_comment.go

@@ -0,0 +1,86 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleComment struct {
+	Id              int       `orm:"column(id);pk" description:"留言id"`
+	UserId          int       `description:"用户id"`
+	RealName        string    `description:"用户姓名"`
+	ArticleId       int       `description:"文章id"`
+	ActivityId      int       `description:"活动id"`
+	VideoId         int       `description:"视频id"`
+	ActivityVoiceId int       `description:"活动音频ID"`
+	AskserieVideoId int       `description:" 系列问答视频ID askserie_video_id"`
+	IndustryId      int       `description:"产业id"`
+	CreateTime      time.Time `description:"创建时间"`
+	Mobile          string    `description:"手机号"`
+	Email           string    `description:"邮箱"`
+	CompanyId       int       `description:"公司id"`
+	CompanyName     string    `description:"公司名称"`
+	Content         string    `description:"内容"`
+	Title           string    `description:"标题"`
+}
+
+// 添加留言
+func AddArticleComment(item *CygxArticleComment) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type AddCygxArticleCommentReq struct {
+	ArticleId int    `description:"文章id"`
+	Content   string `description:"内容"`
+}
+
+// 我的留言列表
+func GetCommentList(userId int) (items []*CygxArticleComment, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			* 
+		FROM
+			cygx_article_comment AS c
+		WHERE
+			user_id = ? ORDER BY c.create_time DESC`
+
+	_, err = o.Raw(sql, userId).QueryRows(&items)
+	return
+}
+
+type CygxArticleCommentResp struct {
+	Id           int       `orm:"column(id);pk" description:"留言id"`
+	UserId       int       `description:"用户id"`
+	ArticleId    int       `description:"文章id"`
+	IndustryId   int       `description:"产业id"`
+	ActivityId   int       `description:"活动id"`
+	CreateTime   time.Time `description:"创建时间"`
+	Mobile       string    `description:"手机号"`
+	Email        string    `description:"邮箱"`
+	CompanyId    int       `description:"公司id"`
+	CompanyName  string    `description:"公司名称"`
+	Content      string    `description:"内容"`
+	Title        string    `description:"标题"`
+	RedirectType int       `description:"跳转类型 1文章 2活动 3产业资源包"`
+	IsCollect    bool      `description:"是否收藏:true,已收藏,false:未收藏"`
+	IsRoadShow   bool      `description:"是否是路演精华"`
+}
+
+type CygxCommentListResp struct {
+	List []*CygxArticleCommentResp
+}
+
+// 通过ID获取详情
+func GetArticleCommentById(id int) (item *CygxArticleCommentResp, err error) {
+	sql := `SELECT * FROM cygx_article_comment WHERE id=? `
+	err = orm.NewOrm().Raw(sql, id).QueryRow(&item)
+	return
+}
+
+type CygxArticleCommentWxResp struct {
+	Content      string `description:"内容"`
+	SourceId     int    `description:"跳转ID"`
+	RedirectType int    `description:"跳转类型 1文章 2活动 3产业资源包"`
+}

+ 28 - 0
models/article_data.go

@@ -0,0 +1,28 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleData struct {
+	Id         int       `orm:"column(id);pk"`
+	ArticleId  int       `description:"文章id"`
+	CreateTime time.Time `description:"创建时间"`
+	Cover      string    `description:"封面图片,公司logo"`
+}
+
+//新增文章
+func AddCygxArticleData(item *CygxArticleData) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+//获取数量
+func GetCygxArticleDataCount(articcleId int) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_data WHERE article_id=? `
+	err = o.Raw(sqlCount, articcleId).QueryRow(&count)
+	return
+}

+ 299 - 0
models/article_department.go

@@ -0,0 +1,299 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+type CygxArticleDepartment struct {
+	DepartmentId int       `orm:"column(department_id);pk;主键ID"`
+	CreateTime   time.Time `description:"创建时间"`
+	NickName     string    `description:"昵称"`
+	Remark       string    `description:"备注"`
+	Remarks      string    `description:"备注辅助字段"`
+	Content      string    `description:"初始内容"`
+}
+
+type CygxArticleDepartmentRep struct {
+	DepartmentId int    `description:"作者ID"`
+	CreateTime   string `description:"创建时间"`
+	NickName     string `description:"昵称"`
+	ImgUrl       string `description:"头像链接"`
+	FollowNum    int    `description:"是否关注 1是 ,0 否"`
+	IsMyFollow   bool   `description:"是否关注"`
+	List         []*IndustrialManagementIdName
+}
+
+type CygxArticleDepartmentRepPc struct {
+	DepartmentId int    `description:"作者ID"`
+	CreateTime   string `description:"创建时间"`
+	NickName     string `description:"昵称"`
+	ImgUrl       string `description:"头像链接"`
+	FollowNum    int    `description:"是否关注 1是 ,0 否"`
+	IsMyFollow   bool   `description:"是否关注"`
+	List         []*IndustrialManagementIdNamePc
+}
+
+type CygxArticleDepartmentId struct {
+	DepartmentId int `description:"作者ID"`
+}
+
+type CygxArticleDepartmentList struct {
+	HaveResearch bool               `description:"是否有研选权限"`
+	Paging       *paging.PagingItem `description:"分页数据"`
+	ListnNew     []*IndustrialManagementIdInt
+	List         []*CygxArticleDepartmentRep
+}
+
+type CygxArticleDepartmentListPc struct {
+	HaveResearch bool               `description:"是否有研选权限"`
+	Paging       *paging.PagingItem `description:"分页数据"`
+	ListnNew     []*IndustrialManagementIdInt
+	List         []*CygxArticleDepartmentRepPc
+}
+
+//详情
+func GetArticleDepartmentDateil(nickName, remarks string) (item *CygxArticleDepartmentRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_department WHERE nick_name = ? AND  remarks = ? LIMIT 1 `
+	err = o.Raw(sql, nickName, remarks).QueryRow(&item)
+	return
+}
+
+func GetArticleDepartmentDateilById(departmentId int) (item *CygxArticleDepartmentRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_department WHERE department_id = ? `
+	err = o.Raw(sql, departmentId).QueryRow(&item)
+	return
+}
+
+//数量
+func GetArticleDepartmentCount(condition string) (count int, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT COUNT(*) count
+		FROM
+		( SELECT COUNT(1)  FROM cygx_article_department AS d
+		INNER JOIN cygx_article AS a ON a.department_id = d.department_id
+		INNER JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = a.article_id
+		INNER JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id WHERE 1= 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY d.department_id ) AS num `
+
+	err = o.Raw(sql).QueryRow(&count)
+	return
+}
+
+//列表
+func GetCygxArticleDepartmentList(startSize, pageSize int, condition string, uid int) (items []*CygxArticleDepartmentRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT d.*,
+		( SELECT COUNT( 1 ) FROM cygx_article AS a INNER JOIN cygx_article_history_record as h ON h.article_id = a.article_id WHERE  a.department_id = d.department_id  AND a.publish_status = 1 ) AS art_num,
+		( SELECT COUNT( 1 ) FROM cygx_article_department_follow AS f  WHERE f.department_id = d.department_id AND f.user_id = ? AND f.type = 1 ) AS follow_num
+		FROM
+		cygx_article_department AS d
+		INNER JOIN cygx_article AS a ON a.department_id = d.department_id
+		INNER JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = a.article_id
+		INNER JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id  WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY
+		d.department_id
+		ORDER BY  art_num DESC  LIMIT ?,?`
+	_, err = o.Raw(sql, uid, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+//列表
+func GetCygxArticleDepartmentListPc(startSize, pageSize int, condition string, uid int) (items []*CygxArticleDepartmentRepPc, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT d.*,
+		( SELECT COUNT( 1 ) FROM cygx_article AS a INNER JOIN cygx_article_history_record as h ON h.article_id = a.article_id WHERE  a.department_id = d.department_id  AND a.publish_status = 1 ) AS art_num,
+		( SELECT COUNT( 1 ) FROM cygx_article_department_follow AS f  WHERE f.department_id = d.department_id AND f.user_id = ? AND f.type = 1 ) AS follow_num
+		FROM
+		cygx_article_department AS d
+		INNER JOIN cygx_article AS a ON a.department_id = d.department_id
+		INNER JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = a.article_id
+		INNER JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id  WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY
+		d.department_id
+		ORDER BY  art_num DESC  LIMIT ?,?`
+	_, err = o.Raw(sql, uid, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+//产业列表
+func GetIndustrialSubjectByDepartment(departmentId int) (items []*IndustrialManagementIdInt, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			m.*,
+			( SELECT GROUP_CONCAT(DISTINCT s.subject_name ORDER BY s.create_time DESC SEPARATOR '/' ) FROM cygx_industrial_subject AS s WHERE s.industrial_management_id = m.industrial_management_id) AS subject_name,
+			( SELECT publish_date FROM cygx_article AS a INNER JOIN cygx_industrial_article_group_management as mg ON mg.article_id = a.article_id  ORDER BY publish_date DESC LIMIT 1  ) AS art_time
+		FROM
+			cygx_article_department AS d
+			INNER JOIN cygx_article AS a ON a.department_id = d.department_id
+			INNER JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = a.article_id
+			INNER JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id 
+			WHERE 1= 1
+			AND d.department_id = ?
+			AND a.publish_status = 1
+			GROUP BY a.article_id
+			ORDER BY art_time DESC
+			LIMIT 4 `
+	_, err = o.Raw(sql, departmentId).QueryRows(&items)
+	return
+}
+
+//最新产业列表
+func GetIndustrialSubjectByDepartmentNew() (items []*IndustrialManagementIdInts, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+	a.article_id,
+	a.industrial_and_subject_ids,
+	m.*,
+	MAX( a.publish_date ) art_time
+FROM
+	cygx_article_department AS d
+	INNER  JOIN cygx_article AS a ON a.department_id = d.department_id
+	LEFT JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = a.article_id
+	LEFT JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id 
+	LEFT JOIN cygx_industrial_article_group_subject AS sg  ON sg.article_id = a.article_id
+WHERE
+	1 = 1 
+	AND a.publish_status = 1 
+	AND a.industrial_and_subject_ids != '' 
+GROUP BY
+	a.industrial_and_subject_ids 
+ORDER BY
+	art_time DESC 
+	LIMIT 6 `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+//获取作者数量
+func GetDepartmentCount(departmentId int) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_department WHERE department_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, departmentId).QueryRow(&count)
+	return
+}
+
+type IndustrialSubjectList struct {
+	SubjectName string `description:"标的名称"`
+}
+
+//最新标的列表
+func GetIndustrialSubjectNewList(condition string) (items []*IndustrialSubjectList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT s.*
+			FROM
+				cygx_industrial_subject AS s
+				INNER JOIN cygx_industrial_article_group_subject AS sg ON sg.industrial_subject_id = s.industrial_subject_id
+				INNER JOIN cygx_article AS art ON art.article_id = sg.article_id
+				INNER JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = art.article_id
+			WHERE
+				1 = 1 
+				AND art.publish_status = 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY s.industrial_subject_id ORDER BY s.create_time DESC LIMIT 4`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+//最新标的列表
+func GetIndustrialSubjectNewListByDepartmentId(departmentId, industrialManagementId int) (items []*IndustrialManagementIdName, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT art.article_id,
+			( SELECT GROUP_CONCAT( DISTINCT s.subject_name ORDER BY s.industrial_subject_id DESC SEPARATOR '/' )  ) AS subject_name
+			FROM
+				cygx_article AS art
+				INNER JOIN cygx_industrial_article_group_subject AS sg ON sg.article_id = art.article_id
+				INNER JOIN cygx_industrial_subject AS s ON s.industrial_subject_id = sg.industrial_subject_id 
+			WHERE
+				department_id = ?
+				AND s.industrial_management_id = ?
+				GROUP BY art.article_id
+				ORDER BY s.create_time DESC  LIMIT 4`
+	_, err = o.Raw(sql, departmentId, industrialManagementId).QueryRows(&items)
+	return
+}
+
+//最新标的列表
+func GetArticleByDepartmentId(departmentId int) (items []*IndustrialManagementIdName, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT article_id,is_report,MAX( publish_date ) art_time  FROM cygx_article WHERE department_id = ? AND  publish_status = 1 AND subject_ids != '' GROUP  BY subject_ids  ORDER BY art_time DESC  LIMIT 4 `
+	_, err = o.Raw(sql, departmentId).QueryRows(&items)
+	return
+}
+
+func GetSubjectNames(articleId int) (subjects string, err error) {
+	sql := ` SELECT GROUP_CONCAT( DISTINCT s.subject_name ORDER BY id ASC SEPARATOR '/' ) AS subject_name 
+				FROM
+				cygx_industrial_article_group_subject as sg 
+				INNER JOIN cygx_industrial_subject as  s ON s.industrial_subject_id = sg.industrial_subject_id 
+				WHERE article_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sql, articleId).QueryRow(&subjects)
+	return
+}
+
+func GetIndustrialNames(articleId int) (Industrial string, err error) {
+	sql := ` SELECT
+	m.industry_name
+FROM
+	cygx_industrial_article_group_management as mg 
+	INNER JOIN cygx_industrial_management as  m ON m.industrial_management_id = mg.industrial_management_id 
+WHERE
+	mg.article_id = ?
+	ORDER BY  m.industrial_management_id DESC
+	LIMIT 1
+`
+	o := orm.NewOrm()
+	err = o.Raw(sql, articleId).QueryRow(&Industrial)
+	return
+}
+
+type IndustrialManagementIdNamePc struct {
+	Title        string `description:"标题"`
+	PublishDate  string `description:"发布时间"`
+	DepartmentId int    `description:"作者ID"`
+	ArticleId    int    `description:"文章id"`
+	IndustryName string `description:"产业名称"`
+	SubjectName  string `description:"标的名称"`
+	IsReport     string `description:"1观点,0纪要"`
+	Pv           int    `description:"Pv"`
+}
+
+//最新标的列表
+func GetArticleByDepartmentIdPc(departmentId int, articleIdGroup string) (items []*IndustrialManagementIdNamePc, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			m.industry_name,
+			(SELECT count(1) FROM cygx_article_history_record_newpv as h WHERE h.article_id = art.article_id ) as pv,
+			GROUP_CONCAT( DISTINCT s.subject_name SEPARATOR '/' ) AS subject_name,
+			art.* 
+		FROM
+			cygx_article AS art
+			LEFT JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = art.article_id
+			LEFT JOIN cygx_industrial_management AS m ON m.industrial_management_id = mg.industrial_management_id
+			LEFT JOIN cygx_industrial_article_group_subject AS sg ON sg.article_id = art.article_id
+			LEFT JOIN cygx_industrial_subject AS s ON s.industrial_subject_id = sg.industrial_subject_id 
+		WHERE
+			department_id = ? 
+			AND publish_status = 1`
+	if articleIdGroup != "" {
+		sql += ` AND art.article_id IN (` + articleIdGroup + `) `
+	}
+	sql += ` GROUP BY art.article_id ORDER BY publish_date DESC `
+	_, err = o.Raw(sql, departmentId).QueryRows(&items)
+	return
+}

+ 80 - 0
models/article_department_follow.go

@@ -0,0 +1,80 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleDepartmentFollow struct {
+	Id           int       `orm:"column(id);pk"`
+	DepartmentId int       `description:"作者ID"`
+	UserId       int       `description:"用户ID"`
+	Mobile       string    `description:"手机号"`
+	Email        string    `description:"邮箱"`
+	CompanyId    int       `description:"公司id"`
+	CompanyName  string    `description:"公司名称"`
+	Type         int       `description:"操作方式,1报名,2取消报名"`
+	CreateTime   time.Time `description:"创建时间"`
+	ModifyTime   time.Time `description:"更新时间"`
+	RealName     string    `description:"用户实际名称"`
+}
+
+type ArticleDepartmentIdRep struct {
+	DepartmentId int `description:"作者ID"`
+}
+
+//添加
+func AddArticleDepartmentFollow(item *CygxArticleDepartmentFollow) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type CygxArticleDepartmentFollowResp struct {
+	Status   int  `description:"1:关注,2:取消关注"`
+	GoFollow bool `description:"是否去关注"`
+}
+
+func RemoveArticleDepartmentFollow(userId, industrialManagementId, doType int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_article_department_follow WHERE user_id=? AND department_id=? `
+	_, err = o.Raw(sql, userId, industrialManagementId).Exec()
+	return
+}
+
+//获取数量
+func GetArticleDepartmentFollow(userId, departmentId int, condition string) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_article_department_follow WHERE user_id=? AND department_id=? ` + condition
+	err = orm.NewOrm().Raw(sql, userId, departmentId).QueryRow(&count)
+	return
+}
+
+//获取数量
+func GetArticleDepartmentFollowByUid(userId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_article_department_follow WHERE user_id=? `
+	err = orm.NewOrm().Raw(sql, userId).QueryRow(&count)
+	return
+}
+
+//获取列表信息根据手机号分组
+func GetArticleDepartmentFollowByMobileList(condition string) (items []*CygxArticleDepartmentFollow, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_department_follow  WHERE 1 =1  ` + condition + `  GROUP BY user_id  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+//修改用户关注作者的相关信息
+func UpdateCygxArticleDepartmentFollow(wxUser *WxUserItem) (err error) {
+	o := orm.NewOrm()
+	var sql string
+	if wxUser.Mobile != "" {
+		sql = `UPDATE cygx_article_department_follow SET email=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE mobile=? `
+		_, err = o.Raw(sql, wxUser.Email, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Mobile).Exec()
+	} else if wxUser.Email != "" {
+		sql = `UPDATE cygx_article_department_follow SET mobile=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE email=? `
+		_, err = o.Raw(sql, wxUser.Mobile, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Email).Exec()
+	}
+
+	return
+}

+ 153 - 0
models/article_history_record.go

@@ -0,0 +1,153 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+type CygxArticleHistoryRecord 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:"修改时间"`
+	StopTime    int       `description:"停留时间"`
+	OutType     int       `description:"退出方式,1正常退出,2强制关闭"`
+}
+
+type CygxArticleHistoryResp struct {
+	Pv        int `description:"阅读PV"`
+	ArticleId int `description:"文章id"`
+	Num       int `description:"数量"`
+}
+
+// 添加历史信息
+func AddCygxArticleHistoryRecord(item *CygxArticleHistoryRecord) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	//var count int
+	//sql := `SELECT COUNT(1) AS count FROM cygx_article_history_record WHERE user_id=? AND article_id=? `
+	//err = o.Raw(sql, item.UserId, item.ArticleId).QueryRow(&count)
+
+	sql := `UPDATE wx_user SET report_last_view_time=NOW() WHERE user_id=?`
+	_, err = o.Raw(sql, item.UserId).Exec()
+	if err != nil {
+		return
+	}
+	//if count > 0 {
+	//	sql := `UPDATE cygx_article_history_record SET modify_time=NOW() WHERE user_id=? AND article_id=? `
+	//	_, err = o.Raw(sql, item.UserId, item.ArticleId).Exec()
+	//} else {
+	//	item.ModifyTime = time.Now()
+	//	lastId, err = o.Insert(item)
+	//}
+	item.ModifyTime = time.Now()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 获取用户阅读记录
+func GetUserToArticleCount(uid, articleId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_article_history_record WHERE user_id=? AND article_id=? `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, articleId).QueryRow(&count)
+	return
+}
+
+type AddStopTimeRep struct {
+	ArticleId int    `description:"文章ID"`
+	StopTime  int    `description:"停留时间"`
+	OutType   int    `description:"退出方式,1正常退出,2强制关闭"`
+	Source    string `description:"来源,MOBILE:手机端,PC:电脑端"`
+}
+
+type AddStopTimeHtgjRep struct {
+	ArticleId   int    `description:"文章ID"`
+	StopTime    int    `description:"停留时间"`
+	OutType     int    `description:"退出方式,1正常退出,2强制关闭"`
+	Source      string `description:"来源,MOBILE:手机端,PC:电脑端"`
+	CompanyCode string `description:"机构编码"`
+	CompanyName string `description:"机构名称"`
+	Email       string `description:"机构邮箱"`
+	Sign        string `description:"签名"`
+}
+
+type AddStopTimeNewRep struct {
+	Id        int `description:"ID"`
+	ArticleId int `description:"文章ID"`
+	StopTime  int `description:"停留时间"`
+	OutType   int `description:"退出方式,1正常退出,2强制关闭"`
+}
+
+type ArticleDetailAddStopTimeRep struct {
+	HasPermission int `description:"1:有该行业权限,正常展示,2:无该行业权限,不存在权益客户下,3:无该品类权限,已提交过申请,4:无该行业权限,未提交过申请,5:潜在客户,未提交过申请,6:潜在客户,已提交过申请"`
+	HasFree       int `description:"1:已付费(至少包含一个品类的权限),2:未付费(没有任何品类权限)"`
+}
+
+func UpdateArticleStopTime(item *AddStopTimeNewRep) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_article_history_record SET stop_time = ?,out_type = ? WHERE id =?`
+	_, err = o.Raw(sql, item.StopTime, item.OutType, item.Id).Exec()
+	return
+}
+
+// 获取最新的一条阅读记录
+func GetNewArticleHistoryRecord(uid, articleId int) (item *AddStopTimeNewRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM  cygx_article_history_record WHERE user_id = ? AND article_id = ? ORDER BY id DESC LIMIT 1;`
+	err = o.Raw(sql, uid, articleId).QueryRow(&item)
+	return
+}
+
+// 获取用户阅读记录
+func GetNoAddStoptimeArticleCount(uid, articleId int) (count int, err error) {
+	sqlCount := `SELECT COUNT(1) AS count FROM cygx_article_history_record WHERE user_id=? AND article_id=? AND create_time > '` + utils.OnlineTime + `' AND stop_time = 0 `
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, uid, articleId).QueryRow(&count)
+	return
+}
+
+// 最新标的列表
+func GetArticleHistoryList() (items []*CygxArticleHistoryRecordNewpv, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *  FROM cygx_article_history_record WHERE company_id != 16 `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 获取用户阅读记录
+func GetUserToArticleHistory(uid int, articleIdArr []int) (items []*CygxArticleHistoryResp, err error) {
+	arrLen := len(articleIdArr)
+	if arrLen == 0 {
+		return
+	}
+	sql := `SELECT
+			article_id 
+		FROM
+			cygx_article_history_record 
+		WHERE
+			1 = 1 
+		AND user_id = ?
+			AND article_id IN (` + utils.GetOrmInReplace(len(articleIdArr)) + `)   
+		GROUP BY
+			article_id `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, uid, articleIdArr).QueryRows(&items)
+	return
+}

+ 49 - 0
models/article_history_record_all.go

@@ -0,0 +1,49 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+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:"是否删除"`
+}
+
+// 获取数量
+func GetCygxArticleHistoryRecordAllCountBycondition(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_history_record_all as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 列表
+func GetCygxArticleHistoryRecordAllList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxArticleHistoryRecordAll, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_history_record_all as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?  `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}

+ 351 - 0
models/article_history_record_newpv.go

@@ -0,0 +1,351 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"strconv"
+	"time"
+)
+
+type CygxArticleHistoryRecordNewpv struct {
+	Id          int `orm:"column(id);pk"`
+	ArticleId   int
+	UserId      int
+	CreateTime  time.Time
+	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:电脑端"`
+}
+
+// 添加阅读记录信息
+func AddCygxArticleViewRecordNewpv(item *CygxArticleHistoryRecordNewpv) (lastId int64, err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	lastId, err = o.Insert(item)
+
+	//写入记录到总的统计表
+	record := new(CygxArticleHistoryRecordAll)
+	record.UserId = item.UserId
+	record.ArticleId = item.ArticleId
+	record.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
+	record.ModifyTime = item.ModifyTime
+	record.Mobile = item.Mobile
+	record.Email = item.Email
+	record.CompanyId = item.CompanyId
+	record.CompanyName = item.CompanyName
+	record.StopTime = item.StopTime
+	record.OutType = item.OutType
+	record.Source = item.Source
+	record.Platfor = 1
+	lastId, err = o.Insert(record)
+
+	// 软删除当天策略平台的文章阅读记录
+	if item.Mobile != "" {
+		sql := `UPDATE cygx_article_history_record_all 
+			SET is_del = 1 
+			WHERE
+			article_id = ? 
+			AND mobile = ?
+			AND platfor = 2
+			AND create_time >= date(NOW()) `
+		_, err = o.Raw(sql, record.ArticleId, record.Mobile).Exec()
+	}
+	return
+}
+
+// 获取最新的一条阅读记录
+func GetNewArticleHistoryRecordNewpv(uid, articleId int, modifytime string) (item *AddStopTimeNewRep, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM  cygx_article_history_record_newpv WHERE user_id = ? AND article_id = ? 	AND modify_time <='` + modifytime + `'  ORDER BY id DESC LIMIT 1;`
+	err = o.Raw(sql, uid, articleId).QueryRow(&item)
+	return
+}
+
+// 把十分钟之内的阅读记录进行累加
+func UpdateCygxArticleViewRecordNewpv(itemRep *CygxArticleHistoryRecordNewpv, stopTime int) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	sql := `UPDATE cygx_article_history_record_newpv 
+			SET modify_time = NOW(), stop_time = stop_time + ` + strconv.Itoa(stopTime) + `
+			WHERE
+			article_id = ? 
+			AND user_id = ?
+			AND out_type = 2
+			AND timestampdiff(MINUTE,modify_time,NOW()) < 10`
+	_, err = o.Raw(sql, itemRep.ArticleId, itemRep.UserId).Exec()
+
+	// 修改总表的停留时间
+	sql = `UPDATE cygx_article_history_record_all 
+			SET modify_time = NOW(), stop_time = stop_time + ` + strconv.Itoa(stopTime) + `
+			WHERE
+			article_id = ? 
+			AND user_id = ?
+			AND out_type = 2
+			AND timestampdiff(MINUTE,modify_time,NOW()) < 10`
+	_, err = o.Raw(sql, itemRep.ArticleId, itemRep.UserId).Exec()
+
+	return
+}
+
+// 把十分钟之内的阅读记录进行累加
+func UpdateCygxArticleViewRecordNewpvList(itemRep *CygxArticleHistoryRecordNewpv, stopTime int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_article_history_record_newpv 
+			SET stop_time = stop_time + ` + strconv.Itoa(stopTime) + `
+			WHERE
+			article_id = ? 
+			AND user_id = ? 
+			AND modify_time = ? 
+			AND id = ?`
+	_, err = o.Raw(sql, itemRep.ArticleId, itemRep.UserId, itemRep.ModifyTime, itemRep.Id).Exec()
+
+	return
+}
+
+// 获取当天总表的阅读记录
+func GetArticleHistoryRecordAllList() (items []*CygxArticleHistoryRecordNewpv, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_article_history_record_all WHERE create_time >= date(NOW()) 
+			AND mobile <> '' 
+			AND platfor = 1
+			GROUP BY mobile,article_id `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 获取列表信息根据手机号分组
+func GetArticleHistoryRecordAllByMobileList(condition string) (items []*CygxArticleHistoryRecordAll, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_history_record_all  WHERE 1 = 1 ` + condition + `  GROUP BY mobile   `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 修改用户阅读的相关信息
+func UpdateCygxArticleHistoryRecordAll(wxUser *WxUserItem) (err error) {
+	o := orm.NewOrm()
+	var sql string
+	if wxUser.Mobile != "" {
+		sql = `UPDATE cygx_article_history_record_all SET email=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE mobile=? `
+		_, err = o.Raw(sql, wxUser.Email, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Mobile).Exec()
+	} else if wxUser.Email != "" {
+		sql = `UPDATE cygx_article_history_record_all SET mobile=?,company_id=?,company_name=?,user_id=?,real_name=? WHERE email=? `
+		_, err = o.Raw(sql, wxUser.Mobile, wxUser.CompanyId, wxUser.CompanyName, wxUser.UserId, wxUser.RealName, wxUser.Email).Exec()
+	}
+	return
+}
+
+type EsUserInteraction struct {
+	Id                       int    `description:"主键ID"`
+	ArticleId                int    `description:"文章id"`
+	ArticleType              int    `description:"文章类型 1:查研观向, 2:策略平台"`
+	Title                    string `description:"标题"`
+	PublishDate              string `description:"发布时间"`
+	CreateTime               string `description:"创建时间"`
+	StopTime                 string `description:"阅读停留时间"`
+	RealName                 string `description:"姓名"`
+	CompanyName              string `description:"公司名称"`
+	CompanyId                int    `description:"公司ID"`
+	SellerName               string `description:"所属销售"`
+	SellerId                 int    `description:"所属销售ID"`
+	Mobile                   string `description:"手机号"`
+	Email                    string `description:"邮箱"`
+	UserId                   int    `description:"用户ID"`
+	UserArticleHistoryNum    int    `description:"用户阅读数量"`
+	CompanyArticleHistoryNum int    `description:"机构阅读数量"`
+}
+
+// 机构阅读记录列表
+func GetCygxArticleHistoryRecordByCompanyList(condition string, startSize, pageSize int) (items []*EsUserInteraction, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+			r.id,
+			art.title,
+			art.article_id,
+			art.article_id_md5,
+			art.publish_date,
+			art.category_name,
+			r.create_time,
+			r.mobile,
+			r.user_id,
+			r.company_name,
+			cp.seller_name,
+			cp.seller_id,
+			cp.company_id,
+			r.real_name,
+			r.stop_time,
+			ci.article_history_num AS company_article_history_num,
+			ui.article_history_num AS user_article_history_num 
+		FROM
+			cygx_article_history_record_all AS r
+			INNER JOIN cygx_article AS art ON art.article_id = r.article_id
+			INNER JOIN company_product AS cp ON cp.company_id = r.company_id 
+			AND cp.product_id = 2
+			INNER JOIN cygx_company_interaction_num AS ci ON ci.company_id = r.company_id
+			INNER JOIN cygx_user_interaction_num AS ui ON ui.user_id = r.user_id 
+		WHERE
+			1 = 1 
+			AND r.is_del = 0 ` + condition + ` GROUP BY r.id  `
+	if startSize > 0 || pageSize > 0 {
+		sql += ` LIMIT ` + strconv.Itoa(startSize) + "," + strconv.Itoa(pageSize)
+	}
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 机构阅读记录列表
+func GetCygxArticleHistoryRecordByCompanyListNew(condition string, pars interface{}, startSize, pageSize int) (items []*EsUserInteraction, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+			r.id,
+			art.title,
+			art.article_id,
+			art.article_id_md5,
+			art.publish_date,
+			art.category_name,
+			r.create_time,
+			r.mobile,
+			r.user_id,
+			r.company_name,
+			r.company_id,
+			r.real_name,
+			r.stop_time,
+			ci.article_history_num AS company_article_history_num,
+			ui.article_history_num AS user_article_history_num 
+		FROM
+			cygx_article_history_record_all AS r
+			INNER JOIN cygx_article AS art ON art.article_id = r.article_id
+			LEFT JOIN cygx_company_interaction_num AS ci ON ci.company_id = r.company_id
+			LEFT JOIN cygx_user_interaction_num AS ui ON ui.user_id = r.user_id 
+		WHERE
+			1 = 1 
+			AND r.is_del = 0 ` + condition + ` GROUP BY r.id  `
+	if startSize > 0 || pageSize > 0 {
+		sql += ` LIMIT ` + strconv.Itoa(startSize) + "," + strconv.Itoa(pageSize)
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 获取阅读记录数量
+func GetCygxArticleHistoryCountByCompany(condition string) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := `SELECT
+	COUNT( 1 ) AS count 
+FROM
+	(
+	SELECT
+		COUNT( 1 ) 
+	FROM
+		cygx_article_history_record_all AS r
+		INNER JOIN cygx_article AS art ON art.article_id = r.article_id
+		INNER JOIN company_product AS cp ON cp.company_id = r.company_id 
+		AND cp.product_id = 2
+		INNER JOIN cygx_company_interaction_num AS ci ON ci.company_id = r.company_id
+		INNER JOIN cygx_user_interaction_num AS ui ON ui.user_id = r.user_id 
+	WHERE
+		r.is_del = 0 ` + condition + `
+	GROUP BY
+	r.id 
+	) AS count `
+	err = o.Raw(sqlCount).QueryRow(&count)
+	return
+}
+
+type CygxArticleHistoryAllTopResp struct {
+	Pv        int `description:"阅读PV"`
+	ArticleId int `description:"文章id"`
+	Num       int `description:"数量"`
+}
+
+// 获取近15天之内的阅读数据最多的15报告
+func GetCygxArticleHistoryAllTop(pars []interface{}, condition string) (items []*CygxArticleHistoryAllTopResp, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+			COUNT( 1 ) AS pv,
+			a.article_id 
+		FROM
+			cygx_article_history_record_all AS l
+			INNER JOIN cygx_article AS a ON a.article_id = l.article_id
+			INNER JOIN cygx_report_mapping AS m ON m.category_id = a.category_id 
+			WHERE
+				1 = 1 
+				AND l.platfor = 1` + condition + `
+			GROUP BY
+				l.article_id 
+			ORDER BY
+				pv DESC ,a.publish_date DESC 
+				LIMIT 15 `
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetCygxArticleHistoryRecordNewpvList(condition string, pars []interface{}) (items []*CygxArticleHistoryRecordNewpv, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_history_record_newpv as art WHERE 1= 1  `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+type ListPvUvResp struct {
+	ArticleId int `description:"文章ID"`
+	Pv        int `description:"pv"`
+	Uv        int `description:"pv"`
+}
+
+// 列表
+func GetCygxArticleHistoryRecordNewpvListPv(condition string, pars []interface{}) (items []*ListPvUvResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+			COUNT( 1 ) AS pv,
+			article_id
+		FROM
+			cygx_article_history_record_newpv  WHERE 1 = 1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY article_id `
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 获取数量
+func GetCygxArticleHistoryRecordAllCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_history_record_all  WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}

+ 80 - 0
models/article_interview_apply.go

@@ -0,0 +1,80 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxInterviewApply struct {
+	InterviewApplyId int       `orm:"column(interview_apply_id);pk"`
+	UserId           int       `description:"用户id"`
+	CompanyId        int       `description:"客户id"`
+	Status           string    `description:"'待邀请','待访谈','已完成','已取消'"`
+	InterviewTime    time.Time `description:"访谈时间"`
+	ArticleId        int       `description:"纪要id"`
+	Sort             int       `description:"排序"`
+	ArticleTitle     string    `description:"纪要标题"`
+	CreateTime       time.Time `description:"创建时间"`
+	ModifyTime       time.Time `description:"修改时间"`
+	ArticleIdMd5     string    `description:"纪要id"`
+}
+
+//添加申请访谈信息
+func AddCygxInterviewApply(item *CygxInterviewApply) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type ArticleInterviewApplyReq struct {
+	ArticleId int `description:"报告id"`
+}
+
+type ArticleInterviewApplyResp struct {
+	Status int `description:"1:申请成功,2:取消申请"`
+}
+
+func RemoveArticleInterviewApply(userId, articleId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_interview_apply WHERE user_id=? AND article_id=? AND status<>'已取消' `
+	_, err = o.Raw(sql, userId, articleId).Exec()
+	return
+}
+
+func GetArticleInterviewApplyUsersCount(articleId int) (count int, err error) {
+	sql := `SELECT COUNT(user_id) AS count FROM cygx_interview_apply WHERE article_id=? `
+	err = orm.NewOrm().Raw(sql, articleId).QueryRow(&count)
+	return
+}
+
+func GetArticleInterviewApply(userId, articleId int) (item *CygxInterviewApply, err error) {
+	sql := `SELECT * FROM cygx_interview_apply WHERE user_id=? AND article_id=? AND status<>'已取消' `
+	err = orm.NewOrm().Raw(sql, userId, articleId).QueryRow(&item)
+	return
+}
+
+func GetArticleInterviewApplyCount(userId, articleId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_interview_apply WHERE user_id=? AND article_id=? AND status<>'已取消'  `
+	err = orm.NewOrm().Raw(sql, userId, articleId).QueryRow(&count)
+	return
+}
+
+type ArticleInterviewApplyList struct {
+	Id               int `orm:"column(id);pk"`
+	ArticleId        int
+	UserId           int
+	CreateTime       string
+	Title            string `description:"标题"`
+	TitleEn          string `description:"英文标题 "`
+	UpdateFrequency  string `description:"更新周期"`
+	CreateDate       string `description:"创建时间"`
+	PublishDate      string `description:"发布时间"`
+	Body             string `description:"内容"`
+	Abstract         string `description:"摘要"`
+	CategoryName     string `description:"一级分类"`
+	SubCategoryName  string `description:"二级分类"`
+	Status           string `description:"'待邀请','待访谈','已完成','已取消'"`
+	InterviewTime    string `description:"访谈时间"`
+	ExpertBackground string `description:"专家背景"`
+	ExpertNumber     string `description:"专家编号"`
+}

+ 85 - 0
models/article_top_history_record.go

@@ -0,0 +1,85 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ArticleTopHistoryRecord 报告阅读飙升榜
+type ArticleTopHistoryRecord struct {
+	Id                int       `orm:"column(id);pk"`
+	ArticleId         int       `description:"文章ID"`
+	Title             string    `description:"文章标题"`
+	PublishDate       string    `description:"发布日期"`
+	ChartPermissionId int       `description:"行业ID"`
+	PermissionName    string    `description:"行业名称"`
+	Pv                int       `description:"PV"`
+	CreateTime        time.Time `description:"创建时间"`
+}
+
+func (item *ArticleTopHistoryRecord) TableName() string {
+	return "cygx_article_top_history_record"
+}
+
+// GetTopReadRecordArticleListFromSource 获取阅读量排行榜源报告
+func GetTopReadRecordArticleListFromSource(startTime, endTime time.Time) (list []*ArticleTopHistoryRecord, err error) {
+	sql := `SELECT
+				a.article_id,
+				a.title,
+				date_format(a.publish_date, '%Y-%m-%d') AS publish_date,
+				m.chart_permission_id,
+				m.chart_permission_name as permission_name,
+				COUNT(1) AS pv
+			FROM
+				cygx_article_history_record_newpv AS l
+			JOIN cygx_article AS a ON a.article_id = l.article_id
+			JOIN cygx_report_mapping AS m ON m.category_id = a.category_id
+			WHERE
+				a.publish_status = 1 AND l.create_time BETWEEN ? AND ?
+			GROUP BY
+				l.article_id
+			ORDER BY
+				pv DESC,
+				a.publish_date DESC`
+	_, err = orm.NewOrm().Raw(sql, startTime, endTime).QueryRows(&list)
+	return
+}
+
+// UpdateTopReadRecordArticleList 更新榜单
+func UpdateTopReadRecordArticleList(items []*ArticleTopHistoryRecord) (err error) {
+	o := orm.NewOrm()
+	tx, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+		} else {
+			_ = tx.Commit()
+		}
+	}()
+	// 重置榜单
+	sql := `DELETE FROM cygx_article_top_history_record WHERE 1 = 1 `
+	_, err = tx.Raw(sql).Exec()
+	if err != nil {
+		return
+	}
+	// 新增今日榜单
+	_, err = tx.InsertMulti(len(items), items)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// GetTopReadRecordArticleListByCondition 获取阅读量排行榜
+func GetTopReadRecordArticleListByCondition(limit int, condition string, pars []interface{}) (list []*ArticleTopHistoryRecord, err error) {
+	sql := `SELECT * FROM cygx_article_top_history_record WHERE 1 = 1 `
+	if condition != `` {
+		sql += condition
+	}
+	sql += ` ORDER BY pv DESC, publish_date DESC LIMIT ?`
+	_, err = orm.NewOrm().Raw(sql, pars, limit).QueryRows(&list)
+	return
+}

+ 70 - 0
models/article_type.go

@@ -0,0 +1,70 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleType struct {
+	ArticleTypeId      int       `orm:"column(article_type_id);pk";description:"文章类型ID"`
+	ArticleTypeName    string    `description:"类型名称"`
+	Sort               int       `description:"排序字段"`
+	CreateTime         time.Time `description:"创建时间"`
+	ModifyTime         time.Time `description:"最后修改时间"`
+	IsSendEs           int       `description:"这种报告类型是否同步到Es"`
+	YanxPermissionId   int       `description:"研选类型所对应的ID"`
+	YanxPermissionName string    `description:"研选类型所对应的名称"`
+	IcoLink            string    `description:"图标链接地址"`
+	IcoLinkM           string    `description:"移动端图标链接地址"`
+	IsShowLinkButton   int       `description:"这种报告类型是否展示查看报告链接"`
+	ButtonStyle        string    `description:"按钮展示样式"`
+}
+
+type CygxArticleTypeResp struct {
+	ArticleTypeId   int    `description:"文章类型ID"`
+	ArticleTypeName string `description:"类型名称"`
+	ButtonStyle     string `description:"按钮展示样式"`
+}
+
+type CygxArticleTypeListResp struct {
+	List []*CygxArticleTypeResp
+}
+
+// 详情
+func GetCygxArticleTypeDetailById(activityTypeId int) (item *CygxArticleType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_type WHERE article_type_id = ? `
+	err = o.Raw(sql, activityTypeId).QueryRow(&item)
+	return
+}
+
+// 获取数量
+func GetCygxArticleTypeCount(condition string) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := `SELECT COUNT(1) AS count  FROM cygx_article_type WHERE  1=1 ` + condition
+	err = o.Raw(sqlCount).QueryRow(&count)
+	return
+}
+
+// 报告类型列表
+func GetCygxArticleTypeList() (items []*CygxArticleType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_type ORDER BY sort DESC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 报告类型列表
+func GetCygxArticleTypeListCondition(condition string) (items []*CygxArticleType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_type   WHERE  1=1 ` + condition + ` ORDER BY sort DESC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetArticleTypeInfo(activityTypeId int) (item *CygxArticleType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_article_type   WHERE  article_type_id=? `
+	err = o.Raw(sql, activityTypeId).QueryRow(&item)
+	return
+}

+ 24 - 0
models/article_view_record.go

@@ -0,0 +1,24 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxArticleViewRecord 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:"公司名称"`
+}
+
+//添加收藏信息
+func AddCygxArticleViewRecord(item *CygxArticleViewRecord) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}

+ 49 - 0
models/askserie_video_collect.go

@@ -0,0 +1,49 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxAskserieVideoCollect struct {
+	Id               int       `orm:"column(id);pk"`
+	AskserieVideoId  int       `description:"askserie_video_id"`
+	UserId           int       `description:"用户ID"`
+	CreateTime       time.Time `description:"创建时间"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+	ModifyTime       time.Time `description:"更新时间"`
+}
+
+// 添加
+func AddCygxAskserieVideoCollect(item *CygxAskserieVideoCollect) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+func RemoveAskserieVideoCollect(userId, askserieVideoId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_askserie_video_collect WHERE user_id=? AND askserie_video_id=? `
+	_, err = o.Raw(sql, userId, askserieVideoId).Exec()
+	return
+}
+
+func GetAskserieVideoCount(userId, askserieVideoId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_askserie_video_collect WHERE user_id=? AND askserie_video_id=? `
+	err = orm.NewOrm().Raw(sql, userId, askserieVideoId).QueryRow(&count)
+	return
+}
+
+func GetUserCygxAskserieVideoCollectList(userId int) (items []*CygxAskserieVideoCollect, err error) {
+	sql := `SELECT a.* FROM cygx_askserie_video_collect AS a 
+			WHERE a.user_id=?
+           ORDER BY a.id DESC `
+	_, err = orm.NewOrm().Raw(sql, userId).QueryRows(&items)
+	return
+}

+ 36 - 0
models/askserie_video_collection.go

@@ -0,0 +1,36 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxAskserieVideoCollection struct {
+	Id               int       `orm:"column(id);pk"`
+	AskserieVideoId  int       `description:"askserie_video_id"`
+	UserId           int       `description:"用户ID"`
+	CreateTime       time.Time `description:"创建时间"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+	ModifyTime       time.Time `description:"更新时间"`
+	Content          string    `description:"留言内容"`
+}
+
+// 添加
+func AddCygxAskserieVideoCollection(item *CygxAskserieVideoCollection) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+func UpdateAskserieVideoCommentNum(askserieVideoId int) (err error) {
+	sql := `UPDATE cygx_askserie_video SET comment_num = comment_num+1 WHERE askserie_video_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, askserieVideoId).Exec()
+	return
+}

+ 50 - 0
models/askserie_video_history_record.go

@@ -0,0 +1,50 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxAskserieVideoHistoryRecord struct {
+	Id               int       `orm:"column(id);pk"`
+	AskserieVideoId  int       `description:"askserie_video_id"`
+	UserId           int       `description:"用户ID"`
+	CreateTime       time.Time `description:"创建时间"`
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+	ModifyTime       time.Time `description:"更新时间"`
+	VideoDuration    int       `description:"播放时长"`
+}
+
+// 添加
+func AddCygxAskserieVideoHistoryRecord(item *CygxAskserieVideoHistoryRecord) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+func UpdateAskserieVideoCounts(askserieVideoId int) (err error) {
+	sql := `UPDATE cygx_askserie_video SET video_counts = video_counts+1 WHERE askserie_video_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, askserieVideoId).Exec()
+	return
+}
+
+func GetLastCygxAskserieVideoHistoryRecord(activityId, userId int) (item *CygxActivityVoiceHistory, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_askserie_video_history_record WHERE askserie_video_id=?  AND user_id=? AND register_platform = 1 ORDER BY create_time DESC limit 1 `
+	err = o.Raw(sql, activityId, userId).QueryRow(&item)
+	return
+}
+
+func UpdateLastCygxAskserieVideoHistoryRecord(playSeconds string, lastId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_askserie_video_history_record SET video_duration = video_duration+? WHERE id=? `
+	_, err = o.Raw(sql, playSeconds, lastId).Exec()
+	return
+}

+ 91 - 0
models/banner.go

@@ -0,0 +1,91 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type CygxBannerResp struct {
+	BannerId       int            `description:"BannerId等于0新增,大于零修改"`
+	ImgId          int            `description:"cygx_banner_img主键ID"`
+	IndexImg       string         `description:"小程序封面图"`
+	ListType       string         `description:"ABC哪一列"`
+	BannerTypeName string         `description:"添加类型名称"`
+	Title          string         `description:"标题"`
+	Link           string         `description:"链接地址"`
+	Subtitle       string         `description:"副标题"`
+	BannerUrlResp  *BannerUrlResp `description:"跳转地址"`
+}
+
+type CygxBannerIdReq struct {
+	BannerId int `description:"BannerId"`
+}
+
+type GetCygxBannerImgRespDetailResp struct {
+	Detail *CygxBannerResp
+}
+
+// 通过ID获取详情
+func GetCygxBannerDetail(banneId int) (item *CygxBannerResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_banner  WHERE banner_id=? `
+	err = o.Raw(sql, banneId).QueryRow(&item)
+	return
+}
+
+// 获取数量
+func GetCygxBannerCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_banner as art WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 列表
+func GetCygxBannerList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxBannerResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_banner as art WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,?  `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+type CygxBannerListResp struct {
+	List []*CygxBannerResp
+}
+
+type CygxBannerImgResp struct {
+	ImgId    int    `description:"图片ID"`
+	IndexImg string `description:"小程序封面图"`
+}
+
+type BannerUrlResp struct {
+	ChartPermissionId int    `description:"行业id"`
+	SourceId          int    `description:"资源ID"`
+	Type              int    `description:"类型:1普通文本,2:文章、3:活动、4:产业、5:关于我们、6:产品内测"`
+	Body              string `description:"内容"`
+	Path              string `description:"小程序路径"`
+}
+
+type BannerUrlYxResp struct {
+	IndexImg string `description:"小程序封面图"`
+	Path     string `description:"小程序路径"`
+}
+
+type BannerUrlYxListResp struct {
+	ListA []*BannerUrlYxResp
+	ListB []*BannerUrlYxResp
+}
+
+// 列表
+func GetCygxBannerImgList() (items []*CygxBannerImgResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_banner_img as art WHERE 1= 1 `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 29 - 0
models/banner_history.go

@@ -0,0 +1,29 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxBannerHistory struct {
+	Id               int `orm:"column(id);pk"`
+	BannerId         int `description:"BannerId等于0新增,大于零修改"`
+	UserId           int
+	CreateTime       time.Time
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	ModifyTime       time.Time `description:"修改时间"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+}
+
+// 添加历史信息
+func AddCygxBannerHistory(item *CygxBannerHistory) (lastId int64, err error) {
+	o := orm.NewOrm()
+	item.ModifyTime = time.Now()
+	lastId, err = o.Insert(item)
+	return
+}

+ 74 - 0
models/banner_yx_survey.go

@@ -0,0 +1,74 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+//type CygxBannerYxSurvey struct {
+//	SuveryId         int       `gorm:"column:suvery_id;primary_key;AUTO_INCREMENT" json:"suvery_id"`
+//	UserId           int       `gorm:"column:user_id" json:"user_id"`                                        // 用户ID
+//	Mobile           string    `gorm:"column:mobile" json:"mobile"`                                          // 手机号
+//	Email            string    `gorm:"column:email" json:"email"`                                            // 邮箱
+//	CompanyId        int       `gorm:"column:company_id;default:0" json:"company_id"`                        // 公司ID
+//	CompanyName      string    `gorm:"column:company_name" json:"company_name"`                              // 公司名称
+//	RealName         string    `gorm:"column:real_name" json:"real_name"`                                    // 用户实际名称
+//	SellerName       string    `gorm:"column:seller_name" json:"seller_name"`                                // 所属销售
+//	CreateTime       time.Time `gorm:"column:create_time" json:"create_time"`                                // 创建时间
+//	ModifyTime       time.Time `gorm:"column:modify_time" json:"modify_time"`                                // 修改时间
+//	RegisterPlatform int       `gorm:"column:register_platform;default:1;NOT NULL" json:"register_platform"` // 来源 1小程序,2:网页
+//	Content          string    `gorm:"column:content;NOT NULL" json:"content"`                               // 内容
+//}
+
+type CygxBannerYxSurvey struct {
+	SuveryId         int `orm:"column(suvery_id);pk"`
+	UserId           int
+	CreateTime       time.Time
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	ModifyTime       time.Time `description:"修改时间"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	Content          string    `description:"内容"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+}
+
+type CygxBannerYxSurveyReq struct {
+	Content string `description:"内容"`
+}
+
+type CygxBannerYxSurveyResp struct {
+	SuveryId         int    `gorm:"column:suvery_id;primary_key;AUTO_INCREMENT" json:""`
+	UserId           int    `gorm:"column:user_id" json:""`                              // 用户ID
+	Mobile           string `gorm:"column:mobile" json:""`                               // 手机号
+	Email            string `gorm:"column:email" json:""`                                // 邮箱
+	CompanyId        int    `gorm:"column:company_id;default:0" json:""`                 // 公司ID
+	CompanyName      string `gorm:"column:company_name" json:""`                         // 公司名称
+	RealName         string `gorm:"column:real_name" json:""`                            // 用户实际名称
+	SellerName       string `gorm:"column:seller_name" json:""`                          // 所属销售
+	CreateTime       string `gorm:"column:create_time" json:""`                          // 创建时间
+	ModifyTime       string `gorm:"column:modify_time" json:""`                          // 修改时间
+	RegisterPlatform int    `gorm:"column:register_platform;default:1;NOT NULL" json:""` // 来源 1小程序,2:网页
+	Content          string `gorm:"column:content;NOT NULL" json:""`                     // 内容
+}
+
+// 添加信息
+func AddCygxBannerYxSurvey(item *CygxBannerYxSurvey) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 通过ID获取详情
+func GetCygxBannerYxSurveyDetail(suveryId int) (item *CygxBannerYxSurveyResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_banner_yx_survey  WHERE suvery_id=?  `
+	err = o.Raw(sql, suveryId).QueryRow(&item)
+	return
+}
+
+type CygxBannerYxSurveyRespDetailResp struct {
+	Detail *CygxBannerYxSurveyResp
+}

+ 31 - 0
models/base.go

@@ -0,0 +1,31 @@
+package models
+
+type BaseResponse struct {
+	Ret     int
+	Msg     string
+	ErrMsg  string
+	ErrCode string
+	Data    interface{}
+	Success bool `description:"true 执行成功,false 执行失败"`
+	IsSendEmail bool `json:"-"`
+}
+
+type BaseResponseRef struct {
+	Ret     int
+	Msg     string
+	ErrMsg  string
+	ErrCode string
+	Data    string
+}
+
+type BaseResponseResult struct {
+	Ret     int    `description:"状态:200 成功,408 重新登录,403:为失败"`
+	Msg     string `description:"提示信息,对用户展示"`
+	ErrMsg  string `description:"错误信息,供开发定位问题"`
+	ErrCode string `description:"错误编码,预留"`
+	Data    string `description:"返回数据,json格式字符串"`
+}
+
+func (r *BaseResponse) Init() *BaseResponse {
+	return &BaseResponse{Ret: 403,IsSendEmail: true}
+}

+ 154 - 0
models/chart_permission.go

@@ -0,0 +1,154 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+)
+
+type ChartPermission struct {
+	ChartPermissionId int    `description:"权限id"`
+	PermissionName    string `description:"权限名称"`
+	IsShowSustainable bool   `description:"是否展示限免标签"`
+	ImageUrlM         string `description:"图片地址"`
+	IsChoose          bool   `description:"是否选择"`
+}
+
+type ActivityChartPermission struct {
+	ChartPermissionId int    `description:"权限id"`
+	PermissionName    string `description:"权限名称"`
+	IsChoose          bool   `description:"是否选择"`
+}
+
+type ChartPermissionResp struct {
+	List []*ChartPermission
+}
+
+func GetChartPermissionAll(condition string) (items []*ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM chart_permission WHERE product_id=2 AND show_type=1  AND permission_type!=2  ` + condition + ` ORDER BY sort ASC `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetChartPermissionListRai() (items []*ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM chart_permission WHERE product_id=2  ORDER BY sort ASC `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetCategoryId(chartPermissionId int) (category_id string, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT GROUP_CONCAT(a.category_id) AS category_id 
+			FROM cygx_report_mapping AS a
+			WHERE a.chart_permission_id=? AND a.is_summary = 1
+			GROUP BY a.chart_permission_id `
+	err = o.Raw(sql, chartPermissionId).QueryRow(&category_id)
+	return
+}
+
+func GetChartPermissionReportAll(condition string) (items []*ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM chart_permission WHERE product_id=2 AND is_report=1 AND permission_type!=2 ` + condition + ` ORDER BY sort ASC `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetChartPermissionById(chartPermissionId int) (item *ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM chart_permission WHERE chart_permission_id = ? `
+	err = o.Raw(sql, chartPermissionId).QueryRow(&item)
+	return
+}
+
+func GetChartPermissionActivity() (items []*ActivityChartPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM chart_permission WHERE chart_permission_id IN (19,20,21,22,23,31) ORDER BY sort ASC `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 处理添加主观客观之后的分类ID错误
+func GetUserCompanyPermission(companyId int) (items []*ActivityChartPermission, err error) {
+	list, err := GetUserCompanyPermissionSandO(companyId)
+	if err != nil {
+		return
+	}
+	if len(list) == 0 {
+		return
+	}
+	var chartPermissionName string
+	for _, v := range list {
+		chartPermissionName += "'" + v.PermissionName + "'" + ","
+	}
+	chartPermissionName = strings.Trim(chartPermissionName, ",")
+	sql := ` SELECT b.*
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE a.product_id=2
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+            AND b.is_other=0
+			AND c.status IN('正式','试用','永续')
+			AND a.status IN('正式','试用','永续') 
+			AND b.chart_permission_name IN (` + chartPermissionName + `)
+			GROUP BY b.chart_permission_name
+			ORDER BY b.sort ASC `
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func GetUserCompanyPermissionSandO(companyId int) (items []*ActivityChartPermission, err error) {
+	sql := ` SELECT b.*
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND a.product_id=2
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+            AND b.is_other=0
+			AND c.status IN('正式','试用','永续')
+			AND a.status IN('正式','试用','永续') 
+			AND b.chart_permission_name != '专家'
+			GROUP BY b.chart_permission_name
+			ORDER BY b.sort ASC `
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Raw(sql, companyId).QueryRows(&items)
+	return
+}
+
+// 获取策略下面的所有分类
+func GetCompanyReportPermissionAll() (items []*CompanyReportPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM company_report_permission WHERE chart_permission_id IN (19,20,21,22) AND status IN ('正式','试用','永续')  AND created_time <= '2021-12-28 15:05:43'`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 获取海通国际开通的默认权限
+func GetCompanyPermissionIdWithHtgj() (chartpermissionids string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT chart_permission_id  ORDER BY b.sort ASC  SEPARATOR ',') AS chartpermissionids
+			FROM chart_permission as  b 
+			WHERE chart_permission_name IN ('医药','消费','科技','智造','买方研选')`
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql).QueryRow(&chartpermissionids)
+	return
+}
+
+// GetChartPermissionById 主键获取权限
+func GetChartPermissionByRemark(remark string) (item *ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM chart_permission WHERE remark = ? LIMIT 1`
+	err = o.Raw(sql, remark).QueryRow(&item)
+	return
+}
+
+func GetChartPermissionIdByName(condition string, pars []interface{}) (chartpermissionids string, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT GROUP_CONCAT(DISTINCT chart_permission_id   SEPARATOR ',') AS chartpermissionids FROM chart_permission  WHERE product_id=2  ` + condition
+	err = o.Raw(sql, pars).QueryRow(&chartpermissionids)
+	return
+}

+ 276 - 0
models/company.go

@@ -0,0 +1,276 @@
+package models
+
+import "github.com/beego/beego/v2/client/orm"
+
+type CompanyDetail struct {
+	CompanyId   int    `orm:"column(company_id);pk"`
+	CompanyName string `description:"客户名称"`
+	Status      string `description:"客户状态"`
+	SellerId    int    `description:"销售id"`
+	SellerName  string `description:"销售名称"`
+	Mobile      string `description:"销售手机号"`
+	ProductId   int    `description:"1,FICC,2权益"`
+	IsSuspend   int    `description:"1:暂停,0:启用"`
+}
+
+func GetCompanyDetailById(companyId int) (item *CompanyDetail, err error) {
+	//sql := ` SELECT a.company_id,a.company_name,b.status,b.seller_id,b.seller_name,c.mobile
+	//        FROM company AS a
+	//		INNER JOIN company_product AS b ON a.company_id=b.company_id
+	//		LEFT JOIN admin AS c ON b.seller_id=c.admin_id
+	//		WHERE a.company_id=? AND  b.product_id=2 `
+
+	sql := ` SELECT a.company_id,a.company_name,b.status,b.seller_id,b.seller_name,c.mobile,p.product_id
+            FROM company AS a
+			INNER JOIN company_product AS b ON a.company_id=b.company_id
+			INNER JOIN company_report_permission AS p ON p.company_id = a.company_id
+			INNER JOIN chart_permission AS cp ON cp.chart_permission_id=p.chart_permission_id
+			LEFT JOIN admin AS c ON b.seller_id=c.admin_id
+			WHERE a.company_id=? AND cp.cygx_auth=1
+			OR (a.company_id = ? AND  cp.permission_name = '策略' ) ORDER BY  b.product_id  DESC LIMIT 1` // 兼容永续状态
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId, companyId).QueryRow(&item)
+	return
+}
+
+func GetCompanyDetailByIdGroup(companyId int) (item *CompanyDetail, err error) {
+	sql := ` SELECT a.company_id,a.company_name,b.status,b.seller_id,b.seller_name,c.mobile ,b.is_suspend
+            FROM company AS a
+			INNER JOIN company_product AS b ON a.company_id=b.company_id
+			INNER JOIN company_report_permission AS p ON p.company_id = a.company_id
+			INNER JOIN chart_permission AS cp ON cp.chart_permission_id = p.chart_permission_id
+			LEFT JOIN admin AS c ON b.seller_id=c.admin_id
+			WHERE a.company_id=? AND b.product_id = 2 
+			OR (a.company_id = ? AND  cp.permission_name = '策略' ) 
+			ORDER BY b.product_id DESC  LIMIT 0,1 `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId, companyId).QueryRow(&item)
+	return
+}
+
+func GetCountCompanyDetailByIdGroup(companyId int) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count
+            FROM company AS a
+			INNER JOIN company_product AS b ON a.company_id=b.company_id
+			INNER JOIN company_report_permission AS p ON p.company_id = a.company_id
+			INNER JOIN chart_permission AS cp ON cp.chart_permission_id = p.chart_permission_id
+			LEFT JOIN admin AS c ON b.seller_id=c.admin_id
+			WHERE a.company_id=? AND b.product_id = 2    OR (a.company_id = ? AND  cp.permission_name = '策略' )   `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId, companyId).QueryRow(&count)
+	return
+}
+
+//原有权限叫校验,下方更改与2021-5.18
+//func GetCompanyPermission(companyId int) (permission string, err error) {
+//	sql := ` SELECT GROUP_CONCAT(DISTINCT b.chart_permission_name  ORDER BY b.sort ASC SEPARATOR ',') AS permission
+//			FROM company_report_permission AS a
+//			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+//			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+//			WHERE  a.company_id=?
+//			AND a.product_id=2
+//            AND b.show_type=1
+//			AND c.status IN('正式','试用','永续') `
+//	o := orm.NewOrm()
+//	err = o.Raw(sql, companyId).QueryRow(&permission)
+//	return
+//}
+
+func GetCompanyPermission(companyId int) (permission string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT b.remark  ORDER BY b.sort ASC SEPARATOR ',') AS permission
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+			AND c.status IN('正式','试用','永续')
+			AND a.status IN('正式','试用','永续') `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&permission)
+	return
+}
+
+func GetCompanyPermissionName(companyId int) (permission string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT b.chart_permission_name  ORDER BY b.sort ASC SEPARATOR ',') AS permission
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+			AND c.status IN('正式','试用','永续')
+			AND a.status IN('正式','试用','永续') `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&permission)
+	return
+}
+
+func GetCompanyPermissionByUser(companyId int) (permission string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT b.remark  ORDER BY b.sort ASC  SEPARATOR ',') AS permission
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+			AND c.status IN('正式','试用','永续')
+			AND a.status IN('正式','试用','永续') `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&permission)
+	return
+}
+
+type PermissionItem struct {
+	ChartPermissionId int    `description:"权限id"`
+	PermissionName    string `description:"权限名称"`
+	IsUpgrade         int    `description:"是否升级,1是,0否"`
+	Remark            string `description:"备注区分主观客观"`
+}
+
+func GetCompanyPermissionList(companyId int) (items []*PermissionItem, err error) {
+	sql := ` SELECT b.chart_permission_id,b.permission_name,b.remark,a.is_upgrade
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+			AND c.status IN('正式','试用','永续')
+			AND a.status IN('正式','试用','永续')   ORDER BY b.sort ASC `
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Raw(sql, companyId).QueryRows(&items)
+	return
+}
+
+// 获取用户权限不限制状态
+func GetCompanyPermissionByUserNoStatus(companyId int) (permission string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT b.remark  ORDER BY b.sort ASC  SEPARATOR ',') AS permission
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND c.is_suspend=0
+            AND b.cygx_auth=1`
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&permission)
+	return
+}
+
+// 获取正式权限
+func GetCompanyPermissionByUserZhengShi(companyId int) (permission string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT b.remark  ORDER BY b.sort ASC  SEPARATOR ',') AS permission
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+			AND a.status IN('正式') `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&permission)
+	return
+}
+
+func GetCompanyPermissionByName(name string) (permission string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT b.chart_permission_name  ORDER BY b.sort ASC SEPARATOR '/') AS permission
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			INNER JOIN company AS cm ON cm.company_id=c.company_id 
+			WHERE  cm.company_name=?
+			AND b.product_id = 2 `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, name).QueryRow(&permission)
+	return
+}
+
+func GetCompanyDetailAllById(companyId int) (item *CompanyDetail, err error) {
+	sql := ` SELECT a.company_id,a.company_name,b.status,b.seller_id,b.seller_name,c.mobile 
+            FROM company AS a
+			INNER JOIN company_product AS b ON a.company_id=b.company_id
+			INNER JOIN company_report_permission AS p ON p.company_id = a.company_id
+			INNER JOIN chart_permission AS cp ON cp.chart_permission_id=p.chart_permission_id
+			LEFT JOIN admin AS c ON b.seller_id=c.admin_id
+			WHERE a.company_id=? AND cp.cygx_auth=1
+			OR (a.company_id = ? AND  cp.permission_name = '策略' )` // 兼容永续状态
+	//WHERE a.company_id=?  AND b.status IN('正式','试用','永续')`
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId, companyId).QueryRow(&item)
+	return
+}
+
+// 获取对应销售以及销售的手机号
+func GetSellerDetailAllByCompanyId(companyId int) (item *CompanyDetail, err error) {
+	sql := ` SELECT c.mobile ,c.real_name as seller_name
+			FROM
+			company AS a
+			INNER JOIN company_product AS b ON a.company_id = b.company_id
+			INNER JOIN admin AS c ON b.seller_id = c.admin_id 
+			WHERE
+			b.product_id = 2 
+			AND a.company_id = ? LIMIT 1`
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&item)
+	return
+}
+
+func GetCompanySellerName(companyId int) (sellerName string, err error) {
+	sql := ` SELECT
+			GROUP_CONCAT( DISTINCT p.seller_name SEPARATOR '/' ) AS sellerName 
+		FROM
+			company_product AS p
+		WHERE
+			p.company_id = ? `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&sellerName)
+	return
+}
+
+type CompanyProductStatus struct {
+	IsSuspend int `description:"1:暂停,0:启用"`
+}
+
+type CompanyProductDetial struct {
+	IsSuspend int    `description:"1:暂停,0:启用"`
+	Scale     string `description:"管理规模,空不填,1::50亿以下,2:50~100亿,3:100亿以上。多个用, 隔开"`
+}
+
+func GetCompanyProductDetail(companyId, productId int) (item *CompanyProductDetial, err error) {
+	sql := ` SELECT * FROM company_product WHERE company_id = ? AND product_id = ?; `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId, productId).QueryRow(&item)
+	return
+}
+
+// 获取公司详情详情
+func GetCompanyByName(companyName string) (item *Company, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT *  FROM company WHERE company_name = ? LIMIT 1`
+	err = o.Raw(sql, companyName).QueryRow(&item)
+	return
+}
+
+// 获取公司详情详情
+func GetCompanyById(companyId int) (item *Company, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT *  FROM company WHERE company_id = ? LIMIT 1`
+	err = o.Raw(sql, companyId).QueryRow(&item)
+	return
+}
+
+// 获取公司详情详情
+func GetCompanyByThirdName(tripartiteCompanyCode string) (item *Company, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT *  FROM company WHERE tripartite_company_code = ? LIMIT 1`
+	err = o.Raw(sql, tripartiteCompanyCode).QueryRow(&item)
+	return
+}
+
+// 更新机构互动量
+func UpdateComapanyInteractionNum(interactionNum, interactionNumSeller, companyId int) (err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `UPDATE company SET interaction_num = ? ,  interaction_num_seller = ?  WHERE company_id=? `
+	_, err = o.Raw(sql, interactionNum, interactionNumSeller, companyId).Exec()
+	return
+}

+ 33 - 0
models/company/company_approval.go

@@ -0,0 +1,33 @@
+package company
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CompanyApproval struct {
+	CompanyApprovalId   int `orm:"column(company_approval_id);pk"`
+	CompanyId           int
+	ProductId           int
+	ApproveStatus       string    `description:"'待审批','已审批','驳回','已撤回'"`
+	ApproveUserId       int       `description:"审批人"`
+	ApproveRoleTypeCode string    `description:"审批人角色类型"`
+	ApproveRealName     string    `description:"审批人姓名"`
+	ApproveTime         time.Time `description:"审批时间"`
+	ApproveContent      string    `description:"待审内容"`
+	ApplyMethod         int       `description:"申请类型:1:试用->正式,2:冻结—>试用,3:试用延期,4:原销售申请领取流失客户,5:正式客户申请服务更新,6:正式客户补充协议"`
+	ApplyReasons        string    `description:"申请原因"`
+	ApplyUserId         int       `description:"申请人"`
+	ApplyRealName       string    `description:"申请人姓名"`
+	CreateTime          time.Time `description:"申请时间"`
+	ModifyTime          time.Time `description:"修改时间"`
+	CompanyContractId   int       `description:"合同id"`
+	IsFormal            int       `description:"是否已经转正式,0是没有转正式,1是已经转过正式"`
+}
+
+func GetCompanyApprovalById(companyId int) (item *CompanyApproval, err error) {
+	sql := `SELECT * FROM company_approval WHERE company_id=? AND product_id=2 AND approve_status='已审批' order by company_approval_id desc LIMIT 1 `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&item)
+	return
+}

+ 26 - 0
models/company/company_contract.go

@@ -0,0 +1,26 @@
+package company
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CompanyContractPermission struct {
+	Id                int       `orm:"column(id);pk" description:"客户合同id"`
+	CompanyId         int       `description:"客户id"`
+	CompanyContractId int       `description:"合同id"`
+	ChartPermissionId int       `description:"权限id"`
+	IsUpgrade         int       `description:"是否升级,1是,0否"`
+	ExpensiveYx       int       `description:"权益研选: 0-3w; 1-5w"`
+	StartDate         string    `description:"开始日期"`
+	EndDate           string    `description:"结束日期"`
+	CreateTime        time.Time `description:"创建时间"`
+	ModifyTime        time.Time `description:"修改时间"`
+}
+
+func GetCompanyContractPermissionCheck(companyContractId, permissionId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT COUNT(1) AS count FROM company_contract_permission AS a WHERE a.company_contract_id=? AND a.chart_permission_id=? `
+	err = o.Raw(sql, companyContractId, permissionId).QueryRow(&count)
+	return
+}

+ 174 - 0
models/company_activity_trip.go

@@ -0,0 +1,174 @@
+package models
+
+import "github.com/beego/beego/v2/client/orm"
+
+func GetCountCompanyDetailByIdGroupTrip(companyId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT
+	COUNT( 1 ) AS count 
+FROM
+	company AS a
+	INNER JOIN company_product AS b ON a.company_id = b.company_id
+	INNER JOIN company_report_permission AS p ON p.company_id = a.company_id
+	INNER JOIN chart_permission AS cp ON cp.chart_permission_id = p.chart_permission_id
+	LEFT JOIN admin AS c ON b.seller_id = c.admin_id 
+WHERE
+	a.company_id = ? 
+	AND b.product_id = 2 
+	AND b.status = '正式' 
+	AND p.is_upgrade =  1
+	OR (
+		a.company_id = ? 
+	AND b.product_id = 2 
+	AND b.status = '永续') `
+	err = o.Raw(sql, companyId, companyId).QueryRow(&count)
+	return
+}
+
+func GetCompanyDetailByIdGroupTrip(companyId int) (item *CompanyDetail, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT a.company_id,a.company_name,b.status,b.seller_id,b.seller_name,c.mobile ,b.is_suspend
+            FROM company AS a
+			INNER JOIN company_product AS b ON a.company_id=b.company_id
+			INNER JOIN company_report_permission AS p ON p.company_id = a.company_id
+			INNER JOIN chart_permission AS cp ON cp.chart_permission_id = p.chart_permission_id
+			LEFT JOIN admin AS c ON b.seller_id=c.admin_id
+			WHERE a.company_id=? AND b.product_id = 2  
+			ORDER BY b.product_id DESC  LIMIT 0,1  `
+	err = o.Raw(sql, companyId).QueryRow(&item)
+	return
+}
+
+func GetCompanyPermissionByUserTrip(companyId int) (permission string, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT
+			GROUP_CONCAT( DISTINCT b.remark ORDER BY b.sort ASC SEPARATOR ',' ) AS permission 
+		FROM
+			company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id = b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id = c.company_id 
+			AND a.product_id = c.product_id 
+		WHERE
+			a.company_id = ? 
+			AND c.is_suspend = 0 
+			AND b.cygx_auth = 1 
+			AND a.is_upgrade = 1 
+			AND c.STATUS IN ( '正式' ) 
+			OR ( a.company_id = ? AND c.is_suspend = 0 AND b.cygx_auth = 1 AND c.STATUS IN ( '永续' ) ) 
+			OR ( a.company_id = ? AND c.is_suspend = 0 AND b.cygx_auth = 1 AND b.chart_permission_name = '策略' AND c.STATUS IN ( '正式' ) )`
+	err = o.Raw(sql, companyId, companyId, companyId).QueryRow(&permission)
+	return
+}
+
+// 获取可查看升级权限的正式权限
+func GetCompanyPermissionByUserZhengShiTrip(companyId int) (permission string, err error) {
+	sql := ` SELECT GROUP_CONCAT(DISTINCT b.chart_permission_name  ORDER BY b.sort ASC  SEPARATOR ',') AS permission
+			FROM company_report_permission AS a
+			INNER JOIN chart_permission AS b ON a.chart_permission_id=b.chart_permission_id
+			INNER JOIN company_product AS c ON a.company_id=c.company_id AND a.product_id=c.product_id
+			WHERE  a.company_id=?
+			AND c.is_suspend=0
+            AND b.cygx_auth=1
+			AND ( a.is_upgrade = 1 AND c.STATUS = '正式' OR c.STATUS = '永续' ) `
+	o := orm.NewOrmUsingDB("weekly_report")
+	err = o.Raw(sql, companyId).QueryRow(&permission)
+	return
+}
+
+// GetCompanyReportPermissionUpgrade 获取升级的权限类型
+func GetCompanyReportPermissionUpgrade(companyId, productId int) (items []*CompanyReportPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT
+	re.*
+FROM
+	company_report_permission  as re 
+	INNER JOIN chart_permission as  c ON c.chart_permission_id = re.chart_permission_id
+WHERE
+	re.company_id = ? 
+	AND re.product_id = ? 
+	AND re.is_upgrade = 1 
+	AND c.permission_type = 1
+	AND STATUS = '正式' `
+	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+	return
+}
+
+// GetChartPermissionByIds 主键获取权限
+func GetChartPermissionByIds(permissionIds []string) (list []*ChartPermission, err error) {
+	qb, _ := orm.NewQueryBuilder("mysql")
+	// 构建查询对象
+	qb.Select("*").From("chart_permission").
+		Where("chart_permission_id").In(permissionIds...)
+	// 导出 SQL 语句
+	sql := qb.String()
+
+	// 执行 SQL 语句
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
+// GetCompanyPermissionNameCheck 通过名称判断客户是否开了某一类型的权限
+func GetCompanyPermissionNameCheck(companyId, productId int, permissionName string) (count int, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT
+			COUNT( 1 ) AS count 
+		FROM
+			company_report_permission AS a 
+			INNER JOIN chart_permission as  c  ON c.chart_permission_id = a.chart_permission_id
+		WHERE
+			a.company_id = ?
+			AND a.STATUS = '正式'
+			AND a.product_id = ? 
+			AND c.chart_permission_name = ? `
+	err = o.Raw(sql, companyId, productId, permissionName).QueryRow(&count)
+	return
+}
+
+// GetCompanyReportPermissionByCompanyIdAndProductId 获取权限类型
+func GetCompanyReportPermissionByCompanyIdAndProductId(companyId, productId int) (items []*CompanyReportPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT
+	re.*
+FROM
+	company_report_permission  as re 
+	INNER JOIN chart_permission as  c ON c.chart_permission_id = re.chart_permission_id
+WHERE
+	re.company_id = ? 
+	AND re.product_id = ? 
+	AND STATUS = '正式' `
+	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+	return
+}
+
+// GetCompanyReportPermissionByCompanyIdAndProductIdForInit 获取权限类型-初始化用,去掉正式的判断
+func GetCompanyReportPermissionByCompanyIdAndProductIdForInit(companyId, productId int) (items []*CompanyReportPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT
+	re.*
+FROM
+	company_report_permission  as re 
+	INNER JOIN chart_permission as  c ON c.chart_permission_id = re.chart_permission_id
+WHERE
+	re.company_id = ? 
+	AND re.product_id = ? 
+	AND STATUS NOT IN ('正式','永续') GROUP BY re.chart_permission_id `
+	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+	return
+}
+
+// GetCompanyReportPermissionByCompanyIdAndProductIdForInit 获取权限类型-初始化total用,去掉权限的判断
+func GetCompanyReportPermissionByCompanyIdAndProductIdForInit2(companyId, productId int) (items []*CompanyReportPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT
+	re.*
+FROM
+	company_report_permission  as re 
+	INNER JOIN chart_permission as  c ON c.chart_permission_id = re.chart_permission_id
+WHERE
+	re.company_id = ? 
+	AND re.product_id = ? 
+	 `
+	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+	return
+}

+ 76 - 0
models/company_interaction_num.go

@@ -0,0 +1,76 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxCompanyInteractionNum struct {
+	Id                  int       `orm:"column(id);pk"`
+	CompanyId           int       `description:"用户ID"`
+	ArticleHistoryNum   int       `description:"文章浏览数量"`
+	ArticleCountNum     int       `description:"文章收藏数量"`
+	ChartCountNum       int       `description:"图表收藏"`
+	IndustryFllowNum    int       `description:"产业关注数量"`
+	DepartmentFollowNum int       `description:"作者关注数量"`
+	KeyWordNum          int       `description:"关键词搜索次数"`
+	ActivityOnLineNum   int       `description:"线上活动报名次数"`
+	ActivityOfficeNum   int       `description:"线下活动报名次数"`
+	ActivityNum         int       `description:"活动报名次数"`
+	TripNum             int       `description:"专项产业调研数量"`
+	RoadshowVideoNum    int       `description:"产业视频播放量"`
+	ActivityVideoNum    int       `description:"活动视频播放量"`
+	ActivityVoiceNum    int       `description:"活动音频播放量"`
+	RoadshowNum         int       `description:"路演播放总数量"`
+	TagNum              int       `description:"标签点击次数"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"更新时间"`
+}
+
+// 添加
+func AddCygxCompanyInteractionNum(item *CygxCompanyInteractionNum) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 修改
+func UpdateCygxCompanyInteractionNum(item *CygxCompanyInteractionNum) (err error) {
+	updateParams := make(map[string]interface{})
+	updateParams["CompanyId"] = item.CompanyId
+	updateParams["ArticleHistoryNum"] = item.ArticleHistoryNum
+	updateParams["ArticleCountNum"] = item.ArticleCountNum
+	updateParams["ChartCountNum"] = item.ChartCountNum
+	updateParams["IndustryFllowNum"] = item.IndustryFllowNum
+	updateParams["DepartmentFollowNum"] = item.DepartmentFollowNum
+	updateParams["KeyWordNum"] = item.KeyWordNum
+	updateParams["ActivityOnLineNum"] = item.ActivityOnLineNum
+	updateParams["ActivityOfficeNum"] = item.ActivityOfficeNum
+	updateParams["ActivityNum"] = item.ActivityNum
+	updateParams["TripNum"] = item.TripNum
+	updateParams["RoadshowVideoNum"] = item.RoadshowVideoNum
+	updateParams["ActivityVideoNum"] = item.ActivityVideoNum
+	updateParams["ActivityVoiceNum"] = item.ActivityVoiceNum
+	updateParams["RoadshowNum"] = item.RoadshowNum
+	updateParams["TagNum"] = item.TagNum
+	updateParams["CreateTime"] = time.Now()
+	updateParams["ModifyTime"] = time.Now()
+	whereParam := map[string]interface{}{"company_id": item.CompanyId}
+	err = UpdateByExpr(CygxCompanyInteractionNum{}, whereParam, updateParams)
+	return
+}
+
+// 获取列表
+func GetCygxCompanyInteractionNumList() (items []*CygxCompanyInteractionNum, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_company_interaction_num   `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// 批量添加用户互动信息
+func AddCygxCompanyInteractionNumList(items []*CygxCompanyInteractionNum) (lastId int64, err error) {
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(1, items)
+	return
+}

+ 24 - 0
models/company_product.go

@@ -0,0 +1,24 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+)
+
+// 获取是否属于权益客户
+func GetCountCompanyProductCompanyId(companyId, productId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT  COUNT(1) AS count FROM company_product WHERE company_id = ?  AND product_id = ?  `
+	err = o.Raw(sql, companyId, productId).QueryRow(&count)
+	return
+}
+
+// 获取列表
+func GetCompanyProductList(condition string, pars []interface{}) (items []*CompanyProduct, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT *  FROM company_product WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}

+ 46 - 0
models/company_report_permission.go

@@ -0,0 +1,46 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CompanyReportPermission struct {
+	CompanyReportPermissionId int64 `orm:"column(company_report_permission_id);pk"`
+	CompanyId                 int
+	ReportPermissionId        int
+	CreatedTime               time.Time
+	LastUpdatedTime           time.Time
+	ChartPermissionId         int
+	StartDate                 string `description:"权限开始日期"`
+	EndDate                   string `description:"权限结束日期"`
+	ProductId                 int    `description:"产品id"`
+	ProductName               string `description:"产品名称"`
+	CompanyContractId         int    `description:"合同id"`
+	Status                    string `description:"'正式','试用','关闭'"`
+	ModifyTime                string `description:"修改时间"`
+	IsUpgrade                 int    `description:"是否升级,1是,0否"`
+	ExpensiveYx               int    `description:"权益研选: 0-3w; 1-5w"`
+}
+
+// 通过查询条件获取详情
+func GetCompanyReportPermissionDetailByCondition(condition string, pars []interface{}) (item *CompanyReportPermission, err error) {
+	if condition == "" {
+		return
+	}
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM company_report_permission  WHERE 1 = 1  ` + condition
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// 列表
+func GetCompanyReportPermissionList(condition string, pars []interface{}) (items []*CompanyReportPermission, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT * FROM company_report_permission  WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}

+ 23 - 0
models/company_user_type.go

@@ -0,0 +1,23 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxCompanyUserType struct {
+	Id             int `orm:"column(id);pk" description:"分析师id"`
+	CompanyId      int
+	CustomerTypeId int       `description:"用户身份ID"`
+	PackageType    int       `description:"1:70万 2:45w"`
+	CreateTime     time.Time `description:"创建时间"`
+	ModifyTime     time.Time `description:"创建时间"`
+}
+
+// 通过活动ID获取详情
+func GetCygxCompanyUserType(companyId int) (item *CygxCompanyUserType, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *  FROM cygx_company_user_type AS a WHERE a.company_id=?  `
+	err = o.Raw(sql, companyId).QueryRow(&item)
+	return
+}

+ 113 - 0
models/config.go

@@ -0,0 +1,113 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+var (
+	HomeHeaderTabConfigKey              = "home_header_tab"
+	MicroRoadShowListDataRatioConfigKey = "micro_roadshow_list_data_ratio"
+	HomeNewListAudioNumKey              = "home_new_list_audio_num"
+	MicroRoadshowDefaultImgKey          = "micro_roadshow_default_img"
+)
+
+type CygxConfig struct {
+	ConfigId    int    `json:"-" orm:"column(config_id);pk"`
+	ConfigCode  string `json:"-"`
+	ConfigValue string
+	Remark      string    `json:"-"`
+	CreateTime  time.Time `json:"-"`
+}
+
+type KeyWord struct {
+	KeyWord string `description:"关键词"`
+}
+
+func GetConfigByCode(configCode string) (item *CygxConfig, err error) {
+	sql := `SELECT * FROM cygx_config WHERE config_code=? `
+	err = orm.NewOrm().Raw(sql, configCode).QueryRow(&item)
+	return
+}
+
+// 更改配置信息
+func UpdateConfigByCode(configValue, countryCode string) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_config SET  config_value= ? WHERE config_code=? `
+	_, err = o.Raw(sql, configValue, countryCode).Exec()
+	return
+}
+
+type ConfigResp struct {
+	Item    *CygxConfig
+	List    []*KeyWord `description:"图表搜索推荐"`
+	ListHot []*KeyWord `description:"热搜关键词"`
+}
+
+type ConfigImgListResp struct {
+	List []*ConfigImgResp
+}
+
+type ConfigImgResp struct {
+	Img    string `description:"图片"`
+	Height string `description:"高度"`
+}
+
+type ConfigImgHbResp struct {
+	HbImg     string `description:"海报"`
+	ButtonImg string `description:"按钮图片"`
+}
+
+// 获取是否展示限免标签
+func GetShowSustainable() (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT(1) FROM cygx_config WHERE config_code= 'is_show_sustainable' AND config_value = 1 `
+	err = o.Raw(sqlCount).QueryRow(&count)
+	return
+}
+
+// 通过报告精选来获取最新的推荐搜索词
+func GetHotSearch() (permission string, err error) {
+	sql := `SELECT
+			GROUP_CONCAT( DISTINCT rl.subject_name ORDER BY rl.article_sun_id ASC SEPARATOR ',' ) AS subject_name 
+		FROM
+			cygx_report_selection_log AS rl 
+		WHERE
+			rl.article_id = (
+			SELECT
+				MAX( article_id ) 
+			FROM
+				cygx_report_selection 
+		WHERE
+			publish_status = 1)`
+	o := orm.NewOrm()
+	err = o.Raw(sql).QueryRow(&permission)
+	return
+}
+
+// HomeHeaderTabList 首页头部导航列表
+type HomeHeaderTabList struct {
+	Home       []*HomeHeaderTab `description:"首页"`
+	SearchPage []*HomeHeaderTab `description:"搜索页"`
+}
+
+// HomeHeaderTab 首页头部导航
+type HomeHeaderTab struct {
+	Id     int    `description:"导航ID"`
+	Name   string `description:"导航名称"`
+	IsShow bool   `description:"是否展示"`
+}
+
+// MicroRoadShowDefaultImgList 微路演行业默认背景图列表
+type MicroRoadShowDefaultImgList struct {
+	Audio []*MicroRoadShowDefaultImg `description:"音频"`
+	Video []*MicroRoadShowDefaultImg `description:"视频"`
+}
+
+// MicroRoadShowDefaultImg 微路演行业默认背景图
+type MicroRoadShowDefaultImg struct {
+	ChartPermissionId   int    `description:"行业ID"`
+	ChartPermissionName string `description:"行业名称"`
+	ImgUrl              string `description:"背景图"`
+	ShareImg            string `description:"分享图"`
+}

+ 322 - 0
models/crm_company.go

@@ -0,0 +1,322 @@
+package models
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_mfyx/utils"
+	"time"
+)
+
+type Company struct {
+	CompanyId             int       `orm:"column(company_id);pk"`
+	CompanyName           string    `description:"客户名称"`
+	CompanyType           int       `orm:"column(type)"`
+	CreditCode            string    `description:"社会统一信用码"`
+	CompanyCode           string    `description:"客户编码"`
+	Sort                  int       `description:"优先级"`
+	IsFeeCustomer         int       `description:"是否付费用户"`
+	Country               string    `description:"国家编码"`
+	Province              string    `description:"省"`
+	City                  string    `description:"市"`
+	Address               string    `description:"详细地址"`
+	Enabled               int       `description:"用户状态"`
+	CreatedTime           time.Time `description:"创建时间"`
+	LastUpdatedTime       time.Time `description:"最后一次阅读时间"`
+	Seller                string    `description:"销售员"`
+	SellsId               int       `description:"销售员id"`
+	CompanyBelong         string    `description:"客户所属,ficc:ficc客户,public_offering:公募客户,partner:合作伙伴"`
+	StartDate             string    `description:"合同开始日期"`
+	EndDate               string    `description:"合同结束日期"`
+	LastType              int       `description:"原客户标签"`
+	IsVip                 int       `description:"0:普通用户,1:大客户"`
+	FirstStartDate        string    `description:"首次设置为试用客户开始时间"`
+	FirstEndDate          string    `description:"首次设置为试用客户结束时间"`
+	DateType              int       `description:"设置流失类型,1:1个月,2:2个月,3:3个月"`
+	Remark                string    `description:"备注信息"`
+	RegionType            string    `description:"地区类型,国内,国外"`
+	OpenCompanyCode       string    `description:"开放给第三方的客户编码,不让第三方定位我们的客户信息"`
+	TripartiteCompanyCode string    `description:"第三方给过来的客户编码,判断客户是否存在"`
+}
+
+type CompanyLog struct {
+	Id              int       `orm:"column(id);pk"`
+	CompanyId       int       `description:"客户id"`
+	CompanyName     string    `description:"客户名称"`
+	CreditCode      string    `description:"统一社会信用码"`
+	CompanyCode     string    `description:"客户编码"`
+	Sort            int       `description:"优先级"`
+	IsFeeCustomer   int       `description:"是否付费用户"`
+	Country         string    `description:"国家编码"`
+	ProvinceId      int       `description:"省id"`
+	CityId          int       `description:"市id"`
+	Address         string    `description:"详细地址"`
+	Ctype           int       `orm:"column(type)" description:"客户标签,1:付费客户,2:试用客户,3:流失客户,4:潜在客户" `
+	Enabled         int       `description:"用户状态"`
+	CreatedTime     time.Time `description:"创建时间"`
+	LastUpdatedTime time.Time `description:"最后修改时间"`
+	Seller          string    `description:"销售员"`
+	SellsId         int       `description:"销售员ID"`
+	CompanyBelong   string    `description:"客户所属,ficc:ficc客户,public_offering:公募客户,partner:合作伙伴"`
+	StartDate       string    `description:"合同开始日期"`
+	EndDate         string    `description:"合同结束日期"`
+	LoseReason      string    `description:"流失原因"`
+	LastType        int       `description:"原客户标签"`
+	FirstStartDate  string    `description:"首次设置为试用客户开始时间"`
+	FirstEndDate    string    `description:"首次设置为试用客户结束时间"`
+	DateType        int       `description:"日期类型"`
+	AdminId         int       `description:"操作人id"`
+	LogType         string    `description:"日志类型"`
+	LogCreateTime   time.Time `description:"日志创建时间"`
+	Province        string    `description:"省"`
+	City            string    `description:"市"`
+}
+
+type CompanyOperationRecord struct {
+	Id              int       `orm:"column(id);pk"`
+	CompanyId       int       `description:"客户id"`
+	CompanyName     string    `description:"客户名称"`
+	SellerId        int       `description:"销售员id"`
+	SysUserId       int       `description:"操作者id"`
+	SysRealName     string    `description:"操作者名称"`
+	Remark          string    `description:"备注"`
+	Operation       string    `description:"操作"`
+	CreateTime      time.Time `description:"操作时间"`
+	ProductId       int       `description:"产品id"`
+	ProductName     string    `description:"产品名称"`
+	ApproveUserId   int       `description:"审批人id"`
+	ApproveRealName string    `description:"审批人姓名"`
+	ApproveContent  string    `description:"审批人内容"`
+	ApproveRemark   string    `description:"审批人内容"`
+	Status          string    `description:"状态"`
+}
+
+type CompanyPermissionLog struct {
+	Id                int `orm:"column(id);pk"`
+	CompanyId         int
+	ChartPermissionId int
+	CreateTime        time.Time
+	SysUserId         int
+	SysUserName       string
+	StartDate         string
+	EndDate           string
+	ProductId         int
+	ProductName       string
+}
+
+type CompanyProduct struct {
+	CompanyProductId    int       `orm:"column(company_product_id);pk" description:"客户产品id"`
+	CompanyId           int       `description:"客户id"`
+	ProductId           int       `description:"产品id"`
+	ProductName         string    `description:"产品名称"`
+	CompanyName         string    `description:"客户名称"`
+	Source              string    `description:"来源"`
+	Reasons             string    `description:"新增理由"`
+	Status              string    `description:"客户状态"`
+	IndustryId          int       `description:"行业id"`
+	IndustryName        string    `description:"行业名称"`
+	SellerId            int       `description:"销售id"`
+	SellerName          string    `description:"销售名称"`
+	GroupId             int       `description:"销售分组id"`
+	DepartmentId        int       `description:"销售部门id"`
+	IsSuspend           int       `description:"1:暂停,0:启用"`
+	SuspendTime         time.Time `description:"暂停启用时间"`
+	TryOutTime          time.Time `description:"正式转试用时间"`
+	RenewalReason       string    `description:"正式转试用后的续约情况说明"`
+	LastDescriptionTime time.Time `description:"上次添加说明时间"`
+	RenewalIntention    int       `description:"是否勾选无续约意向,1:确认,0:未确认"`
+	ApproveStatus       string    `description:"审批状态:'审批中','通过','驳回'"`
+	FreezeTime          time.Time `description:"冻结时间"`
+	FreezeReason        time.Time `description:"冻结理由"`
+	Remark              string    `description:"备注信息"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"修改时间"`
+	StartDate           string    `description:"开始日期"`
+	EndDate             string    `description:"结束日期"`
+	ContractEndDate     time.Time `description:"合同结束日期"`
+	LoseReason          string    `description:"流失原因"`
+	LossTime            time.Time `description:"流失时间"`
+	CompanyType         string    `description:"客户类型"`
+	OpenCode            string    `description:"开放给第三方的编码,不让第三方定位我们的客户信息"`
+}
+
+type CompanyProductLog struct {
+	Id               int       `orm:"column(id);pk"`
+	CompanyProductId int       `description:"产品id"`
+	CompanyId        int       `description:"客户id"`
+	ProductId        int       `description:"产品id"`
+	ProductName      string    `description:"产品名称"`
+	CompanyName      string    `description:"客户名称"`
+	Source           string    `description:"来源"`
+	Reasons          string    `description:"新增理由"`
+	Status           string    `description:"客户状态"`
+	IndustryId       int       `description:"行业id"`
+	IndustryName     string    `description:"行业名称"`
+	SellerId         int       `description:"所属销售id"`
+	SellerName       string    `description:"所属销售名称"`
+	GroupId          int       `description:"所属销售分组id"`
+	DepartmentId     int       `description:"所属销售部门id"`
+	IsSuspend        int       `description:"1:暂停,0:启用"`
+	SuspendTime      time.Time `description:"暂停时间"`
+	FreezeTime       time.Time `description:"冻结时间"`
+	Remark           string    `description:"备注信息"`
+	StartDate        string    `description:"开始日期"`
+	EndDate          string    `description:"结束日期"`
+	CreateTime       time.Time `description:"创建时间"`
+	ModifyTime       time.Time `description:"修改时间"`
+	LoseReason       string    `description:"流失原因"`
+	LossTime         time.Time `description:"流失时间"`
+	LogType          string    `description:"日志类型"`
+	LogCreateTime    time.Time `description:"日志创建时间"`
+	AdminId          int       `description:"操作人id"`
+	ApproveStatus    string    `description:"审批状态:'审批中','通过','驳回'"`
+	FreezeStartDate  string    `description:"冻结开始日期"`
+	FreezeEndDate    string    `description:"冻结结束日期"`
+}
+
+//type CompanyReportPermission struct {
+//之前的结构体已存在
+//}
+
+type CompanySource struct {
+	SourceId   int    `orm:"column(source_id);pk"`
+	SourceName string `description:"来源名称"`
+}
+
+// 判断公司名称是否存在
+func GetCompanyCountByName(companyName string) (count int, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT  COUNT(1) AS count FROM company WHERE company_name = ?`
+	err = o.Raw(sql, companyName).QueryRow(&count)
+	return
+}
+
+// 判断三方公司公司名称是否存在
+func GetCompanyCountByThirdName(tripartiteCompanyCode string) (count int, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT  COUNT(1) AS count FROM company WHERE tripartite_company_code = ?`
+	err = o.Raw(sql, tripartiteCompanyCode).QueryRow(&count)
+	return
+}
+
+// 获取来源详情
+func GetCompanySourceByName(companyName string) (item *CompanySource, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT *  FROM company_source WHERE source_name = ?`
+	err = o.Raw(sql, companyName).QueryRow(&item)
+	return
+}
+
+func GetCompanyCode() (companyCode string, err error) {
+	var num int
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT COUNT(1) AS num FROM company WHERE created_time >=? `
+	err = o.Raw(sql, time.Now().Format(utils.FormatDate)).QueryRow(&num)
+	if err != nil {
+		return
+	}
+	companyCode = "KH" + time.Now().Format("20060102") + fmt.Sprintf("%03d", num)
+	return
+}
+
+// 新增客户
+func AddCompany(item *Company) (lastId int64, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 更新客户基础信息
+func (company *Company) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Update(company, cols...)
+	fmt.Println(company)
+	fmt.Println(err)
+	return
+}
+
+// 新增客户产品
+func AddCompanyProduct(item *CompanyProduct) (newId int64, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	newId, err = o.Insert(item)
+	return
+}
+
+// 新增客户产品
+func AddCompanyProductLog(item *CompanyProductLog) (err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Insert(item)
+	return
+}
+
+func GetCompanyReportPermissionCount(companyId, productId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := `SELECT COUNT(1) AS count FROM company_report_permission WHERE company_id=? AND product_id=? `
+	err = o.Raw(sql, companyId, productId).QueryRow(&count)
+	return
+}
+
+func DeleteCompanyReportPermission(companyId, productId int) (err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` DELETE FROM company_report_permission WHERE company_id=? AND product_id=? `
+	_, err = o.Raw(sql, companyId, productId).Exec()
+	return
+}
+
+// 新增客户权限
+func AddCompanyReportPermission(item *CompanyReportPermission) (err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Insert(item)
+	return
+}
+
+// 新增客户权限日志
+func AddCompanyPermissionLog(item *CompanyPermissionLog) (err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Insert(item)
+	return
+}
+
+// 新增客户操作记录
+func AddCompanyOperationRecord(item *CompanyOperationRecord) (lastId int64, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 新增客户产品
+func AddCompanyLog(item *CompanyLog) (err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	_, err = o.Insert(item)
+	return
+}
+
+type UserSellerRelation struct {
+	RelationId int64     `orm:"column(relation_id);pk"`
+	UserId     int       `description:"用户id"`
+	CompanyId  int       `description:"企业用户id"`
+	SellerId   int       `description:"销售id"`
+	Seller     string    `description:"销售员名称"`
+	ProductId  int       `description:"产品id"`
+	Mobile     string    `description:"手机号"`
+	Email      string    `description:"邮箱"`
+	ModifyTime time.Time `description:"修改时间"`
+	CreateTime time.Time `description:"创建时间"`
+}
+
+// 添加销售员与员工的关系
+func AddUserSellerRelation(userId int64, companyId, sellerId, productId int, seller, mobile, email string) (lastId int64, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	relation := UserSellerRelation{
+		UserId:     int(userId),
+		SellerId:   sellerId,
+		CompanyId:  companyId,
+		Seller:     seller,
+		ProductId:  productId,
+		Mobile:     mobile,
+		Email:      email,
+		CreateTime: time.Now(),
+		ModifyTime: time.Now(),
+	}
+	lastId, err = o.Insert(&relation)
+	return
+}

+ 45 - 0
models/cygx_activity_special_points_company.go

@@ -0,0 +1,45 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxActivitySpecialInheritPointsCompany struct {
+	Id                  int       `orm:"column(id);pk"`
+	CompanyId           int       // 公司ID
+	CompanyName         string    // 公司名称
+	Points              int   // 公司剩余点数
+	CreateTime          time.Time // 创建时间
+	ModifyTime          time.Time // 更新时间
+	ChartPermissionId   int       // 品种ID
+	ChartPermissionName string    // 品种名称
+}
+
+func AddCygxActivitySpecialPointsCompany(item *CygxActivitySpecialInheritPointsCompany) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	if err != nil {
+		return
+	}
+	return
+}
+
+func AddCygxActivitySpecialInheritPointsCompanyMulti(items []*CygxActivitySpecialInheritPointsCompany) (err error) {
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(1, items)
+	return
+}
+
+func GetCygxActivitySpecialInheritPointsByCompanyId(companyId int) (list []*CygxActivitySpecialInheritPointsCompany, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity_special_inherit_points_company WHERE company_id = ?  `
+	_, err = o.Raw(sql,companyId).QueryRows(&list)
+	return
+}
+func DelCygxActivitySpecialInheritPointsByCompanyId(companyId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_activity_special_inherit_points_company WHERE company_id = ?  `
+	_, err = o.Raw(sql,companyId).Exec()
+	return
+}

+ 43 - 0
models/cygx_industry_top.go

@@ -0,0 +1,43 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxIndustryTop struct {
+	Id                     int       `orm:"column(id);pk"`
+	IndustrialManagementId int       `description:"产业D"`
+	UserId                 int       `description:"用户ID"`
+	CreateTime             time.Time `description:"创建时间"`
+}
+
+type CygxIndustryTopRep struct {
+	IndustrialManagementId int `description:"产业D"`
+}
+
+//添加收藏信息
+func AddCygxIndustryTop(item *CygxIndustryTop) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+type CygxIndustryTopResp struct {
+	Status       int `description:"1:收藏,2:取消收藏"`
+	CollectCount int `description:"收藏总数"`
+}
+
+func RemoveCygxIndustryTop(userId, industrialManagementId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM cygx_industry_top WHERE user_id=? AND industrial_management_id=? `
+	_, err = o.Raw(sql, userId, industrialManagementId).Exec()
+	return
+}
+
+//判断这篇文章是否被用户收藏
+func GetCygxIndustryTop(userId, industrialManagementId int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM cygx_industry_top WHERE user_id=? AND industrial_management_id=? `
+	err = orm.NewOrm().Raw(sql, userId, industrialManagementId).QueryRow(&count)
+	return
+}

+ 96 - 0
models/cygx_morning_meeting_gather.go

@@ -0,0 +1,96 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+type CygxMorningMeetingGather struct {
+	Id          int       `orm:"column(id);pk"`
+	MeetingIds  string    `description:"主表ID多个用 , 隔开"`
+	PublishTime string    `description:"发布日期"`
+	CreateTime  time.Time `description:"创建时间"`
+	ModifyTime  time.Time `description:"更新时间"`
+	Title       string    `description:"标题"`
+	Status      int       `description:"0:未发布,1:已发布"`
+}
+
+// 添加
+func AddCygxMorningMeetingGather(item *CygxMorningMeetingGather) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+func GetCygxMorningMeetingGatherCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM cygx_morning_meeting_gather WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+type CygxMorningMeetingGatherResp struct {
+	Id           int    `description:"ID"`
+	Title        string `description:"标题"`
+	IndustryName string `description:"多个产业名称"`
+}
+
+type CygxMorningMeetingGatherListResp struct {
+	Paging *paging.PagingItem `description:"分页数据"`
+	List   []*CygxMorningMeetingGatherResp
+}
+
+// 列表
+func GetCygxMorningMeetingGatherList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxMorningMeetingGather, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_morning_meeting_gather WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,? `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+func GetCygxMorningMeetingGatherById(condition string, pars []interface{}) (item *CygxMorningMeetingGather, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_morning_meeting_gather WHERE  1= 1`
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+type CygxMorningMeetingGatherDetailListResp struct {
+	Id                   int                      `description:"ID"`
+	IndustryId           int                      `description:"产业id"` // 产业id
+	IndustryName         string                   `description:"产业名称"` // 产业名称
+	ChartPermissionName  string                   `description:"行业名称"` // 行业名称
+	ChartPermissionId    int                      `description:"行业id"` // 行业id
+	MeetingId            int                      `description:"主表id"` // 主表id
+	Content              string                   `description:"内容"`   // 内容
+	PublishTime          string                   `description:"发布日期"`
+	ReportLink           string                   `description:"报告链接"`
+	LinkArticleId        int                      `description:"报告ID链接"`
+	Title                string                   `description:"标题"`
+	IndustrialSubjectIds string                   `description:"标的id"`
+	ListSubject          []*CygxIndustrialSubject `description:"标的列表"`
+}
+
+type CygxMorningMeetingGatherDetailResp struct {
+	HasPermission int `description:"1:有该行业权限,正常展示,2:无该行业权限,不存在权益客户下,3:无该品类权限,已提交过申请,4:无该行业权限,未提交过申请,5:潜在客户,未提交过申请,6:潜在客户,已提交过申请"`
+	Detail        *CygxMorningMeetingGatherDetail
+}
+
+type CygxMorningMeetingGatherDetail struct {
+	Id          int    `description:"ID"`
+	Title       string `description:"标题"`
+	PublishTime string `description:"发布日期"`
+	Department  string `description:"作者"`
+	List        []*CygxMorningMeetingGatherDetailListResp
+}

+ 74 - 0
models/cygx_morning_meeting_review_chapter.go

@@ -0,0 +1,74 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// CygxMorningMeetingReviewChapter [...]
+type CygxMorningMeetingReviewChapter struct {
+	Id                   int       `orm:"column(id);pk"`
+	MeetingTime          time.Time `json:"meetingTime"` // 晨会日期
+	CreateTime           time.Time `json:"createTime"`
+	ModifyTime           time.Time `json:"modifyTime"`
+	IndustryId           int       `json:"industryId"`          // 产业id
+	IndustryName         string    `json:"industryName"`        // 产业名称
+	ChartPermissionName  string    `json:"chartPermissionName"` // 行业名称
+	ChartPermissionId    int       `json:"chartPermissionId"`   // 行业id
+	IndustrialSubjectIds string    `json:"industrialSubjectId"` // 标的id
+	MeetingId            int64     `json:"meetingId"`           // 主表id
+	Content              string    `json:"content"`             // 内容
+}
+
+// 通过ID获取详情
+func GetCygxMorningMeetingReviewChapterDetail(id int) (item *CygxMorningMeetingReviewChapter, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_morning_meeting_review_chapter  WHERE id =? `
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+// 列表
+func GetCygxMorningMeetingReviewChapterList(condition string, pars []interface{}) (items []*CygxMorningMeetingGatherDetailListResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT c.*,r.publish_time
+			FROM cygx_morning_meeting_review_chapter  as  c 
+			INNER JOIN cygx_morning_meeting_reviews as r ON  r.id = c.meeting_id   WHERE 1 = 1  AND r.status = 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+type IndustrialSubjectItem struct {
+	IndustrialSubjectId int    `orm:"column(industrial_subject_id);pk" description:"标的id"`
+	SubjectName         string `description:"标的名称"`
+}
+
+type CygxMorningMeetingReviewChapterRespItem struct {
+	Id                    int                      `orm:"column(id);pk"`
+	MeetingTime           time.Time                `json:"meetingTime"` // 晨会日期
+	CreateTime            time.Time                `json:"createTime"`
+	ModifyTime            time.Time                `json:"modifyTime"`
+	IndustryId            int                      `json:"industryId"`            // 产业id
+	IndustryName          string                   `json:"industryName"`          // 产业名称
+	ChartPermissionName   string                   `json:"chartPermissionName"`   // 行业名称
+	ChartPermissionId     int                      `json:"chartPermissionId"`     // 行业id
+	IndustrialSubjectList []*IndustrialSubjectItem `json:"industrialSubjectList"` // 标的list
+	MeetingId             int64                    `json:"meetingId"`             // 主表id
+	Content               string                   `json:"content"`               // 内容
+}
+
+type CygxMorningMeetingReviewChapterResp struct {
+	MeetingTime string
+	Status      int
+	List        []*CygxMorningMeetingReviewChapterRespItem
+}
+
+func GetCygxMorningMeetingReviewsListByIndustrialIds(industrialIds string) (items []*CygxMorningMeetingReviewChapter, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_morning_meeting_review_chapter WHERE industry_id IN (` + industrialIds + `)  `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 125 - 0
models/cygx_morning_meeting_reviews.go

@@ -0,0 +1,125 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+// CygxMorningMeetingReviews [...]
+type CygxMorningMeetingReviews struct {
+	Id            int       `orm:"column(id);pk"`
+	MeetingTime   time.Time `json:"meetingTime"` // 晨会日期
+	PublishTime   time.Time `json:"publishTime"` // 发布日期
+	CreateTime    time.Time `json:"createTime"`
+	ModifyTime    time.Time `json:"modifyTime"`
+	Status        int       `json:"status"`       // 0:未发布,1:已发布
+	PartNums      int       `json:"partNums"`     // 段落数
+	IndustryNames string    `json:"industryName"` // 产业名称
+}
+
+//添加晨报点评
+func AddCygxMorningMeetingReviews(item *CygxMorningMeetingReviews) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(item)
+	return
+}
+
+//列表
+func GetCygxMorningMeetingReviewsList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxMorningMeetingReviews, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_morning_meeting_reviews WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` LIMIT ?,? `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+func GetCygxMorningMeetingReviewsListCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM cygx_morning_meeting_reviews WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+type CygxMorningMeetingReviewItem struct {
+	Id            int    `orm:"column(id);pk"`
+	MeetingTime   string `json:"meetingTime"` // 晨会日期
+	PublishTime   string `json:"publishTime"` // 发布日期
+	CreateTime    string `json:"createTime"`
+	ModifyTime    string `json:"modifyTime"`
+	Status        int    `json:"status"`       // 0:未发布,1:已发布
+	PartNums      int    `json:"partNums"`     // 段落数
+	IndustryNames string `json:"industryName"` // 产业名称
+}
+
+type CygxMorningMeetingReviewsList struct {
+	List   []*CygxMorningMeetingReviewItem
+	Paging *paging.PagingItem `description:"分页数据"`
+}
+
+func GetMorningMeetingReviewById(reviewId int) (item *CygxMorningMeetingReviews, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_morning_meeting_reviews WHERE id=?`
+	err = o.Raw(sql, reviewId).QueryRow(&item)
+	return
+}
+
+// 发布报告
+func PublishMorningMeetingReviewById(reviewId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_morning_meeting_reviews SET status=1,publish_time=now(),modify_time=NOW() WHERE id = ? `
+	_, err = o.Raw(sql, reviewId).Exec()
+	return
+}
+
+type MorningReviewPublishReq struct {
+	ReviewIds string `description:"晨会id,多个用英文逗号隔开"`
+}
+
+type MorningReviewPublishCancelReq struct {
+	ReviewId int `description:"晨会id"`
+}
+
+//取消发布报告
+func PublishCancelMorningMeetingReview(reviewId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_morning_meeting_reviews SET status=0,publish_time=null WHERE id =?  `
+	_, err = o.Raw(sql, reviewId).Exec()
+	return
+}
+
+type MorningReviewDeleteReq struct {
+	ReviewId int `description:"晨会id"`
+}
+
+
+//删除晨会点评
+func DeleteMorningMeeting(reviewId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_morning_meeting_reviews WHERE id =? `
+	_, err = o.Raw(sql, reviewId).Exec()
+	return
+}
+
+//更新晨报点评
+func UpdateCygxMorningMeetingReviews(item *CygxMorningMeetingReviews) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_morning_meeting_reviews
+			SET
+			  meeting_time =?,
+			  publish_time = ?,
+			  modify_time = ?,
+			  part_nums = ?,
+			  industry_names = ?,
+			  status = ? 
+			WHERE id = ? `
+	_, err = o.Raw(sql, item.MeetingTime, item.PublishTime, item.ModifyTime, item.PartNums, item.IndustryNames, item.Status, item.Id).Exec()
+
+	return
+}

+ 138 - 0
models/cygx_tag.go

@@ -0,0 +1,138 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxTag struct {
+	TagId         int64     `orm:"column(tag_id);pk"`
+	TagName       string    `orm:"column(tag_name);NOT NULL"`       // 标签名
+	ArticleTypes  string    `orm:"column(article_types);NOT NULL"`  // 报告系列
+	ActivityTypes string    `orm:"column(activity_types);NOT NULL"` // 活动类型
+	Industries    string    `orm:"column(industries);NOT NULL"`     // 产业
+	SubjectNames  string    `orm:"column(subject_names);NOT NULL"`  // 标的
+	Sort          int       `orm:"column(sort);"`                   // 优先级
+	ModifyTime    time.Time `orm:"column(modify_time)"`             // 修改时间
+	CreateTime    time.Time `orm:"column(create_time)"`             // 创建时间
+	OnlineTime    time.Time `orm:"column(online_time)"`             // 上线时间
+	OfflineTime   time.Time `orm:"column(offline_time)"`            // 下线时间
+	Status        int       `orm:"column(status);NOT NULL"`         // 状态:0-禁用 1-启用
+}
+
+func (m *CygxTag) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(m, cols...)
+	return
+}
+
+type CygxTagList struct {
+	TagId         int64    `orm:"column(tag_id);pk"`
+	TagName       string   `orm:"column(tag_name);NOT NULL"`       // 标签名
+	ArticleTypes  string   `orm:"column(article_types);NOT NULL"`  // 报告系列
+	ActivityTypes string   `orm:"column(activity_types);NOT NULL"` // 活动类型
+	Industries    string   `orm:"column(industries);NOT NULL"`     // 产业
+	SubjectNames  string   `orm:"column(subject_names);NOT NULL"`  // 标的
+	Sort          int      `orm:"column(sort);"`                   // 优先级
+	ModifyTime    string   `orm:"column(modify_time)"`             // 修改时间
+	CreateTime    string   `orm:"column(create_time)"`             // 创建时间
+	OnlineTime    string   `orm:"column(online_time)"`             // 上线时间
+	OfflineTime   string   `orm:"column(offline_time)"`            // 下线时间
+	Status        int      `orm:"column(status);NOT NULL"`         // 状态:0-禁用 1-启用
+	CheckList     []string // ABCD勾选了哪几列
+	TagType       int      `description:"1:热门活动、2:海外研究、3:路演回放、4:语音问答"`
+}
+
+type CygxTagListResp struct {
+	List           []*CygxTagList
+	ListPermission []*ChartPermission
+}
+
+// 列表
+func GetCygxTagListCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxTagList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_tag as a WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	if startSize+pageSize > 0 {
+		sql += ` LIMIT ?,?  `
+		_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	} else {
+		_, err = o.Raw(sql, pars).QueryRows(&items)
+	}
+
+	return
+}
+
+// 获取tag列表
+func GetCygxTagList(cond string) (items []*CygxTagList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_tag  WHERE 1=1 AND status = 1 `
+	if cond != "" {
+		sql += cond
+	} else {
+		sql += `  ORDER BY sort ASC `
+	}
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+func UpdateCygxTagStatus(id, status int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	if status == 1 {
+		sql = ` UPDATE  cygx_tag
+			SET
+			  status =1,
+			  online_time = NOW(),
+			  modify_time = NOW() 
+			WHERE tag_id = ?`
+	} else {
+		sql = ` UPDATE  cygx_tag
+			SET
+			  status =0,
+			  offline_time = NOW(),
+			  modify_time = NOW() 
+			WHERE tag_id = ?`
+	}
+
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+// GetCygxTagByTagId 根据指标id获取指标信息
+func GetCygxTagByTagId(tagId int) (item *CygxTag, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_tag WHERE tag_id=? `
+	err = o.Raw(sql, tagId).QueryRow(&item)
+	return
+}
+
+// GetCygxTagMinSort 获取最小不等于0的排序
+func GetCygxTagMinSort() (sort int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT min(sort) FROM cygx_tag WHERE  sort <> 0 `
+	err = o.Raw(sql).QueryRow(&sort)
+	return
+}
+
+// MoveDownCygxTagBySort 往下移动
+func MoveDownCygxTagBySort(prevSort, currentSort int) (err error) {
+	o := orm.NewOrm()
+	sql := `update cygx_tag set sort = sort - 1 where sort <= ? and sort> ? `
+	_, err = o.Raw(sql, prevSort, currentSort).Exec()
+	return
+}
+
+// MoveUpCygxTagBySort 往下移动
+func MoveUpCygxTagBySort(prevSort, currentSort int) (err error) {
+	o := orm.NewOrm()
+	sql := `update cygx_tag set sort = sort + 1 where sort >= ? and sort< ? `
+	_, err = o.Raw(sql, prevSort, currentSort).Exec()
+	return
+}
+
+type CygxTagIdReq struct {
+	TagId int `description:"TagId"`
+}

+ 29 - 0
models/cygx_tag_history.go

@@ -0,0 +1,29 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxTagHistory struct {
+	Id               int `orm:"column(id);pk"`
+	TagId         int `description:"TagId等于0新增,大于零修改"`
+	UserId           int
+	CreateTime       time.Time
+	Mobile           string    `description:"手机号"`
+	Email            string    `description:"邮箱"`
+	CompanyId        int       `description:"公司id"`
+	CompanyName      string    `description:"公司名称"`
+	ModifyTime       time.Time `description:"修改时间"`
+	RealName         string    `description:"用户实际名称"`
+	SellerName       string    `description:"所属销售"`
+	RegisterPlatform int       `description:"来源 1小程序,2:网页"`
+}
+
+// 添加历史信息
+func AddCygxTagHistory(item *CygxTagHistory) (lastId int64, err error) {
+	o := orm.NewOrm()
+	item.ModifyTime = time.Now()
+	lastId, err = o.Insert(item)
+	return
+}

+ 36 - 0
models/cygx_user_record.go

@@ -0,0 +1,36 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxUserRecord struct {
+	UserRecordId  int       `orm:"column(user_record_id);pk" description:"id"`
+	OpenId        string    `description:"用户openid,最大长度:32"`
+	UnionId       string    `description:"用户unionid,最大长度:64"`
+	Subscribe     int       `description:"是否关注,0:未关注,1:已关注"`
+	SubscribeTime string    `description:"关注/取消关注时间"`
+	CreateTime    time.Time `description:"创建时间"`
+}
+
+// 优化建议
+func AddCygxUserRecord(item *CygxUserRecord) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 获取数量
+func GetCygxUserRecordCount(openId string) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_user_record WHERE open_id=? `
+	err = o.Raw(sqlCount, openId).QueryRow(&count)
+	return
+}
+
+func GetCygxUserRecordSubscribe(unionId string) (item *CygxUserRecord, err error) {
+	sql := ` SELECT * FROM cygx_user_record WHERE union_id=?  AND subscribe = 1  limit 1 `
+	err = orm.NewOrm().Raw(sql, unionId).QueryRow(&item)
+	return
+}

+ 358 - 0
models/cygx_yanxuan_special.go

@@ -0,0 +1,358 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+type CygxYanxuanSpecial struct {
+	Id           int       `orm:"column(id);pk"`
+	UserId       int       // 用户ID
+	CreateTime   time.Time // 创建时间
+	ModifyTime   time.Time // 修改时间
+	PublishTime  time.Time // 提审过审或驳回时间
+	Content      string    // 内容
+	Tags         string    // 标签
+	Status       int       // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl       string    // 图片链接
+	DocUrl       string    // 文档链接
+	Reason       string    // 理由
+	Title        string    // 标题
+	Type         int       // 类型1:笔记,2:观点
+	CompanyTags  string    // 公司标签
+	IndustryTags string    // 行业标签
+	AdminName    string    // 审核人员姓名
+}
+
+type CygxYanxuanSpecialItem struct {
+	Id              int    `orm:"column(id);pk"`
+	UserId          int    // 用户ID
+	CreateTime      string // 创建时间
+	ModifyTime      string // 修改时间
+	PublishTime     string // 提审过审或驳回时间
+	Content         string // 内容
+	Tags            string // 标签
+	Status          int    // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl          string // 图片链接
+	DocUrl          string // 文档链接
+	SpecialName     string // 专栏名称
+	Introduction    string // 介绍
+	Label           string // 标签
+	NickName        string // 昵称
+	RealName        string // 姓名
+	Mobile          string // 手机号
+	HeadImg         string // 头像
+	BgImg           string // 背景图
+	Reason          string // 理由
+	Title           string // 标题
+	Type            int    // 类型1:笔记,2:观点
+	CollectNum      int
+	MyCollectNum    int
+	IsCollect       int
+	CompanyTags     string
+	IndustryTags    string
+	ContentHasImg   int  //正文是否包含图片 1包含 0不包含
+	ContentHasStyle bool //正文是否包含格式
+	Docs            []Doc
+	Pv              string `description:"Pv"`
+	Uv              string `description:"Uv"`
+}
+
+type CygxYanxuanSpecialResp struct {
+	CygxYanxuanSpecialItem
+	Docs          []Doc
+	CompanyTags   []string
+	IndustryTags  []string
+	HasPermission int  `description:"1:正常展示,2:不展示"`
+	ExamineStatus int  `description:"1:未发布,2:审核中 3:已发布 4:驳回"`
+	IsShowExamine bool `description:"是否展示审核状态按钮"`
+}
+
+type CygxYanxuanSpecialCenterResp struct {
+	Id              int    `orm:"column(id);pk"`
+	UserId          int    // 用户ID
+	CreateTime      string // 创建时间
+	ModifyTime      string // 修改时间
+	PublishTime     string // 提审过审或驳回时间
+	Content         string // 内容
+	Tags            string // 标签
+	Status          int    // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl          string // 图片链接
+	DocUrl          string // 文档链接
+	SpecialName     string // 专栏名称
+	Introduction    string // 介绍
+	Label           string // 标签
+	NickName        string // 昵称
+	RealName        string // 姓名
+	Mobile          string // 手机号
+	HeadImg         string // 头像
+	BgImg           string // 背景图
+	Reason          string // 理由
+	Title           string // 标题
+	Type            int    // 类型1:笔记,2:观点
+	CollectNum      int
+	MyCollectNum    int
+	IsCollect       int
+	CompanyTags     string
+	IndustryTags    string
+	ContentHasImg   int  //正文是否包含图片 1包含 0不包含
+	ContentHasStyle bool //正文是否包含格式
+	Docs            []Doc
+	Annotation      string   `description:"核心观点"`
+	Source          string   `description:"来源"`
+	Pv              string   `description:"Pv"`
+	Uv              string   `description:"Uv"`
+	PublishDate     string   // 提审过审或驳回时间      string `description:"核心观点"`
+	BodyHighlight   []string `description:"搜索高亮展示结果"`
+}
+
+type Doc struct {
+	DocName   string
+	DocSuffix string
+	DocUrl    string
+	DocIcon   string
+}
+
+func GetYanxuanSpecialList(userId int, condition string, pars []interface{}, startSize, pageSize int) (items []*CygxYanxuanSpecialCenterResp, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.bg_img,b.head_img,b.introduction,b.label,b.mobile,b.nick_name,b.real_name,b.special_name,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  ) AS collect_num,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  AND user_id = ? ) AS my_collect_num 
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id 
+ WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += `ORDER BY a.publish_time DESC `
+	if startSize+pageSize > 0 {
+		sql += ` LIMIT ?,? `
+		_, err = o.Raw(sql, userId, pars, startSize, pageSize).QueryRows(&items)
+	} else {
+		_, err = o.Raw(sql, userId, pars).QueryRows(&items)
+	}
+	return
+}
+
+func GetYanxuanSpecialListBycondition(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxYanxuanSpecialCenterResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT a.* FROM cygx_yanxuan_special AS a WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	if startSize+pageSize > 0 {
+		sql += ` LIMIT ?,? `
+		_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	} else {
+		_, err = o.Raw(sql, pars).QueryRows(&items)
+	}
+	return
+}
+
+type EnableCygxYanxuanSpecialReq struct {
+	Id     int    // 文章id
+	Status int    // 1通过2驳回
+	Reason string //理由
+}
+
+func EnableYanxuanSpecial(id, status int, reason, adminName string) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET status=?,reason=?,admin_name = ? , publish_time=NOW() WHERE id = ? `
+	_, err = o.Raw(sql, status, reason, adminName, id).Exec()
+	return
+}
+
+type SpecialListResp struct {
+	IsAuthor             bool               `description:"是否开通了研选专栏"`
+	IsImproveInformation bool               `description:"作者信息是否完善"`
+	Paging               *paging.PagingItem `description:"分页数据"`
+	List                 []*CygxYanxuanSpecialCenterResp
+}
+
+func GetYanxuanSpecialById(specialId, userId int) (item *CygxYanxuanSpecialItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.bg_img,b.head_img,b.introduction,b.label,b.mobile,
+b.nick_name,b.real_name,b.special_name,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  ) AS collect_num,
+( SELECT count( 1 ) FROM cygx_yanxuan_special_collect AS ac WHERE ac.yanxuan_special_id = a.id  AND user_id = ? ) AS my_collect_num
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id 
+ WHERE a.id=? `
+	err = o.Raw(sql, userId, specialId).QueryRow(&item)
+	return
+}
+
+func GetYanxuanSpecialBySpecialId(specialId int) (item *CygxYanxuanSpecialItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*
+FROM cygx_yanxuan_special AS a
+ WHERE a.id=? `
+	err = o.Raw(sql, specialId).QueryRow(&item)
+	return
+}
+
+type CygxYanxuanSpecialReq struct {
+	Id                  int    `orm:"column(id);pk"`
+	Content             string // 内容
+	Tags                string // 标签
+	DoType              int    // 1保存 2发布
+	ImgUrl              string // 图片链接
+	DocUrl              string // 文档链接
+	Title               string // 标题
+	Type                int    // 类型1:笔记,2:观点
+	IndustryTags        string // 行业标签
+	CompanyTags         string // 公司标签
+	IsApprovalPersonnel bool   // 是否是审批人员操作
+}
+
+func AddCygxYanxuanSpecial(item *CygxYanxuanSpecial) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+func UpdateYanxuanSpecial(item *CygxYanxuanSpecial) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET title=?,content=?,company_tags=?,industry_tags=?,img_url=?,doc_url=?,type=?,status=?,
+	modify_time=NOW(),publish_time=NOW(),admin_name = ? WHERE id = ? `
+	_, err = o.Raw(sql, item.Title, item.Content, item.CompanyTags, item.IndustryTags, item.ImgUrl, item.DocUrl, item.Type, item.Status, item.AdminName, item.Id).Exec()
+	return
+}
+
+func GetYanxuanSpecialIndustry(keyword string) (IndustryNames []string, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	if keyword == "" {
+		sql = `SELECT industry_name FROM cygx_yanxuan_special_industry `
+	} else {
+		sql = `SELECT industry_name FROM cygx_yanxuan_special_industry WHERE industry_name LIKE '%` + keyword + `%' `
+	}
+	_, err = o.Raw(sql).QueryRows(&IndustryNames)
+	return
+}
+
+type CancelPublishCygxYanxuanSpecialReq struct {
+	Id int // 文章id
+}
+
+func CancelPublishYanxuanSpecial(id int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET status=1,publish_time=NOW(),modify_time=NOW() WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+type DelCygxYanxuanSpecialReq struct {
+	Id int // 文章id
+}
+
+func DelYanxuanSpecial(id int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `DELETE FROM cygx_yanxuan_special WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+type CygxYanxuanSpecialCheckReq struct {
+	Content string   // 内容
+	ImgUrl  []string // 图片
+}
+
+func GetYanxuanSpecialFollowUserById(specialId int) (items []int, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT b.user_id
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_follow AS b ON a.user_id = b.follow_user_id
+ WHERE a.id=? `
+	_, err = o.Raw(sql, specialId).QueryRows(&items)
+	return
+}
+
+func GetYanxuanSpecialItemById(specialId int) (item *CygxYanxuanSpecialItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.bg_img,b.head_img,b.introduction,b.label,b.mobile,
+b.nick_name,b.real_name,b.special_name
+FROM cygx_yanxuan_special AS a
+JOIN cygx_yanxuan_special_author AS b ON a.user_id = b.user_id 
+ WHERE a.id=? `
+	err = o.Raw(sql, specialId).QueryRow(&item)
+	return
+}
+
+// 获取数量
+func GetCygxYanxuanSpecialCount(condition string, pars []interface{}) (count int, err error) {
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_yanxuan_special as a  WHERE 1= 1  `
+	if condition != "" {
+		sqlCount += condition
+	}
+	o := orm.NewOrm()
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// UpdateYanxuanSpecialPv 修改研选专栏的阅读Pv
+func UpdateYanxuanSpecialPv(id int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_yanxuan_special SET pv=pv+1 WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+// UpdateYanxuanSpecialUv 修改研选专栏的阅读Uv
+func UpdateYanxuanSpecialUv(id int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_yanxuan_special SET uv=uv+1 WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+func UpdateYanxuanSpecialPvNUm(pv, id int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_yanxuan_special SET pv = ? WHERE id = ? `
+	_, err = o.Raw(sql, pv, id).Exec()
+	return
+}
+
+func UpdateYanxuanSpecialUvUm(pv, id int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE cygx_yanxuan_special SET uv = ? WHERE id = ? `
+	_, err = o.Raw(sql, pv, id).Exec()
+	return
+}
+
+// 增加收藏数量
+func UpdateYanxuanSpecialarticleCollectNumIncrease(id int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET article_collect_num = article_collect_num +1  WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+// 减少收藏数量
+func UpdateYanxuanSpecialarticleCollectNumReduce(id int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET article_collect_num = article_collect_num  - 1  WHERE id = ? `
+	_, err = o.Raw(sql, id).Exec()
+	return
+}
+
+// 更新收藏数量
+func UpdateYanxuanSpecialarticleCollectNum(collectNum, id int) (err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `UPDATE cygx_yanxuan_special SET article_collect_num = ?  WHERE id = ? `
+	_, err = o.Raw(sql, collectNum, id).Exec()
+	return
+}

+ 34 - 0
models/cygx_yanxuan_special_approval_log.go

@@ -0,0 +1,34 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxYanxuanSpecialApprovalLog struct {
+	ApprovalLogId    int       `orm:"column(approval_log_id);pk"`
+	UserId           int       // 用户ID
+	CreateTime       time.Time // 创建时间
+	ModifyTime       time.Time // 修改时间
+	Content          string    // 内容
+	Tags             string    // 标签
+	ApprovalStatus   int       // 1通过、2驳回
+	ImgUrl           string    // 图片链接
+	DocUrl           string    // 文档链接
+	Reason           string    // 理由
+	Title            string    // 标题
+	Type             int       // 类型1:笔记,2:观点
+	CompanyTags      string    // 公司标签
+	IndustryTags     string    // 行业标签
+	YanxuanSpecialId int       // cygx_yanxuan_special 表主键ID
+	AdminName        string    // 审核人员姓名
+	AdminUserId      int       // 审核人员用户ID
+	SpecialName      string    // 专栏名称
+	NickName         string    // 昵称
+}
+
+func AddCygxYanxuanSpecialApprovalLog(item *CygxYanxuanSpecialApprovalLog) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}

Some files were not shown because too many files changed in this diff