Forráskód Böngészése

Merge branch 'master' of http://8.136.199.33:3000/hongze/hz_crm_api into cygx/cygx_14_6

zhangchuanxing 6 napja
szülő
commit
089422b886

+ 6 - 1
controllers/company.go

@@ -3408,7 +3408,7 @@ func (this *CompanyController) Detail() {
 			}
 
 			// CRM8.8-权益权限列表调用较多、统一进行调整
-			plist, e := services.RaiCompanyPermissionAndCheckList(companyId, isEdit, utils.FilterPermissionNameRai)
+			plist, e := services.RaiCompanyPermissionAndCheckList(companyId, isEdit, utils.FilterPermissionNameRai2)
 			if e != nil {
 				br.Msg = "获取客户权益权限列表信息失败"
 				br.ErrMsg = "获取客户权益权限列表信息失败,Err:" + e.Error()
@@ -4502,6 +4502,11 @@ func (this *CompanyController) Delete() {
 		br.Ret = 408
 		return
 	}
+	//禁止删除
+	br.Msg = "删除失败"
+	br.ErrMsg = "删除失败"
+	return
+
 	var req company.DeletePptReq
 	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
 	if err != nil {

+ 3 - 3
controllers/company_apply_v2.go

@@ -147,7 +147,7 @@ func (this *CompanyApplyController) ApplyServiceUpdate() {
 
 		//权益的新签合同重新定义,如果合同起始时间在新签合同起始日期 1年之内的,仍为新签合同。
 		raicontractType = req.ContractType
-		if raicontractType != "新签合同" && companyProduct.Status != utils.COMPANY_STATUS_FOREVER {
+		if raicontractType != "新签合同" {
 			//startDateTime, _ := time.Parse(utils.FormatDate, req.StartDate)
 			//startDateTime = startDateTime.AddDate(-1, 0, 0)
 			totalLastYear, err := contractService.GetCompanyContractCountRaiByLastYear(req.CompanyId, req.StartDate)
@@ -681,7 +681,7 @@ func (this *CompanyApplyController) ApplyTurnPositive() {
 		if productId == 2 {
 			//权益的新签合同重新定义,如果合同起始时间在新签合同起始日期 1年之内的,仍为新签合同。
 			raicontractType = contractType
-			if raicontractType != "新签合同" && companyProduct.Status != utils.COMPANY_STATUS_FOREVER {
+			if raicontractType != "新签合同" {
 				//startDateTime, _ := time.Parse(utils.FormatDate, req.StartDate)
 				//startDateTime = startDateTime.AddDate(-1, 0, 0)
 				totalLastYear, err := contractService.GetCompanyContractCountRaiByLastYear(req.CompanyId, req.StartDate)
@@ -1294,7 +1294,7 @@ func (this *CompanyApplyController) ApplyBySystemContract() {
 	if productId == 2 {
 		//权益的新签合同重新定义,如果合同起始时间在新签合同起始日期 1年之内的,仍为新签合同。
 		raicontractType = contractType
-		if raicontractType != "新签合同" && companyProduct.Status != utils.COMPANY_STATUS_FOREVER {
+		if raicontractType != "新签合同" {
 			//startDateTime := contractDetail.StartDate.AddDate(-1, 0, 0)
 			totalLastYear, err := contractService.GetCompanyContractCountRaiByLastYear(req.CompanyId, contractDetail.StartDate.Format(utils.FormatDate))
 			if err != nil {

+ 22 - 0
controllers/company_renewal.go

@@ -478,6 +478,28 @@ func (this *CompanyRenewalController) CompanyContractNoRenewedAscribeAdd() {
 		br.ErrMsg = "新建失败,Err:" + err.Error()
 		return
 	}
+	//新增操作记录
+	if productId == utils.COMPANY_PRODUCT_RAI_ID {
+		cp, err := company.GetCompanyProductByCompanyIdAndProductId(companyId, productId)
+		if err != nil {
+			br.Msg = "获取客户信息失败"
+			br.ErrMsg = "获取客户信息失败,Err:" + err.Error()
+			return
+		}
+		if cp.IsShare == 1 {
+			err = company.UpdateCompanyProductCancelisShare(companyId, productId)
+			if err != nil {
+				br.Msg = "取消共享失败"
+				br.ErrMsg = "取消共享失败,Err:" + err.Error()
+				return
+			}
+			remark := "确认不续约,自动取消共享"
+			operation := "no_renewed"
+			services.AddCompanyOperationRecord(companyId, cp.SellerId, sysUser.AdminId, productId, sysUser.AdminId, cp.CompanyName,
+				"权益", sysUser.RealName, remark, operation, "", sysUser.RealName, "", cp.Status)
+		}
+
+	}
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "新建成功"

+ 10 - 1
controllers/company_seller.go

@@ -7509,7 +7509,16 @@ func (this *CompanySellerController) CheckListRaiServerType() {
 	list := make([]company.DepartmentGroupSellers, 0)
 	listServer := make([]company.DepartmentGroupSellers, 0)
 
-	condition := " AND role_type_code IN ('rai_seller','rai_group') AND enabled = 1 AND  rai_enabled = 1 "
+	// 获取图片识别手机号的配置
+	crmConfig, err := company.GetConfigDetailByCode("rai_data_summary_seller")
+	if err != nil {
+		br.Msg = "获取配置失败"
+		br.ErrMsg = "获取配置失败"
+		br.IsSendEmail = false
+		return
+	}
+
+	condition := " AND role_type_code IN ('rai_seller','rai_group') AND enabled = 1 AND  rai_enabled = 1 OR   admin_id  IN( " + crmConfig.ConfigValue + ") "
 	var pars []interface{}
 	//名字带6 的属于服务组
 	//if serverType == "开拓" {

+ 15 - 1
controllers/company_user.go

@@ -1508,6 +1508,13 @@ func (this *CompanyUserController) DeleteUser() {
 		br.Ret = 408
 		return
 	}
+	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
+		//非admin 禁止删除
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败"
+		return
+	}
+
 	var req company.DeleteUserReq
 	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
 	if err != nil {
@@ -2491,6 +2498,7 @@ func (this *CompanyController) PotentialUserDelete() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
+
 	var req models.PotentialUserDeleteReq
 	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
 	if err != nil {
@@ -2498,7 +2506,6 @@ func (this *CompanyController) PotentialUserDelete() {
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 		return
 	}
-
 	sysUser := this.SysUser
 	if sysUser == nil {
 		br.Msg = "请登录"
@@ -2506,6 +2513,12 @@ func (this *CompanyController) PotentialUserDelete() {
 		br.Ret = 408
 		return
 	}
+	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
+		//非admin 禁止删除
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败"
+		return
+	}
 
 	//删除用户
 	err = services.DeleteWxUser(req.UserId)
@@ -2753,6 +2766,7 @@ func (this *CompanyController) PotentialUserMove() {
 		OpUserName:             sysUser.RealName,
 		CreateTime:             time.Now(),
 	})
+	wxUser.CompanyId = oldWxUser.CompanyId
 	go services.AddWxUserMoveLog(wxUser, sysUser, req.CompanyId) // 添加用户移动日志记录
 	br.Ret = 200
 	br.Success = true

+ 1 - 1
controllers/cygx/activity.go

@@ -1085,7 +1085,7 @@ func (this *ActivityCoAntroller) ActivityList() {
 		}
 		list[k].IsUpload = mapUpload[v.ActivityId]
 		//是否展示签到码
-		if (v.ActivityTypeId == 5 || v.ActivityTypeId == 6 || v.ActivityTypeId == 8) && v.SigninImg != "" && v.ActiveState == 1 && v.PublishStatus == 1 {
+		if utils.InArrayByInt(utils.SHOW_SIGNIN_BUTTON_ACTIVITY_TYPE_ID, v.ActivityTypeId) && v.SigninImg != "" && v.ActiveState == 1 && v.PublishStatus == 1 {
 			list[k].IsShowSigninButton = true
 		}
 	}

+ 6 - 2
controllers/cygx/contract_allocation.go

@@ -1127,11 +1127,15 @@ func (this *ContractAllocationController) CompanyContractStatistics() {
 	}
 
 	var list []*cygx.AllocationPermissionStatisticsListResp
-	permissionNameArr := []string{"医药", "消费", "科技", "智造", "策略", "固收", "买方研选"}
+	permissionNameArr := []string{"医药", "消费", "科技", "智造", "策略", "固收", "研选订阅"}
 	for _, v := range permissionNameArr {
 		item := new(cygx.AllocationPermissionStatisticsListResp)
 		item.ChartPermissionName = v
-		item.List = mapPermissionUser[v]
+		if len(mapPermissionUser[v]) == 0 {
+			item.List = make([]*cygx.AllocationRealNameStatisticsListResp, 0)
+		} else {
+			item.List = mapPermissionUser[v]
+		}
 		list = append(list, item)
 	}
 

+ 111 - 35
controllers/cygx/morning_meeting_review.go

@@ -90,7 +90,7 @@ func (this *MorningMeetingController) List() {
 		return
 	}
 
-	condition += ` ORDER BY publish_time DESC  `
+	condition += ` ORDER BY meeting_time DESC ,id DESC  `
 	resp := new(cygx.CygxMorningMeetingReviewsList)
 	list, err := cygx.GetCygxMorningMeetingReviewsList(condition, pars, startSize, pageSize)
 	if err != nil {
@@ -109,6 +109,7 @@ func (this *MorningMeetingController) List() {
 			Status:        item.Status,
 			PartNums:      item.PartNums,
 			IndustryNames: item.IndustryNames,
+			OpUserName:    item.OpUserName,
 		}
 		if item.Status == 1 {
 			respItem.PublishTime = item.PublishTime.Local().Format(utils.FormatDateTime)
@@ -165,19 +166,26 @@ func (this *MorningMeetingController) PreserveAndPublish() {
 	}
 	industryNames := strings.Join(industryNameslice, ",")
 
-	if reqList.MeetingId <= 0 {
-		//先新增主表
-		reviewItem := cygx.CygxMorningMeetingReviews{
-			MeetingTime:   meetingTime,
-			CreateTime:    time.Now(),
-			ModifyTime:    time.Now(),
-			PartNums:      len(reqList.List),
-			IndustryNames: industryNames,
-		}
+	//先新增主表
+	reviewItem := cygx.CygxMorningMeetingReviews{
+		MeetingTime:   meetingTime,
+		CreateTime:    time.Now(),
+		ModifyTime:    time.Now(),
+		PartNums:      len(reqList.List),
+		IndustryNames: industryNames,
+		OpUserId:      sysUser.AdminId,
+		OpUserName:    sysUser.RealName,
+	}
+	if reqList.DoType == 1 {
+		reviewItem.Status = 2
+	}
 
+	if reqList.MeetingId <= 0 {
 		if reqList.DoType == 1 {
-			reviewItem.PublishTime = time.Now()
-			reviewItem.Status = 1
+			//reviewItem.PublishTime = time.Now()
+			//reviewItem.Status = 2
+		} else {
+			reviewItem.Status = 5
 		}
 
 		meetingId, err := cygx.AddCygxMorningMeetingReviews(&reviewItem)
@@ -254,10 +262,10 @@ func (this *MorningMeetingController) PreserveAndPublish() {
 			br.Msg = "保存成功"
 			br.Data = meetingId
 		} else {
-			for _, item := range reqList.List {
-				go services.SendWxMsgWithCygxMorningMeeting(int(meetingId), item.IndustryId, item.IndustryName)
-				go cygxService.UpdateIndustrialManagementTimeLineDateList3ByRedis(item.IndustryId) //处理产业管理时间线相关内容的数据
-			}
+			//for _, item := range reqList.List {
+			//go services.SendWxMsgWithCygxMorningMeeting(int(meetingId), item.IndustryId, item.IndustryName)
+			//	go cygxService.UpdateIndustrialManagementTimeLineDateList3ByRedis(item.IndustryId) //处理产业管理时间线相关内容的数据
+			//}
 			//添加到首页最新
 			listchapter, err := cygx.GetCygxMorningMeetingReviewsListById(int(meetingId))
 			if err != nil {
@@ -267,8 +275,9 @@ func (this *MorningMeetingController) PreserveAndPublish() {
 			}
 			for _, itemchapter := range listchapter {
 				//go cygxService.UpdateResourceData(itemchapter.Id, "meetingreviewchapt", "add", time.Now().Format(utils.FormatDateTime))
-				go cygxService.UpdateMeetingreviewchaptResourceData(itemchapter.Id) //写入首页最新  cygx_resource_data 表
-				go elastic.AddComprehensiveMeetingreviewchapt(itemchapter.Id)       //Es添加晨会精华
+				//go cygxService.UpdateMeetingreviewchaptResourceData(itemchapter.Id)                                 //写入首页最新  cygx_resource_data 表
+				//go elastic.AddComprehensiveMeetingreviewchapt(itemchapter.Id)                                       //Es添加晨会精华
+				go cygxService.AddCygxMorningMeetingReviewLog(itemchapter, "提交审核", sysUser.RealName, sysUser.AdminId, 2) //添加晨会精华日志信息,并发送模版消息
 			}
 			br.Msg = "发布成功"
 			br.Data = meetingId
@@ -285,22 +294,14 @@ func (this *MorningMeetingController) PreserveAndPublish() {
 			return
 		}
 
-		reviewItem := cygx.CygxMorningMeetingReviews{
-			Id:            reqList.MeetingId,
-			MeetingTime:   meetingTime,
-			ModifyTime:    time.Now(),
-			PartNums:      len(reqList.List),
-			IndustryNames: industryNames,
-		}
-
 		if reqList.DoType == 1 {
-			reviewItem.PublishTime = time.Now()
-			reviewItem.Status = 1
+			//reviewItem.PublishTime = time.Now()
+			//reviewItem.Status = 2
 		} else {
-			reviewItem.PublishTime = reviewInfo.PublishTime
+			//reviewItem.PublishTime = reviewInfo.PublishTime
 			reviewItem.Status = reviewInfo.Status
 		}
-
+		reviewItem.Id = reqList.MeetingId
 		err = cygx.UpdateCygxMorningMeetingReviews(&reviewItem)
 		if err != nil {
 			br.Msg = "更新晨报点评失败!"
@@ -439,13 +440,14 @@ func (this *MorningMeetingController) PreserveAndPublish() {
 		if reqList.DoType == 0 {
 			br.Msg = "保存成功"
 		} else {
-			for _, item := range reqList.List {
-				go services.SendWxMsgWithCygxMorningMeeting(reqList.MeetingId, item.IndustryId, item.IndustryName)
-				go cygxService.UpdateIndustrialManagementTimeLineDateList3ByRedis(item.IndustryId) //处理产业管理时间线相关内容的数据
-			}
+			//for _, item := range reqList.List {
+			//	go services.SendWxMsgWithCygxMorningMeeting(reqList.MeetingId, item.IndustryId, item.IndustryName)
+			//	go cygxService.UpdateIndustrialManagementTimeLineDateList3ByRedis(item.IndustryId) //处理产业管理时间线相关内容的数据
+			//}
 			for _, itemchapter := range listchapter {
 				//go cygxService.UpdateResourceData(itemchapter.Id, "meetingreviewchapt", "add", time.Now().Format(utils.FormatDateTime))
-				go cygxService.UpdateMeetingreviewchaptResourceData(itemchapter.Id) //写入首页最新  cygx_resource_data 表
+				//go cygxService.UpdateMeetingreviewchaptResourceData(itemchapter.Id) //写入首页最新  cygx_resource_data 表
+				go cygxService.AddCygxMorningMeetingReviewLog(itemchapter, "提交审核", sysUser.RealName, sysUser.AdminId, 2) //添加晨会精华日志信息,并发送模版消息
 			}
 			br.Msg = "发布成功"
 		}
@@ -882,3 +884,77 @@ func MorningMeetingHistoryListExport(this *MorningMeetingController, resp cygx.C
 	br.Success = true
 	br.Msg = "导出成功"
 }
+
+// @Title 提交审核与撤回审核接口
+// @Description 提交审核与撤回审核接口
+// @Param	request	body cygx.MorningReviewApproveSubmiteq true "type json string"
+// @Success 200 Ret=200 取消发布成功
+// @router /morningMeeting/approve/submit [post]
+func (this *MorningMeetingController) ApproveSubmitReport() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req cygx.MorningReviewApproveSubmiteq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	reviewId := req.ReviewId
+	status := req.Status
+	if reviewId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,晨会id不可为空"
+		return
+	}
+	if status != 2 && status != 4 {
+		br.Msg = "操作失败"
+		br.ErrMsg = "发布状态错误"
+		return
+	}
+	var operate string
+	if status == 2 {
+		operate = "提交审核"
+	} else {
+		operate = "撤回"
+	}
+
+	//reviewInfo, err := cygx.GetMorningMeetingReviewById(reviewId)
+	//if err != nil {
+	//	br.Msg = "取消发布失败"
+	//	br.ErrMsg = "取消发布失败,Err:" + err.Error()
+	//	return
+	//}
+
+	//添加到首页最新
+	listchapter, err := cygx.GetCygxMorningMeetingReviewsListById(reviewId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	err = cygx.UpdateMorningMeetingReviewStatusById(status, reviewId)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败失败,Err:" + err.Error()
+		return
+	}
+	for _, itemchapter := range listchapter {
+		go cygxService.AddCygxMorningMeetingReviewLog(itemchapter, operate, sysUser.RealName, sysUser.AdminId, status) //添加晨会精华日志信息,并发送模版消息
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = operate + "成功"
+}

+ 30 - 3
controllers/cygx/summary_manage.go

@@ -1241,17 +1241,25 @@ func (this *SummaryManage) ArticleHistoryExport() {
 		br.ErrMsg = "获取策略品台数据失败,Err:" + err.Error()
 		return
 	}
-	var mobilesCl string
+	var mobilesArr []string
 	if len(listClPv) > 0 {
 		for _, v := range listClPv {
 			if v.Mobile != "" {
-				mobilesCl += v.Mobile + ","
+				mobilesArr = append(mobilesArr, v.Mobile)
+			}
+		}
+	}
+	if len(list) > 0 {
+		for _, v := range list {
+			if v.Mobile != "" {
+				mobilesArr = append(mobilesArr, v.Mobile)
 			}
 		}
 	}
 	mapMobileCompany := make(map[string]string)
 	mapMobileSellName := make(map[string]string)
-	mobilesCl = strings.TrimRight(mobilesCl, ",")
+	mapMobileRealName := make(map[string]string)
+	mobilesCl := strings.Join(mobilesArr, ",")
 
 	if mobilesCl != "" {
 		listClCompanyName, err := cygx.GetCygxCelueArticleComapnyName(mobilesCl)
@@ -1279,6 +1287,25 @@ func (this *SummaryManage) ArticleHistoryExport() {
 		}
 	}
 
+	listUser, err := models.GetWxUserRaiSllerListByUserMobile(mobilesArr)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	//获取用户当前最新的公司信息
+	for _, v := range listUser {
+		mapMobileRealName[v.Mobile] = v.RealName
+	}
+
+	for _, v := range list {
+		if v.Mobile != "" {
+			if v.RealName == "" {
+				v.RealName = mapMobileRealName[v.Mobile]
+			}
+		}
+	}
+
 	var listClPvPower []*cygx.ArticleHistoryRep
 
 	if len(mapMobileSellWithUser) != 0 {

+ 53 - 0
controllers/roadshow/calendar.go

@@ -11,6 +11,7 @@ import (
 	"hongze/hz_crm_api/models/roadshow"
 	"hongze/hz_crm_api/models/system"
 	"hongze/hz_crm_api/services"
+	cygxService "hongze/hz_crm_api/services/cygx"
 	roadshowService "hongze/hz_crm_api/services/roadshow"
 	"hongze/hz_crm_api/utils"
 	"strconv"
@@ -57,6 +58,7 @@ func (this *CalendarController) Add() {
 		return
 	}
 	var req roadshow.AddActivityReq
+	var resp roadshow.AddActivityResp
 	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
@@ -209,6 +211,8 @@ func (this *CalendarController) Add() {
 	var productItemRai *company.CompanyProduct
 	roleTypeCode := sysUser.RoleTypeCode
 	//如果是权益销售、权益销售组长、权益管理员 添加的路演信息,做销售与共享销售信息关联查看
+
+	var isRaiRoadShow bool //是否属于权益的路演
 	if req.CompanyId > 0 && req.ActivityType == "路演" && (roleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER ||
 		roleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP || roleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN) {
 		productItemRai, err = company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, utils.COMPANY_PRODUCT_RAI_ID)
@@ -217,6 +221,21 @@ func (this *CalendarController) Add() {
 			br.ErrMsg = "获取客户信息失败, Err: " + err.Error()
 			return
 		}
+		points, addType, err := roadshowService.CheckAddRoadShowCompanyPoint(req.CompanyId, req.ResearcherList)
+		if err != nil {
+			br.Msg = "添加失败"
+			br.ErrMsg = "获取客户信息失败, Err: " + err.Error()
+			return
+		}
+		if addType == 3 {
+			br.Msg = "客户暂无路演权限,请开通对应行业权限或者购买【路演服务】权限"
+			br.ErrMsg = "客户暂无路演权限,请开通对应行业权限或者购买【路演服务】权限 "
+			return
+		}
+		isRaiRoadShow = true
+		resp.Points = points
+		resp.AddType = addType
+
 	}
 
 	rsCalendar := new(roadshow.RsCalendar)
@@ -335,11 +354,17 @@ func (this *CalendarController) Add() {
 		}
 	}
 
+	//13  给公司添加路演,对应专项调研扣点处理
+	if isRaiRoadShow {
+		go cygxService.SpecialActivityPointsBillRoadShow(int(rsCalendarId), sysUser.AdminId)
+	}
+
 	//if req.ActivityType == "公开会议" {
 	//	go roadshowService.SetPublicMeetingUnionCode()
 	//}
 	br.Ret = 200
 	br.Success = true
+	br.Data = resp
 	br.Msg = "保存成功"
 	br.IsAddLog = true
 }
@@ -379,6 +404,7 @@ func (this *CalendarController) Edit() {
 	}
 
 	var req roadshow.EditActivityReq
+	var resp roadshow.AddActivityResp
 	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
@@ -627,6 +653,7 @@ func (this *CalendarController) Edit() {
 
 	//如果是权益客户,添加销售跟共享销售的信息
 	roleTypeCode := sysUser.RoleTypeCode
+	var isRaiRoadShow bool //是否属于权益的路演
 	//如果是权益销售、权益销售组长、权益管理员 添加的路演信息,做销售与共享销售信息关联查看
 	if req.CompanyId > 0 && req.ActivityType == "路演" && (roleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER ||
 		roleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP || roleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN) {
@@ -637,10 +664,25 @@ func (this *CalendarController) Edit() {
 			br.ErrMsg = "获取客户信息失败, Err: " + err.Error()
 			return
 		}
+		isRaiRoadShow = true
 		if productItemRai != nil {
 			calendarUpdateParams["seller_id"] = productItemRai.SellerId
 			calendarUpdateParams["share_seller_id"] = productItemRai.ShareSellerId
 		}
+		points, addType, err := roadshowService.CheckAddRoadShowCompanyPoint(req.CompanyId, req.ResearcherList)
+		if err != nil {
+			br.Msg = "添加失败"
+			br.ErrMsg = "获取客户信息失败, Err: " + err.Error()
+			return
+		}
+		if addType == 3 {
+			br.Msg = "客户暂无路演权限,请开通对应行业权限或者购买【路演服务】权限"
+			br.ErrMsg = "客户暂无路演权限,请开通对应行业权限或者购买【路演服务】权限 "
+			return
+		}
+		isRaiRoadShow = true
+		resp.Points = points
+		resp.AddType = addType
 	}
 
 	err = roadshow.UpdateRsCalendar(calendarWhereParams, calendarUpdateParams)
@@ -875,6 +917,10 @@ func (this *CalendarController) Edit() {
 			}(v.ResearcherId, req.RsCalendarId, int(rsCalendarResearcherId))
 		}
 	}
+	//13  给公司添加路演,对应专项调研扣点处理
+	if isRaiRoadShow {
+		go cygxService.SpecialActivityPointsBillRoadShow(req.RsCalendarId, sysUser.AdminId)
+	}
 
 	//for k, v := range req.ResearcherList {
 	//	rsCalendarResearcherItem, err := roadshow.GetRsCalendarResearcherById(req.RsCalendarResearcherId)
@@ -1051,6 +1097,7 @@ func (this *CalendarController) Edit() {
 	//}
 	br.Ret = 200
 	br.Success = true
+	br.Data = resp
 	br.Msg = "保存成功"
 	br.IsAddLog = true
 }
@@ -1882,6 +1929,12 @@ func (this *CalendarController) Delete() {
 		}
 	}
 
+	roleTypeCode := sysUser.RoleTypeCode
+	if rsCalendarItem.CompanyId > 0 && rsCalendarItem.ActivityType == "路演" && (roleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER ||
+		roleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP || roleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN) {
+		go cygxService.SpecialActivityPointsBillRoadShow(req.RsCalendarId, sysUser.AdminId)
+	}
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "删除成功"

+ 206 - 42
controllers/statistic/rai_data_summary.go

@@ -12,6 +12,7 @@ import (
 	"hongze/hz_crm_api/services"
 	cygxService "hongze/hz_crm_api/services/cygx"
 	"hongze/hz_crm_api/utils"
+	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -36,6 +37,8 @@ type StatisticRaiDataSummaryController struct {
 // @Param   ContractButtonType   query   string	  false       "开关类型,:`新签`,`续约`,`收入` 多个用英文逗号隔开, "
 // @Param   StartDate   query   string	  false       "开始时间 "
 // @Param   EndDate   query   string	  false       "结束时间 "
+// @Param   SortParam   query   string  false       "排序字段参数,用来排序的字段, 枚举值:根据列表表头对应参数"
+// @Param   SortType   query   string  true       "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`"
 // @Param   IsExport   query   bool  false       "是否导出excel,默认是false"
 // @Success 200 {object} statistic_report.RaiDataSummaryListResp
 // @router /rai_data_summary/list [get]
@@ -63,6 +66,8 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 	serverButton, _ := this.GetBool("ServerButton")
 	startDate := this.GetString("StartDate")
 	endDate := this.GetString("EndDate")
+	sortParam := this.GetString("SortParam")
+	sortType := this.GetString("SortType")
 
 	adminIdArr := strings.Split(adminId, ",")
 	serviceAdminIdArr := strings.Split(serviceAdminId, ",")
@@ -85,12 +90,22 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 	var pars []interface{}
 	var conditionEnSeller string // 手动禁用的销售
 
-	conditionEnSeller = " AND  real_name  NOT  IN  ('余晔', '于卓铭', '张怡', '王芳6') "
+	// 获取图片识别手机号的配置
+	crmConfig, err := company.GetConfigDetailByCode("rai_data_summary_seller")
+	if err != nil {
+		br.Msg = "获取配置失败"
+		br.ErrMsg = "获取配置失败"
+		br.IsSendEmail = false
+		return
+	}
+	//fmt.Println(crmConfig.ConfigValue)
+
+	conditionEnSeller = " AND  real_name  NOT  IN  ('余晔', '于卓铭', '张怡', '王芳6')  "
 	mapsellerDevelop := make(map[int]bool) // 开拓组销售Map
 	mapsellerService := make(map[int]bool) // 服务组销售Map
 	var sellerIds []string
 	var sellerServiceIds []string
-	condition = " AND role_type_code IN ('rai_seller','rai_group')    " + conditionEnSeller
+	condition = " AND role_type_code IN ('rai_seller','rai_group')    " + conditionEnSeller + " OR   admin_id  IN( " + crmConfig.ConfigValue + ") "
 
 	sellerListAll, err := system.GetSysUserItemsOrderByCreated(condition, pars)
 	if err != nil {
@@ -114,6 +129,7 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 	if adminId != "" {
 		serviceAdminId = ""
 		condition += " AND  admin_id IN (" + adminId + ") "
+		condition += " OR  admin_id IN (" + adminId + ") "
 		sellerIds = make([]string, 0)
 	}
 	if serviceAdminId != "" {
@@ -626,6 +642,9 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 	resp := new(statistic_report.RaiDataSummaryListResp)
 	var items []*statistic_report.RaiDataSummaryResp
 
+	mapSortDateService := make(map[int]float64)
+	mapSortDateDevelop := make(map[int]float64)
+
 	for i := startYear; i <= endYear; i++ {
 		for _, Dv := range dataTypeArr {
 			item := new(statistic_report.RaiDataSummaryResp)
@@ -636,6 +655,8 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 			}
 			keyMapTtoal = fmt.Sprint(item.DataType, "_Develop")
 			keyMapTtoalServer = fmt.Sprint(item.DataType, "_Server_")
+
+			var dataListDevelop []*statistic_report.RaiDataSummaryDetail
 			for _, vS := range sellerDevelop {
 				keyMap = fmt.Sprint(item.DataType, "_", vS.AdminId)
 				sellerItem := new(statistic_report.RaiDataSummaryDetail)
@@ -643,9 +664,9 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				sellerIds = append(sellerIds, sellerItem.SellerId)
 				sellerItem.SellerName = vS.RealName
 				sellerItem.AddTrialCount = fmt.Sprint(mapAddTrialNum[keyMap])
-				sellerItem.NewContractData = fmt.Sprint(utils.SubFloatToString(mapNewContractMoney[keyMap], 2), " / ", mapNewContractNum[keyMap])             // 新签合同(金额/数量)-(数据)
-				sellerItem.ExpiredContractData = fmt.Sprint(utils.SubFloatToString(mapExpiredContractMoney[keyMap], 2), " / ", mapExpiredContractNum[keyMap]) //"到期合同(金额/数量)-(数据)"
-				sellerItem.RenewedContractData = fmt.Sprint(utils.SubFloatToString(mapRenewedContractMoney[keyMap], 2), " / ", mapRenewedContractNum[keyMap]) // "续约合同(金额/数量)-(数据)"
+				sellerItem.NewContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapNewContractMoney[keyMap], 2), " / ", mapNewContractNum[keyMap])             // 新签合同(金额/数量)-(数据)
+				sellerItem.ExpiredContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapExpiredContractMoney[keyMap], 2), " / ", mapExpiredContractNum[keyMap]) //"到期合同(金额/数量)-(数据)"
+				sellerItem.RenewedContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapRenewedContractMoney[keyMap], 2), " / ", mapRenewedContractNum[keyMap]) // "续约合同(金额/数量)-(数据)"
 				var renewalRateMoey string
 				var renewalRateNum string
 				if mapRenewedContractMoney[keyMap] == 0 || mapExpiredContractMoney[keyMap] == 0 {
@@ -658,8 +679,8 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				} else {
 					renewalRateNum = utils.SubFloatToString(float64(mapRenewedContractCompanyNum[keyMap])/float64(mapExpiredContractCompanyNum[keyMap])*100, 2) + "%"
 				}
-				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                          //"续约率(金额/数量)-(数据)"
-				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.SubFloatToString(confirmedNoRenewalContractMoney[keyMap], 2), " / ", confirmedNoRenewalContractNum[keyMap]) //"确认不续约合同(金额/数量)-(数据)"
+				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                                //"续约率(金额/数量)-(数据)"
+				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.FormatNumberWithCommas(confirmedNoRenewalContractMoney[keyMap], 2), " / ", confirmedNoRenewalContractNum[keyMap]) //"确认不续约合同(金额/数量)-(数据)"
 
 				var confirmNonRenewalRateMoey string
 				var confirmNonRenewalRateNum string
@@ -679,21 +700,73 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				if mapSignedClientNum[keyMap] == 0 || mapSignedClientMoney[keyMap] == 0 {
 					sellerItem.AverageRevenueCount = "0"
 				} else {
-					sellerItem.AverageRevenueCount = utils.SubFloatToString(mapSignedClientMoney[keyMap]/float64(mapSignedClientNum[keyMap]), 2) //客单价
+					sellerItem.AverageRevenueCount = utils.FormatNumberWithCommas(mapSignedClientMoney[keyMap]/float64(mapSignedClientNum[keyMap]), 2) //客单价
 				}
 
-				sellerItem.InvoiceAmountCount = utils.SubFloatToString(mapInvoiceAmountMoney[keyMap], 2)   //"开票金额-(数据)"
-				sellerItem.PaymentReceivedCount = utils.SubFloatToString(mapPaymentAmountMoney[keyMap], 2) //"开票金额-(数据)"
+				sellerItem.InvoiceAmountCount = utils.FormatNumberWithCommas(mapInvoiceAmountMoney[keyMap], 2)   //"开票金额-(数据)"
+				sellerItem.PaymentReceivedCount = utils.FormatNumberWithCommas(mapPaymentAmountMoney[keyMap], 2) //"开票金额-(数据)"
 				if mapInvoiceAmountMoney[keyMap] == 0 || mapPaymentAmountMoney[keyMap] == 0 {
 					sellerItem.UnpaidRatioCount = "0%"
 				} else {
 					sellerItem.UnpaidRatioCount = utils.SubFloatToString((mapInvoiceAmountMoney[keyMap]-mapPaymentAmountMoney[keyMap])/mapInvoiceAmountMoney[keyMap]*100, 2) + "%" //"未到款比例-(数据)"
 				}
-				sellerItem.NewCustomerInvoicingCount = utils.SubFloatToString(mapNewCustomerInvoicingMoney[keyMap], 2)               // "新客开票-(数据)"
-				sellerItem.NewCustomerPaymentsReceivedCount = utils.SubFloatToString(mapNewCustomerPaymentsReceivedMoney[keyMap], 2) // "新客到款-(数据)"
+				sellerItem.NewCustomerInvoicingCount = utils.FormatNumberWithCommas(mapNewCustomerInvoicingMoney[keyMap], 2)               // "新客开票-(数据)"
+				sellerItem.NewCustomerPaymentsReceivedCount = utils.FormatNumberWithCommas(mapNewCustomerPaymentsReceivedMoney[keyMap], 2) // "新客到款-(数据)"
 				if developButton || serverButton || adminId != "" {
 					item.DataList = append(item.DataList, sellerItem)
+					dataListDevelop = append(dataListDevelop, sellerItem)
 				}
+
+				//处理要排序的值
+				switch sortParam {
+				case "AddTrialCount": //新增试用
+					mapSortDateDevelop[vS.AdminId] = mapAddTrialNum[keyMap]
+				case "NewContractData": //新签合同
+					mapSortDateDevelop[vS.AdminId] = mapNewContractMoney[keyMap]
+				case "ExpiredContractData": //到期合同
+					mapSortDateDevelop[vS.AdminId] = mapExpiredContractMoney[keyMap]
+				case "RenewedContractData": //续约合同
+					mapSortDateDevelop[vS.AdminId] = mapRenewedContractMoney[keyMap]
+				case "RenewalRateData": //续约率
+					if mapRenewedContractMoney[keyMap] == 0 || mapExpiredContractMoney[keyMap] == 0 {
+						mapSortDateDevelop[vS.AdminId] = 0
+					} else {
+						mapSortDateDevelop[vS.AdminId] = mapRenewedContractMoney[keyMap] / mapExpiredContractMoney[keyMap]
+					}
+				case "ConfirmedNoRenewalContractData": //确认不续约合同
+					mapSortDateDevelop[vS.AdminId] = confirmedNoRenewalContractMoney[keyMap]
+				case "ConfirmNonRenewalRateData": //确认不续约率
+					if confirmedNoRenewalContractMoney[keyMap] == 0 || mapExpiredContractMoney[keyMap] == 0 {
+						mapSortDateDevelop[vS.AdminId] = 0
+					} else {
+						mapSortDateDevelop[vS.AdminId] = confirmedNoRenewalContractMoney[keyMap] / mapExpiredContractMoney[keyMap]
+					}
+				case "SignedClientCount": //签约客户数量
+					mapSortDateDevelop[vS.AdminId] = float64(mapSignedClientNum[keyMap])
+				case "AverageRevenueCount": //客单价
+					if mapSignedClientNum[keyMap] == 0 || mapSignedClientMoney[keyMap] == 0 {
+						mapSortDateDevelop[vS.AdminId] = 0
+					} else {
+						mapSortDateDevelop[vS.AdminId] = mapSignedClientMoney[keyMap] / float64(mapSignedClientNum[keyMap])
+					}
+				case "InvoiceAmountCount": //开票金额
+					mapSortDateDevelop[vS.AdminId] = mapInvoiceAmountMoney[keyMap]
+				case "PaymentReceivedCount": //到款金额
+					mapSortDateDevelop[vS.AdminId] = mapPaymentAmountMoney[keyMap]
+				case "UnpaidRatioCount": //未到款比例
+					if mapInvoiceAmountMoney[keyMap] == 0 || mapPaymentAmountMoney[keyMap] == 0 {
+						mapSortDateDevelop[vS.AdminId] = 0
+					} else {
+						mapSortDateDevelop[vS.AdminId] = (mapInvoiceAmountMoney[keyMap] - mapPaymentAmountMoney[keyMap]) / mapInvoiceAmountMoney[keyMap]
+					}
+				case "NewCustomerInvoicingCount": //新开票金额
+					mapSortDateDevelop[vS.AdminId] = mapNewCustomerInvoicingMoney[keyMap]
+				case "NewCustomerPaymentsReceivedCount": //新客到款
+					mapSortDateDevelop[vS.AdminId] = mapNewCustomerPaymentsReceivedMoney[keyMap]
+				}
+			}
+			if sortType != "" && sortParam != "" && len(mapSortDateDevelop) > 0 {
+				item.DataList = handleMapSortDate(mapSortDateDevelop, dataListDevelop, sortType)
 			}
 
 			if len(sellerDevelop) > 0 && adminId == "" {
@@ -701,9 +774,9 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				sellerItem.SellerId = strings.Join(sellerIds, ",")
 				sellerItem.SellerName = "开拓组合计"
 				sellerItem.AddTrialCount = fmt.Sprint(mapAddTrialNum[keyMapTtoal])
-				sellerItem.NewContractData = fmt.Sprint(utils.SubFloatToString(mapNewContractMoney[keyMapTtoal], 2), " / ", mapNewContractNum[keyMapTtoal])             // 新签合同(金额/数量)-(数据)
-				sellerItem.ExpiredContractData = fmt.Sprint(utils.SubFloatToString(mapExpiredContractMoney[keyMapTtoal], 2), " / ", mapExpiredContractNum[keyMapTtoal]) //"到期合同(金额/数量)-(数据)"
-				sellerItem.RenewedContractData = fmt.Sprint(utils.SubFloatToString(mapRenewedContractMoney[keyMapTtoal], 2), " / ", mapRenewedContractNum[keyMapTtoal]) // "续约合同(金额/数量)-(数据)"
+				sellerItem.NewContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapNewContractMoney[keyMapTtoal], 2), " / ", mapNewContractNum[keyMapTtoal])             // 新签合同(金额/数量)-(数据)
+				sellerItem.ExpiredContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapExpiredContractMoney[keyMapTtoal], 2), " / ", mapExpiredContractNum[keyMapTtoal]) //"到期合同(金额/数量)-(数据)"
+				sellerItem.RenewedContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapRenewedContractMoney[keyMapTtoal], 2), " / ", mapRenewedContractNum[keyMapTtoal]) // "续约合同(金额/数量)-(数据)"
 				var renewalRateMoey string
 				var renewalRateNum string
 				if mapRenewedContractMoney[keyMapTtoal] == 0 || mapExpiredContractMoney[keyMapTtoal] == 0 {
@@ -716,8 +789,8 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				} else {
 					renewalRateNum = utils.SubFloatToString(float64(mapRenewedContractCompanyNum[keyMapTtoal])/float64(mapExpiredContractCompanyNum[keyMapTtoal])*100, 2) + "%"
 				}
-				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                                    //"续约率(金额/数量)-(数据)"
-				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.SubFloatToString(confirmedNoRenewalContractMoney[keyMapTtoal], 2), " / ", confirmedNoRenewalContractNum[keyMapTtoal]) //"确认不续约合同(金额/数量)-(数据)"
+				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                                          //"续约率(金额/数量)-(数据)"
+				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.FormatNumberWithCommas(confirmedNoRenewalContractMoney[keyMapTtoal], 2), " / ", confirmedNoRenewalContractNum[keyMapTtoal]) //"确认不续约合同(金额/数量)-(数据)"
 
 				var confirmNonRenewalRateMoey string
 				var confirmNonRenewalRateNum string
@@ -737,21 +810,22 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				if mapSignedClientNum[keyMapTtoal] == 0 || mapSignedClientMoney[keyMapTtoal] == 0 {
 					sellerItem.AverageRevenueCount = "0"
 				} else {
-					sellerItem.AverageRevenueCount = utils.SubFloatToString(mapSignedClientMoney[keyMapTtoal]/float64(mapSignedClientNum[keyMapTtoal]), 2) //客单价
+					sellerItem.AverageRevenueCount = utils.FormatNumberWithCommas(mapSignedClientMoney[keyMapTtoal]/float64(mapSignedClientNum[keyMapTtoal]), 2) //客单价
 				}
 
-				sellerItem.InvoiceAmountCount = utils.SubFloatToString(mapInvoiceAmountMoney[keyMapTtoal], 2)   //"开票金额-(数据)"
-				sellerItem.PaymentReceivedCount = utils.SubFloatToString(mapPaymentAmountMoney[keyMapTtoal], 2) //"开票金额-(数据)"
+				sellerItem.InvoiceAmountCount = utils.FormatNumberWithCommas(mapInvoiceAmountMoney[keyMapTtoal], 2)   //"开票金额-(数据)"
+				sellerItem.PaymentReceivedCount = utils.FormatNumberWithCommas(mapPaymentAmountMoney[keyMapTtoal], 2) //"开票金额-(数据)"
 				if mapInvoiceAmountMoney[keyMapTtoal] == 0 || mapPaymentAmountMoney[keyMapTtoal] == 0 {
 					sellerItem.UnpaidRatioCount = "0%"
 				} else {
 					sellerItem.UnpaidRatioCount = utils.SubFloatToString((mapInvoiceAmountMoney[keyMapTtoal]-mapPaymentAmountMoney[keyMapTtoal])/mapInvoiceAmountMoney[keyMapTtoal]*100, 2) + "%" //"未到款比例-(数据)"
 				}
-				sellerItem.NewCustomerInvoicingCount = utils.SubFloatToString(mapNewCustomerInvoicingMoney[keyMapTtoal], 2)               // "新客开票-(数据)"
-				sellerItem.NewCustomerPaymentsReceivedCount = utils.SubFloatToString(mapNewCustomerPaymentsReceivedMoney[keyMapTtoal], 2) // "新客到款-(数据)"
+				sellerItem.NewCustomerInvoicingCount = utils.FormatNumberWithCommas(mapNewCustomerInvoicingMoney[keyMapTtoal], 2)               // "新客开票-(数据)"
+				sellerItem.NewCustomerPaymentsReceivedCount = utils.FormatNumberWithCommas(mapNewCustomerPaymentsReceivedMoney[keyMapTtoal], 2) // "新客到款-(数据)"
 				item.DataList = append(item.DataList, sellerItem)
 			}
 
+			var dataListService []*statistic_report.RaiDataSummaryDetail
 			for _, vS := range sellerService {
 				keyMap = fmt.Sprint(item.DataType, "_Server_", vS.AdminId)
 				sellerItem := new(statistic_report.RaiDataSummaryDetail)
@@ -760,9 +834,9 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				sellerServiceIds = append(sellerServiceIds, sellerItem.SellerId)
 				sellerItem.SellerName = vS.RealName
 				sellerItem.AddTrialCount = fmt.Sprint(mapAddTrialNum[keyMap])
-				sellerItem.NewContractData = fmt.Sprint(utils.SubFloatToString(mapNewContractMoneyServer[keyMap], 2), " / ", mapNewContractNumServer[keyMap])             // 新签合同(金额/数量)-(数据)
-				sellerItem.ExpiredContractData = fmt.Sprint(utils.SubFloatToString(mapExpiredContractMoneyServer[keyMap], 2), " / ", mapExpiredContractNumServer[keyMap]) //"到期合同(金额/数量)-(数据)"
-				sellerItem.RenewedContractData = fmt.Sprint(utils.SubFloatToString(mapRenewedContractMoneyServer[keyMap], 2), " / ", mapRenewedContractNumServer[keyMap]) // "续约合同(金额/数量)-(数据)"
+				sellerItem.NewContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapNewContractMoneyServer[keyMap], 2), " / ", mapNewContractNumServer[keyMap])             // 新签合同(金额/数量)-(数据)
+				sellerItem.ExpiredContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapExpiredContractMoneyServer[keyMap], 2), " / ", mapExpiredContractNumServer[keyMap]) //"到期合同(金额/数量)-(数据)"
+				sellerItem.RenewedContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapRenewedContractMoneyServer[keyMap], 2), " / ", mapRenewedContractNumServer[keyMap]) // "续约合同(金额/数量)-(数据)"
 				var renewalRateMoey string
 				var renewalRateNum string
 				if mapRenewedContractMoneyServer[keyMap] == 0 || mapExpiredContractMoneyServer[keyMap] == 0 {
@@ -775,8 +849,8 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				} else {
 					renewalRateNum = utils.SubFloatToString(float64(mapRenewedContractCompanyNumServer[keyMap])/float64(mapExpiredContractCompanyNumServer[keyMap])*100, 2) + "%"
 				}
-				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                                      //"续约率(金额/数量)-(数据)"
-				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.SubFloatToString(confirmedNoRenewalContractMoneyServer[keyMap], 2), " / ", confirmedNoRenewalContractNumServer[keyMap]) //"确认不续约合同(金额/数量)-(数据)"
+				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                                            //"续约率(金额/数量)-(数据)"
+				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.FormatNumberWithCommas(confirmedNoRenewalContractMoneyServer[keyMap], 2), " / ", confirmedNoRenewalContractNumServer[keyMap]) //"确认不续约合同(金额/数量)-(数据)"
 
 				var confirmNonRenewalRateMoey string
 				var confirmNonRenewalRateNum string
@@ -796,31 +870,84 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				if mapSignedClientNumServer[keyMap] == 0 || mapSignedClientMoneyServer[keyMap] == 0 {
 					sellerItem.AverageRevenueCount = "0"
 				} else {
-					sellerItem.AverageRevenueCount = utils.SubFloatToString(mapSignedClientMoneyServer[keyMap]/float64(mapSignedClientNumServer[keyMap]), 2) //客单价
+					sellerItem.AverageRevenueCount = utils.FormatNumberWithCommas(mapSignedClientMoneyServer[keyMap]/float64(mapSignedClientNumServer[keyMap]), 2) //客单价
 				}
 
-				sellerItem.InvoiceAmountCount = utils.SubFloatToString(mapInvoiceAmountMoney[keyMap], 2)   //"开票金额-(数据)"
-				sellerItem.PaymentReceivedCount = utils.SubFloatToString(mapPaymentAmountMoney[keyMap], 2) //"开票金额-(数据)"
+				sellerItem.InvoiceAmountCount = utils.FormatNumberWithCommas(mapInvoiceAmountMoney[keyMap], 2)   //"开票金额-(数据)"
+				sellerItem.PaymentReceivedCount = utils.FormatNumberWithCommas(mapPaymentAmountMoney[keyMap], 2) //"开票金额-(数据)"
 				if mapInvoiceAmountMoney[keyMap] == 0 || mapPaymentAmountMoney[keyMap] == 0 {
 					sellerItem.UnpaidRatioCount = "0%"
 				} else {
 					sellerItem.UnpaidRatioCount = utils.SubFloatToString((mapInvoiceAmountMoney[keyMap]-mapPaymentAmountMoney[keyMap])/mapInvoiceAmountMoney[keyMap]*100, 2) + "%" //"未到款比例-(数据)"
 				}
-				sellerItem.NewCustomerInvoicingCount = utils.SubFloatToString(mapNewCustomerInvoicingMoney[keyMap], 2)               // "新客开票-(数据)"
-				sellerItem.NewCustomerPaymentsReceivedCount = utils.SubFloatToString(mapNewCustomerPaymentsReceivedMoney[keyMap], 2) // "新客到款-(数据)"
+				sellerItem.NewCustomerInvoicingCount = utils.FormatNumberWithCommas(mapNewCustomerInvoicingMoney[keyMap], 2)               // "新客开票-(数据)"
+				sellerItem.NewCustomerPaymentsReceivedCount = utils.FormatNumberWithCommas(mapNewCustomerPaymentsReceivedMoney[keyMap], 2) // "新客到款-(数据)"
 				if developButton || serverButton || serviceAdminId != "" {
 					item.DataList = append(item.DataList, sellerItem)
+					dataListService = append(dataListService, sellerItem)
+				}
+
+				//处理要排序的值
+				switch sortParam {
+				case "AddTrialCount": //新增试用
+					mapSortDateService[vS.AdminId] = mapAddTrialNum[keyMap]
+				case "NewContractData": //新签合同
+					mapSortDateService[vS.AdminId] = mapNewContractMoneyServer[keyMap]
+				case "ExpiredContractData": //到期合同
+					mapSortDateService[vS.AdminId] = mapExpiredContractMoneyServer[keyMap]
+				case "RenewedContractData": //续约合同
+					mapSortDateService[vS.AdminId] = mapRenewedContractMoneyServer[keyMap]
+				case "RenewalRateData": //续约率
+					if mapRenewedContractMoneyServer[keyMap] == 0 || mapExpiredContractMoneyServer[keyMap] == 0 {
+						mapSortDateService[vS.AdminId] = 0
+					} else {
+						mapSortDateService[vS.AdminId] = mapRenewedContractMoneyServer[keyMap] / mapExpiredContractMoneyServer[keyMap]
+					}
+				case "ConfirmedNoRenewalContractData": //确认不续约合同
+					mapSortDateService[vS.AdminId] = confirmedNoRenewalContractMoneyServer[keyMap]
+				case "ConfirmNonRenewalRateData": //确认不续约率
+					if confirmedNoRenewalContractMoneyServer[keyMap] == 0 || mapExpiredContractMoneyServer[keyMap] == 0 {
+						mapSortDateService[vS.AdminId] = 0
+					} else {
+						mapSortDateService[vS.AdminId] = confirmedNoRenewalContractMoneyServer[keyMap] / mapExpiredContractMoneyServer[keyMap]
+					}
+				case "SignedClientCount": //签约客户数量
+					mapSortDateService[vS.AdminId] = float64(mapSignedClientNumServer[keyMap])
+				case "AverageRevenueCount": //客单价
+					if mapSignedClientNumServer[keyMap] == 0 || mapSignedClientMoneyServer[keyMap] == 0 {
+						mapSortDateService[vS.AdminId] = 0
+					} else {
+						mapSortDateService[vS.AdminId] = mapSignedClientMoneyServer[keyMap] / float64(mapSignedClientNumServer[keyMap])
+					}
+				case "InvoiceAmountCount": //开票金额
+					mapSortDateService[vS.AdminId] = mapInvoiceAmountMoney[keyMap]
+				case "PaymentReceivedCount": //到款金额
+					mapSortDateService[vS.AdminId] = mapPaymentAmountMoney[keyMap]
+				case "UnpaidRatioCount": //未到款比例
+					if mapInvoiceAmountMoney[keyMap] == 0 || mapPaymentAmountMoney[keyMap] == 0 {
+						mapSortDateService[vS.AdminId] = 0
+					} else {
+						mapSortDateService[vS.AdminId] = (mapInvoiceAmountMoney[keyMap] - mapPaymentAmountMoney[keyMap]) / mapInvoiceAmountMoney[keyMap]
+					}
+				case "NewCustomerInvoicingCount": //新开票金额
+					mapSortDateService[vS.AdminId] = mapNewCustomerInvoicingMoney[keyMap]
+				case "NewCustomerPaymentsReceivedCount": //新客到款
+					mapSortDateService[vS.AdminId] = mapNewCustomerPaymentsReceivedMoney[keyMap]
 				}
 			}
+			if sortType != "" && sortParam != "" && len(mapSortDateService) > 0 {
+				item.DataList = handleMapSortDate(mapSortDateService, dataListService, sortType)
+			}
+
 			if len(sellerService) > 0 && serviceAdminId == "" {
 				sellerItem := new(statistic_report.RaiDataSummaryDetail)
 				sellerItem.IsServerSeller = true
 				sellerItem.SellerId = strings.Join(sellerServiceIds, ",")
 				sellerItem.SellerName = "服务组合计"
 				sellerItem.AddTrialCount = fmt.Sprint(mapAddTrialNum[keyMapTtoalServer])
-				sellerItem.NewContractData = fmt.Sprint(utils.SubFloatToString(mapNewContractMoneyServer[keyMapTtoalServer], 2), " / ", mapNewContractNumServer[keyMapTtoalServer])             // 新签合同(金额/数量)-(数据)
-				sellerItem.ExpiredContractData = fmt.Sprint(utils.SubFloatToString(mapExpiredContractMoneyServer[keyMapTtoalServer], 2), " / ", mapExpiredContractNumServer[keyMapTtoalServer]) //"到期合同(金额/数量)-(数据)"
-				sellerItem.RenewedContractData = fmt.Sprint(utils.SubFloatToString(mapRenewedContractMoneyServer[keyMapTtoalServer], 2), " / ", mapRenewedContractNumServer[keyMapTtoalServer]) // "续约合同(金额/数量)-(数据)"
+				sellerItem.NewContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapNewContractMoneyServer[keyMapTtoalServer], 2), " / ", mapNewContractNumServer[keyMapTtoalServer])             // 新签合同(金额/数量)-(数据)
+				sellerItem.ExpiredContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapExpiredContractMoneyServer[keyMapTtoalServer], 2), " / ", mapExpiredContractNumServer[keyMapTtoalServer]) //"到期合同(金额/数量)-(数据)"
+				sellerItem.RenewedContractData = fmt.Sprint(utils.FormatNumberWithCommas(mapRenewedContractMoneyServer[keyMapTtoalServer], 2), " / ", mapRenewedContractNumServer[keyMapTtoalServer]) // "续约合同(金额/数量)-(数据)"
 				var renewalRateMoey string
 				var renewalRateNum string
 				if mapRenewedContractMoneyServer[keyMapTtoalServer] == 0 || mapExpiredContractMoneyServer[keyMapTtoalServer] == 0 {
@@ -833,8 +960,8 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				} else {
 					renewalRateNum = utils.SubFloatToString(float64(mapRenewedContractCompanyNumServer[keyMapTtoalServer])/float64(mapExpiredContractCompanyNumServer[keyMapTtoalServer])*100, 2) + "%"
 				}
