package oa import ( "fmt" "time" "WiiCITMS/models/oa" "WiiGenerates/WiiCITMS/generates/v1/go/types" "WiiGoLibrary/apply/middle/process/v1" "WiiGoLibrary/framework/db/v1/utils/mssql/unique" "WiiGoLibrary/framework/hub/v1/dblib" ) // CreateScheduleRequest 创建日程请求 type CreateScheduleRequest struct { OwnerStaffGuid string `json:"ownerStaffGuid"` Title string `json:"title"` Description string `json:"description"` Location string `json:"location"` StartTime string `json:"startTime"` // RFC3339 EndTime string `json:"endTime"` // RFC3339 AllDay bool `json:"allDay"` RemindMinutesBefore int `json:"remindMinutesBefore"` } // CreateSchedule 创建日程 func CreateSchedule(req CreateScheduleRequest) (*oa.ScheduleModel, *process.Process) { if req.OwnerStaffGuid == "" || req.Title == "" || req.StartTime == "" || req.EndTime == "" { return nil, process.FailError(types.InvalidParamError, fmt.Errorf("缺少必填参数")) } owner, err := unique.FromString(req.OwnerStaffGuid) if err != nil { return nil, process.FailError(types.InvalidParamError, err) } start, err := time.Parse(time.RFC3339, req.StartTime) if err != nil { return nil, process.FailError(types.InvalidParamError, err) } end, err := time.Parse(time.RFC3339, req.EndTime) if err != nil { } if !end.After(start) { return nil, process.FailError(types.InvalidParamError, fmt.Errorf("结束时间必须晚于开始时间")) } // 冲突检查(不阻断创建) if _, _, proc := checkConflictsInternal(conflictCheckReq{OwnerStaffGuid: req.OwnerStaffGuid, Start: start, End: end, ExcludeGuid: ""}); proc.IsError() { return nil, proc } m := &oa.ScheduleModel{} m.OwnerStaffGuid = owner m.Title = req.Title m.Description = req.Description m.Location = req.Location m.StartTime = start m.EndTime = end m.AllDay = req.AllDay m.RemindMinutesBefore = req.RemindMinutesBefore m.Reminded = false m.Status = 0 r := dblib.DBIns.DB.Create(m) if r.Error != nil { return nil, process.FailError(types.CreateWorkflowError, r.Error) } return m, process.Success(200) } // CheckScheduleConflicts 冲突检查,返回冲突列表 func CheckScheduleConflicts(ownerStaffGuid, startISO, endISO, excludeGuid string) ([]*oa.ScheduleModel, bool, *process.Process) { start, err := time.Parse(time.RFC3339, startISO) if err != nil { return nil, false, process.FailError(types.InvalidParamError, err) } end, err := time.Parse(time.RFC3339, endISO) if err != nil { return nil, false, process.FailError(types.InvalidParamError, err) } res := make([]*oa.ScheduleModel, 0) owner, err := unique.FromString(ownerStaffGuid) if err != nil { return res, false, process.FailError(types.InvalidParamError, err) } db := dblib.DBIns.DB.Model(&oa.ScheduleModel{}). Where("OwnerStaffGuid = ? AND Status = 0 AND (RecordStatus & 524288) = 0", owner). Where("StartTime < ? AND EndTime > ?", end, start) if excludeGuid != "" { if guid, e := unique.FromString(excludeGuid); e == nil { db = db.Where("RecordGuid <> ?", guid) } } r := db.Find(&res) if r.Error != nil { return res, false, process.FailError(types.QueryWorkflowError, r.Error) } return res, len(res) > 0, process.Success(200) } // CancelSchedule 取消日程 func CancelSchedule(scheduleGuid string) *process.Process { guid, err := unique.FromString(scheduleGuid) if err != nil { return process.FailError(types.InvalidParamError, err) } r := dblib.DBIns.DB.Model(&oa.ScheduleModel{}).Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", guid).Update("Status", 1) if r.Error != nil { return process.FailError(types.UpdateWorkflowError, r.Error) } return process.Success(200) } // checkConflictsInternal 内部冲突检查实现 type conflictCheckReq struct { OwnerStaffGuid string Start time.Time End time.Time ExcludeGuid string } func checkConflictsInternal(req conflictCheckReq) ([]*oa.ScheduleModel, bool, *process.Process) { res := make([]*oa.ScheduleModel, 0) owner, err := unique.FromString(req.OwnerStaffGuid) if err != nil { return res, false, process.FailError(types.InvalidParamError, err) } db := dblib.DBIns.DB.Model(&oa.ScheduleModel{}). Where("OwnerStaffGuid = ? AND Status = 0 AND (RecordStatus & 524288) = 0", owner). Where("StartTime < ? AND EndTime > ?", req.End, req.Start) if req.ExcludeGuid != "" { if eg, e := unique.FromString(req.ExcludeGuid); e == nil { db = db.Where("RecordGuid <> ?", eg) } } r := db.Find(&res) if r.Error != nil { return res, false, process.FailError(types.QueryWorkflowError, r.Error) } return res, len(res) > 0, process.Success(200) } // UpdateSchedule 更新日程 type UpdateScheduleRequest struct { Title string `json:"title"` Description string `json:"description"` Location string `json:"location"` StartTime string `json:"startTime"` EndTime string `json:"endTime"` AllDay *bool `json:"allDay"` RemindMinutesBefore *int `json:"remindMinutesBefore"` } func UpdateSchedule(scheduleGuid string, req UpdateScheduleRequest) (*oa.ScheduleModel, *process.Process) { guid, err := unique.FromString(scheduleGuid) if err != nil { return nil, process.FailError(types.InvalidParamError, err) } m := &oa.ScheduleModel{} r := dblib.DBIns.DB.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", guid).First(m) if r.Error != nil { return nil, process.FailError(types.QueryWorkflowError, r.Error) } if req.Title != "" { m.Title = req.Title } if req.Description != "" { m.Description = req.Description } if req.Location != "" { m.Location = req.Location } var ( newStart time.Time newEnd time.Time hasTimeChange bool ) if req.StartTime != "" { v, e := time.Parse(time.RFC3339, req.StartTime) if e != nil { return nil, process.FailError(types.InvalidParamError, e) } newStart = v hasTimeChange = true } if req.EndTime != "" { v, e := time.Parse(time.RFC3339, req.EndTime) if e != nil { return nil, process.FailError(types.InvalidParamError, e) } newEnd = v hasTimeChange = true } if hasTimeChange { if req.StartTime == "" { newStart = m.StartTime } if req.EndTime == "" { newEnd = m.EndTime } if !newEnd.After(newStart) { return nil, process.FailError(types.InvalidParamError, fmt.Errorf("结束时间必须晚于开始时间")) } if _, _, proc := checkConflictsInternal(conflictCheckReq{OwnerStaffGuid: m.OwnerStaffGuid.String(), Start: newStart, End: newEnd, ExcludeGuid: m.RecordGuid.String()}); proc.IsError() { return nil, proc } m.StartTime, m.EndTime = newStart, newEnd m.Reminded = false } if req.AllDay != nil { m.AllDay = *req.AllDay } if req.RemindMinutesBefore != nil { m.RemindMinutesBefore = *req.RemindMinutesBefore m.Reminded = false } r = dblib.DBIns.DB.Save(m) if r.Error != nil { return nil, process.FailError(types.UpdateWorkflowError, r.Error) } return m, process.Success(200) } // ListSchedules 列表 type ListSchedulesRequest struct { OwnerStaffGuid string `json:"ownerStaffGuid"` From string `json:"from"` To string `json:"to"` Limit int `json:"limit"` Offset int `json:"offset"` } func ListSchedules(req ListSchedulesRequest) ([]*oa.ScheduleModel, *process.Process) { res := make([]*oa.ScheduleModel, 0) if req.OwnerStaffGuid == "" { return res, process.FailError(types.InvalidParamError, fmt.Errorf("ownerStaffGuid 必填")) } owner, err := unique.FromString(req.OwnerStaffGuid) if err != nil { return res, process.FailError(types.InvalidParamError, err) } from := time.Now() to := from.AddDate(0, 1, 0) if req.From != "" { if v, e := time.Parse(time.RFC3339, req.From); e == nil { from = v } } if req.To != "" { if v, e := time.Parse(time.RFC3339, req.To); e == nil { to = v } } if to.Before(from) { from, to = to, from } limit := req.Limit if limit <= 0 { limit = 20 } offset := req.Offset if offset < 0 { offset = 0 } db := dblib.DBIns.DB.Model(&oa.ScheduleModel{}). Where("OwnerStaffGuid = ? AND Status = 0 AND (RecordStatus & 524288) = 0", owner). Where("StartTime < ? AND EndTime > ?", to, from). Order("StartTime ASC"). Limit(limit).Offset(offset) r := db.Find(&res) if r.Error != nil { return res, process.FailError(types.QueryWorkflowError, r.Error) } return res, process.Success(200) }