package plat import ( "context" "dashoo.cn/micro/app/service/dingtalk_log" "dashoo.cn/opms_libary/myerrors" "database/sql" "fmt" "github.com/gogf/gf/errors/gerror" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" "strings" "dashoo.cn/micro/app/dao/plat" model "dashoo.cn/micro/app/model/plat" "dashoo.cn/micro/app/service" libary_dingtalk "dashoo.cn/opms_libary/plugin/dingtalk" "dashoo.cn/opms_libary/plugin/dingtalk/calendar" "dashoo.cn/opms_libary/plugin/dingtalk/message" ) type scheduleService struct { *service.ContextService Dao *plat.PlatScheduleDao } func NewScheduleService(ctx context.Context) (svc *scheduleService, err error) { svc = new(scheduleService) if svc.ContextService, err = svc.Init(ctx); err != nil { return nil, err } svc.Dao = plat.NewPlatScheduleDao(svc.Tenant) return svc, nil } // GetList 日程列表 // 数据类型:(前后端约定)10 查询参与者,其他 查询组织者 func (s *scheduleService) GetList(req *model.ScheduleSearchReq) (total int, scheduleList []*model.GetScheduleRes, err error) { Model := s.Dao.M.InnerJoin("plat_schedule_attendee", "plat_schedule.id=plat_schedule_attendee.sch_id") where := "" if req.DataType == "10" { where = fmt.Sprintf("plat_schedule_attendee.user_id=%v", s.GetCxtUserId()) Model = Model.Where("plat_schedule_attendee.user_id = ", s.GetCxtUserId()) } else { where = fmt.Sprintf("plat_schedule.user_id=%v", s.GetCxtUserId()) Model = Model.Where("plat_schedule.user_id = ", s.GetCxtUserId()) } if req.SchDate != nil { schDate := gconv.String(req.SchDate) begin := strings.Split(schDate, " ")[0] + " 00:00:00" end := strings.Split(schDate, " ")[0] + " 23:59:59" Model = Model.Where("plat_schedule.sch_date >= ? AND plat_schedule.sch_date <= ? ", begin, end) where += fmt.Sprintf(" AND plat_schedule.sch_date >= %v AND plat_schedule.sch_date <= %v", begin, end) } total, err = Model.Count() if err != nil { err = myerrors.DbError("获取总行数失败") return } err = Model.Page(req.GetPage()).Order("plat_schedule.id desc").Group("plat_schedule.id").Fields("plat_schedule.*").Scan(&scheduleList) if err != nil { return } // 获取参与者信息 var attendees []*model.PlatScheduleAttendee err = s.Dao.M.InnerJoin("plat_schedule_attendee", "plat_schedule.id=plat_schedule_attendee.sch_id").Order("plat_schedule_attendee.id ASC").Where(where).Fields("plat_schedule_attendee.*").Scan(&attendees) if err == sql.ErrNoRows { return total, scheduleList, nil } else if err != nil { return } // 组合参与者信息 for index, att := range attendees { for schIndex, sch := range scheduleList { if att.SchId == sch.Id { scheduleList[schIndex].Attendees = append(scheduleList[schIndex].Attendees, attendees[index]) break } } } return } // GetUserBusyStatus 获取用户忙闲信息 func (s *scheduleService) GetUserBusyStatus(req *model.UserBusyStatusReq) (UserBusyInfo interface{}, err error) { // 构造请求参数 var param calendar.DingIsUserBusyParams param.BeginTime = fmt.Sprintf("%vT%v+08:00", req.BeginTime.Format("Y-m-d"), req.BeginTime.Format("H:i:s")) param.EndTime = fmt.Sprintf("%vT%v+08:00", req.EndTime.Format("Y-m-d"), req.EndTime.Format("H:i:s")) param.UserIds = req.UserIds param.UserId = s.GetCxtUserDingtalkId() // 记录日志 dingtalk_log.Create(s.Ctx, "10", gconv.String(¶m)) // 调用钉钉接口 client := libary_dingtalk.NewClient() cal := client.GetCalendar() returnData, err := cal.GetUserBusyStatus(¶m) if err != nil { return 0, err } UserBusyInfo = returnData return } //Create 创建日程信息 func (s *scheduleService) Create(req *model.AddScheduleSeq) (insertId int64, err error) { schedule := new(model.PlatSchedule) if err = gconv.Struct(req, schedule); err != nil { return } service.SetCreatedInfo(schedule, s.GetCxtUserId(), s.GetCxtUserName()) schedule.UserId = s.GetCxtUserId() schedule.UserName = s.GetCxtUserName() // 构造请求参数 var param calendar.DingAddScheduleParams param.Summary = schedule.SchTitle param.Description = schedule.SchContent param.BeginTime = fmt.Sprintf("%vT%v+08:00", req.SchDate.Format("Y-m-d"), req.SchDate.Format("H:i:s")) param.EndTime = fmt.Sprintf("%vT%v+08:00", req.SchDateEnd.Format("Y-m-d"), req.SchDateEnd.Format("H:i:s")) param.UserIds = req.UserIds param.UserId = s.GetCxtUserDingtalkId() // 记录日志 dingtalk_log.Create(s.Ctx, "10", gconv.String(¶m)) // 调用钉钉接口 client := libary_dingtalk.NewClient() cal := client.GetCalendar() returnData, err := cal.CreateSchedule(¶m) if err != nil { return 0, err } // 将钉钉日程回填到系统中 schedule.DingScheduleId = *returnData.Id insertId, err = s.Dao.InsertAndGetId(schedule) if err != nil { return 0, err } // 回填 日程参与人的信息 到系统中 var attendees []*model.PlatScheduleAttendee for _, att := range returnData.Attendees { attendee := &model.PlatScheduleAttendee{ SchId: int(insertId), DingScheduleId: schedule.DingScheduleId, UserId: 0, // TODO 用户id需要关联到此处 UserUnionId: *att.Id, UserName: *att.DisplayName, } service.SetCreatedInfo(attendee, s.GetCxtUserId(), s.GetCxtUserName()) attendees = append(attendees, attendee) } _, err = s.Dao.DB.Model("plat_schedule_attendee").Save(attendees) return } // SaveByDingEvent 保存日程信息 func (s *scheduleService) SaveByDingEvent(msg *message.MixMessage) (err error) { if msg.ChangeType == "cancelled" || msg.ChangeType == "deleteView" { // 钉钉日程删除或者取消,本地日程需要删除 _, err = s.Dao.Delete("ding_schedule_id", msg.CalendarEventId) return err } else { // 构造请求参数 var param calendar.DingGetScheduleParams param.EventId = msg.CalendarEventId param.UserId = msg.UnionIdList[0] // 记录日志 dingtalk_log.Create(s.Ctx, "10", gconv.String(¶m)) // 获取日程详情 // 调用钉钉接口 client := libary_dingtalk.NewClient() cal := client.GetCalendar() returnData, err := cal.GetScheduleByEventId(¶m) if err != nil { return err } // 将日程数据回填 // 新建日程 if msg.ChangeType == "created" { err = s.addScheduleByDing(returnData) return err } else if msg.ChangeType == "updated" { // 获取系统中日程数据 schedule, err := s.Dao.Where("ding_schedule_id", msg.CalendarEventId).FindOne() if err != nil { // 查询不到数据时 if err == sql.ErrNoRows { err = s.addScheduleByDing(returnData) return err } else { return err } } // 查询不到数据时 if schedule == nil { err = s.addScheduleByDing(returnData) return err } else { // 能查询到数据,则更新数据 updateScheduleByDing(returnData, schedule) // 获取日程参与者 var attendees []*model.PlatScheduleAttendee var saveAttendees []*model.PlatScheduleAttendee err = s.Dao.DB.Model("plat_schedule_attendee").Where("sch_id", schedule.Id).Scan(&attendees) if err != nil && err != sql.ErrNoRows { return err } now := gtime.Now() // 将attendees所有数据标记为删除 for index := range attendees { attendees[index].DeletedTime = now } // 更新数据,并且将未删除的参与者的删除标记去掉 for _, dingSchedule := range returnData.Attendees { isNew := true for index, schedule := range attendees { if schedule.UserUnionId == *dingSchedule.Id { attendees[index].DeletedTime = nil service.SetUpdatedInfo(attendees[index], 0, "钉钉回调参数修改") saveAttendees = append(saveAttendees, attendees[index]) isNew = false break } } if isNew { attendee := &model.PlatScheduleAttendee{ SchId: schedule.Id, DingScheduleId: schedule.DingScheduleId, UserId: 0, // TODO 用户id需要关联到此处 UserUnionId: *dingSchedule.Id, UserName: *dingSchedule.DisplayName, } service.SetCreatedInfo(attendee, 0, "钉钉回调参数创建") service.SetUpdatedInfo(attendee, 0, "钉钉回调参数修改") saveAttendees = append(saveAttendees, attendee) } } // 保存删除数据 for index, att := range attendees { if att.DeletedTime != nil { saveAttendees = append(saveAttendees, attendees[index]) } } // 保存数据 _, err = s.Dao.Save(schedule) if err != nil { return err } // 保存参与人 _, err = s.Dao.DB.Model("plat_schedule_attendee").Save(saveAttendees) return err } } else { return gerror.New("未知的修改类型:" + msg.ChangeType) } } } // 根据钉钉数据创建日程 func (s *scheduleService) addScheduleByDing(rsp *calendar.GetEventResponse) error { var schedule model.PlatSchedule service.SetCreatedInfo(&schedule, 0, "钉钉回调参数创建") if rsp.Summary != nil { schedule.SchTitle = *rsp.Summary } if rsp.Description != nil { schedule.SchContent = *rsp.Description } if rsp.Start != nil && rsp.Start.DateTime != nil { schedule.SchDate = gtime.NewFromStr(*rsp.Start.DateTime) } if rsp.End != nil && rsp.End.DateTime != nil { schedule.SchDateEnd = gtime.NewFromStr(*rsp.End.DateTime) } schedule.UserId = 0 // TODO 获取系统的用户Id if rsp.Organizer != nil && rsp.Organizer.Id != nil { schedule.UserUnionId = *rsp.Organizer.Id } if rsp.Organizer != nil && rsp.Organizer.DisplayName != nil { schedule.UserName = *rsp.Organizer.DisplayName } if rsp.Id != nil { schedule.DingScheduleId = *rsp.Id } insertId, err := s.Dao.InsertAndGetId(schedule) if err != nil { return err } // 回填 日程参与人的信息 到系统中 var attendees []*model.PlatScheduleAttendee for _, att := range rsp.Attendees { attendee := &model.PlatScheduleAttendee{ SchId: int(insertId), DingScheduleId: schedule.DingScheduleId, UserId: 0, // TODO 用户id需要关联到此处 UserUnionId: *att.Id, UserName: *att.DisplayName, } service.SetCreatedInfo(attendee, 0, "钉钉回调参数创建") attendees = append(attendees, attendee) } _, err = s.Dao.DB.Model("plat_schedule_attendee").Save(attendees) return err } // 根据钉钉数据,更新日程主表数据 func updateScheduleByDing(rsp *calendar.GetEventResponse, schedule *model.PlatSchedule) { service.SetUpdatedInfo(schedule, 0, "钉钉回调参数修改") if rsp.Summary != nil { schedule.SchTitle = *rsp.Summary } if rsp.Description != nil { schedule.SchContent = *rsp.Description } if rsp.Start != nil && rsp.Start.DateTime != nil { schedule.SchDate = gtime.NewFromStr(*rsp.Start.DateTime) } if rsp.End != nil && rsp.End.DateTime != nil { schedule.SchDateEnd = gtime.NewFromStr(*rsp.End.DateTime) } schedule.UserId = 0 // TODO 获取系统的用户Id if rsp.Organizer != nil && rsp.Organizer.Id != nil { schedule.UserUnionId = *rsp.Organizer.Id } if rsp.Organizer != nil && rsp.Organizer.DisplayName != nil { schedule.UserName = *rsp.Organizer.DisplayName } }