-				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                                                            //"续约率(金额/数量)-(数据)"
-				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.SubFloatToString(confirmedNoRenewalContractMoneyServer[keyMapTtoalServer], 2), " / ", confirmedNoRenewalContractNumServer[keyMapTtoalServer]) //"确认不续约合同(金额/数量)-(数据)"
+				sellerItem.RenewalRateData = fmt.Sprint(renewalRateMoey, " / ", renewalRateNum)                                                                                                                                  //"续约率(金额/数量)-(数据)"
+				sellerItem.ConfirmedNoRenewalContractData = fmt.Sprint(utils.FormatNumberWithCommas(confirmedNoRenewalContractMoneyServer[keyMapTtoalServer], 2), " / ", confirmedNoRenewalContractNumServer[keyMapTtoalServer]) //"确认不续约合同(金额/数量)-(数据)"
 
 				var confirmNonRenewalRateMoey string
 				var confirmNonRenewalRateNum string
@@ -854,18 +981,18 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 				if mapSignedClientNumServer[keyMapTtoalServer] == 0 || mapSignedClientMoneyServer[keyMapTtoalServer] == 0 {
 					sellerItem.AverageRevenueCount = "0"
 				} else {
-					sellerItem.AverageRevenueCount = utils.SubFloatToString(mapSignedClientMoneyServer[keyMapTtoalServer]/float64(mapSignedClientNumServer[keyMapTtoalServer]), 2) //客单价
+					sellerItem.AverageRevenueCount = utils.FormatNumberWithCommas(mapSignedClientMoneyServer[keyMapTtoalServer]/float64(mapSignedClientNumServer[keyMapTtoalServer]), 2) //客单价
 				}
 
