浏览代码

新增日历和事项接口

longyu 3 年之前
父节点
当前提交
fd0041a16c

+ 630 - 0
controllers/roadshow/calendar.go

@@ -20,6 +20,229 @@ type CalendarController struct {
 	controllers.BaseAuth
 }
 
+// @Title 新增路演活动接口
+// @Description 新增路演活动接口
+// @Param	request	body roadshow.AddActivityReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /add [post]
+func (this *CalendarController) Add() {
+
+	sysUser := this.AdminWx
+	if sysUser == nil {
+		this.FailWithMessage("请登录", "请登录,SysUser Is Empty")
+		return
+	}
+
+	deleteCache := true
+	cacheKey := "CACHE_RS_ACTIVITY_WX_ADD_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 5*time.Second) {
+		deleteCache = false
+		this.FailWithMessage("系统处理中,请稍后重试!", "系统处理中,请稍后重试!"+sysUser.RealName+";data:"+string(this.Ctx.Input.RequestBody))
+		return
+	}
+	var req roadshow.AddActivityReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		this.FailWithMessage("参数解析异常", "参数解析失败,Err:"+err.Error())
+		return
+	}
+
+	if len(req.ResearcherList) <= 0 {
+		this.FailWithMessage("请选择研究员!", "请选择研究员!")
+		return
+	}
+
+	researcherMap := make(map[int]string)
+	var checkIsAdd []string
+	//var tipMsg string
+	for _, v := range req.ResearcherList {
+		if v.ResearcherId <= 0 {
+			this.FailWithMessage("请选择研究员!", "请选择研究员!")
+			return
+		}
+		if v.ResearcherName == "" {
+			this.FailWithMessage("请选择研究员!", "请选择研究员!")
+			return
+		}
+		if v.StartDate == "" {
+			this.FailWithMessage("请选择开始日期!", "请选择开始日期!")
+			return
+		}
+		if v.EndDate == "" {
+			this.FailWithMessage("请选择结束日期!", "请选择结束日期!")
+			return
+		}
+		if v.StartTime == "" {
+			this.FailWithMessage("请选择开始时间!", "请选择开始时间!")
+			return
+		}
+		if v.EndTime == "" {
+			this.FailWithMessage("请选择结束时间!", "请选择结束时间!")
+			return
+		}
+		if v.StartWeek == "" {
+			this.FailWithMessage("请选择周!", "请选择周!")
+			return
+		}
+
+		if v.EndWeek == "" {
+			this.FailWithMessage("请选择周!", "请选择周!")
+			return
+		}
+
+		startDateTime := v.StartDate + " " + v.StartTime
+		endDateTime := v.EndDate + " " + v.EndTime
+
+		startP, _ := time.ParseInLocation(utils.FormatDateTime, startDateTime, time.Local)
+		endP, _ := time.ParseInLocation(utils.FormatDateTime, endDateTime, time.Local)
+
+		if startP.Before(time.Now()) || startP.Equal(time.Now()) {
+			this.FailWithMessage("活动开始时间不能小于当前时间!", "活动开始时间不能小于当前时间!")
+			return
+		}
+
+		if endP.Before(time.Now()) || endP.Equal(time.Now()) {
+			this.FailWithMessage("活动结束时间不能小于当前时间!", "活动结束时间不能小于当前时间!")
+			return
+		}
+
+		if startP.After(endP) || startP.Equal(endP) {
+			this.FailWithMessage("活动开始时间应小于结束时间!", "活动开始时间应小于结束时间!")
+			return
+		}
+
+		if realName, ok := researcherMap[v.ResearcherId]; ok {
+			this.FailWithMessage("研究员:"+realName+" 被重复选择", "研究员:"+realName+" 被重复选择")
+			return
+		}
+		researcherMap[v.ResearcherId] = v.ResearcherName
+
+		//同步上海数据
+		researcherInfo, err := admin.GetAdminWxById(v.ResearcherId)
+		if err != nil {
+			this.FailWithMessage("研究员异常", "获取研究员异常,Err:"+err.Error())
+			return
+		}
+		_ = roadshowService.SyncCalendarFromShanghai(researcherInfo.Mobile, v.StartDate, v.EndDate)
+
+		//校验事项时间冲突
+		{
+			matterCount, err := roadshowService.CheckMatters(startDateTime, endDateTime, v.ResearcherId, 0)
+			if err != nil {
+				this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckMattersCount!Err:"+err.Error())
+				return
+			}
+			if matterCount > 0 {
+				checkIsAdd = append(checkIsAdd, v.ResearcherName)
+			}
+		}
+
+		//校验活动时间冲突
+		{
+			calendarCount, err := roadshowService.CheckCalendar(startDateTime, endDateTime, "1,2", v.ResearcherId, 0)
+			if err != nil {
+				this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckCalendar!Err:"+err.Error())
+				return
+			}
+			if calendarCount > 0 {
+				checkIsAdd = append(checkIsAdd, v.ResearcherName)
+			}
+		}
+	}
+
+	if len(checkIsAdd) > 0 {
+		this.FailWithMessage(strings.Join(checkIsAdd, ",")+" 时间已被占用!", "时间冲突检测失败-CheckMattersCount!")
+		return
+	}
+
+	rsCalendar := new(roadshow.RsCalendar)
+	rsCalendar.SysUserId = sysUser.AdminId
+	rsCalendar.SysUserRealName = sysUser.RealName
+	rsCalendar.ActivityType = req.ActivityType
+	rsCalendar.RoadshowType = req.RoadshowType
+	rsCalendar.RoadshowPlatform = req.RoadshowPlatform
+	rsCalendar.CompanyId = req.CompanyId
+	rsCalendar.CompanyName = req.CompanyName
+	rsCalendar.Province = req.Province
+	rsCalendar.ProvinceCode = req.ProvinceCode
+	rsCalendar.City = req.City
+	rsCalendar.CityCode = req.CityCode
+	rsCalendar.Theme = req.Theme
+	rsCalendar.CooperationName = req.CooperationName
+	rsCalendar.CreateTime = time.Now()
+	rsCalendar.ModifyTime = time.Now()
+	rsCalendar.ActivityCategory = req.ActivityCategory
+	rsCalendar.Source = 0
+	rsCalendar.Title = getTitle(req.ActivityType, req.RoadshowType, req.ActivityCategory, req.RoadshowPlatform, req.Province, req.City)
+	rsCalendarId, err := roadshow.AddRsCalendar(rsCalendar)
+	if err != nil {
+		this.FailWithMessage("保存失败", "保存日历活动信息失败!Err:"+err.Error())
+		return
+	}
+	//if researcherId != 99 {
+	for k, v := range req.ResearcherList {
+		researcher := new(roadshow.RsCalendarResearcher)
+		researcher.RsCalendarId = int(rsCalendarId)
+		researcher.ResearcherId = v.ResearcherId
+		researcher.ResearcherName = v.ResearcherName
+		researcher.StartDate = v.StartDate
+		researcher.EndDate = v.EndDate
+		researcher.StartTime = v.StartTime
+		researcher.EndTime = v.EndTime
+		researcher.StartWeek = v.StartWeek
+		researcher.EndWeek = v.EndWeek
+		researcher.CreateTime = time.Now()
+		researcher.ModifyTime = time.Now()
+		researcher.ResearcherSort = k + 1
+		if req.ActivityType == "路演" || req.ActivityType == "公开会议" {
+			researcher.Status = 1
+		} else {
+			researcher.Status = 2
+		}
+		rsCalendarResearcherId, err := roadshow.AddRsCalendarResearcher(researcher)
+		if err != nil {
+			this.FailWithMessage("保存失败", "保存日历活动-研究员信息失败!Err:"+err.Error())
+			return
+		}
+		rsCalendar.RsCalendarId = int(rsCalendarId)
+		researcher.RsCalendarResearcherId = int(rsCalendarResearcherId)
+		go roadshowService.CalendarToSH(*rsCalendar, *researcher)
+
+		//模板消息通知
+		{
+			go func() {
+				sysAdmin, _ := admin.GetAdminWxById(v.ResearcherId)
+				if sysAdmin != nil && req.ActivityType != "内部会议" && req.ActivityType != "报告电话会" {
+					first := "您收到一个新的【" + req.ActivityType + "】申请,请及时处理"
+					keyword1 := sysUser.RealName
+					keyword2 := "--"
+					keyword3 := time.Now().Format(utils.FormatDateTime)
+					startDateSub := v.StartDate[5:]
+					startDateSub = strings.Replace(startDateSub, "-", ".", -1)
+					var keyword4 string
+					if req.ActivityType == "路演" {
+						keyword4 = startDateSub + "(" + v.StartWeek + ")" + " " + v.StartTime[:5] + "~" + v.EndTime[:5] + " ," + req.CompanyName + "(" + req.RoadshowType + req.ActivityType + ")"
+					} else {
+						keyword4 = startDateSub + "(" + v.StartWeek + ")" + " " + v.StartTime[:5] + "~" + v.EndTime[:5] + " ," + req.Theme + "(" + req.RoadshowType + req.ActivityType + ")"
+					}
+					remark := "请尽快完成审批"
+					wxAppPath := "pages-approve/activity/detail?RsCalendarId=" + strconv.Itoa(int(rsCalendarId)) + "&RsCalendarResearcherId=" + strconv.Itoa(int(rsCalendarResearcherId))
+					openIdList, _ := models.GetAdminOpenIdByMobile(sysAdmin.Mobile)
+					if len(openIdList) > 0 {
+						services.SendWxMsgWithRoadshowPending(first, keyword1, keyword2, keyword3, keyword4, remark, wxAppPath, sysAdmin.Mobile)
+					}
+				}
+			}()
+		}
+	}
+	this.OkDetailed(nil, "保存成功")
+}
+
 // CalendarList
 // @Title 我的日历列表
 // @Description 我的日历列表接口
@@ -310,3 +533,410 @@ func (this *CalendarController) CalendarDetail() {
 	resp.CompanyDetail = companyDetailView
 	this.OkDetailed(resp, "获取成功")
 }
