package roadshow import ( "encoding/json" "errors" "fmt" "github.com/rdlucklib/rdluck_tools/http" "hongze/hz_crm_api/models/roadshow" "hongze/hz_crm_api/models/system" "hongze/hz_crm_api/services/alarm_msg" "hongze/hz_crm_api/utils" "io/ioutil" netHttp "net/http" "net/url" "strconv" "strings" "time" ) type SyncCalendarFromShanghaiRecord struct { UserPhone string `description:"手机号"` StartDate string `description:"开始时间"` EndDate string `description:"结束时间"` } // 上海路演数据同步到自系统 从Redis获取 func InsertSyncCalendarFromShanghai() { var err error defer func() { if err != nil { go alarm_msg.SendAlarmMsg("上海路演数据同步到自系统 失败;InsertSyncCalendarFromShanghai ERR:"+err.Error(), 3) } }() for { utils.Rc.Brpop(utils.CACHE_KEY_SHANG_HAI_RS_CALENDAR_API, func(b []byte) { record := new(SyncCalendarFromShanghaiRecord) if err := json.Unmarshal(b, &record); err != nil { fmt.Println("json unmarshal wrong!") } //fmt.Println(record.UserPhone) _ = SyncCalendarFromShanghai(record.UserPhone, record.StartDate, record.EndDate) }) } } // 上海路演数据同步到自系统请求放到Redis func InsertSyncCalendarFromShanghaiLPush(userPhone, startDate, endDate string) bool { log := &SyncCalendarFromShanghaiRecord{UserPhone: userPhone, StartDate: startDate, EndDate: endDate} if utils.Re == nil { err := utils.Rc.LPush(utils.CACHE_KEY_SHANG_HAI_RS_CALENDAR_API, log) if err != nil { fmt.Println(err) go alarm_msg.SendAlarmMsg("上海路演数据同步到自系统 失败;InsertSyncCalendarFromShanghaiLPush ERR:"+err.Error(), 3) } return true } return false } // getAccessToken token内部请求接口 func getAccessToken() (tokenData roadshow.TokenData, err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("更新上海的token失败;ERR:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"更新上海的token失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers) } }() getUrl := fmt.Sprintf(utils.CRM_OPEN_API_URL+"/v1/auth/getAccessToken?app_key=%s&app_secret=%s", utils.CRM_OPEN_API_APP_KEY, utils.CRM_OPEN_API_APP_SECRET) body, err := http.Get(getUrl) if err != nil { err = errors.New("NewRequest Err:" + err.Error()) return } var tokenResp roadshow.GetTokenResp err = json.Unmarshal(body, &tokenResp) if err != nil { err = errors.New("Unmarshal Err:" + err.Error()) return } if tokenResp.Code != 1 { err = errors.New("getAccessToken err:" + tokenResp.Msg) return } tokenData = tokenResp.TokenData return } // refreshAccessToken 强制刷新获取accessToken func refreshAccessToken() (token string, err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("刷新上海的token失败;ERR:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"刷新上海的token失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers) } }() tokenInfo, tmpErr := getAccessToken() if tmpErr != nil { err = tmpErr return } token = tokenInfo.AccessToken //token存入redis err = utils.Rc.Put("SH_ACCESS_TOKEN", token, time.Duration(tokenInfo.ExpireIn-600)*time.Second) if err != nil { go alarm_msg.SendAlarmMsg("获取上海的token失败;上海token存入redis失败,ERR:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"获取上海的token失败:"+time.Now().Format("2006-01-02 15:04:05"), "上海token存入redis失败:", utils.EmailSendToUsers) } return } // getCalendarFrom 获取上海方的路演活动列表 func getCalendarFrom(userPhone, startDate, endDate string) (list []roadshow.UserCalendar, err error) { exUrl := utils.CRM_OPEN_API_URL + "/v1/calendar/userCalendarList" form := url.Values{ "user_phone": {userPhone}, "start_time": {startDate}, "end_time": {endDate}, } body, err := getCurl(exUrl, form, 0) if err != nil { err = errors.New("NewRequest Err:" + err.Error()) return } var userCalendarList roadshow.UserCalendarList err = json.Unmarshal(body, &userCalendarList) if err != nil { err = errors.New("Unmarshal Err:" + err.Error()) return } list = userCalendarList.Data //fmt.Println(response) //userCalendarList := response.([]interface{}) // //for _, userCalendar := range userCalendarList { // fmt.Println(userCalendar) // fmt.Printf("type :%T;\n", userCalendar) // //list = append(list, userCalendar.(roadshow.UserCalendar)) //} //fmt.Println(userCalendarList) //list = userCalendarList return } // creatSHCalendar 新增上海日历活动 func creatSHCalendar(userPhone, toUserPhone, content, startTime, endTime string, calendarType int8, selfCalendarId int) (err error, errMsg string) { logMsg := `` defer func() { if err != nil { if logMsg != `` { errMsg = logMsg } } }() finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/create" form := url.Values{ "user_phone": {userPhone}, "to_user_phone": {toUserPhone}, "content": {content}, "start_time": {startTime}, "end_time": {endTime}, } //发送创建请求 body, err, logMsg := postCurl(finalUrl, form, 0) if err != nil { err = errors.New("NewRequest Err:" + err.Error()) return } var creatSHCalendarResp roadshow.CreatSHCalendarResp err = json.Unmarshal(body, &creatSHCalendarResp) if err != nil { err = errors.New("Unmarshal Err:" + err.Error()) return } calendar := creatSHCalendarResp.Data //上海系统id sThirdId := calendar.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()) fmt.Println(err) return } return } // updateSHCalendar 内部函数,只用于发送修改上海日历的http请求 func updateSHCalendar(thirdCalendarId, researcherMobile, content, startTime, endTime string) (calendarResp roadshow.CreatSHCalendarResp, err error) { finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/update" form := url.Values{ "calendar_id": {thirdCalendarId}, "to_user_phone": {researcherMobile}, "content": {content}, "start_time": {startTime}, "end_time": {endTime}, } //发送创建请求 _, err, _ = postCurl(finalUrl, form, 0) if err != nil { err = errors.New("NewRequest Err:" + err.Error()) return } return } // deleteSHCalendar 删除上海方的路演 func deleteSHCalendar(userPhone string, calendarId int) (err error) { finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/delete" form := url.Values{ "user_phone": {userPhone}, "calendar_id": {fmt.Sprintf("%v", calendarId)}, } //发送创建请求 _, err, _ = postCurl(finalUrl, form, 0) if err != nil { err = errors.New("NewRequest Err:" + err.Error()) return } return } // ShResponse 上海数据返回结构体 type ShResponse struct { Code int `json:"code" description:"1:正常返回;4001:token失效"` Msg string `json:"msg" description:"文字描述"` Time int `json:"time" description:"时间戳"` Data interface{} `json:"data" description:"业务数据"` } // getCurl get请求上海接口 func getCurl(urlStr string, params url.Values, num int) (body []byte, err error) { if err != nil { go alarm_msg.SendAlarmMsg("get请求上海接口失败,ERR:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"get请求上海接口失败:"+time.Now().Format("2006-01-02 15:04:05"), "get请求上海接口失败:"+err.Error(), utils.EmailSendToUsers) } token, err := GetAccessToken(false) if err != nil { return } params.Add("access_token", token) getUrl := urlStr + "?" + params.Encode() body, err = http.Get(getUrl) if err != nil { utils.FileLog.Info(fmt.Sprint("get Err:", err.Error(), ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body))) err = errors.New("NewRequest Err:" + err.Error()) return } var response ShResponse err = json.Unmarshal(body, &response) if err != nil { utils.FileLog.Info(fmt.Sprint("get Err:", err.Error(), ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body))) err = errors.New("Unmarshal Err:" + err.Error()) return } //如果是token失效,同时只是第一次请求(没有尝试强制刷新token,那么重新请求) if response.Code == 4001 && num <= 0 { utils.FileLog.Info(fmt.Sprint("get data err", ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body))) //token失效 _, tmpErr := refreshAccessToken() if tmpErr != nil { err = tmpErr } num++ params.Del("access_token") return getCurl(urlStr, params, num) } else if response.Code != 1 { utils.FileLog.Info(fmt.Sprint("get data err", ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body))) err = errors.New(response.Msg) return } itemApiLog := new(roadshow.RsCalendarApiLog) itemApiLog.CreateTime = time.Now() itemApiLog.Remark = "get请求上海接口" itemApiLog.Url = getUrl itemApiLog.Body = utils.ReplaceSpaceAndWrap(fmt.Sprint(params)) itemApiLog.Result = string(body) go roadshow.AddRsCalendarApiLog(itemApiLog) return } // postCurl post请求上海接口 func postCurl(urlStr string, form url.Values, num int) (body []byte, err error, errMsg string) { logMsg := `` defer func() { if err != nil { if logMsg != `` { errMsg = logMsg go alarm_msg.SendAlarmMsg("post请求上海接口失败,ERR:"+err.Error()+";errMsg:"+errMsg, 3) //go utils.SendEmail(utils.APPNAME+"post请求上海接口失败:"+time.Now().Format("2006-01-02 15:04:05"), "post请求上海接口失败:"+errMsg, utils.EmailSendToUsers) } } }() token, err := GetAccessToken(false) if err != nil { return } finalUrl := urlStr + "?access_token=" + token //发送创建请求 resp, err := netHttp.PostForm(finalUrl, 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 { logMsg = fmt.Sprint("post err; request:", form.Encode(), "; errMsg:", err.Error()) utils.FileLog.Info(logMsg) return } logMsg = fmt.Sprint("post request:", form.Encode(), "; response:", string(body)) utils.FileLog.Info(logMsg) var response ShResponse err = json.Unmarshal(body, &response) if err != nil { utils.FileLog.Info("post Err:", err.Error(), ";url:", finalUrl, ";params:", form.Encode(), ";response:", string(body)) err = errors.New("Unmarshal Err:" + err.Error()) return } utils.FileLog.Info(fmt.Sprint("post request url:", finalUrl, ";params:", form.Encode(), ";response:", string(body))) itemApiLog := new(roadshow.RsCalendarApiLog) itemApiLog.CreateTime = time.Now() itemApiLog.Remark = "post请求上海接口" itemApiLog.Url = urlStr itemApiLog.Body = utils.ReplaceSpaceAndWrap(fmt.Sprint(form)) itemApiLog.Result = string(body) go roadshow.AddRsCalendarApiLog(itemApiLog) //如果是token失效,同时只是第一次请求(没有尝试强制刷新token,那么重新请求) if response.Code == 4001 && num <= 0 { //token失效 _, tmpErr := refreshAccessToken() if tmpErr != nil { err = tmpErr } num++ return postCurl(urlStr, form, num) } else if response.Code != 1 { utils.FileLog.Info(fmt.Sprint("post data err", ";url:", finalUrl, ";params:", form.Encode(), ";response:", string(body))) err = errors.New(response.Msg) return } return } // GetAccessToken 获取accessToken func GetAccessToken(isRefresh bool) (token string, err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("获取上海的token失败,ERR:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"获取上海的token失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers) } }() token, redisErr := utils.Rc.RedisString("SH_ACCESS_TOKEN") //如果从redis中accessToken 获取失败或者token为空了,再或者需要强制刷新了,那么重新获取accessToken if redisErr != nil || token == `` || isRefresh { return refreshAccessToken() } return } // CalendarToSH 创建活动时同步上海的前置函数 func CalendarToSH(rsCalendar roadshow.RsCalendar, researcher roadshow.RsCalendarResearcher) { if researcher.Status != 2 { //研究员的路演申请,需要研究员接受后,再同步到老CRM return } var err error errMsg := `` defer func() { if err != nil { errMsg = err.Error() + ";" + errMsg go alarm_msg.SendAlarmMsg("新建上海研究员日历失败,ERR:"+err.Error()+";errMsg:"+errMsg, 3) //go utils.SendEmail(utils.APPNAME+"新建上海研究员日历失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers) } }() //redis获取创建者及研究员信息 userInfo, err := getAdminInfoById(rsCalendar.SysUserId) if err != nil { utils.FileLog.Info("getAdminInfoById err: " + err.Error()) return } researcherInfo, err := getAdminInfoById(researcher.ResearcherId) if err != nil { utils.FileLog.Info("getAdminInfoById err: " + err.Error()) return } 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, errMsg = creatSHCalendar(userInfo.Mobile, researcherInfo.Mobile, rsCalendar.CompanyName+rsCalendar.Title, startTime, endTime, 1, researcher.RsCalendarResearcherId) if err != nil { utils.FileLog.Info("CreatSHCalendar err: " + err.Error()) fmt.Println(err) return } // 更新路演与研究员关系表的同步字段 whereParams := make(map[string]interface{}) updateParams := make(map[string]interface{}) whereParams["rs_calendar_researcher_id"] = researcher.RsCalendarResearcherId updateParams["is_synced"] = 1 updateParams["modify_time"] = time.Now() 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) (err error) { errMsg := `` defer func() { if err != nil { errMsg = err.Error() + ";" + errMsg go alarm_msg.SendAlarmMsg("新建上海研究员事项失败,ERR:"+err.Error()+";errMsg:"+errMsg, 3) //go utils.SendEmail(utils.APPNAME+"新建上海研究员事项失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers) } }() //获取研究员信息 researcherInfo, err := getAdminInfoById(matter.SysUserId) if err != nil { //utils.FileLog.Info("getAdminInfoById 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, errMsg = creatSHCalendar(researcherInfo.Mobile, researcherInfo.Mobile, matter.MatterContent, startTime, endTime, 2, matter.RsMattersId) if err != nil { return } // 修改事项的同步字段 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 { err = fmt.Errorf("UpdateRsMatters err: " + err.Error()) } return } // UpdateSHCalendar 更新上海日历活动 func UpdateSHCalendar(rsCalendarId, rsCalendarResearcherId int, activityType, roadshowType, activityCategory, roadshowPlatform, province, city string, calendarResearcherList []*roadshow.CalendarResearcher) (err error) { errMsg := `` defer func() { if errMsg != `` { if err != nil { errMsg = err.Error() + ";" + errMsg } go alarm_msg.SendAlarmMsg("更新上海日历活动失败,errMsg:"+errMsg, 3) //go utils.SendEmail(utils.APPNAME+"更新上海日历活动失败:"+time.Now().Format("2006-01-02 15:04:05"), errMsg, utils.EmailSendToUsers) } }() //查询关联表获取信息 var condition string var pars []interface{} condition = ` AND self_calendar_id = ? and calendar_type = 1 ` pars = append(pars, rsCalendarResearcherId) relationItem, err := roadshow.GetRelationByPars(condition, pars) if err != nil { err = errors.New("GetRelationByPars err:" + err.Error()) fmt.Println(err) return } //需要同时修改创建人及研究员的日历(目前听说只有1个,先按一个处理吧) for _, researcher := range calendarResearcherList { 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(activityType, roadshowType, activityCategory, roadshowPlatform, province, city) //发送更新请求 _, err = updateSHCalendar(fmt.Sprintf("%v", relationItem.ThirdCalendarId), relationItem.ResearcherMobile, title, startTime, endTime) if err != nil { errMsg += fmt.Sprint("更新研究员日历信息:", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";") } //// 更新路演活动的信息 //calWhereParams := make(map[string]interface{}) //calWhereParams["rs_calendar_id"] = rsCalendarId //err = roadshow.UpdateRsCalendarRelation(calWhereParams, updateParams) //if err != nil { // errMsg += fmt.Sprint("UpdateRsCalendar:", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";") // return //} } // 更新路演活动中 研究员的信息 whereParams := make(map[string]interface{}) updateParams := make(map[string]interface{}) whereParams["rs_calendar_researcher_id"] = rsCalendarResearcherId updateParams["is_synced"] = 1 updateParams["modify_time"] = time.Now() err = roadshow.UpdateCalendarResearcher(whereParams, updateParams) if err != nil { errMsg += fmt.Sprint("UpdateCalendarResearcher:", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";") return } // 更新路演活动的信息 calWhereParams := make(map[string]interface{}) calWhereParams["rs_calendar_id"] = rsCalendarId err = roadshow.UpdateRsCalendar(calWhereParams, updateParams) if err != nil { errMsg += fmt.Sprint("UpdateRsCalendar:", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";") return } return } // UpdateSHCalendarByMatter 更新上海日历活动 func UpdateSHCalendarByMatter(req roadshow.UpdateMattersReq) (err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("更新上海日历活动失败,Err:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"更新上海日历活动失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers) } }() if err != nil { return } //需要同时修改创建人及研究员的日历 //查询关联表获取信息 var condition string var pars []interface{} condition = ` AND self_calendar_id = ? and calendar_type = 2 ` pars = append(pars, req.RsMattersId) relationItem, err := roadshow.GetRelationByPars(condition, pars) if err != nil { err = errors.New("GetRelationByPars err:" + err.Error()) fmt.Println(err) return } 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") //发送更新请求 _, err = updateSHCalendar(fmt.Sprintf("%v", relationItem.ThirdCalendarId), relationItem.ResearcherMobile, relationItem.CustomerName+req.MatterContent, startTime, endTime) if err == nil { 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 } } return } // DeleteSHCalendar 删除上海日历活动 func DeleteSHCalendar(rsCalendarResearcherId int) (err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg(fmt.Sprint("删除上海日历活动失败,关系id:", rsCalendarResearcherId, ";err:", err.Error()), 3) //go utils.SendEmail(utils.APPNAME+"删除上海日历活动失败:"+time.Now().Format("2006-01-02 15:04:05"), fmt.Sprint("关系id:", rsCalendarResearcherId, ";err:", err.Error()), utils.EmailSendToUsers) } }() var condition string var pars []interface{} condition = ` AND self_calendar_id = ? and calendar_type = 1 ` pars = append(pars, rsCalendarResearcherId) relationItem, err := roadshow.GetRelationByPars(condition, pars) if err != nil { logInfo := fmt.Sprint("删除上海日历活动失败;rsCalendarResearcherId:,", rsCalendarResearcherId, " ;GetRelationByPars err"+err.Error()) err = errors.New(logInfo) utils.FileLog.Info(logInfo) if err.Error() == utils.ErrNoRow() { err = nil return } return } //删除上海方的路演 err = deleteSHCalendar(relationItem.UserPhone, relationItem.ThirdCalendarId) if err != nil { return } //删除活动表及事项表 err = roadshow.DeleteRsCalendarRelation(relationItem.RelationId) if err != nil { err = errors.New("DeleteRsCalendarRelation err:" + err.Error()) return } return } // DeleteSHMatter 删除上海日历事项 func DeleteSHMatter(matterId int) (err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("删除上海研究员日历失败;ERR:"+err.Error(), 3) //go utils.SendEmail(utils.APPNAME+"删除上海日历事项失败:", "删除上海研究员日历失败 "+err.Error(), utils.EmailSendToUsers) } }() var condition string var pars []interface{} condition = ` AND self_calendar_id = ? and calendar_type = 2 ` pars = append(pars, matterId) relationItem, err := roadshow.GetRelationByPars(condition, pars) if err != nil { err = errors.New(fmt.Sprint("删除上海日历事项失败;matterId:,", matterId, " ;GetRelationByPars err"+err.Error())) utils.FileLog.Info(err.Error()) if err.Error() == utils.ErrNoRow() { err = nil return } return } //删除上海方的路演 err = deleteSHCalendar(relationItem.UserPhone, relationItem.ThirdCalendarId) //删除活动表及事项表 err = roadshow.DeleteRsCalendarRelation(relationItem.RelationId) if err != nil { err = errors.New("DeleteRsCalendarRelation err:" + err.Error()) return } return } // SyncCalendarFromShanghai 上海路演数据同步到自系统 func SyncCalendarFromShanghai(userPhone, startDate, endDate string) (err error) { errMsgList := make([]string, 0) defer func() { if len(errMsgList) > 0 { //fmt.Println("err:", errMsg) if err != nil { errMsgList = append(errMsgList, fmt.Sprint("ERR:"+err.Error(), ";")) } go alarm_msg.SendAlarmMsg("上海路演数据同步到自系统失败;errMsg:"+strings.Join(errMsgList, "\n"), 3) //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 { errMsgList = append(errMsgList, `结束日期转time类型失败,err:`+err.Error()) return } //往后延迟一天,避免截止到当天 endDate = endDateTime.AddDate(0, 0, 1).Format(utils.FormatDate) currDay := time.Now().Format(utils.FormatDate) nowDateTime, _ := time.ParseInLocation(utils.FormatDate, currDay, time.Local) //如果传入的结束日期早于当前日期,那么就不去查询了 if endDateTime.Before(nowDateTime) { return } //获取当前研究员信息 userPhoneInfo, err := getAdminInfo(userPhone) if err != nil { errMsgList = append(errMsgList, fmt.Sprint("获取手机号信息失败:手机号:", userPhone, ";err:"+err.Error(), ";")) return } //根据研究员和开始/结束日期获取上海的活动路演 rsCalendarResearcherList, err := roadshow.GetRsCalendarResearcherInfoIByResearcherIdAndDate(userPhoneInfo.AdminId, currDay, endDate) if err != nil { errMsgList = append(errMsgList, fmt.Sprint("获取研究员日程信息失败:手机号:", userPhone, ";err:"+err.Error(), ";")) return } //待删除的活动路演 deleteRsCalendarResearcherMap := make(map[int][]*roadshow.RsCalendarResearcherRelationInfo) for _, v := range rsCalendarResearcherList { tmpList, ok := deleteRsCalendarResearcherMap[v.ThirdCalendarId] if !ok { tmpList = make([]*roadshow.RsCalendarResearcherRelationInfo, 0) } tmpList = append(tmpList, v) deleteRsCalendarResearcherMap[v.ThirdCalendarId] = tmpList } //以当前日期作为起始日期去同步 list, err := getCalendarFrom(userPhone, currDay, endDate) if err != nil { errMsgList = append(errMsgList, fmt.Sprint("获取第三方路演日历数据失败,", "userPhone:", userPhone, ";currDay:", currDay, ";endDate:", endDate, ";err:"+err.Error())) return } thirdIdList := make([]int, 0) if len(list) > 0 { for _, v := range list { thirdIdList = append(thirdIdList, v.ID) //移除还存在的活动,保留不存在的活动 delete(deleteRsCalendarResearcherMap, v.ID) } rsCalendarRelationList, tmpErr := roadshow.GetRsCalendarRelationListByThirdIds(thirdIdList) if tmpErr != nil { err = tmpErr errMsgList = append(errMsgList, "获取关联列表失败,err:"+tmpErr.Error()) return } rsCalendarRelationMap := make(map[int]*roadshow.RsCalendarRelation) for _, rsCalendarRelation := range rsCalendarRelationList { rsCalendarRelationMap[rsCalendarRelation.ThirdCalendarId] = rsCalendarRelation } for _, v := range list { //展示优先级:1、customer_name 2、project_name 3、title 需求池953 if v.CustomerName != "" { v.Title = v.CustomerName } else if v.ProjectName != "" { v.Title = v.ProjectName } if rsCalendarRelation, ok := rsCalendarRelationMap[v.ID]; ok { //存在的话,那么就去查找对应的信息 if rsCalendarRelation.CalendarType == 1 { //路演 rsCalendarResearcherInfo, tmpErr := roadshow.GetRsCalendarResearcherById(rsCalendarRelation.SelfCalendarId) if tmpErr != nil { errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID:", v.ID, "获取路演研究员信息失败;err:"+tmpErr.Error(), ";")) continue } rsCalendarInfo, tmpErr := roadshow.GetRsCalendarById(rsCalendarResearcherInfo.RsCalendarId) if tmpErr != nil { errMsgList = append(errMsgList, 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 } if rsCalendarResearcherInfo.Status == 4 { // 被删除了,现在是需要更新 isUpdate = true } researcherList := make([]system.AdminItem, 0) researcherMap := make(map[int]system.AdminItem) addResearcherList := make([]system.AdminItem, 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 { errMsgList = append(errMsgList, 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 || researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER || researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN { researcherList = append(researcherList, researcherInfo) researcherMap[researcherInfo.AdminId] = researcherInfo } } } //没有研究员 if len(researcherList) <= 0 { errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID:", v.ID, ";对方研究员信息失败;")) continue } rsCalendarResearcherList, tmpErr := roadshow.GetRsCalendarResearcherListByRsCalendarId(rsCalendarInfo.RsCalendarId) if tmpErr != nil { errMsgList = append(errMsgList, 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 { errMsgList = append(errMsgList, 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 errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID:", v.ID, "修改关联关系失败;err:"+tmpErr.Error(), ";")) return } } } else { //事项 //事项都是由自系统创建的,不需要依靠上海方来修改 } } else { //数据不存在 createUser, tmpErr := getAdminInfo(v.UserPhone) if tmpErr != nil { errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID:", v.ID, "获取创建人失败,创建人手机号:", v.UserPhone, ";err:"+tmpErr.Error(), ";")) continue } //研究员列表 researcherList := make([]system.AdminItem, 0) researcherMobileList := strings.Split(v.ResearcherMobile, ",") if len(researcherMobileList) > 0 { for _, mobile := range researcherMobileList { researcherInfo, tmpErr := getAdminInfo(mobile) if tmpErr != nil { errMsgList = append(errMsgList, 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 || researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER || researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN || researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN { researcherList = append(researcherList, researcherInfo) } } } //没有研究员 if len(researcherList) <= 0 { continue } //数据入库 tmpErr = roadshow.SyncRsCalendarRelation(v, createUser, researcherList) if tmpErr != nil { err = tmpErr errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID:", v.ID, "绑定关联关系失败;err:"+tmpErr.Error(), ";")) continue } //fmt.Println("createUser:", createUser) } } } var itemsApiLog []*roadshow.RsCalendarApiLog //上海那边已经删除了路演,这边也要同步删除 for _, deleteRsCalendarResearcherList := range deleteRsCalendarResearcherMap { for _, deleteRsCalendarResearcher := range deleteRsCalendarResearcherList { // 更新路演与研究员关系表的状态字段 whereParams := make(map[string]interface{}) updateParams := make(map[string]interface{}) whereParams["rs_calendar_researcher_id"] = deleteRsCalendarResearcher.RsCalendarResearcherId updateParams["status"] = 4 updateParams["modify_time"] = time.Now() tmpErr := roadshow.UpdateCalendarResearcher(whereParams, updateParams) if tmpErr != nil { err = tmpErr errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID:", deleteRsCalendarResearcher.ThirdCalendarId, "删除关联关系失败;err:"+tmpErr.Error(), ";")) continue } itemApiLog := new(roadshow.RsCalendarApiLog) itemApiLog.CreateTime = time.Now() itemApiLog.Remark = "对比上海接口之后手动删除" itemApiLog.Url = fmt.Sprint("userPhone", userPhone, "currDay", currDay, "endDate", endDate) itemApiLog.Body = "" itemApiLog.Result = "" itemApiLog.RsCalendarResearcherId = deleteRsCalendarResearcher.RsCalendarResearcherId itemsApiLog = append(itemsApiLog, itemApiLog) // 更新路演的同步字段 //calWhereParams := make(map[string]interface{}) //calUpdateParams := make(map[string]interface{}) //calWhereParams["rs_calendar_id"] = deleteRsCalendarResearcher.RsCalendarId //updateParams["is_synced"] = 1 //err = roadshow.UpdateRsCalendar(calWhereParams, calUpdateParams) } } if len(itemsApiLog) > 0 { go roadshow.AddRsCalendarApiLogList(itemsApiLog) } return } // CreateOaUser 新增系统用户 func CreateOaUser(mobile, username string, groupId int) (err error) { defer func() { if err != nil { errMsg := fmt.Sprint("手机号:", mobile, ";username:", username, ";分组id:", groupId, ";err:", err.Error()) go alarm_msg.SendAlarmMsg("系统用户同步到上海失败;ERR:"+err.Error()+";errMsg:"+errMsg, 3) //go utils.SendEmail(utils.APPNAME+"系统用户同步到上海失败:"+time.Now().Format("2006-01-02 15:04:05"), errMsg, utils.EmailSendToUsers) } }() finalUrl := utils.CRM_OPEN_API_URL + "/v1/OaUser/create" //发送创建请求 form := url.Values{} form.Add("mobile", mobile) form.Add("username", username) form.Add("group_id", fmt.Sprint(groupId)) //发送创建请求 _, err, _ = postCurl(finalUrl, form, 0) if err != nil { err = errors.New("NewRequest Err:" + err.Error()) return } return } // getAdminInfo 通过手机号获取用户信息 func getAdminInfo(mobile string) (adminInfo system.AdminItem, err error) { adminMap := make(map[string]system.AdminItem) redisAdminData, redisErr := utils.Rc.RedisString(utils.CACHE_KEY_ADMIN) if redisErr != nil { list, err := system.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 } // getAdminInfoById 通过用户id获取用户信息 func getAdminInfoById(sysId int) (adminInfo system.AdminItem, err error) { adminMap := make(map[int]system.AdminItem) redisAdminData, redisErr := utils.Rc.RedisString(utils.CACHE_KEY_ADMIN_ID) if redisErr != nil { list, err := system.GetSysuserList("", []interface{}{}, 0, 1000) // GetSysuserList for _, tmpAdminInfo := range list { adminMap[tmpAdminInfo.AdminId] = *tmpAdminInfo } //入缓存 redisJsonData, err := json.Marshal(adminMap) if err == nil { _ = utils.Rc.Put(utils.CACHE_KEY_ADMIN_ID, string(redisJsonData), time.Minute*30) } } else { err := json.Unmarshal([]byte(redisAdminData), &adminMap) if err != nil { fmt.Println("用户数据,json转换失败:", err) } } adminInfo, ok := adminMap[sysId] if !ok { err = fmt.Errorf("找不到该用户id,sysId:" + fmt.Sprint(sysId)) } 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 } // GetCalendarFrom 获取上海方的路演活动列表 func GetCalendarFrom(userPhone, startDate, endDate string) (list []roadshow.UserCalendar, err error) { list, err = getCalendarFrom(userPhone, startDate, endDate) return }