-				sellerItem.InvoiceAmountCount = utils.SubFloatToString(mapInvoiceAmountMoney[keyMapTtoalServer], 2)   //"开票金额-(数据)"
-				sellerItem.PaymentReceivedCount = utils.SubFloatToString(mapPaymentAmountMoney[keyMapTtoalServer], 2) //"开票金额-(数据)"
+				sellerItem.InvoiceAmountCount = utils.FormatNumberWithCommas(mapInvoiceAmountMoney[keyMapTtoalServer], 2)   //"开票金额-(数据)"
+				sellerItem.PaymentReceivedCount = utils.FormatNumberWithCommas(mapPaymentAmountMoney[keyMapTtoalServer], 2) //"开票金额-(数据)"
 				if mapInvoiceAmountMoney[keyMapTtoalServer] == 0 || mapPaymentAmountMoney[keyMapTtoalServer] == 0 {
 					sellerItem.UnpaidRatioCount = "0%"
 				} else {
 					sellerItem.UnpaidRatioCount = utils.SubFloatToString((mapInvoiceAmountMoney[keyMapTtoalServer]-mapPaymentAmountMoney[keyMapTtoalServer])/mapInvoiceAmountMoney[keyMapTtoalServer]*100, 2) + "%" //"未到款比例-(数据)"
 				}