+
+// @Title 事项列表
+// @Description 事项列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Success 200 {object} roadshow.MattersListResp
+// @router /matters/list [get]
+func (this *CalendarController) MattersList() {
+	sysUser := this.AdminWx
+	if sysUser == nil {
+		this.FailWithMessage("请登录", "请登录,SysUser Is Empty")
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	var total int
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize10
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+
+	condition += ` AND a.sys_user_id=?`
+	pars = append(pars, sysUser.AdminId)
+
+	resp := new(roadshow.MattersListResp)
+	total, err := roadshow.GetMattersListCount(condition, pars)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		this.FailWithMessage("获取事项信息失败", "获取事项信息失败,GetMattersListCount,Err:"+err.Error())
+		return
+	}
+	page = paging.GetPaging(currentIndex, pageSize, total)
+	dataList, err := roadshow.GetMattersList(condition, pars, startSize, pageSize)
+	if err != nil {
+		this.FailWithMessage("获取事项信息失败", "获取事项信息失败,GetMattersList,Err:"+err.Error())
+		return
+	}
+	resp.Paging = page
+	resp.List = dataList
+	this.OkDetailed(resp, "获取成功")
+}
+
+// @Title 新增事项接口
+// @Description 新增事项接口
+// @Param	request	body roadshow.AddMattersReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /matters/add [post]
+func (this *CalendarController) MattersAdd() {
+
+	sysUser := this.AdminWx
+	if sysUser == nil {
+		this.FailWithMessage("请登录", "请登录,SysUser Is Empty")
+		return
+	}
+
+	deleteCache := true
+	cacheKey := "CACHE_RS_MATTERS_ADD_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		this.FailWithMessage("系统处理中,请稍后重试!", "系统处理中,请稍后重试!"+sysUser.RealName+";data:"+string(this.Ctx.Input.RequestBody))
+		return
+	}
+	var req roadshow.AddMattersReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		this.FailWithMessage("参数解析异常", "参数解析失败,Err:"+err.Error())
+		return
+	}
+	if req.StartDate == "" {
+		this.FailWithMessage("请选择开始日期!", "请选择开始日期!")
+		return
+	}
+	if req.EndDate == "" {
+		this.FailWithMessage("请选择结束日期!", "请选择结束日期!")
+		return
+	}
+	if req.StartTime == "" {
+		this.FailWithMessage("请选择开始时间!", "请选择开始时间!")
+		return
+	}
+	if req.EndTime == "" {
+		this.FailWithMessage("请选择结束时间!", "请选择结束时间!")
+		return
+	}
+	if req.StartWeek == "" {
+		this.FailWithMessage("请选择周!", "请选择周!")
+		return
+	}
+	if req.EndWeek == "" {
+		this.FailWithMessage("请选择周!", "请选择周!")
+		return
+	}
+	if req.MatterContent == "" {
+		this.FailWithMessage("请选择研究员!", "请选择研究员!")
+		return
+	}
+
+	startDateTime := req.StartDate + " " + req.StartTime
+	endDateTime := req.EndDate + " " + req.EndTime
+	//校验事项时间冲突
+	{
+		matterCount, err := roadshowService.CheckMatters(startDateTime, endDateTime, sysUser.AdminId, 0)
+		if err != nil {
+			this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckMattersCount!Err:"+err.Error())
+			return
+		}
+		if matterCount > 0 {
+			this.FailWithMessage("当前时间已被占用!", "时间冲突检测失败-CheckMattersCount!")
+			return
+		}
+	}
+
+	//校验活动时间冲突--待接受
+	{
+		calendarCount, err := roadshowService.CheckCalendar(startDateTime, endDateTime, "1", sysUser.AdminId, 0)
+		if err != nil {
+			this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckCalendarResearcherCount!Err:"+err.Error())
+			return
+		}
+		if calendarCount > 0 {
+			this.FailWithMessage("当前时间与待处理的申请有冲突,请与相关销售沟通!", "时间冲突检测失败-CheckCalendarResearcherCount!")
+			return
+		}
+	}
+
+	//校验活动时间冲突--已接受
+	{
+		calendarCount, err := roadshowService.CheckCalendar(startDateTime, endDateTime, "2", sysUser.AdminId, 0)
+		if err != nil {
+			this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckCalendarResearcherCount!Err:"+err.Error())
+			return
+		}
+		if calendarCount > 0 {
+			this.FailWithMessage("当前时间已被占用!", "时间冲突检测失败-CheckCalendarResearcherCount!")
+			return
+		}
+	}
+
+	startP, _ := time.ParseInLocation(utils.FormatDateTime, startDateTime, time.Local)
+	endP, _ := time.ParseInLocation(utils.FormatDateTime, endDateTime, time.Local)
+
+	if startP.Before(time.Now()) || startP.Equal(time.Now()) {
+		this.FailWithMessage("事项开始时间不能小于当前时间!", "事项开始时间不能小于当前时间!")
+		return
+	}
+
+	if endP.Before(time.Now()) || endP.Equal(time.Now()) {
+		this.FailWithMessage("事项结束时间不能小于当前时间!", "事项结束时间不能小于当前时间!")
+		return
+	}
+
+	if startP.After(endP) || startP.Equal(endP) {
+		this.FailWithMessage("事项开始时间应小于结束时间!", "事项开始时间应小于结束时间!")
+		return
+	}
+
+	item := new(roadshow.RsMatters)
+	item.SysUserId = sysUser.AdminId
+	item.SysUserRealName = sysUser.RealName
+	item.StartDate = req.StartDate
+	item.EndDate = req.EndDate
+	item.StartTime = req.StartTime
+	item.EndTime = req.EndTime
+	item.StartWeek = req.StartWeek
+	item.EndWeek = req.EndWeek
+	item.MatterContent = req.MatterContent
+	item.Status = 1
+	item.CreateTime = time.Now()
+	item.ModifyTime = time.Now()
+	id, err := roadshow.AddRsMatters(item)
+	if err != nil {
+		this.FailWithMessage("保存失败!", "保存失败,AddRsMatters Err:"+err.Error())
+		return
+	}
+	item.RsMattersId = int(id)
+	go roadshowService.MatterToSH(*item)
+	this.OkDetailed(nil, "保存成功")
+}
+
+// @Title 修改事项接口
+// @Description 修改事项接口
+// @Param	request	body roadshow.UpdateMattersReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /matters/update [post]
+func (this *CalendarController) MattersUpdate() {
+	sysUser := this.AdminWx
+	if sysUser == nil {
+		this.FailWithMessage("请登录", "请登录,SysUser Is Empty")
+		return
+	}
+
+	deleteCache := true
+	cacheKey := "CACHE_RS_MATTERS_UPDATE_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		this.FailWithMessage("系统处理中,请稍后重试!", "系统处理中,请稍后重试!")
+		return
+	}
+	var req roadshow.UpdateMattersReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		this.FailWithMessage("参数解析失败!", "参数解析失败,Err:"+err.Error())
+		return
+	}
+	updateParams := make(map[string]interface{})
+	if req.RsMattersId <= 0 {
+		this.FailWithMessage("参数错误!", "参数错误")
+		return
+	}
+
+	if req.StartDate == "" {
+		this.FailWithMessage("请选择开始日期!", "请选择开始日期")
+		return
+	} else {
+		updateParams["start_date"] = req.StartDate
+	}
+	if req.EndDate == "" {
+		this.FailWithMessage("请选择结束日期!", "请选择结束日期")
+		return
+	} else {
+		updateParams["end_date"] = req.EndDate
+	}
+	if req.StartTime == "" {
+		this.FailWithMessage("请选择开始时间!", "请选择开始时间")
+		return
+	} else {
+		updateParams["start_time"] = req.StartTime
+	}
+	if req.EndTime == "" {
+		this.FailWithMessage("请选择结束时间!", "请选择结束时间")
+		return
+	} else {
+		updateParams["end_time"] = req.EndTime
+	}
+	if req.StartWeek == "" {
+		this.FailWithMessage("请选择周!", "请选择周")
+		return
+	} else {
+		updateParams["start_week"] = req.StartWeek
+	}
+	if req.EndWeek == "" {
+		this.FailWithMessage("请选择周!", "请选择周")
+		return
+	} else {
+		updateParams["end_week"] = req.EndWeek
+	}
+	if req.MatterContent == "" {
+		this.FailWithMessage("请选择研究员!", "请选择研究员")
+		return
+	} else {
+		updateParams["matter_content"] = req.MatterContent
+	}
+
+	startDateTime := req.StartDate + " " + req.StartTime
+	endDateTime := req.EndDate + " " + req.EndTime
+
+	startP, _ := time.ParseInLocation(utils.FormatDateTime, startDateTime, time.Local)
+	endP, _ := time.ParseInLocation(utils.FormatDateTime, endDateTime, time.Local)
+
+	if startP.Before(time.Now()) || startP.Equal(time.Now()) {
+		this.FailWithMessage("事项开始时间不能小于当前时间!", "事项开始时间不能小于当前时间!")
+		return
+	}
+
+	if endP.Before(time.Now()) || endP.Equal(time.Now()) {
+		this.FailWithMessage("事项结束时间不能小于当前时间!", "事项结束时间不能小于当前时间!")
+		return
+	}
+
+	if startP.After(endP) || startP.Equal(endP) {
+		this.FailWithMessage("事项开始时间应小于结束时间!", "事项开始时间应小于结束时间!")
+		return
+	}
+
+	matterItem, err := roadshow.GetMattersById(req.RsMattersId)
+	if err != nil {
+		this.FailWithMessage("保存失败!", "保存失败,GetMattersById,Err:"+err.Error())
+		return
+	}
+	//校验事项时间冲突
+	{
+		if matterItem != nil && (matterItem.StartDate != req.StartDate ||
+			matterItem.StartTime != req.StartTime ||
+			matterItem.EndDate != req.EndDate ||
+			matterItem.EndTime != req.EndTime) {
+
+			matterCount, err := roadshowService.CheckMatters(startDateTime, endDateTime, sysUser.AdminId, matterItem.RsMattersId)
+			if err != nil {
+				this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckMattersCount!Err:"+err.Error())
+				return
+			}
+			if matterCount > 0 {
+				this.FailWithMessage("时间冲突,已存在时间段内的事项!", "时间冲突检测失败-CheckMattersCount!")
+				return
+			}
+		}
+	}
+
+	//校验活动时间冲突--待接受
+	{
+		calendarCount, err := roadshowService.CheckCalendar(startDateTime, endDateTime, "1", sysUser.AdminId, 0)
+		if err != nil {
+			this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckCalendarResearcherCount!Err:"+err.Error())
+			return
+		}
+		if calendarCount > 0 {
+			this.FailWithMessage("当前时间与待处理的申请有冲突,请与相关销售沟通!", "时间冲突检测失败-CheckCalendarResearcherCount!")
+			return
+		}
+	}
+	//校验活动时间冲突--待接受
+	{
+		calendarCount, err := roadshowService.CheckCalendar(startDateTime, endDateTime, "2", sysUser.AdminId, 0)
+		if err != nil {
+			this.FailWithMessage("时间冲突检测失败!", "时间冲突检测失败-CheckCalendarResearcherCount!Err:"+err.Error())
+			return
+		}
+		if calendarCount > 0 {
+			this.FailWithMessage("时间冲突,已存在时间段内的活动!", "时间冲突检测失败-CheckCalendarResearcherCount!")
+			return
+		}
+	}
+
+	whereParams := make(map[string]interface{})
+
+	whereParams["rs_matters_id"] = req.RsMattersId
+
+	updateParams["modify_time"] = time.Now()
+
+	err = roadshow.UpdateRsMatters(whereParams, updateParams)
+	if err != nil {
+		this.FailWithMessage("保存失败!", "保存失败!UpdateRsMatters:"+err.Error())
+		return
+	}
+	go roadshowService.UpdateSHCalendarByMatter(req)
+	this.OkDetailed(nil, "保存成功")
+}
+
+// @Title 删除事项接口
+// @Description 删除事项接口
+// @Param	request	body roadshow.DeleteMattersReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /matters/delete [post]
+func (this *CalendarController) MattersDelete() {
+	sysUser := this.AdminWx
+	if sysUser == nil {
+		this.FailWithMessage("请登录", "请登录,SysUser Is Empty")
+		return
+	}
+
+	var req roadshow.DeleteMattersReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		this.FailWithMessage("参数解析失败", "参数解析失败,Err:"+err.Error())
+		return
+	}
+
+	if req.RsMattersId <= 0 {
+		this.FailWithMessage("参数错误", "参数错误")
+		return
+	}
+
+	err = roadshow.DeleteRsMatters(req.RsMattersId)
+	if err != nil {
+		this.FailWithMessage("保存失败", "保存失败!DeleteRsMatters:"+err.Error())
+		return
+	}
+	go roadshowService.DeleteSHMatter(req.RsMattersId)
+	this.OkDetailed(nil, "删除成功")
+}
+
+func getTitle(activityType, roadshowType, activityCategory, roadshowPlatform, province, city string) string {
+	var title string
+	switch activityType {
+	case "内部会议":
+		title = "内部会议"
+	case "公开会议", "路演":
+		if roadshowType == "线上" {
+			title = roadshowType + activityType + roadshowPlatform
+		} else {
+			title = roadshowType + activityType + province + city
+		}
+	case "报告电话会":
+		title = activityCategory + "电话会"
+	}
+	return title
+}