-				sellerItem.NewCustomerInvoicingCount = utils.SubFloatToString(mapNewCustomerInvoicingMoney[keyMapTtoalServer], 2)               // "新客开票-(数据)"
-				sellerItem.NewCustomerPaymentsReceivedCount = utils.SubFloatToString(mapNewCustomerPaymentsReceivedMoney[keyMapTtoalServer], 2) // "新客到款-(数据)"
+				sellerItem.NewCustomerInvoicingCount = utils.FormatNumberWithCommas(mapNewCustomerInvoicingMoney[keyMapTtoalServer], 2)               // "新客开票-(数据)"
+				sellerItem.NewCustomerPaymentsReceivedCount = utils.FormatNumberWithCommas(mapNewCustomerPaymentsReceivedMoney[keyMapTtoalServer], 2) // "新客到款-(数据)"
 				item.DataList = append(item.DataList, sellerItem)
 			}
 			items = append(items, item)
@@ -878,6 +1005,43 @@ func (this *StatisticRaiDataSummaryController) RaiDataSummaryList() {
 	br.Data = resp
 }
 
+// 排序处理
+func handleMapSortDate(mapSort map[int]float64, dataList []*statistic_report.RaiDataSummaryDetail, orderType string) (dataListResp []*statistic_report.RaiDataSummaryDetail) {
+	type kvSort struct {
+		AdminIdKey int
+		AdminValue float64
+	}
+
+	var adminSlice []kvSort
+	for k, v := range mapSort {
+		adminSlice = append(adminSlice, kvSort{k, v})
+	}
+
+	if orderType == "asc" {
+		// 2. 按Value从小到大排序
+		sort.Slice(adminSlice, func(i, j int) bool {
+			return adminSlice[i].AdminValue < adminSlice[j].AdminValue // "<" 表示升序
+		})
+	} else {
+		// 2.1 按Value从大到小排序
+		sort.Slice(adminSlice, func(i, j int) bool {
+			return adminSlice[i].AdminValue > adminSlice[j].AdminValue // ">" 表示降序
+		})
+	}
+
+	// 3. 输出排序结果
+	for _, vsort := range adminSlice {
+		//fmt.Println("vsort.AdminIdKey", vsort.AdminIdKey, "vsort.AdminValue", vsort.AdminValue)
+		for _, vDate := range dataList {
+			if vDate.SellerId == strconv.Itoa(vsort.AdminIdKey) {
+				dataListResp = append(dataListResp, vDate)
+			}
+		}
+	}
+	//fmt.Println("dataListResp", dataListResp)
+	return
+}
+
 // MergeCompanyList
 // @Title 权益数据汇总弹窗详情
 // @Description 权益数据汇总弹窗详情接口

+ 5 - 1
controllers/statistic_report.go

@@ -3797,7 +3797,11 @@ func (this *StatisticReportController) IncrementalCompanyList() {
 
 	//条件
 	if adminId != "" {
-		condition += ` AND c.seller_id in  (` + adminId + `) `
+		if dataType == "未续约客户" {
+			condition += ` AND (c.share_seller_id in  (` + adminId + `) OR c.seller_id in  (` + adminId + `)) `
+		}else{
+			condition += ` AND c.seller_id in  (` + adminId + `) `
+		}
 		//pars = append(pars, adminId)
 	} else {
 

+ 2 - 2
models/company/company_permission.go

@@ -379,7 +379,7 @@ func GetCompanyListCompanyIdByPermissionIdStr(permissionStr string) (company_id
 		SELECT 
 		GROUP_CONCAT(DISTINCT company_id) AS company_id
 		FROM company_report_permission
-		WHERE report_permission_id IN (?)
+		WHERE chart_permission_id IN (?)
 		#GROUP  BY company_id
 		`
 	err = o.Raw(sql, permissionStr).QueryRow(&company_id)
@@ -639,7 +639,7 @@ func GetCompanyIdsStrByReportPermissionIds(permissionIds []int) (companyIds []in
 			FROM
 				company_report_permission
 			WHERE
-				report_permission_id IN (` + utils.GetOrmInReplace(len(permissionIds)) + `) AND (DATE(NOW()) BETWEEN start_date AND end_date) AND status IN ('试用', '正式', '永续')`
+				chart_permission_id IN (` + utils.GetOrmInReplace(len(permissionIds)) + `) AND (DATE(NOW()) BETWEEN start_date AND end_date) AND status IN ('试用', '正式', '永续')`
 	_, err = o.Raw(sql, permissionIds).QueryRows(&companyIds)
 	return
 }

+ 15 - 0
models/company/company_product.go

@@ -734,3 +734,18 @@ func UpdateCompanyProductSellerUnexpiredInitinit16_1_05(sellerId int, sellerName
 	_, err = o.Raw(sql, sellerId, sellerName, companyId).Exec()
 	return
 }
+
+// 取消共享销售
+func UpdateCompanyProductCancelisShare(companyId, productId int) (err error) {
+	o := orm.NewOrm()
+	sql := `UPDATE company_product SET
+                            is_share = 0 , 
+                            share_seller = '',
+                            share_group_id = 0,
+                            share_seller_id = 0 , 
+                            share_seller_id_last  = 0 , 
+                            share_seller_last = ''
+                            WHERE company_id = ?  AND product_id= ? `
+	_, err = o.Raw(sql, companyId, productId).Exec()
+	return
+}

+ 19 - 1
models/cygx/cygx_morning_meeting_reviews.go

@@ -17,6 +17,8 @@ type CygxMorningMeetingReviews struct {
 	Status        int       `json:"status"`       // 0:未发布,1:已发布
 	PartNums      int       `json:"partNums"`     // 段落数
 	IndustryNames string    `json:"industryName"` // 产业名称
+	OpUserId      int       `description:"操作人编号"`
+	OpUserName    string    `description:"操作人名称"`
 }
 
 // 添加晨报点评
@@ -59,6 +61,7 @@ type CygxMorningMeetingReviewItem struct {
 	IndustryNames string `json:"industryName"` // 产业名称
 	Pv            int    `description:"PV"`
 	Uv            int    `description:"UV"`
+	OpUserName    string `description:"操作人名称"`
 }
 
 type CygxMorningMeetingReviewsList struct {
@@ -81,6 +84,14 @@ func PublishMorningMeetingReviewById(reviewId int) (err error) {
 	return
 }
 
+// 发布报告
+func UpdateMorningMeetingReviewStatusById(status, reviewId int) (err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `UPDATE cygx_morning_meeting_reviews SET status= ?,publish_time=now(),modify_time=NOW() WHERE id = ? `
+	_, err = o.Raw(sql, status, reviewId).Exec()
+	return
+}
+
 type MorningReviewPublishReq struct {
 	ReviewIds string `description:"晨会id,多个用英文逗号隔开"`
 }
@@ -89,6 +100,11 @@ type MorningReviewPublishCancelReq struct {
 	ReviewId int `description:"晨会id"`
 }
 
+type MorningReviewApproveSubmiteq struct {
+	ReviewId int `description:"晨会id"`
+	Status   int `description:"0:未发布,1:已发布,2:待审核、3:已驳回、4:已撤回、5:未提交"`
+}
+
 // 取消发布报告
 func PublishCancelMorningMeetingReview(reviewId int) (err error) {
 	o := orm.NewOrmUsingDB("hz_cygx")
@@ -146,9 +162,11 @@ func UpdateCygxMorningMeetingReviews(item *CygxMorningMeetingReviews) (err error
 			  modify_time = ?,
 			  part_nums = ?,
 			  industry_names = ?,
+			  op_user_id = ?,
+			  op_user_name = ?,
 			  status = ? 
 			WHERE id = ? `
-	_, err = o.Raw(sql, item.MeetingTime, item.PublishTime, item.ModifyTime, item.PartNums, item.IndustryNames, item.Status, item.Id).Exec()
+	_, err = o.Raw(sql, item.MeetingTime, item.PublishTime, item.ModifyTime, item.PartNums, item.IndustryNames, item.OpUserId, item.OpUserName, item.Status, item.Id).Exec()
 
 	return
 }

+ 41 - 0
models/cygx/morning_meeting_review_log.go

@@ -0,0 +1,41 @@
+package cygx
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxMorningMeetingReviewLog struct {
+	LogId                int       `orm:"column(log_id);pk"`
+	MeetingTime          time.Time `description:"晨会日期"`
+	CreateTime           time.Time `description:"创建时间"`
+	ModifyTime           time.Time `description:"修改时间"`
+	IndustryId           int       `description:"产业ID"`
+	IndustryName         string    `description:"产业名称"`
+	ChartPermissionName  string    `description:"行业名称"`
+	ChartPermissionId    int       `description:"行业ID"`
+	IndustrialSubjectIds string    `description:"标的ID"`
+	MeetingId            int       `description:"主表ID"`
+	Content              string    `description:"内容"`
+	ReportLink           string    `description:"报告链接"`
+	LinkArticleId        int       `description:"跳转的文章ID"`
+	Title                string    `description:"标题"`
+	Remark               string    `description:"备注说明"`
+	Operate              string    `description:"操作内容"`
+	OpUserId             int       `description:"操作人编号"`
+	OpUserName           string    `description:"操作人名称"`
+}
+
+// 添加晨报点评章节日志信息
+func AddCygxMorningMeetingReviewLog(item *CygxMorningMeetingReviewLog) (newId int64, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	newId, err = o.Insert(item)
+	return
+}
+
+func GetCygxMorningMeetingReviewLogByLogId(logId int) (item *CygxMorningMeetingReviewLog, err error) {
+	o := orm.NewOrmUsingDB("hz_cygx")
+	sql := `SELECT * FROM cygx_morning_meeting_review_log WHERE  log_id =  ? `
+	err = o.Raw(sql, logId).QueryRow(&item)
+	return
+}

+ 1 - 0
models/db.go

@@ -442,6 +442,7 @@ func initCygx() {
 		new(cygx.CygxActivitySpecialMeetingDetail),
 		new(cygx.CygxMorningMeetingReviewChapter),
 		new(cygx.CygxMorningMeetingReviews),
+		new(cygx.CygxMorningMeetingReviewLog), //晨会操作日志
 		new(cygx.CygxResourceData),
 		new(cygx.CygxReportSelectionChartLog),
 		new(cygx.CygxActivitySpecialTripBill),

+ 5 - 0
models/roadshow/calendar.go

@@ -29,6 +29,11 @@ type AddActivityReq struct {
 	EnglishCompany   int `description:"是否为英文客户"`
 }
 
+type AddActivityResp struct {
+	Points  int `description:"点数"`
+	AddType int `description:"添加类型,1成功(扣点数),2成功(不扣点数),3失败"`
+}
+
 type CalendarResearcher struct {
 	ResearcherId   int    `description:"研究员id"`
 	ResearcherName string `description:"研究员名称"`

+ 2 - 1
models/roadshow/rs_calendar_relation.go

@@ -371,10 +371,11 @@ func GetRsCalendarResearcherInfoIByResearcherIdAndDate(researcherId int, startDa
 	//WHERE b.source=1 and a.status=2 and c.calendar_type=1 and a.researcher_id=? and start_date>=? and end_date <= ? `
 
 	//杭州创建的路演活动,如果上海被删除了,那么也要同步删除杭州的(所以相对于上面的逻辑,下面移除了来源的where条件)
+	// 需求池1065 同步上海CRM路演信息时,若某路演在我们的CRM中创建,即便在上海CRM中没有查到,也不做删除
 	sql := `SELECT a.*,c.third_calendar_id,c.calendar_type FROM rs_calendar_researcher a 
 join rs_calendar b on a.rs_calendar_id=b.rs_calendar_id
 join rs_calendar_relation c on a.rs_calendar_researcher_id=c.self_calendar_id
-WHERE a.status=2 and c.calendar_type=1 and a.researcher_id=? and start_date>=? and end_date <= ? `
+WHERE a.status=2 and c.calendar_type=1 AND b.source = 1 and a.researcher_id=? and start_date>=? and end_date <= ? `
 	_, err = o.Raw(sql, researcherId, startDate, endDate).QueryRows(&items)
 	return
 }

+ 1 - 1
models/statistic_report.go

@@ -822,7 +822,7 @@ func GetIncrementalCompanyListByOperationRecord(condition string, pars []interfa
 	sql1 += ` GROUP BY a.company_id, a.product_id `
 
 	//查询真正的数据
-	sql := `SELECT a.id, a.company_id, b.company_name, c.seller_id, c.seller_name, c.seller_name_init, a.product_id, a.product_name, a.create_time, b.region_type, c.renewal_reason, c.renewal_todo, c.status , a.sys_real_name, a.operation FROM company_operation_record a
+	sql := `SELECT a.id, a.company_id, b.company_name, c.seller_id, c.seller_name, c.seller_name_init, a.product_id, a.product_name, a.create_time, b.region_type, c.renewal_reason, c.renewal_todo, c.status , a.sys_real_name, a.operation, c.share_seller FROM company_operation_record a
 		RIGHT JOIN company b ON a.company_id = b.company_id
 		JOIN company_product c ON b.company_id = c.company_id 
 		AND a.product_id = c.product_id

+ 7 - 5
models/system/sys_admin.go

@@ -466,19 +466,21 @@ func GetSysuserRaiList() (items []*AdminItem, err error) {
 	sql := `SELECT
 			real_name,
 			mobile,
+			group_id,
 			group_name 
 		FROM
 			admin 
 		WHERE
-			role_type_code IN ('rai_group','rai_seller')
-			AND group_id NOT IN ( 19, 10, 17 )
+			role_type_code IN ( 'rai_group', 'rai_seller' ) 
+			AND group_id NOT IN ( 19, 10, 17, 68, 72 ) 
 			AND enabled = 1 
-			OR real_name IN ( '沈涛', '张传星' ) ` // 先写死,看情况要不要改
+			OR real_name IN ( '沈涛', '张传星' ) 
+			OR ( group_name = '未分组' AND enabled = 1 ) ` // 先写死,看情况要不要改
 	_, err = o.Raw(sql).QueryRows(&items)
 	return
 }
 
-// GetSysuserRaiList 获取除服务组之外的所有权益销售
+// GetSysuserRaiListNoServer 获取除服务组之外的所有权益销售
 func GetSysuserRaiListNoServer() (items []*AdminItem, err error) {
 	o := orm.NewOrm()
 	sql := `SELECT  * FROM admin WHERE role_type_code  IN ('rai_group','rai_seller')   AND role_name NOT IN ('权益服务销售','权益服务组长')  `
@@ -557,4 +559,4 @@ func UpdateAdminRoleInfoByRoleId(roleId int, roleName string, roleTypeCode strin
 	sql := `UPDATE admin SET role_name = ?, role_type_code = ? WHERE role_id = ?`
 	_, err = o.Raw(sql, roleName, roleTypeCode, roleId).Exec()
 	return
-}
+}

+ 9 - 0
routers/commentsRouter.go

@@ -2167,6 +2167,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:MorningMeetingController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:MorningMeetingController"],
+        beego.ControllerComments{
+            Method: "ApproveSubmitReport",
+            Router: `/morningMeeting/approve/submit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:MorningMeetingController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:MorningMeetingController"],
         beego.ControllerComments{
             Method: "Delete",

+ 6 - 6
services/company.go

@@ -876,7 +876,7 @@ func GetCompanyPermissionButton(roleTypeCode, status, itemSellerIds, itemGroupId
 				return
 			} else if status == utils.COMPANY_STATUS_TRY_OUT { //试用
 				button.BtnEdit = true
-				button.BtnDelete = true
+				//button.BtnDelete = true //需求池1067
 				if productId == utils.COMPANY_PRODUCT_RAI_ID {
 					button.BtnRemarkViewHistory = true
 				} else {
@@ -898,21 +898,21 @@ func GetCompanyPermissionButton(roleTypeCode, status, itemSellerIds, itemGroupId
 				return
 			} else if status == utils.COMPANY_STATUS_LOSE { //流失
 				//button.BtnModifySeller = true
-				button.BtnDelete = true
+				//button.BtnDelete = true //需求池1067
 				if productId == utils.COMPANY_PRODUCT_RAI_ID {
 					button.BtnRemarkViewHistory = true
 				}
 				return
 			} else if status == utils.COMPANY_STATUS_CLOSE { // 关闭
 				//button.BtnModifySeller = true
-				button.BtnDelete = true
+				//button.BtnDelete = true //需求池1067
 				if productId == utils.COMPANY_PRODUCT_FICC_ID {
 					button.BtnLoss = true // 超管/FICC管理员可关闭转流失
 				}
 				return
 			} else { //永续
 				//button.BtnModifySeller = true
-				button.BtnDelete = true
+				//button.BtnDelete = true //需求池1067
 				button.BtnEdit = true
 				if productId == utils.COMPANY_PRODUCT_RAI_ID {
 					button.BtnRemarkViewHistory = true
@@ -1027,7 +1027,7 @@ func GetCompanyPermissionButton(roleTypeCode, status, itemSellerIds, itemGroupId
 						}
 					} else if productStatus == utils.COMPANY_STATUS_TRY_OUT { //试用
 						button.BtnEdit = true
-						button.BtnDelete = true
+						//button.BtnDelete = true //需求池1067
 						button.BtnSuspend = true
 						button.BtnDelay = true
 						button.BtnTurnPositive = true
@@ -1191,7 +1191,7 @@ func GetCompanyPermissionButton(roleTypeCode, status, itemSellerIds, itemGroupId
 						button.BtnRemarkViewHistory = true
 					} else if productStatus == utils.COMPANY_STATUS_TRY_OUT { //试用
 						button.BtnEdit = true
-						button.BtnDelete = true
+						//button.BtnDelete = true //需求池1067
 						button.BtnSuspend = true
 						button.BtnDelay = true
 						button.BtnTurnPositive = true

+ 20 - 18
services/cygx/acitvity.go

@@ -1256,15 +1256,16 @@ func DoActivityOnenIdWxTemplateMsg(activityId int) (err error) {
 		item := new(models.OpenIdList)
 		item.UserId = v.UserId
 		item.OpenId = v.OpenId
-		if mapUserIdChooseSend[v.UserId] == 0 {
-			//如果小助手没有选择过权限信息,那么做消息推送
-			OpenIdList = append(OpenIdList, item)
-		} else {
-			//如果勾选了权限信息,则要满足 1选择产业,2没有选择不接受任何消息推送,3活动对应的主客观跟自己选择的一致。
-			if mapOpenidFllow[v.UserId] != "" && mapOpenidRefuset[v.UserId] == "" && mapUserIdChooseTypeSend[v.UserId] != 0 {
-				OpenIdList = append(OpenIdList, item)
-			}
-		}
+		OpenIdList = append(OpenIdList, item)
+		//if mapUserIdChooseSend[v.UserId] == 0 {
+		//	//如果小助手没有选择过权限信息,那么做消息推送
+		//	OpenIdList = append(OpenIdList, item)
+		//} else {
+		//	//如果勾选了权限信息,则要满足 1选择产业,2没有选择不接受任何消息推送,3活动对应的主客观跟自己选择的一致。
+		//	if mapOpenidFllow[v.UserId] != "" && mapOpenidRefuset[v.UserId] == "" && mapUserIdChooseTypeSend[v.UserId] != 0 {
+		//		OpenIdList = append(OpenIdList, item)
+		//	}
+		//}
 	}
 
 	var openiditems []*cygx.CygxActivityUserTemplateRecord
@@ -1292,15 +1293,16 @@ func DoActivityOnenIdWxTemplateMsg(activityId int) (err error) {
 		item := new(models.OpenIdList)
 		item.UserId = v.UserId
 		item.OpenId = v.OpenId
-		if mapUserIdChooseSend[v.UserId] == 0 {
-			//如果小助手没有选择过权限信息,那么做消息推送
-			OpenIdListYx = append(OpenIdListYx, item)
-		} else {
-			//如果勾选了权限信息,则要满足 1选择产业,2没有选择不接受任何消息推送,3活动对应的主客观跟自己选择的一致。
-			if mapOpenidFllow[v.UserId] != "" && mapOpenidRefuset[v.UserId] == "" && mapUserIdChooseTypeSend[v.UserId] != 0 {
-				OpenIdListYx = append(OpenIdListYx, item)
-			}
-		}
+		OpenIdListYx = append(OpenIdListYx, item)
+		//if mapUserIdChooseSend[v.UserId] == 0 {
+		//	//如果小助手没有选择过权限信息,那么做消息推送
+		//	OpenIdListYx = append(OpenIdListYx, item)
+		//} else {
+		//	//如果勾选了权限信息,则要满足 1选择产业,2没有选择不接受任何消息推送,3活动对应的主客观跟自己选择的一致。
+		//	if mapOpenidFllow[v.UserId] != "" && mapOpenidRefuset[v.UserId] == "" && mapUserIdChooseTypeSend[v.UserId] != 0 {
+		//		OpenIdListYx = append(OpenIdListYx, item)
+		//	}
+		//}
 	}
 
 	var openIdArrYx []string

+ 19 - 0
services/cygx/activity_points_set.go

@@ -409,6 +409,25 @@ func SpecialActivityPointsBillSubmitMeeting(activityId, adminId int) (err error)
 	return
 }
 
+// 13  给公司添加路演,对应专项调研扣点处理
+func SpecialActivityPointsBillRoadShow(activityId, adminId int) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			msg := fmt.Sprint("activityId:", activityId)
+			go alarm_msg.SendAlarmMsg("专项调研活动到会研选扣点处理,写入Redis队列消息失败:"+err.Error()+msg, 2)
+		}
+	}()
+	log := &cygx.YanXuanActivityPointsRedis{ActivityId: activityId, SourceType: 13, AdminId: adminId, Source: 2, CreateTime: time.Now()}
+	if utils.Re == nil {
+		err := utils.Rc.LPush(utils.CYGX_YANXUAN_POINTS_KEY, log)
+		if err != nil {
+			fmt.Println("YanXuanActivityPointsRedis LPush Err:" + err.Error())
+		}
+	}
+	return
+}
+
 func init0703() {
 	//2023.07.03剩余服务点数初始化
 	path := "0703.xlsx"

+ 1 - 1
services/cygx/activity_poster.go

@@ -97,7 +97,7 @@ func MakeActivitySigninImg(activityId int) (imgUrl string, err error) {
 	if activityInfo == nil {
 		return
 	}
-	if activityInfo.ActivityTypeId != 5 && activityInfo.ActivityTypeId != 6 && activityInfo.ActivityTypeId != 8 {
+	if !utils.InArrayByInt(utils.SHOW_SIGNIN_BUTTON_ACTIVITY_TYPE_ID, activityInfo.ActivityTypeId) {
 		return
 	}
 	itemToken, err := models.GetWxToken(utils.WxCygxAppId, utils.WxCygxAppSecret)

+ 25 - 0
services/cygx/activity_special.go

@@ -953,3 +953,28 @@ func CheckSpecialActivityPointsByUserIds(userIds string, activityLen int) (err e
 	}
 	return
 }
+
+//// 根据用户ID,活动场次,校验用户是否有剩余点数报名专项调研活动
+//func CheckRoadShowSpecialActivityPointsByComapnId(comapnId int) (err error) {
+//
+//	var condition string
+//	var pars []interface{}
+//	pars = make([]interface{}, 0)
+//	condition = ` AND  company_id IN (` + utils.GetOrmInReplace(len(comPanyIds)) + `) `
+//	pars = append(pars, comPanyIds)
+//	activitySpecialPermissionPointsList, e := cygx.GetCygxActivitySpecialPermissionPointsList(condition, pars)
+//	if e != nil && e.Error() != utils.ErrNoRow() {
+//		err = errors.New("GetCygxActivitySpecialPermissionPointsList, Err:" + e.Error())
+//		return
+//	}
+//	for _, v := range activitySpecialPermissionPointsList {
+//		mapCompanyPointNow[v.CompanyId] = v.Points
+//	}
+//	//如果需要新增的点数,大于公司剩余的点数,那么就做报错处理
+//	for _, v := range userList {
+//		if mapCompanyPointAdd[v.CompanyId] > mapCompanyPointNow[v.CompanyId] {
+//			err = errors.New("您的专项调研次数已用完,如仍想参加,请与您的对口销售商议")
+//		}
+//	}
+//	return
+//}

+ 0 - 2
services/cygx/mail.go

@@ -19,7 +19,6 @@ func SendResearchSummaryEmail(detail *cygx.DetailCygxResearchSummaryRep, touser
 	m.SetHeader("From", "hzcygx@hzinsights.com ")
 	//m.SetHeader("To", touser...)
 	var user []string
-	user = append(user, "zqliu@hzinsights.com ")
 	user = append(user, "tshen@hzinsights.com ")
 	user = append(user, "hdong@hzinsights.com ")
 	user = append(user, "cxzhang@hzinsights.com ")
@@ -287,7 +286,6 @@ func SendMinutesSummaryEmail(detail *cygx.DetailCygxMinutesSummaryRep, touser []
 	m.SetHeader("From", "hzcygx@hzinsights.com ")
 	//m.SetHeader("To", touser...)
 	var user []string
-	user = append(user, "zqliu@hzinsights.com ")
 	user = append(user, "tshen@hzinsights.com ")
 	user = append(user, "hdong@hzinsights.com ")
 	user = append(user, "cxzhang@hzinsights.com ")

+ 118 - 0
services/cygx/morning_meeting.go

@@ -3,9 +3,13 @@ package cygx
 import (
 	"errors"
 	"fmt"
+	"hongze/hz_crm_api/models"
 	"hongze/hz_crm_api/models/cygx"
+	"hongze/hz_crm_api/services"
 	"hongze/hz_crm_api/services/alarm_msg"
 	"hongze/hz_crm_api/utils"
+	"strconv"
+	"time"
 )
 
 //func init() {
@@ -43,3 +47,117 @@ func GetCygxMorningMeetingReviewChapterHistoryPvUvMap(articleIdArr []int) (mapPv
 	}
 	return
 }
+
+// 添加晨会精华操作日志
+func AddCygxMorningMeetingReviewLog(itemReq *cygx.CygxMorningMeetingReviewChapter, operate, opUserName string, opUserId, status int) {
+
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go alarm_msg.SendAlarmMsg("添加晨会精华操作日志 失败,AddCygxMorningMeetingReviewLog Err:"+err.Error(), 3)
+		}
+	}()
+
+	item := new(cygx.CygxMorningMeetingReviewLog)
+	item.MeetingTime = itemReq.MeetingTime
+	item.CreateTime = time.Now()
+	item.ModifyTime = time.Now()
+	item.IndustryId = itemReq.IndustryId
+	item.IndustryName = itemReq.IndustryName
+	item.ChartPermissionName = itemReq.ChartPermissionName
+	item.ChartPermissionId = itemReq.ChartPermissionId
+	item.IndustrialSubjectIds = itemReq.IndustrialSubjectIds
+	item.MeetingId = int(itemReq.MeetingId)
+	item.Content = itemReq.Content
+	item.ReportLink = itemReq.ReportLink
+	item.LinkArticleId = itemReq.LinkArticleId
+	item.Title = itemReq.Title
+	//item.Remark = remark
+	item.Operate = operate
+	item.OpUserName = opUserName
+	item.OpUserId = opUserId
+
+	newId, e := cygx.AddCygxMorningMeetingReviewLog(item)
+	if e != nil {
+		err = errors.New("AddCygxMorningMeetingReviewLog, Err: " + e.Error())
+		return
+	}
+
+	if status == 2 {
+		SendWxMsgMorningMeetingApproveSubmit(int(newId))
+	}
+	return
+}
+
+// 晨会点评提交新内容审核时,给合规(指定手机号15721524062、15221002612)发送模板消息
+func SendWxMsgMorningMeetingApproveSubmit(logId int) (err error) {
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg(fmt.Sprint("晨会点评内容完成审核时,给提交人发送模板消息失败 logId ", logId, err.Error()), 2)
+		}
+	}()
+	time.Sleep(1 * time.Second) // 延迟1秒
+	var first string
+	var keyword1 string
+	var keyword2 string
+	var keyword3 string
+	var keyword4 string
+	var remark string
+
+	logDetail, e := cygx.GetCygxMorningMeetingReviewLogByLogId(logId)
+	if e != nil {
+		err = errors.New("GetCygxMorningMeetingReviewLogByLogId, Err: " + e.Error())
+		return
+	}
+	meetingId := logDetail.MeetingId
+
+	keyword1 = logDetail.OpUserName
+	keyword2 = "--"
+	keyword3 = time.Now().Format(utils.FormatDateTime)
+	keyword4 = "提交了晨会点评待审核"
+
+	configCode := "cygx_morning_meeting_mobile"
+	detailConfig, e := cygx.GetConfigByCode(configCode)
+	if e != nil {
+		err = errors.New("GetConfigByCode, Err: " + e.Error())
+		return
+	}
+
+	mobile := detailConfig.ConfigValue
+	openIdList, e := models.GetWxOpenIdByMobileList(mobile)
+	if e != nil {
+		err = errors.New("GetWxOpenIdByMobileList, Err: " + e.Error())
+		return
+	}
+	if len(openIdList) == 0 {
+		return
+	}
+
+	openIdArr := make([]string, 0)
+	for _, v := range openIdList {
+		openIdArr = append(openIdArr, v.OpenId)
+	}
+	redirectUrl := ""
+
+	redirectUrl = utils.WX_MSG_PATH_MORNING_MEETING_LOG_DETAIL + strconv.Itoa(logId)
+	if utils.RunMode != "release" {
+		redirectUrl = ""
+	}
+
+	sendInfo := new(services.SendWxTemplate)
+	sendInfo.First = first
+	sendInfo.Keyword1 = keyword1
+	sendInfo.Keyword2 = keyword2
+	sendInfo.Keyword3 = keyword3
+	sendInfo.Keyword4 = keyword4
+	sendInfo.Remark = remark
+	sendInfo.TemplateId = utils.WxMsgTemplateIdAskByUser
+	sendInfo.RedirectUrl = redirectUrl
+	sendInfo.RedirectTarget = 3
+	sendInfo.Resource = strconv.Itoa(meetingId)
+	sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ARTICLE_ADD
+	sendInfo.OpenIdArr = openIdArr
+	err = services.SendTemplateMsg(sendInfo)
+	return
+}

+ 4 - 4
services/cygx/resource_data.go

@@ -110,7 +110,7 @@ func UpdateActivityResourceData(sourceId int) {
 		item.SearchTag = detail.ActivityTypeName
 		item.ChartPermissionId = detail.ChartPermissionId
 		item.PublishDate = publishDate
-		item.SearchTitle = detail.ActivityName
+		item.SearchTitle = detail.ActivityName + "{|}" + detail.Label
 		item.SearchContent = detail.Label + industrialName + subjectName
 		item.SearchOrderTime = detail.ActivityTime
 		item.CreateTime = time.Now()
@@ -383,7 +383,7 @@ func UpdateArticleResourceData(sourceId int) {
 		item.Source = source
 		item.PublishDate = publishDate
 		item.CreateTime = time.Now()
-		item.SearchTitle = detail.Title
+		item.SearchTitle = detail.Title + "{|}" + detail.FieldName + "{|}" + detail.Stock + "{|}" + industrialName + "{|}" + subjectName
 		annotation, e := utils.GetHtmlContentText(detail.Annotation)
 		if e != nil && e.Error() != utils.ErrNoRow() {
 			err = errors.New("GetHtmlContentText, Err: " + e.Error() + "sourceId:" + strconv.Itoa(sourceId))
@@ -1030,7 +1030,7 @@ func UpdateActivityVoiceResourceData(sourceId int) {
 		item.PublishDate = publishDate
 		item.ChartPermissionId = activityInfo.ChartPermissionId
 		item.CreateTime = utils.StrDateToDate(activityInfo.ActivityTime)
-		item.SearchTitle = voiceDetail.VoiceName
+		item.SearchTitle = voiceDetail.VoiceName + "{|}" + activityInfo.Label
 		item.SearchContent = activityInfo.Label + industrialName + subjectName
 		item.SearchOrderTime = activityInfo.ActivityTime
 		if totalData == 0 {
@@ -1133,7 +1133,7 @@ func UpdateActivityVideoResourceData(sourceId int) {
 		item.PublishDate = publishDate
 		item.ChartPermissionId = activityInfo.ChartPermissionId
 		item.CreateTime = utils.StrDateToDate(activityInfo.ActivityTime)
-		item.SearchTitle = videoDetail.VideoName
+		item.SearchTitle = videoDetail.VideoName + "{|}" + activityInfo.Label
 		item.SearchContent = activityInfo.Label + industrialName + subjectName
 		item.SearchOrderTime = activityInfo.ActivityTime
 		if totalData == 0 {

+ 65 - 0
services/roadshow/calendar.go

@@ -5,6 +5,8 @@ import (
 	"errors"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/http"
+	"hongze/hz_crm_api/models/company"
+	"hongze/hz_crm_api/models/cygx"
 	"hongze/hz_crm_api/models/roadshow"
 	"hongze/hz_crm_api/models/system"
 	"hongze/hz_crm_api/services/alarm_msg"
@@ -1097,3 +1099,66 @@ func GetCalendarFrom(userPhone, startDate, endDate string) (list []roadshow.User
 	list, err = getCalendarFrom(userPhone, startDate, endDate)
 	return
 }
+
+// 公司添加路演的时候,校验公司对应点数,以及研究员关联行业的权限
+func CheckAddRoadShowCompanyPoint(companyId int, researcherList []*roadshow.CalendarResearcher) (points int, addType int, err error) {
+	addType = 1
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg("获取公司剩余点数失败:"+err.Error(), 2)
+		}
+	}()
+	pointsCompany, e := cygx.GetCygxActivitySpecialPermissionPointsCount(companyId)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetCygxActivitySpecialPermissionPointsCount, Err: " + e.Error())
+		return
+	}
+	productItemRai, e := company.GetCompanyProductByCompanyIdAndProductId(companyId, utils.COMPANY_PRODUCT_RAI_ID)
+	if e != nil {
+		err = errors.New("GetCompanyProductByCompanyIdAndProductId, Err: " + e.Error())
+		return
+	}
+
+	permissionStr, e := cygx.GetCompanyPermission(companyId)
+	if e != nil {
+		err = errors.New("GetCompanyPermission, Err: " + e.Error())
+		return
+	}
+
+	//用户没有路演服务,以及研究员所关联行业的权限,就进行报错提示
+	var isHaveWangFang bool // 研究员里面是否包含王芳
+	if !strings.Contains(permissionStr, utils.LU_YAN_FU_WU) {
+		var adminIds []string
+		for _, v := range researcherList {
+			adminIds = append(adminIds, strconv.Itoa(v.ResearcherId))
+		}
+		askEmailList, e := cygx.GetAskEmailListByAdminIds(strings.Join(adminIds, ","))
+		if e != nil {
+			err = errors.New("GetAskEmailListByAdminIds, Err: " + e.Error())
+			return
+		}
+		for _, v := range askEmailList {
+			if v.Name == "王芳" { // 王芳,不需要判断权限和点数,以及对应的点数弹窗提示
+				isHaveWangFang = true
+				continue
+			}
+			if !strings.Contains(permissionStr, v.ChartPermissionName) {
+				addType = 3
+				return
+			}
+		}
+	}
+
+	if pointsCompany > 0 || productItemRai.Status == utils.COMPANY_STATUS_FORMAL {
+		points = len(researcherList)
+		if isHaveWangFang {
+			points--
+			if points == 0 {
+				addType = 2
+			}
+		}
+	} else {
+		addType = 2
+	}
+	return
+}

+ 26 - 0
utils/common.go

@@ -2361,3 +2361,29 @@ func GetAttendanceDetailSecondsByYiDong(str string) string {
 	timeStr += "''"
 	return timeStr
 }
+
+// 浮点类型转为千分位字符串
+func FormatNumberWithCommas(num float64, m int) string {
+	// 先格式化为2位小数字符串
+	str := strconv.FormatFloat(num, 'f', m, 64)
+
+	// 分割整数和小数部分
+	parts := strings.Split(str, ".")
+	intPart := parts[0]
+	decimalPart := parts[1] // 已截取2位小数
+
+	// 从右往左每3位加逗号
+	var formatted strings.Builder
+	n := len(intPart)
+	for i := 0; i < n; i++ {
+		if (n-i)%3 == 0 && i != 0 {
+			formatted.WriteByte(',')
+		}
+		formatted.WriteByte(intPart[i])
+	}
+	if decimalPart == "00" {
+		return formatted.String()
+	} else {
+		return formatted.String() + "." + decimalPart
+	}
+}

+ 1 - 0
utils/config.go

@@ -444,6 +444,7 @@ func WxRelease() {
 	//模板消息
 	{
 		TemplateIdByProduct = "Cp2wF8gvBtxyWV4DeYuI172oqwyYXVRSm3AyJO42d84"
+		WxMsgTemplateIdAskByUser = "IpS-yuNNQc8osCoy20jPHNkvBUyKRL1NGn7c0G9xmQA" //手机号用户【XXX】发送模板消息模板ID(小助手)
 		TemplateIdByCompanyApply = "yqaDUavXAKBpsPqTr0zYXAGIQYeCijZtWwFsT07wTbE"
 		WxMsgTemplateIdActivityChangeApply = "dYg6iHooRq74PyCXmw_Ns7qdJZmbtLoKS2p2FKeaXl0"
 		//销售跨部门领取客户通知

+ 19 - 16
utils/constants.go

@@ -429,7 +429,9 @@ const (
 
 )
 
-var FilterPermissionNameRai = []string{"专家", "研选/专项点数", "海外调研"} // 权益某些地方不展示的行业
+var FilterPermissionNameRai = []string{"专家", "路演/专项点数", "海外调研", "路演服务"} // 权益某些地方不展示的行业
+var FilterPermissionNameRai2 = []string{"专家", "路演/专项点数", "海外调研"}        // 权益某些地方不展示的行业
+var SHOW_SIGNIN_BUTTON_ACTIVITY_TYPE_ID = []int{4, 5, 6, 8}             //展示下载签到码的活动类型
 
 // GetRaiChartPermissionIdSpecialPoint 获取权益权限,专项路演调研权限ID
 func GetRaiChartPermissionIdSpecialPoint() (chartPermissionId int) {
@@ -503,21 +505,22 @@ const (
 
 // 查研观向小程序 模板消息地址路由
 const (
-	WX_MSG_PATH_ARTICLE_DETAIL                  = "pageMy/reportDetail/reportDetail?id="                          //文章详情模板消息地址
-	WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL         = "activityPages/specialDetail/specialDetail?id="                 //专项调研活动模板消息地址
-	WX_MSG_PATH_ROAD_ESSENCE                    = "reportPages/roadEssence/roadEssence?id="                       //路演精华模板消息地址
-	WX_MSG_PATH_ACTIVITY_DETAIL                 = "activityPages/activityDetail/activityDetail?id="               //活动模板消息地址
-	WX_MSG_PATH_PRODUCTINTERIOR_DETAIL          = "reportPages/internalDetials/internalDetials?id="               //产品内测模版消息地址
-	WX_MSG_PATH_ACTIVITY_SIGNIN                 = "pages-signIn/isSignIn/isSignIn"                                //扫s码签到地址
-	WX_MSG_PATH_THIS_WEEK_DETAIL                = "/reportPages/reportSecretDetail/reportSecretDetail?type=2&id=" //本周研究汇总详情模板消息地址
-	WX_MSG_PATH_LAST_WEEK_DETAIL                = "/reportPages/reportSecretDetail/reportSecretDetail?type=3&id=" //上周纪要汇总详情模板消息地址
-	WX_MSG_PATH_KEY_COMPANY_DETAIL              = "/reportPages/keyCompany/keyCompany?id="                        //重点公司详情模板消息地址
-	WX_MSG_PATH_INDUSTRY_DETAIL                 = "/reportPages/IndustryReport/IndustryReport?id="                //产业详情模板消息地址
-	CYGX_YANXUAN_POINTS_KEY              string = "CYGX_YANXUAN_POINTS_KEY"                                       //查研观向研选活动扣点KEY(冲突,先放这里)
-	WX_MSG_PATH_YX_SPECIAL_DETAIL               = "pages-purchaser/noteAndViewpoint/noteAndViewpoint?id="         //研选专栏详情
-	WX_MSG_PATH_YX_SPECIAL_ENABLE_DETAIL        = "pages-purchaser/toExamine/toExamine?id="                       //研选专栏审核详情页面
-	WX_MSG_PATH_YX_SPECIAL_CENTER               = "pages-purchaser/contentAllPage/contentAllPage?Status=4"        //研选专栏内容中心
-	WX_MSG_PATH_QUESTIONNAIRE_DETAIL            = "pages-purchaser/themeVote/themeVote?id="                       //问卷调查详情页
+	WX_MSG_PATH_ARTICLE_DETAIL                    = "pageMy/reportDetail/reportDetail?id="                          //文章详情模板消息地址
+	WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL           = "activityPages/specialDetail/specialDetail?id="                 //专项调研活动模板消息地址
+	WX_MSG_PATH_ROAD_ESSENCE                      = "reportPages/roadEssence/roadEssence?id="                       //路演精华模板消息地址
+	WX_MSG_PATH_ACTIVITY_DETAIL                   = "activityPages/activityDetail/activityDetail?id="               //活动模板消息地址
+	WX_MSG_PATH_PRODUCTINTERIOR_DETAIL            = "reportPages/internalDetials/internalDetials?id="               //产品内测模版消息地址
+	WX_MSG_PATH_ACTIVITY_SIGNIN                   = "pages-signIn/isSignIn/isSignIn"                                //扫s码签到地址
+	WX_MSG_PATH_THIS_WEEK_DETAIL                  = "/reportPages/reportSecretDetail/reportSecretDetail?type=2&id=" //本周研究汇总详情模板消息地址
+	WX_MSG_PATH_LAST_WEEK_DETAIL                  = "/reportPages/reportSecretDetail/reportSecretDetail?type=3&id=" //上周纪要汇总详情模板消息地址
+	WX_MSG_PATH_KEY_COMPANY_DETAIL                = "/reportPages/keyCompany/keyCompany?id="                        //重点公司详情模板消息地址
+	WX_MSG_PATH_INDUSTRY_DETAIL                   = "/reportPages/IndustryReport/IndustryReport?id="                //产业详情模板消息地址
+	CYGX_YANXUAN_POINTS_KEY                string = "CYGX_YANXUAN_POINTS_KEY"                                       //查研观向研选活动扣点KEY(冲突,先放这里)
+	WX_MSG_PATH_YX_SPECIAL_DETAIL                 = "pages-purchaser/noteAndViewpoint/noteAndViewpoint?id="         //研选专栏详情
+	WX_MSG_PATH_YX_SPECIAL_ENABLE_DETAIL          = "pages-purchaser/toExamine/toExamine?id="                       //研选专栏审核详情页面
+	WX_MSG_PATH_YX_SPECIAL_CENTER                 = "pages-purchaser/contentAllPage/contentAllPage?Status=4"        //研选专栏内容中心
+	WX_MSG_PATH_QUESTIONNAIRE_DETAIL              = "pages-purchaser/themeVote/themeVote?id="                       //问卷调查详情页
+	WX_MSG_PATH_MORNING_MEETING_LOG_DETAIL        = "pages-meeting/toExamine/toExamine?LogId="                      //晨会精华模板消息日志跳转详情
 )
 
 // 图表类型