+ 187 - 10
models/roadshow/calendar.go

@@ -3,6 +3,7 @@ package roadshow
 import (
 	"github.com/rdlucklib/rdluck_tools/orm"
 	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_mobile_admin/models/tables/admin"
 	"time"
 )
 
@@ -48,9 +49,12 @@ type RsCalendar struct {
 	CityCode         string `description:"市编码"`
 	Theme            string `description:"会议主题"`
 	CooperationName  string `description:"合作方名称"`
+	Title            string `description:"展示在日历的标题"`
+	Source           int8   `description:"来源,0:自系统,1:上海方的"`
 	CreateTime       time.Time
 	ModifyTime       time.Time
 	ActivityCategory string `description:"活动类别"`
+	IsSynced         int    `description:"是否与上海同步 0:未同步 1:已同步"`
 }
 
 type RsCalendarResearcher struct {
@@ -64,14 +68,16 @@ type RsCalendarResearcher struct {
 	EndTime                string `description:"结束时间"`
 	StartWeek              string `description:"开始日期对应周"`
 	EndWeek                string `description:"结束日期对应周"`
-	Status                 int    `description:"状态:1:待接受,2:已接受,3:已拒绝,4:已删除,5:已撤回"`
-	RefuseReason           string `description:"拒绝理由"`
-	RefuseTime             string `description:"拒绝时间"`
-	ApproveTime            string `description:"审批时间"`
-	DeleteReason           string `description:"删除原因"`
-	DeleteTime             string `description:"删除时间"`
-	CreateTime             string
-	ModifyTime             string
+	CreateTime             time.Time
+	ModifyTime             time.Time
+	Status                 int       `description:"状态:1:待接受,2:已接受,3:已拒绝,4:已删除,5:已撤回,6:已结束"`
+	RefuseReason           string    `description:"拒绝理由"`
+	RefuseTime             time.Time `description:"拒绝时间"`
+	DeleteReason           string    `description:"删除理由"`
+	DeleteTime             time.Time `description:"删除时间"`
+	ApproveTime            time.Time `description:"接受时间"`
+	IsSynced               int       `description:"是否与上海同步 0:未同步 1:已同步"`
+	ResearcherSort         int       `description:"研究员新增排序"`
 }
 
 func GetRsCalendarById(rsCalendarId int) (item *RsCalendar, err error) {
@@ -160,9 +166,9 @@ func GetCalendarList(condition string, pars []interface{}, status int, pageLimit
 	if condition != "" {
 		sql += condition
 	}
-	if status==1 {
+	if status == 1 {
 		sql += ` ORDER BY a.create_time ASC LIMIT ?,? `
-	}else{
+	} else {
 		sql += ` ORDER BY a.create_time DESC LIMIT ?,? `
 	}
 	_, err = o.Raw(sql, pars, pageLimit).QueryRows(&list)
@@ -226,8 +232,10 @@ type RsMatters struct {
 	StartWeek       string    `description:"开始日期周"`
 	EndWeek         string    `description:"结束日期周"`
 	MatterContent   string    `description:"事项内容"`
+	Status          int8      `description:"状态:1:进行中,6:已结束"`
 	CreateTime      time.Time `description:"创建时间"`
 	ModifyTime      time.Time `description:"修改时间"`
+	IsSynced        int       `description:"是否与上海同步 0:未同步 1:已同步"`
 }
 
 type UpdateMattersReq struct {
@@ -256,3 +264,172 @@ type CalendarDetailResp struct {
 	RsCalendarResearcherItem *RsCalendarResearcher
 	CompanyDetail            *CompanyDetailView
 }
+
+type MattersListResp struct {
+	Paging *paging.PagingItem
+	List   []*RsMattersView
+}
+
+type RsMattersView struct {
+	RsMattersId     int    `orm:"column(rs_matters_id);pk"`
+	SysUserId       int    `description:"添加事项人id"`
+	SysUserRealName string `description:"创建人姓名"`
+	StartDate       string `description:"开始日期"`
+	EndDate         string `description:"结束日期"`
+	StartTime       string `description:"开始时间"`
+	EndTime         string `description:"结束时间"`
+	StartWeek       string `description:"开始日期周"`
+	EndWeek         string `description:"结束日期周"`
+	MatterContent   string `description:"事项内容"`
+	Status          int8   `description:"状态:1:进行中,6:已结束"`
+	CreateTime      string `description:"创建时间"`
+	ModifyTime      string `description:"修改时间"`
+	IsSynced        int    `description:"是否与上海同步 0:未同步 1:已同步"`
+}
+
+func GetMattersListCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM  rs_matters AS a
+		WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func GetMattersList(condition string, pars []interface{}, pageLimit ...int) (list []*RsMattersView, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM  rs_matters AS a
+		WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY a.create_time DESC LIMIT ?,? `
+	_, err = o.Raw(sql, pars, pageLimit).QueryRows(&list)
+	return
+}
+
+type DeleteMattersReq struct {
+	RsMattersId int `description:"事项id"`
+}
+
+// 删除事项
+func DeleteRsMatters(rsMattersId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM rs_matters WHERE rs_matters_id=? `
+	_, err = o.Raw(sql, rsMattersId).Exec()
+	return err
+}
+
+func CheckMattersCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM  rs_matters AS a
+		WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func GetResearcherFromAdmin(condition string, pars []interface{}) (lists []*admin.Admin, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM admin WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&lists)
+	return
+}
+
+// 更新活动信息
+func UpdateRsCalendar(where, updateParams map[string]interface{}) error {
+	o := orm.NewOrm()
+	ptrStructOrTableName := "rs_calendar"
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range where {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err := qs.Update(updateParams)
+	return err
+}
+
+// 更新
+func UpdateRsMatters(where, updateParams map[string]interface{}) error {
+	o := orm.NewOrm()
+	ptrStructOrTableName := "rs_matters"
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range where {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err := qs.Update(updateParams)
+	return err
+}
+
+type EditActivityReq struct {
+	EditType               int    `description:"修改方式: 1:修改,2:修改重提"`
+	RsCalendarId           int    `description:"路演活动id"`
+	RsCalendarResearcherId int    `description:"活动研究员id"`
+	ActivityType           string `description:"活动类型"`
+	RoadshowType           string `description:"路演形式"`
+	RoadshowPlatform       string `description:"路演平台"`
+	CompanyId              int    `description:"客户id"`
+	CompanyName            string `description:"客户名称"`
+	Province               string `description:"省"`
+	ProvinceCode           string `description:"省编码"`
+	City                   string `description:"市"`
+	CityCode               string `description:"市编码"`
+	Theme                  string `description:"会议主题"`
+	CooperationName        string `description:"合作方名称"`
+	ActivityCategory       string `description:"活动类别"`
+	ResearcherList         []*CalendarResearcher
+}
+
+// GetRsCalendarResearcherListByRsCalendarId 根据路演id获取路演研究员列表
+func GetRsCalendarResearcherListByRsCalendarId(rsCalendarId int) (items []*RsCalendarResearcher, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM rs_calendar_researcher WHERE rs_calendar_id=? `
+	_, err = o.Raw(sql, rsCalendarId).QueryRows(&items)
+	return
+}
+
+func CheckCalendarResearcherCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM  rs_calendar_researcher AS a
+		WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func GetMattersById(rsMatters int) (item *RsMatters, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM  rs_matters
+		WHERE rs_matters_id=? `
+	err = o.Raw(sql, rsMatters).QueryRow(&item)
+	return
+}
+
+//添加RsCalendarResearcher
+func AddRsMatters(item *RsMatters) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(item)
+	return
+}
+
+//添加RsCalendar
+func AddRsCalendar(item *RsCalendar) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+//添加RsCalendarResearcher
+func AddRsCalendarResearcher(item *RsCalendarResearcher) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}

+ 264 - 0
models/roadshow/rs_calendar_relation.go

@@ -2,6 +2,9 @@ package roadshow
 
 import (
 	"github.com/rdlucklib/rdluck_tools/orm"
+	"hongze/hongze_mobile_admin/models/tables/admin"
+	"hongze/hongze_mobile_admin/utils"
+	"strconv"
 	"time"
 )
 
@@ -42,6 +45,39 @@ func GetRelationByPars(condition string, pars []interface{}) (items *RsCalendarR
 	return
 }
 
+func GetPhoneFromResearcher(calendarResearcherId int) (items *string, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT mobile FROM admin AS a INNER JOIN rs_calendar_researcher AS b ON a.admin_id=b.researcher_id WHERE b.rs_calendar_researcher_id=?`
+	err = o.Raw(sql, calendarResearcherId).QueryRow(&items)
+	return
+}
+
+func GetPhoneFromRsCalendarById(rsCalendarId int) (item *string, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT mobile FROM admin AS a INNER JOIN rs_calendar AS b ON a.admin_id=b.sys_user_id WHERE b.rs_calendar_id=? `
+	err = o.Raw(sql, rsCalendarId).QueryRow(&item)
+	return
+}
+
+// GetRsCalendarRelationListByThirdIds 根据第三方id集合获取所有的关系列表
+func GetRsCalendarRelationListByThirdIds(thirdCalendarIds []int) (items []*RsCalendarRelation, err error) {
+	if len(thirdCalendarIds) <= 0 {
+		return
+	}
+	thirdCalendarIdStr := utils.Implode(thirdCalendarIds)
+	o := orm.NewOrm()
+	sql := `SELECT * FROM rs_calendar_relation WHERE third_calendar_id in (` + thirdCalendarIdStr + `) `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// AddRsCalendarRelation 添加自系统路演与第三方路演关系
+func AddRsCalendarRelation(item *RsCalendarRelation) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
 // DeleteRsCalendarRelation 删除关联表
 func DeleteRsCalendarRelation(relationIdd int) (err error) {
 	sql := `DELETE FROM rs_calendar_relation WHERE relation_id=? `
@@ -49,3 +85,231 @@ func DeleteRsCalendarRelation(relationIdd int) (err error) {
 	_, err = o.Raw(sql, relationIdd).Exec()
 	return
 }
+
+// SyncRsCalendarRelation 同步自系统路演与第三方路演关系
+func SyncRsCalendarRelation(thirdUserCalendar UserCalendar, createUser admin.Admin, researcherList []admin.Admin) (err error) {
+	currentStartTimer := time.Unix(int64(thirdUserCalendar.StartTime), 0)
+	currentEndTimer := time.Unix(int64(thirdUserCalendar.EndTime), 0)
+
+	o := orm.NewOrm()
+	o.Begin()
+	defer func() {
+		if err != nil {
+			o.Rollback()
+		} else {
+			o.Commit()
+		}
+	}()
+
+	//路演活动表入库
+	rsCalendar := &RsCalendar{
+		SysUserId:        createUser.AdminId,
+		SysUserRealName:  createUser.RealName,
+		ActivityType:     "路演",
+		RoadshowType:     "",
+		RoadshowPlatform: "",
+		CompanyId:        0,
+		CompanyName:      thirdUserCalendar.CustomerName,
+		Province:         "",
+		ProvinceCode:     "",
+		City:             "",
+		CityCode:         "",
+		Theme:            "",
+		CooperationName:  "",
+		Title:            thirdUserCalendar.Title,
+		Source:           1, //来源,0:自系统,1:上海方的
+		CreateTime:       time.Now(),
+		ModifyTime:       time.Now(),
+		ActivityCategory: "",
+	}
+	rsCalendarId, err := o.Insert(rsCalendar)
+	if err != nil {
+		return
+	}
+	rsCalendar.RsCalendarId = int(rsCalendarId)
+
+	// 路演研究员入库
+	rsCalendarResearcherList := make([]*RsCalendarResearcher, 0)
+	for _, researcheInfo := range researcherList {
+		rsCalendarResearcher := &RsCalendarResearcher{
+			RsCalendarResearcherId: 0,
+			RsCalendarId:           rsCalendar.RsCalendarId,
+			ResearcherId:           researcheInfo.AdminId,
+			ResearcherName:         researcheInfo.RealName,
+			StartDate:              currentStartTimer.Format(utils.FormatDate),
+			EndDate:                currentEndTimer.Format(utils.FormatDate),
+			StartTime:              currentStartTimer.Format(utils.FormatTime),
+			EndTime:                currentEndTimer.Format(utils.FormatTime),
+			StartWeek:              utils.StrDateTimeToWeek(currentStartTimer.Weekday().String()),
+			EndWeek:                utils.StrDateTimeToWeek(currentEndTimer.Weekday().String()),
+			CreateTime:             time.Now(),
+			ModifyTime:             time.Now(),
+			Status:                 2, //1:待接受,2:已接受,3:已拒绝,4:已删除,5:已撤回,6:已结束
+			RefuseReason:           "",
+			//RefuseTime:             time.Time{},
+			DeleteReason: "",
+		}
+		rsCalendarResearcherId, tmpErr := o.Insert(rsCalendarResearcher)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		rsCalendarResearcher.RsCalendarResearcherId = int(rsCalendarResearcherId)
+		rsCalendarResearcherList = append(rsCalendarResearcherList, rsCalendarResearcher)
+	}
+
+	selfCalendarId := 0
+	if len(rsCalendarResearcherList) > 0 {
+		selfCalendarId = rsCalendarResearcherList[0].RsCalendarResearcherId
+	}
+	//关系入库
+	customerId, _ := strconv.Atoi(thirdUserCalendar.CustomerId)
+	rsCalendarRelation := &RsCalendarRelation{
+		//RelationId:       0,
+		CalendarType:     1,              //日历类型;1:路演;2:事项
+		SelfCalendarId:   selfCalendarId, //研究员与路演关系id;
+		ThirdCalendarId:  thirdUserCalendar.ID,
+		UserId:           thirdUserCalendar.UserId,
+		UserPhone:        thirdUserCalendar.UserPhone,
+		UserName:         thirdUserCalendar.UserName,
+		ProjectName:      thirdUserCalendar.ProjectName,
+		ProjectId:        thirdUserCalendar.ProjectId,
+		CustomerId:       customerId,
+		CustomerName:     thirdUserCalendar.CustomerName,
+		CustomerSocial:   thirdUserCalendar.CustomerSocial,
+		ProjectType:      thirdUserCalendar.ProjectType,
+		ProjectFormType:  thirdUserCalendar.ProjectType,
+		Room:             thirdUserCalendar.Room,
+		StartTime:        thirdUserCalendar.StartTime,
+		EndTime:          thirdUserCalendar.EndTime,
+		Content:          thirdUserCalendar.Content,
+		FeedExpert:       thirdUserCalendar.FeedExpert,
+		Title:            thirdUserCalendar.Title,
+		ResearcherMobile: thirdUserCalendar.ResearcherMobile,
+		ModifyTime:       time.Now(),
+		CreateTime:       time.Now(),
+	}
+	rsCalendarRelationId, err := o.Insert(rsCalendarRelation)
+	if err != nil {
+		return
+	}
+	rsCalendarRelation.RelationId = int(rsCalendarRelationId)
+
+	return
+}
+
+// UpdateSyncRsCalendarRelation 同步自系统路演与第三方路演关系
+func UpdateSyncRsCalendarRelation(thirdUserCalendar UserCalendar, rsCalendar *RsCalendar, rsCalendarRelation *RsCalendarRelation, updateRsCalendarResearcherList []*RsCalendarResearcher, delResearcherIdList []int, addResearcherList []admin.Admin) (err error) {
+	currentStartTimer := time.Unix(int64(thirdUserCalendar.StartTime), 0)
+	currentEndTimer := time.Unix(int64(thirdUserCalendar.EndTime), 0)
+
+	//新增研究员
+	//删除研究员
+	//更新研究员
+	o := orm.NewOrm()
+	o.Begin()
+	defer func() {
+		if err != nil {
+			o.Rollback()
+		} else {
+			o.Commit()
+		}
+	}()
+
+	// 路演活动表修改
+	rsCalendar.Title = thirdUserCalendar.Title
+	rsCalendar.ModifyTime = time.Now()
+	_, err = o.Update(rsCalendar, "Title", "ModifyTime")
+	if err != nil {
+		return
+	}
+
+	// 删除路演研究员
+	if len(delResearcherIdList) > 0 {
+		delResearcherIdStr := utils.Implode(delResearcherIdList)
+		sql := `DELETE FROM rs_calendar_researcher WHERE rs_calendar_researcher_id in (` + delResearcherIdStr + `) `
+		_, tmpErr := o.Raw(sql).Exec()
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+	}
+
+	// 修改路演研究员
+	for _, rsCalendarResearcher := range updateRsCalendarResearcherList {
+		rsCalendarResearcher.StartDate = currentStartTimer.Format(utils.FormatDate)
+		rsCalendarResearcher.EndDate = currentEndTimer.Format(utils.FormatDate)
+		rsCalendarResearcher.StartTime = currentStartTimer.Format(utils.FormatTime)
+		rsCalendarResearcher.EndTime = currentEndTimer.Format(utils.FormatTime)
+		rsCalendarResearcher.StartWeek = utils.StrDateTimeToWeek(currentStartTimer.Weekday().String())
+		rsCalendarResearcher.EndWeek = utils.StrDateTimeToWeek(currentEndTimer.Weekday().String())
+		rsCalendarResearcher.ModifyTime = time.Now()
+		_, tmpErr := o.Update(rsCalendar, "StartDate", "EndDate", "StartTime", "EndTime", "StartWeek", "EndWeek", "ModifyTime")
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+	}
+
+	// 路演研究员入库
+	rsCalendarResearcherList := make([]*RsCalendarResearcher, 0)
+	for _, researcheInfo := range addResearcherList {
+		rsCalendarResearcher := &RsCalendarResearcher{
+			RsCalendarResearcherId: 0,
+			RsCalendarId:           rsCalendar.RsCalendarId,
+			ResearcherId:           researcheInfo.AdminId,
+			ResearcherName:         researcheInfo.RealName,
+			StartDate:              currentStartTimer.Format(utils.FormatDate),
+			EndDate:                currentEndTimer.Format(utils.FormatDate),
+			StartTime:              currentStartTimer.Format(utils.FormatTime),
+			EndTime:                currentEndTimer.Format(utils.FormatTime),
+			StartWeek:              utils.StrDateTimeToWeek(currentStartTimer.Weekday().String()),
+			EndWeek:                utils.StrDateTimeToWeek(currentEndTimer.Weekday().String()),
+			CreateTime:             time.Now(),
+			ModifyTime:             time.Now(),
+			Status:                 2, //1:待接受,2:已接受,3:已拒绝,4:已删除,5:已撤回,6:已结束
+			RefuseReason:           "",
+			//RefuseTime:             time.Time{},
+			DeleteReason: "",
+		}
+		rsCalendarResearcherId, tmpErr := o.Insert(rsCalendarResearcher)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		rsCalendarResearcher.RsCalendarResearcherId = int(rsCalendarResearcherId)
+		rsCalendarResearcherList = append(rsCalendarResearcherList, rsCalendarResearcher)
+	}
+
+	// 关系表变更
+	selfCalendarId := rsCalendarRelation.SelfCalendarId
+	if len(updateRsCalendarResearcherList) > 0 {
+		selfCalendarId = updateRsCalendarResearcherList[0].RsCalendarResearcherId //更新的研究员关系表id
+	} else if len(rsCalendarResearcherList) > 0 {
+		selfCalendarId = rsCalendarResearcherList[0].RsCalendarResearcherId //新增的研究员关系表id
+	}
+
+	//关系入库
+	customerId, _ := strconv.Atoi(thirdUserCalendar.CustomerId)
+	rsCalendarRelation.SelfCalendarId = selfCalendarId
+	rsCalendarRelation.UserId = thirdUserCalendar.UserId
+	rsCalendarRelation.UserPhone = thirdUserCalendar.UserPhone
+	rsCalendarRelation.UserName = thirdUserCalendar.UserName
+	rsCalendarRelation.ProjectName = thirdUserCalendar.ProjectName
+	rsCalendarRelation.ProjectId = thirdUserCalendar.ProjectId
+	rsCalendarRelation.CustomerId = customerId
+	rsCalendarRelation.CustomerName = thirdUserCalendar.CustomerName
+	rsCalendarRelation.CustomerSocial = thirdUserCalendar.CustomerSocial
+	rsCalendarRelation.ProjectType = thirdUserCalendar.ProjectType
+	rsCalendarRelation.ProjectFormType = thirdUserCalendar.ProjectType
+	rsCalendarRelation.Room = thirdUserCalendar.Room
+	rsCalendarRelation.StartTime = thirdUserCalendar.StartTime
+	rsCalendarRelation.EndTime = thirdUserCalendar.EndTime
+	rsCalendarRelation.Content = thirdUserCalendar.Content
+	rsCalendarRelation.FeedExpert = thirdUserCalendar.FeedExpert
+	rsCalendarRelation.Title = thirdUserCalendar.Title
+	rsCalendarRelation.ResearcherMobile = thirdUserCalendar.ResearcherMobile
+	rsCalendarRelation.ModifyTime = time.Now()
+	_, err = o.Update(rsCalendarRelation, "SelfCalendarId", "UserId", "UserPhone", "UserName", "ProjectName", "ProjectId", "CustomerId", "CustomerName", "CustomerSocial", "ProjectType", "ProjectFormType", "Room", "StartTime", "EndTime", "Content", "FeedExpert", "Title", "ResearcherMobile", "ModifyTime")
+	return
+}

+ 11 - 0
models/tables/admin/admin.go

@@ -79,3 +79,14 @@ func GetAdminWxById(adminId int) (item *custom.AdminWx, err error) {
 	err = o.Raw(sql, adminId).QueryRow(&item)
 	return
 }
+
+func GetSysuserList(condition string, pars []interface{}, startSize, pageSize int) (items []*Admin, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM admin WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += `ORDER BY created_time DESC LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}

+ 19 - 0
models/wechat_send_msg.go

@@ -0,0 +1,19 @@
+package models
+
+import (
+	"github.com/rdlucklib/rdluck_tools/orm"
+)
+
+type OpenIdList struct {
+	OpenId string
+	UserId int
+}
+
+func GetAdminOpenIdByMobile(mobile string) (items []*OpenIdList, err error) {
+	sql := `SELECT DISTINCT ur.open_id,wu.user_id FROM wx_user AS wu 
+          INNER JOIN company AS c ON c.company_id = wu.company_id 
+          INNER join user_record  as ur on wu.user_id=ur.user_id
+          WHERE ur.open_id != "" and ur.create_platform=1 AND wu.mobile=? `
+	_, err = orm.NewOrm().Raw(sql, mobile).QueryRows(&items)
+	return
+}

+ 45 - 0
routers/commentsRouter_controllers.go

@@ -16,6 +16,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: "/add",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"],
         beego.ControllerComments{
             Method: "CalendarDetail",
@@ -34,6 +43,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "MattersAdd",
+            Router: "/matters/add",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "MattersDelete",
+            Router: "/matters/delete",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "MattersList",
+            Router: "/matters/list",
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"],
+        beego.ControllerComments{
+            Method: "MattersUpdate",
+            Router: "/matters/update",
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hongze_mobile_admin/controllers/roadshow:CalendarController"],
         beego.ControllerComments{
             Method: "Refuse",

+ 693 - 1
services/roadshow/calendar.go

@@ -6,10 +6,13 @@ import (
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/http"
 	"hongze/hongze_mobile_admin/models/roadshow"
+	"hongze/hongze_mobile_admin/models/tables/admin"
 	"hongze/hongze_mobile_admin/utils"
 	"io/ioutil"
 	netHttp "net/http"
 	"net/url"
+	"strconv"
+	"strings"
 	"time"
 )
 
@@ -60,13 +63,348 @@ func GetAccessToken() (token string, err error) {
 	return
 }
 
+func getCalendarFrom(userPhone, startDate, endDate string) (list []roadshow.UserCalendar, err error) {
+	token, err := GetAccessToken()
+	if err != nil {
+		return
+	}
+	exUrl := utils.CRM_OPEN_API_URL + "/v1/calendar/userCalendarList?user_phone=%s&start_time=%s&end_time=%s&access_token=%s"
+	getUrl := fmt.Sprintf(exUrl, userPhone, startDate, endDate, token)
+
+	body, err := http.Get(getUrl)
+	if err != nil {
+		err = errors.New("NewRequest Err:" + err.Error())
+		return
+	}
+
+	var userCalendarList roadshow.UserCalendarList
+	err = json.Unmarshal(body, &userCalendarList)
+	if err != nil {
+		utils.FileLog.Info("getCalendarFrom Err:", "url:", getUrl, ";response:", string(body))
+		err = errors.New("Unmarshal Err:" + err.Error())
+		return
+	}
+
+	if userCalendarList.Code != 1 {
+		utils.FileLog.Info("getCalendarFrom:", "url:", getUrl, ";response:", string(body))
+		err = errors.New(userCalendarList.Msg)
+		return
+	}
+	list = userCalendarList.Data
+	//fmt.Println("userCalendarList", userCalendarList)
+	return
+}
+
+// CalendarToSH 创建活动时同步上海的前置函数
+func CalendarToSH(rsCalendar roadshow.RsCalendar, researcher roadshow.RsCalendarResearcher) {
+	//获取创建者及研究员的信息,长度应为2
+	var condition string
+	var err error
+	var pars []interface{}
+	if rsCalendar.SysUserId == researcher.ResearcherId {
+		condition = ` AND admin_id =? `
+		pars = append(pars, rsCalendar.SysUserId)
+	} else {
+		condition = ` AND admin_id IN (?,?) `
+		pars = append(pars, rsCalendar.SysUserId, researcher.ResearcherId)
+	}
+
+	lists, err := roadshow.GetResearcherFromAdmin(condition, pars)
+	if err != nil {
+		err = errors.New("GetResearcherFromAdmin err:" + err.Error())
+		fmt.Println(err)
+		return
+	}
+	var userPhone, toUserPhone string
+
+	if len(lists) > 0 {
+		//当研究员也是创建者时,lists长度为1 做兼容
+		if len(lists) == 1 && rsCalendar.SysUserId == researcher.ResearcherId {
+			userPhone = lists[0].Mobile
+			toUserPhone = lists[0].Mobile
+		} else if lists[0].AdminId == rsCalendar.SysUserId {
+			userPhone = lists[0].Mobile
+			toUserPhone = lists[1].Mobile
+		} else {
+			userPhone = lists[1].Mobile
+			toUserPhone = lists[0].Mobile
+		}
+		sTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.StartDate+" "+researcher.StartTime, time.Now().Location())
+		startTime := sTime.Format("2006-01-02 15:04")
+		eTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.EndDate+" "+researcher.EndTime, time.Now().Location())
+		endTime := eTime.Format("2006-01-02 15:04")
+		err = CreatSHCalendar(userPhone, toUserPhone, rsCalendar.Title, startTime, endTime, 1, researcher.RsCalendarResearcherId)
+		if err != nil {
+			return
+		}
+	} else {
+		err = errors.New("Parameter Err,未查询到创建者或研究员信息" + err.Error())
+		fmt.Println("Parameter Err: " + err.Error())
+		return
+	}
+	if err != nil {
+		utils.SendEmail("研究员日历同步失败:", "新建上海研究员日历失败 "+err.Error(), utils.EmailSendToUsers)
+	} else {
+		whereParams := make(map[string]interface{})
+		updateParams := make(map[string]interface{})
+
+		whereParams["rs_calendar_researcher_id"] = researcher.RsCalendarResearcherId
+
+		updateParams["is_synced"] = 1
+		err = roadshow.UpdateCalendarResearcher(whereParams, updateParams)
+		if err != nil {
+			utils.FileLog.Info("UpdateCalendarResearcher err: " + err.Error())
+			fmt.Println("UpdateCalendarResearcher err: " + err.Error())
+			return
+		}
+		calWhereParams := make(map[string]interface{})
+		calWhereParams["rs_calendar_id"] = rsCalendar.RsCalendarId
+		err = roadshow.UpdateRsCalendar(calWhereParams, updateParams)
+		if err != nil {
+			utils.FileLog.Info("UpdateRsCalendar err: " + err.Error())
+			fmt.Println("UpdateRsCalendar err: " + err.Error())
+			return
+		}
+	}
+}
+
+// MatterToSH 创建事项时同步上海的前置函数
+func MatterToSH(matter roadshow.RsMatters) {
+	var condition string
+	var pars []interface{}
+	condition = ` AND admin_id =? `
+	pars = append(pars, matter.SysUserId)
+	lists, err := roadshow.GetResearcherFromAdmin(condition, pars)
+	if err != nil || len(lists) == 0 {
+		err = errors.New("GetResearcherFromAdmin err:" + err.Error())
+		return
+	}
+	sTime, _ := time.ParseInLocation(utils.FormatDateTime, matter.StartDate+" "+matter.StartTime, time.Now().Location())
+	startTime := sTime.Format("2006-01-02 15:04")
+	eTime, _ := time.ParseInLocation(utils.FormatDateTime, matter.EndDate+" "+matter.EndTime, time.Now().Location())
+	endTime := eTime.Format("2006-01-02 15:04")
+	err = CreatSHCalendar(lists[0].Mobile, lists[0].Mobile, matter.MatterContent, startTime, endTime, 2, matter.RsMattersId)
+	if err != nil {
+		return
+	}
+	if err != nil {
+		utils.SendEmail("研究员日历同步失败:", "新建上海研究员日历事项失败 "+err.Error(), utils.EmailSendToUsers)
+	} else {
+		updateParams := make(map[string]interface{})
+		whereParams := make(map[string]interface{})
+		updateParams["is_synced"] = 1
+		whereParams["rs_matters_id"] = matter.RsMattersId
+		err = roadshow.UpdateRsMatters(whereParams, updateParams)
+		if err != nil {
+			utils.FileLog.Info("UpdateRsMatters err: " + err.Error())
+			fmt.Println("UpdateRsMatters err: " + err.Error())
+			return
+		}
+	}
+}
+
+// CreatSHCalendar 新增上海日历活动
+func CreatSHCalendar(userPhone, toUserPhone, content, startTime, endTime string, calendarType int8, selfCalendarId int) (err error) {
+	token, err := GetAccessToken()
+	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/create?access_token=" + token
+
+	//creditCode, err := roadshow.GetCreditCodeFromCompany(rsCalendar.CompanyId)
+	//if err != nil {
+	//	err = errors.New("GetCreditCodeFromCompany err:" + err.Error())
+	//	return
+	//}
+	//发送创建请求
+	resp, err := netHttp.PostForm(finalUrl, url.Values{"user_phone": {userPhone}, "to_user_phone": {toUserPhone},
+		"content": {content}, "start_time": {startTime}, "end_time": {endTime}})
+	if err != nil {
+		err = errors.New("NewRequest Err:" + err.Error())
+		return
+	}
+
+	defer resp.Body.Close()
+
+	//解析resp并且存入关联表
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		fmt.Println("reponse error", err)
+		return
+	}
+	var calendarResp roadshow.CreatSHCalendarResp
+	err = json.Unmarshal(body, &calendarResp)
+	if calendarResp.Code != 1 {
+		err = errors.New("Create SHCalendar err:" + calendarResp.Msg)
+		return
+	}
+	sThirdId := calendarResp.Data.CalendarID
+	thirdId, err := strconv.Atoi(sThirdId)
+	if err != nil {
+		err = errors.New("string to int Err:" + err.Error())
+		return
+	}
+	relationItem := roadshow.RsCalendarRelation{
+		UserPhone:        userPhone,
+		CalendarType:     calendarType,
+		SelfCalendarId:   selfCalendarId,
+		ThirdCalendarId:  thirdId,
+		Title:            content,
+		ResearcherMobile: toUserPhone,
+		ModifyTime:       time.Now(),
+		CreateTime:       time.Now(),
+	}
+	_, err = roadshow.AddRsCalendarRelation(&relationItem)
+	if err != nil {
+		err = errors.New("AddRsCalendarRelation Err:" + err.Error())
+		return
+	}
+	return
+}
+
+// UpdateSHCalendar 更新上海日历活动
+func UpdateSHCalendar(req roadshow.EditActivityReq) {
+	var err error
+	//需要同时修改创建人及研究员的日历
+	for _, researcher := range req.ResearcherList {
+		//查询关联表获取信息
+		var condition string
+		var pars []interface{}
+		condition = ` AND self_calendar_id = ? `
+		pars = append(pars, req.RsCalendarResearcherId)
+		relationItem, err := roadshow.GetRelationByPars(condition, pars)
+		if err != nil {
+			err = errors.New("GetRelationByPars err:" + err.Error())
+			fmt.Println(err)
+		}
+
+		sTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.StartDate+" "+researcher.StartTime, time.Now().Location())
+		startTime := sTime.Format("2006-01-02 15:04")
+		eTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.EndDate+" "+researcher.EndTime, time.Now().Location())
+		endTime := eTime.Format("2006-01-02 15:04")
+		title := getTitle(req.ActivityType, req.RoadshowType, req.ActivityCategory, req.RoadshowPlatform, req.Province, req.City)
+		//发送更新请求
+		body, err := updateSHCalendar(fmt.Sprintf("%v", relationItem.ThirdCalendarId), relationItem.ResearcherMobile, title, startTime, endTime)
+		if err != nil {
+			fmt.Println(err)
+		}
+
+		//解析resp判断请求结果是否成功
+		var calendarResp roadshow.CreatSHCalendarResp
+		err = json.Unmarshal(body, &calendarResp)
+		if calendarResp.Code != 1 {
+			err = errors.New("Update SHCalendar err:" + calendarResp.Msg)
+			fmt.Println(err)
+		}
+	}
+	if err != nil {
+		fmt.Println(err)
+		utils.SendEmail("研究员日历同步失败:", "更新上海研究员日历失败 "+err.Error(), utils.EmailSendToUsers)
+	} else {
+		whereParams := make(map[string]interface{})
+		updateParams := make(map[string]interface{})
+		whereParams["rs_calendar_researcher_id"] = req.RsCalendarResearcherId
+		updateParams["is_synced"] = 1
+		err = roadshow.UpdateCalendarResearcher(whereParams, updateParams)
+		if err != nil {
+			fmt.Println("UpdateCalendarResearcher err: ", err.Error())
+			return
+		}
+		calWhereParams := make(map[string]interface{})
+		calWhereParams["rs_calendar_id"] = req.RsCalendarId
+		err = roadshow.UpdateRsCalendar(calWhereParams, updateParams)
+		if err != nil {
+			fmt.Println("UpdateRsCalendar err: ", err.Error())
+			return
+		}
+	}
+}
+
+// UpdateSHCalendarByMatter 更新上海日历活动
+func UpdateSHCalendarByMatter(req roadshow.UpdateMattersReq) {
+	token, err := GetAccessToken()
+	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/update?access_token=" + token
+
+	//需要同时修改创建人及研究员的日历
+	//查询关联表获取信息
+	var condition string
+	var pars []interface{}
+	condition = ` AND self_calendar_id = ? `
+	pars = append(pars, req.RsMattersId)
+	relationItem, err := roadshow.GetRelationByPars(condition, pars)
+	if err != nil {
+		err = errors.New("GetRelationByPars err:" + err.Error())
+		fmt.Println(err)
+	}
+
+	sTime, _ := time.ParseInLocation(utils.FormatDateTime, req.StartDate+" "+req.StartTime, time.Now().Location())
+	startTime := sTime.Format("2006-01-02 15:04")
+	eTime, _ := time.ParseInLocation(utils.FormatDateTime, req.EndDate+" "+req.EndTime, time.Now().Location())
+	endTime := eTime.Format("2006-01-02 15:04")
+	//发送更新请求
+	resp, err := netHttp.PostForm(finalUrl, url.Values{"calendar_id": {fmt.Sprintf("%v", relationItem.ThirdCalendarId)},
+		"to_user_phone": {relationItem.ResearcherMobile}, "content": {relationItem.Content}, "start_time": {startTime}, "end_time": {endTime}})
+	if err != nil {
+		err = errors.New("NewRequest Err:" + err.Error())
+		return
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		fmt.Println("reponse error", err)
+		return
+	}
+
+	//解析resp判断请求结果是否成功
+	var calendarResp roadshow.CreatSHCalendarResp
+	err = json.Unmarshal(body, &calendarResp)
+	if calendarResp.Code != 1 {
+		err = errors.New("Update SHCalendar err:" + calendarResp.Msg)
+		fmt.Println(err)
+	}
+	if err != nil {
+		go utils.SendEmail("研究员日历同步失败:", "更新上海研究员日历失败 "+err.Error(), utils.EmailSendToUsers)
+	} else {
+		updateParams := make(map[string]interface{})
+		whereParams := make(map[string]interface{})
+		updateParams["is_synced"] = 1
+		whereParams["rs_matters_id"] = req.RsMattersId
+		err = roadshow.UpdateRsMatters(whereParams, updateParams)
+		if err != nil {
+			utils.FileLog.Info("UpdateRsMatters err: " + err.Error())
+			fmt.Println("UpdateRsMatters err: " + err.Error())
+			return
+		}
+	}
+}
+
+// updateSHCalendar 内部函数,只用于发送修改上海日历的http请求
+func updateSHCalendar(thirdCalendarId, researcherMobile, content, startTime, endTime string) (body []byte, err error) {
+	token, err := GetAccessToken()
+	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/update?access_token=" + token
+	resp, respErr := netHttp.PostForm(finalUrl, url.Values{"calendar_id": {thirdCalendarId},
+		"to_user_phone": {researcherMobile}, "content": {content}, "start_time": {startTime}, "end_time": {endTime}})
+	if respErr != nil {
+		respErr = errors.New("NewRequest Err:" + respErr.Error())
+		return
+	}
+	defer resp.Body.Close()
+
+	body, bodyErr := ioutil.ReadAll(resp.Body)
+	if bodyErr != nil {
+		fmt.Println("reponse error", bodyErr)
+		return
+	}
+	return
+}
+
 // DeleteSHCalendar 删除上海日历活动
-func DeleteSHCalendar(rsCalendarResearcherId int) (err error) {
+func DeleteSHCalendar(rsCalendarResearcherId int) {
+	var err error
 	defer func() {
 		if err != nil {
 			go utils.SendEmail(utils.APPNAME+"删除上海日历活动失败:"+time.Now().Format("2006-01-02 15:04:05"), fmt.Sprint("关系id:", rsCalendarResearcherId, ";err:", err.Error()), utils.EmailSendToUsers)
 		}
 	}()
+
 	token, err := GetAccessToken()
 	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/delete?access_token=" + token
 
@@ -104,5 +442,359 @@ func DeleteSHCalendar(rsCalendarResearcherId int) (err error) {
 		err = errors.New("DeleteRsCalendarRelation err:" + err.Error())
 		return
 	}
+	if err != nil {
+		//发送邮件解决异常
+		utils.SendEmail("研究员日历同步失败:", "删除上海研究员日历失败 "+err.Error(), utils.EmailSendToUsers)
+		//fmt.Println("DeleteSHCalendar err:",err.Error())
+	}
+}
+
+// DeleteSHMatter 删除上海日历事项
+func DeleteSHMatter(matterId int) {
+	token, err := GetAccessToken()
+	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/delete?access_token=" + token
+
+	var condition string
+	var pars []interface{}
+	condition = ` AND self_calendar_id = ? `
+	pars = append(pars, matterId)
+	relationItem, err := roadshow.GetRelationByPars(condition, pars)
+	if err != nil {
+		err = errors.New("GetRelationByPars err" + err.Error())
+		return
+	}
+	resp, err := netHttp.PostForm(finalUrl, url.Values{"user_phone": {relationItem.UserPhone}, "calendar_id": {fmt.Sprintf("%v", relationItem.ThirdCalendarId)}})
+	if err != nil {
+		err = errors.New("NewRequest Err:" + err.Error())
+		return
+	}
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		fmt.Println("reponse error", err)
+		return
+	}
+	//解析resp判断请求结果是否成功
+	var calendarResp roadshow.CreatSHCalendarResp
+	err = json.Unmarshal(body, &calendarResp)
+	if calendarResp.Code != 1 {
+		err = errors.New("Update SHCalendar err:" + calendarResp.Msg)
+		return
+	}
+	//删除活动表及事项表
+	err = roadshow.DeleteRsCalendarRelation(relationItem.RelationId)
+	if err != nil {
+		err = errors.New("DeleteRsCalendarRelation err:" + err.Error())
+		return
+	}
+	if err != nil {
+		//发送邮件解决异常
+		utils.SendEmail("研究员日历同步失败:", "删除上海研究员日历失败 "+err.Error(), utils.EmailSendToUsers)
+		//fmt.Println("DeleteSHCalendar err:",err.Error())
+	}
+}
+
+// SyncCalendarFromShanghai 上海路演数据同步到自系统
+func SyncCalendarFromShanghai(userPhone, startDate, endDate string) (err error) {
+	errMsg := ``
+	defer func() {
+		if errMsg != `` {
+			//fmt.Println("err:", errMsg)
+			go utils.SendEmail(utils.APPNAME+"上海路演数据同步到自系统失败:"+time.Now().Format("2006-01-02 15:04:05"), errMsg, utils.EmailSendToUsers)
+		}
+	}()
+	//fmt.Println(userPhone, startDate, endDate)
+	endDateTime, err := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
+	if err != nil {
+		errMsg = `结束日期转time类型失败,err:` + err.Error()
+		return
+	}
+	currDay := time.Now().Format(utils.FormatDate)
+	nowDateTime, _ := time.ParseInLocation(utils.FormatDate, currDay, time.Local)
+	//如果传入的结束日期早于当前日期,那么就不去查询了
+	if endDateTime.Before(nowDateTime) {
+		return
+	}
+	//以当前日期作为起始日期去同步
+	list, err := getCalendarFrom(userPhone, currDay, endDate)
+	if err != nil {
+		errMsg = "获取第三方路演日历数据失败,err:" + err.Error()
+		return
+	}
+	thirdIdList := make([]int, 0)
+	if len(list) > 0 {
+		for _, v := range list {
+			thirdIdList = append(thirdIdList, v.ID)
+		}
+		rsCalendarRelationList, tmpErr := roadshow.GetRsCalendarRelationListByThirdIds(thirdIdList)
+		if tmpErr != nil {
+			err = tmpErr
+			errMsg = "获取关联列表失败,err:" + tmpErr.Error()
+			return
+		}
+
+		rsCalendarRelationMap := make(map[int]*roadshow.RsCalendarRelation)
+		for _, rsCalendarRelation := range rsCalendarRelationList {
+			rsCalendarRelationMap[rsCalendarRelation.ThirdCalendarId] = rsCalendarRelation
+		}
+
+		for _, v := range list {
+			fmt.Println(v)
+			thirdIdList = append(thirdIdList, v.ID)
+			if rsCalendarRelation, ok := rsCalendarRelationMap[v.ID]; ok {
+				//存在的话,那么就去查找对应的信息
+				if rsCalendarRelation.CalendarType == 1 {
+					//路演
+					rsCalendarResearcherInfo, tmpErr := roadshow.GetRsCalendarResearcherById(rsCalendarRelation.SelfCalendarId)
+					if tmpErr != nil {
+						errMsg += fmt.Sprint("第三方日历ID:", v.ID, "获取路演研究员信息失败;err:"+tmpErr.Error(), ";")
+						continue
+					}
+					rsCalendarInfo, tmpErr := roadshow.GetRsCalendarById(rsCalendarResearcherInfo.RsCalendarId)
+					if tmpErr != nil {
+						errMsg += fmt.Sprint("第三方日历ID:", v.ID, "获取路演信息失败;err:"+tmpErr.Error(), ";")
+						continue
+					}
+					if rsCalendarInfo.Source == 0 { //自系统创建的路演活动,不需要依靠上海方来修改
+						continue
+					}
+
+					//是否去同步变更数据库
+					isUpdateSync := false
+
+					//是否变更
+					isUpdate := false
+					if v.StartTime != rsCalendarRelation.StartTime {
+						isUpdate = true
+					}
+					if v.EndTime != rsCalendarRelation.EndTime {
+						isUpdate = true
+					}
+					if v.Title != rsCalendarRelation.Title {
+						isUpdate = true
+					}
+
+					researcherList := make([]admin.Admin, 0)
+					researcherMap := make(map[int]admin.Admin)
+
+					addResearcherList := make([]admin.Admin, 0)                  // 需要新增的研究员
+					delResearcherIdList := make([]int, 0)                             //需要删除的路演活动与研究员的关系id
+					updateResearcherList := make([]*roadshow.RsCalendarResearcher, 0) //待更新的路演活动中研究员信息
+
+					if v.ResearcherMobile != rsCalendarRelation.ResearcherMobile {
+						//研究员变更了,需要去改表
+						isUpdateSync = true
+
+						researcherMobileList := strings.Split(v.ResearcherMobile, ",")
+						if len(researcherMobileList) > 0 {
+							for _, mobile := range researcherMobileList {
+								researcherInfo, tmpErr := getAdminInfo(mobile)
+								if tmpErr != nil {
+									errMsg += fmt.Sprint("第三方日历ID:", v.ID, "获取研究员失败,研究员手机号:", mobile, ";err:"+tmpErr.Error(), ";")
+									continue
+								}
+								if researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_RESEARCHR ||
+									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RESEARCHR ||
+									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_RESEARCHR ||
+									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT ||
+									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT {
+									researcherList = append(researcherList, researcherInfo)
+
+									researcherMap[researcherInfo.AdminId] = researcherInfo
+								}
+							}
+						}
+
+						//没有研究员
+						if len(researcherList) <= 0 {
+							errMsg += fmt.Sprint("第三方日历ID:", v.ID, ";对方研究员信息失败;")
+							continue
+						}
+
+						rsCalendarResearcherList, tmpErr := roadshow.GetRsCalendarResearcherListByRsCalendarId(rsCalendarInfo.RsCalendarId)
+						if tmpErr != nil {
+							errMsg += fmt.Sprint("第三方日历ID:", v.ID, "获取路演活动中的研究员列表失败,路演活动ID:", rsCalendarInfo.RsCalendarId, ";err:"+tmpErr.Error(), ";")
+							continue
+						}
+
+						//现有活动中的研究员
+						rsCalendarResearcherMap := make(map[int]*roadshow.RsCalendarResearcher)
+						for _, rsCalendarResearcher := range rsCalendarResearcherList {
+							if _, ok := researcherMap[rsCalendarResearcher.ResearcherId]; ok {
+								if isUpdate {
+									updateResearcherList = append(updateResearcherList, rsCalendarResearcher)
+								}
+							} else {
+								delResearcherIdList = append(delResearcherIdList, rsCalendarResearcher.RsCalendarResearcherId)
+							}
+
+							rsCalendarResearcherMap[rsCalendarResearcher.ResearcherId] = rsCalendarResearcher
+						}
+
+						//校验是否需要新增研究员
+						for adminId, researcherInfo := range researcherMap {
+							//如果
+							if _, ok := rsCalendarResearcherMap[adminId]; !ok {
+								addResearcherList = append(addResearcherList, researcherInfo)
+							}
+						}
+					} else if isUpdate { //如果有字段更新,那么需要将所有的研究员信息更新
+						isUpdateSync = true
+
+						rsCalendarResearcherList, tmpErr := roadshow.GetRsCalendarResearcherListByRsCalendarId(rsCalendarInfo.RsCalendarId)
+						if tmpErr != nil {
+							errMsg += fmt.Sprint("第三方日历ID:", v.ID, "获取路演活动中的研究员列表失败,路演活动ID:", rsCalendarInfo.RsCalendarId, ";err:"+tmpErr.Error(), ";")
+							continue
+						}
+						for _, rsCalendarResearcher := range rsCalendarResearcherList {
+							updateResearcherList = append(updateResearcherList, rsCalendarResearcher)
+						}
+					}
+
+					if isUpdateSync {
+						tmpErr = roadshow.UpdateSyncRsCalendarRelation(v, rsCalendarInfo, rsCalendarRelation, updateResearcherList, delResearcherIdList, addResearcherList)
+						if tmpErr != nil {
+							err = tmpErr
+							errMsg += fmt.Sprint("第三方日历ID:", v.ID, "修改关联关系失败;err:"+tmpErr.Error(), ";")
+							return
+						}
+					}
+				} else {
+					//事项
+					//事项都是由自系统创建的,不需要依靠上海方来修改
+				}
+			} else {
+				//数据不存在
+				createUser, tmpErr := getAdminInfo(v.UserPhone)
+				if tmpErr != nil {
+					errMsg += fmt.Sprint("第三方日历ID:", v.ID, "获取创建人失败,创建人手机号:", v.UserPhone, ";err:"+tmpErr.Error(), ";")
+					continue
+				}
+
+				//研究员列表
+				researcherList := make([]admin.Admin, 0)
+				researcherMobileList := strings.Split(v.ResearcherMobile, ",")
+				if len(researcherMobileList) > 0 {
+					for _, mobile := range researcherMobileList {
+						researcherInfo, tmpErr := getAdminInfo(mobile)
+						if tmpErr != nil {
+							errMsg += fmt.Sprint("第三方日历ID:", v.ID, "获取研究员失败,研究员手机号:", mobile, ";err:"+tmpErr.Error(), ";")
+							continue
+						}
+						if researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_RESEARCHR ||
+							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RESEARCHR ||
+							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_RESEARCHR ||
+							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT ||
+							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT {
+							researcherList = append(researcherList, researcherInfo)
+						}
+					}
+				}
+
+				//没有研究员
+				if len(researcherList) <= 0 {
+					continue
+				}
+				//数据入库
+				tmpErr = roadshow.SyncRsCalendarRelation(v, createUser, researcherList)
+				if tmpErr != nil {
+					err = tmpErr
+					errMsg += fmt.Sprint("第三方日历ID:", v.ID, "绑定关联关系失败;err:"+tmpErr.Error(), ";")
+					return
+				}
+				//fmt.Println("createUser:", createUser)
+			}
+
+		}
+	}
 	return
 }
+
+// CreateOaUser 新增系统用户
+func CreateOaUser(mobile, username string, groupId int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendEmail(utils.APPNAME+"系统用户同步到上海失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
+		}
+	}()
+	token, err := GetAccessToken()
+	finalUrl := utils.CRM_OPEN_API_URL + "/v1/OaUser/create?access_token=" + token
+
+	//发送创建请求
+	form := url.Values{}
+	form.Add("mobile", mobile)
+	form.Add("username", username)
+	form.Add("group_id", fmt.Sprint(groupId))
+	resp, err := netHttp.PostForm(finalUrl, form)
+	fmt.Println("form:", form)
+
+	if err != nil {
+		err = errors.New("NewRequest Err:" + err.Error())
+		return
+	}
+
+	defer resp.Body.Close()
+
+	//解析resp并且存入关联表
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		fmt.Println("reponse error", err)
+		return
+	}
+	fmt.Println("body:", string(body))
+	var calendarResp roadshow.CreatSHCalendarResp
+	err = json.Unmarshal(body, &calendarResp)
+	if calendarResp.Code != 1 {
+		err = errors.New("Create SHCalendar err:" + calendarResp.Msg)
+		return
+	}
+	return
+}
+
+// getAdminInfo 通过手机号获取用户信息
+func getAdminInfo(mobile string) (adminInfo admin.Admin, err error) {
+	adminMap := make(map[string]admin.Admin)
+	redisAdminData, redisErr := utils.Rc.RedisString(utils.CACHE_KEY_ADMIN)
+	if redisErr != nil {
+		list, err := admin.GetSysuserList("", []interface{}{}, 0, 1000)
+		//	GetSysuserList
+		for _, tmpAdminInfo := range list {
+			adminMap[tmpAdminInfo.Mobile] = *tmpAdminInfo
+		}
+
+		//入缓存
+		redisJsonData, err := json.Marshal(adminMap)
+		if err == nil {
+			_ = utils.Rc.Put(utils.CACHE_KEY_ADMIN, string(redisJsonData), time.Minute*30)
+		}
+	} else {
+		err := json.Unmarshal([]byte(redisAdminData), &adminMap)
+		if err != nil {
+			fmt.Println("用户数据,json转换失败:", err)
+		}
+	}
+	adminInfo, ok := adminMap[mobile]
+	if !ok {
+		err = fmt.Errorf("找不到该手机号用户,mobile:" + mobile)
+	}
+
+	return
+}
+
+func getTitle(activityType, roadshowType, activityCategory, roadshowPlatform, province, city string) string {
+	var title string
+	switch activityType {
+	case "内部会议":
+		title = "内部会议"
+	case "公开会议", "路演":
+		if roadshowType == "线上" {
+			title = roadshowType + activityType + roadshowPlatform
+		} else {
+			title = roadshowType + activityType + province + city
+		}
+	case "报告电话会":
+		title = activityCategory + "电话会"
+	}
+	return title
+}

+ 83 - 0
services/roadshow/calendar_check.go

@@ -0,0 +1,83 @@
+package roadshow
+
+import "hongze/hongze_mobile_admin/models/roadshow"
+
+func CheckMatters(startDateTime, endDateTime string, researcherId, rsMattersId int) (matterCount int, err error) {
+	var matterCondition string
+	var matterPars []interface{}
+	if rsMattersId > 0 {
+		matterCondition += " AND rs_matters_id <> ? "
+		matterPars = append(matterPars, rsMattersId)
+	}
+	matterCondition += " AND sys_user_id = ? "
+	matterPars = append(matterPars, researcherId)
+
+	matterCondition += ` AND (((? >=DATE_FORMAT(CONCAT(start_date," ",start_time),'%Y-%m-%d %H:%i:%S') AND ? <= DATE_FORMAT(CONCAT(end_date," ",end_time),'%Y-%m-%d %H:%i:%S')) OR (? >= DATE_FORMAT(CONCAT(start_date," ",start_time),'%Y-%m-%d %H:%i:%S') AND ? <= DATE_FORMAT(CONCAT(end_date," ",end_time),'%Y-%m-%d %H:%i:%S') )))`
+	matterPars = append(matterPars, startDateTime)
+	matterPars = append(matterPars, startDateTime)
+	matterPars = append(matterPars, endDateTime)
+	matterPars = append(matterPars, endDateTime)
+	matterCount, err = roadshow.CheckMattersCount(matterCondition, matterPars)
+
+	if matterCount <= 0 {
+		var matterCondition string
+		var matterPars []interface{}
+		if rsMattersId > 0 {
+			matterCondition += " AND rs_matters_id <> ? "
+			matterPars = append(matterPars, rsMattersId)
+		}
+		matterCondition += " AND sys_user_id = ? "
+		matterPars = append(matterPars, researcherId)
+
+		matterCondition += ` AND ? <=DATE_FORMAT(CONCAT(start_date," ",start_time),'%Y-%m-%d %H:%i:%S')
+								 AND ? >= DATE_FORMAT(CONCAT(end_date," ",end_time),'%Y-%m-%d %H:%i:%S') `
+		matterPars = append(matterPars, startDateTime)
+		matterPars = append(matterPars, endDateTime)
+		matterCount, err = roadshow.CheckMattersCount(matterCondition, matterPars)
+	}
+
+	return
+}
+
+func CheckCalendar(startDateTime, endDateTime, status string, researcherId, rsCalendarResearcherId int) (calendarCount int, err error) {
+	var researcherCondition string
+	var researcherMatterPars []interface{}
+
+	if rsCalendarResearcherId > 0 {
+		researcherCondition += " AND rs_calendar_researcher_id <> ? "
+		researcherMatterPars = append(researcherMatterPars, rsCalendarResearcherId)
+	}
+
+	researcherCondition += " AND researcher_id = ? "
+	researcherMatterPars = append(researcherMatterPars, researcherId)
+
+	researcherCondition += " AND status IN (" + status + ") "
+
+	researcherCondition += ` AND (((? >=DATE_FORMAT(CONCAT(start_date," ",start_time),'%Y-%m-%d %H:%i:%S') AND ? <= DATE_FORMAT(CONCAT(end_date," ",end_time),'%Y-%m-%d %H:%i:%S')) OR (? >= DATE_FORMAT(CONCAT(start_date," ",start_time),'%Y-%m-%d %H:%i:%S') AND ? <= DATE_FORMAT(CONCAT(end_date," ",end_time),'%Y-%m-%d %H:%i:%S') )))`
+	researcherMatterPars = append(researcherMatterPars, startDateTime)
+	researcherMatterPars = append(researcherMatterPars, startDateTime)
+	researcherMatterPars = append(researcherMatterPars, endDateTime)
+	researcherMatterPars = append(researcherMatterPars, endDateTime)
+	calendarCount, err = roadshow.CheckCalendarResearcherCount(researcherCondition, researcherMatterPars)
+	if calendarCount <= 0 {
+		var researcherCondition string
+		var researcherMatterPars []interface{}
+
+		if rsCalendarResearcherId > 0 {
+			researcherCondition += " AND rs_calendar_researcher_id <> ? "
+			researcherMatterPars = append(researcherMatterPars, rsCalendarResearcherId)
+		}
+
+		researcherCondition += " AND researcher_id = ? "
+		researcherMatterPars = append(researcherMatterPars, researcherId)
+
+		researcherCondition += " AND status IN (" + status + ") "
+
+		researcherCondition += ` AND ? <=DATE_FORMAT(CONCAT(start_date," ",start_time),'%Y-%m-%d %H:%i:%S')
+								 AND ? >= DATE_FORMAT(CONCAT(end_date," ",end_time),'%Y-%m-%d %H:%i:%S') `
+		researcherMatterPars = append(researcherMatterPars, startDateTime)
+		researcherMatterPars = append(researcherMatterPars, endDateTime)
+		calendarCount, err = roadshow.CheckCalendarResearcherCount(researcherCondition, researcherMatterPars)
+	}
+	return
+}

+ 62 - 0
services/wechat_send_msg.go

@@ -267,4 +267,66 @@ func SendWxMsgWithRoadshowDetailResult(first, keyword1, keyword2, remark,mobile,
 	}
 	utils.FileLog.Info("send end")
 	return
+}
+
+
+// 路演->研究员收到待处理的申请
+func SendWxMsgWithRoadshowPending(first, keyword1, keyword2, keyword3, keyword4, remark, wxAppPath,mobile string) (err error) {
+	//utils.WxMsgTemplateIdWithRoadshowPending
+	var msg string
+	defer func() {
+		if err != nil {
+			go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
+			utils.FileLog.Info("发送模版消息失败,Err:%s,%s", err.Error(), msg)
+		}
+		if msg != "" {
+			utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
+		}
+	}()
+	utils.FileLog.Info("%s", "services SendMsg")
+
+	accessToken, err := WxGetAccessToken()
+	if err != nil {
+		msg = "GetWxAccessToken Err:" + err.Error()
+		return
+	}
+	if accessToken == "" {
+		msg = "accessToken is empty"
+		return
+	}
+
+	//获取openid列表
+	openIdStr := WxUsersGet()
+	openIdList, err := wx_user.GetOpenIdListByMobile(mobile, openIdStr)
+	if err != nil {
+		msg = "get openIdList err:" + err.Error()
+		return
+	}
+	utils.FileLog.Info("openIdListCount:%s", len(openIdList))
+	//fmt.Println("openIdListCount:", len(openIdList))
+	if len(openIdList) > 0 && utils.TemplateIdByCompanyApply != "" {
+		utils.FileLog.Info("start send")
+		sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
+		fmt.Println("send start")
+		utils.FileLog.Info("send start")
+		sendMap := make(map[string]interface{})
+		sendData := make(map[string]interface{})
+
+
+		sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
+		sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
+		sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
+		sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
+		sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
+		sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
+
+		sendMap["template_id"] = utils.WxMsgTemplateIdWithRoadshowPending
+		//小程序信息
+		if wxAppPath != "" {
+			sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId2, "pagepath": wxAppPath}
+		}
+		sendTemplateMsg(sendUrl, sendMap, openIdList)
+	}
+	utils.FileLog.Info("send end")
+	return
 }

+ 25 - 0
utils/common.go

@@ -712,3 +712,28 @@ func Implode(idIntList []int) (str string) {
 	str = str[:len(str)-1]
 	return
 }
+
+//字符串类型时间转周几
+func StrDateTimeToWeek(strTime string) string {
+	var WeekDayMap = map[string]string{
+		"Monday":    "周一",
+		"Tuesday":   "周二",
+		"Wednesday": "周三",
+		"Thursday":  "周四",
+		"Friday":    "周五",
+		"Saturday":  "周六",
+		"Sunday":    "周日",
+	}
+	var ctime = StrTimeToTime(strTime).Format("2006-01-02")
+	startday, _ := time.Parse("2006-01-02", ctime)
+	staweek_int := startday.Weekday().String()
+	return WeekDayMap[staweek_int]
+}
+
+//字符串转换为time
+func StrTimeToTime(strTime string) time.Time {
+	timeLayout := "2006-01-02 15:04:05"  //转化所需模板
+	loc, _ := time.LoadLocation("Local") //重要:获取时区
+	resultTime, _ := time.ParseInLocation(timeLayout, strTime, loc)
+	return resultTime
+}

+ 6 - 0
utils/constants.go

@@ -91,3 +91,9 @@ const (
 
 var PermissionFiccClassifyArr = [...]string{"宏观经济", "化工产业", "黑色产业", "有色产业"}
 var PermissionAllClassifyArr = [...]string{"宏观经济", "化工产业", "黑色产业", "有色产业", "权益"}
+
+//缓存key
+const (
+	CACHE_KEY_LOGS  = "HZ_ADMIN_CACHE_KEY_LOGS" //api用户操作日志队列
+	CACHE_KEY_ADMIN = "calendar:admin:list"     //系统用户列表缓存key
+)