package equipment import ( "database/sql" "errors" "fmt" "lims_adapter/common" "lims_adapter/dao/equipment" equipment2 "lims_adapter/model/equipment" "lims_adapter/model/user" "strconv" "strings" "time" "dashoo.cn/micro_libary/myerrors" "dashoo.cn/micro_libary/request" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" ) // Service 设备 type Service struct { Dao *equipment.BaseEquipmentQualificationDao Tenant string } // NewSrv 服务初始化 func NewSrv(tenant string) Service { return Service{Dao: equipment.NewBaseEquipmentQualificationDao(tenant), Tenant: tenant} } // AppointmentQualificationList 预约资格分页查询 func (s Service) AppointmentQualificationList(req *equipment2.QualificationListReq) ([]user.UserQualification, int, error) { var current = req.Current var size = req.Size var enabled = req.Enabled var instrumentId = req.InstrumentId var reqType = req.Type entity := s.Dao.DB.Model("base_user a") var userInfo []user.UserQualification where := "a.Enabled = " + strconv.Itoa(enabled) + " and b.EquipmentId = " + strconv.Itoa(instrumentId) if reqType == 1 { // 预约资格查询条件 where += " and (b.Qualification = 1 or b.Qualification = 2)" } else if reqType == 2 { // 优先预约权查询条件 where += " and b.Qualification = 3" } entity.LeftJoin("base_equipment_qualification b", "a.id = b.UserId"). Where(where) count, _ := entity.Count() err := entity.Fields("a.Id, a.UserName, a.RealName, a.Mobile, b.Qualification, b.AuthorizeTime"). Page(current, size).Scan(&userInfo) if err != nil { return nil, 0, err } return userInfo, count, nil } // AdvanceList 优先预约权资格列表查询 func (s Service) AdvanceList(req *equipment2.QualificationListReq) ([]user.UserQualification, int, error) { var current = req.Current var size = req.Size var enabled = req.Enabled var instrumentId = req.InstrumentId entity := s.Dao.DB.Model("base_user a") var userInfo []user.UserQualification entity.LeftJoin("base_equipment_qualification b", "a.id = b.UserId"). Where("a.Enabled = " + strconv.Itoa(enabled) + " and b.EquipmentId = " + strconv.Itoa(instrumentId)) count, _ := entity.Count() err := entity.Fields("a.Id, a.UserName, a.RealName, a.Mobile, b.AuthorizeTime"). Page(current, size).Scan(&userInfo) if err != nil { return nil, 0, err } return userInfo, count, nil } // AddOrUpdateQualification 新增、修改预约资格名单;新增优先预约权名单 func (s Service) AddOrUpdateQualification(req *equipment2.AddOrUpdateQualification, userInfo request.UserInfo) (err error) { entity := s.Dao.M var instrumentId = req.InstrumentId var ids = req.Ids var qualification = 1 if req.QualificationType == "normal" { qualification = 1 } else if req.QualificationType == "senior" { qualification = 2 } else if req.QualificationType == "advance" { qualification = 3 } //if qualification == 1 || qualification == 2 { // 预约资格 for _, v := range ids { where := "EquipmentId = " + strconv.Itoa(instrumentId) + " and UserId = " + strconv.Itoa(v) if qualification == 1 || qualification == 2 { // 预约资格 where += " and Qualification != 3" } else if qualification == 3 { // 优先预约权 // 先判断是否有预约资格,没有则不更新操作 count, _ := s.Dao.DB.Model("base_equipment_qualification").Where("EquipmentId = " + strconv.Itoa(instrumentId) + " and Qualification != 0" + " and UserId = " + strconv.Itoa(v)).Count() if count == 0 { continue } where += " and Qualification = 3" } var qualificationInfo equipment2.BaseEquipmentQualification entity.Where(where).Scan(&qualificationInfo) entity.Data(g.Map{"Id": qualificationInfo.Id, "EquipmentId": instrumentId, "UserId": v, "Qualification": qualification, "CreateOn": gtime.Now(), "AuthorizeTime": gtime.Now(), "CreateUserId": userInfo.Id, "CreateBy": userInfo.RealName}).Save() } //} else if qualification ==3 { // 优先预约权 // for _, v := range ids { // var qualificationInfo model.BaseEquipmentQualification // entity.Where("EquipmentId = " + strconv.Itoa(instrumentId) + " and UserId = " + // strconv.Itoa(v) ).Scan(&qualificationInfo) // entity.Data(g.Map{"Id": qualificationInfo.Id,"EquipmentId": instrumentId, "UserId": v, "CreateOn": gtime.Now(), // "AuthorizeTime": gtime.Now(), "CreateUserId": userInfo.Id, "CreateBy": userInfo.RealName}).Save() // } //} return err } // DeleteQualification 删除预约资格 func (s Service) DeleteQualification(req *equipment2.IdReq, info request.UserInfo) error { _, err := s.Dao.M.Update(g.Map{"Qualification": 0, "ModifiedOn": gtime.Now(), "ModifiedUserId": info.Id, "ModifiedBy": info.RealName}, "UserId = "+strconv.Itoa(req.UserId)+ " and EquipmentId = "+strconv.Itoa(req.EquipmentId)+" and Qualification != 3") if err != nil { return err } return nil } // DeleteAdvance 删除优先预约权人员 func (s Service) DeleteAdvance(req *equipment2.IdReq) error { _, err := s.Dao.M.Delete("UserId = " + strconv.Itoa(req.UserId) + " and EquipmentId = " + strconv.Itoa(req.EquipmentId) + " and Qualification = 3") if err != nil { return err } return nil } // SearchAdvanceTime 查看设备优先预约时间段 func (s Service) SearchAdvanceTime(req *equipment2.QualificationListReq) (advanceTime []equipment2.BaseEquipmentAdvanceTime, count int, err error) { entity := s.Dao.DB.Model("base_equipment_advance_time") err = entity.Where("EquipmentId = " + strconv.Itoa(req.InstrumentId)).Scan(&advanceTime) count, _ = entity.CountColumn("1") err = entity.Fields("Week, StartTime,EndTime").Order("Week").Page(req.Current, req.Size).Scan(&advanceTime) if err != nil { return advanceTime, count, err } return advanceTime, count, nil } // AddAdvanceTime 添加设备优先预约时间段 func (s Service) AddAdvanceTime(req *equipment2.AdvanceTimeReq, info request.UserInfo) error { //for _, v := range domains { // count, err := s.Dao.DB.Model("base_equipment_advance_time").Where("Week = '" + v.Week + // "' and StartTime = '" + v.StartTime + "' and EndTime = '" + v.EndTime + "'").Count() // if err != nil{ // return err // } // if count == 0 { // week, _ := strconv.Atoi(v.Week) // saveEntity := model.BaseEquipmentAdvanceTime{ // EquipmentId: equipmentId, // Week: week, // StartTime: v.StartTime, // EndTime: v.EndTime, // CreateOn: gtime.Now(), // CreateUserId: gconv.Int(info.Id), // CreateBy: info.RealName, // } // s.Dao.DB.Model("base_equipment_advance_time").Insert(saveEntity) // } //} count, err := s.Dao.DB.Model("base_equipment_advance_time").Where("EquipmentId = " + strconv.Itoa(req.EquipmentId) + " and Week = " + req.Week + " and StartTime = '" + req.StartTime + "' and EndTime = '" + req.EndTime + "'").Count() if err != nil { return err } if count > 0 { return errors.New("该时间段已存在,请重新输入!") } week, _ := strconv.Atoi(req.Week) saveEntity := equipment2.BaseEquipmentAdvanceTime{ EquipmentId: req.EquipmentId, Week: week, StartTime: req.StartTime, EndTime: req.EndTime, CreateOn: gtime.Now(), CreateUserId: gconv.Int(info.Id), CreateBy: info.RealName, } _, err = s.Dao.DB.Model("base_equipment_advance_time").Insert(saveEntity) if err != nil { return err } return nil } // DeleteAdvanceTime 删除设备预约时间段 func (s Service) DeleteAdvanceTime(id int) error { _, err := s.Dao.DB.Model("base_equipment_advance_time").Delete("Id = " + strconv.Itoa(id)) if err != nil { return err } return nil } // AppointmentTime 设备预约时间段 func (s Service) AppointmentTime(req *equipment2.IdReq) error { // 先查该人员的预约资格、优先使用权 var qualificationInfo []equipment2.BaseEquipmentQualification s.Dao.DB.Model("base_equipment_qualification").Where("EquipmentId = " + strconv.Itoa(req.EquipmentId)).Order("Qualification").Scan(&qualificationInfo) // 如果是普通预约资格,筛选出周末时间段 if qualificationInfo[0].Qualification == "1" { // TODO 时间获取 } // 如果有预约资格但没有优先使用权,查询优先使用权时间段 if len(qualificationInfo) == 2 && qualificationInfo[1].Qualification == "3" { var appointmentInfo []equipment2.BaseEquipmentAdvanceTime s.Dao.DB.Model("base_equipment_advance_time").Where("EquipmentId = " + strconv.Itoa(req.EquipmentId) + " and UserId").Scan(&appointmentInfo) } return nil } func (s Service) AppointTimeSplit() int { return g.Cfg().GetInt("appointment.time_split", 30) } type AppointTimeInfoAppoint struct { Id int `json:"id"` Start string `json:"start"` End string `json:"end"` Status int `json:"status"` Uid int `json:"uid"` Uname string `json:"uname"` Tel string `json:"tel"` Dept string `json:"dept"` } type AppointTimeInfoInstrument struct { Id int Weekday string BeginAt *gtime.Time EndAt *gtime.Time IsAppointAvailable int // 是否默认可预约 1是 2否 } type TimeSpan struct { Start *gtime.Time `json:"start"` End *gtime.Time `json:"end"` } // 获取指定仪器预约信息 func (s Service) AppointTimeInfo(req *equipment2.AppointTimeInfoReq, userinfo request.UserInfo) (map[string]interface{}, error) { if req.InstrumentId == 0 { return nil, myerrors.NewMsgError(nil, "仪器 Id 不能为空") } if req.Date == nil { return nil, myerrors.NewMsgError(nil, "日期不能为空") } timesplit := s.AppointTimeSplit() days := common.Weekday(req.Date.Time) var instr AppointTimeInfoInstrument err := s.Dao.DB.Table("instrument"). Where("Id", req.InstrumentId). Fields("Id, BeginAt, EndAt, Weekday, IsAppointAvailable"). Struct(&instr) if err != nil { return nil, err } disableExpired := g.Cfg().GetBool("appointment.disableExpired") appointStatus := g.Slice{1, 2} if disableExpired { // 需要包含超时未上机的预约 appointStatus = g.Slice{1, 2, 10} } var appointInfo []AppointTimeInfoAppoint err = s.Dao.DB.Table("appointment a").LeftJoin("base_user b", "a.UserId=b.Id").Unscoped(). Where("a.DeletedAt IS NULL"). Where("a.RelevanceId", req.InstrumentId). WherePri("a.Status", appointStatus). Where("a.EndTime > ?", days[0]). Where("a.EndTime <= ?", days[6].Add(time.Hour*24)). Fields("a.Id, a.StartTime as Start, a.EndTime as End, a.Status, a.UserId as Uid, b.Realname as Uname, b.Mobile as Tel, b.DepartmentName as Dept"). Structs(&appointInfo) if err == sql.ErrNoRows { err = nil } if err != nil { return nil, err } instrWeekStr := strings.Split(instr.Weekday, ",") instrWeek := []int{} for _, i := range instrWeekStr { d, err := strconv.Atoi(i) if err != nil { continue } instrWeek = append(instrWeek, d) } toRemoveDay := []int{} for i := 1; i <= 7; i++ { if !common.SliceIntcontains(instrWeek, i) { toRemoveDay = append(toRemoveDay, i) } } // 普通资格不可以预约周六周日的时间 if instr.IsAppointAvailable != 1 { count, err := s.Dao.DB.Model("base_equipment_qualification"). Where("EquipmentId = ?", req.InstrumentId). Where("UserId = ?", userinfo.Id). Where("Qualification = 1").Count() if err != nil { return nil, err } if count != 0 { if !common.SliceIntcontains(toRemoveDay, 6) { toRemoveDay = append(toRemoveDay, 6) } if !common.SliceIntcontains(toRemoveDay, 7) { toRemoveDay = append(toRemoveDay, 7) } } } // 优先预约权 advanceTimeList := []equipment2.BaseEquipmentAdvanceTime{} qualificationCount, err := s.Dao.DB.Model("base_equipment_qualification"). Where("EquipmentId = ?", req.InstrumentId). Where("UserId = ?", userinfo.Id). Where("Qualification = 3").Count() if err != nil { return nil, err } if qualificationCount == 0 { err := s.Dao.DB.Model("base_equipment_advance_time"). Where("EquipmentId = ?", req.InstrumentId). Structs(&advanceTimeList) if err == sql.ErrNoRows { err = nil } if err != nil { return nil, err } } unavailable := []TimeSpan{} // 仪器设置的可预约范围外 for i, d := range days { if common.SliceIntcontains(toRemoveDay, i+1) { unavailable = append(unavailable, TimeSpan{ Start: gtime.NewFromTime(d), End: gtime.NewFromTime(d.Add(24 * time.Hour)), }) continue } if instr.BeginAt.Hour() != 0 || instr.BeginAt.Minute() != 0 { end := d.Add( time.Hour*time.Duration(instr.BeginAt.Hour()) + time.Minute*time.Duration(instr.BeginAt.Minute())) unavailable = append(unavailable, TimeSpan{ Start: gtime.NewFromTime(d), End: gtime.NewFromTime(end), }) } endat := instr.EndAt.Add(time.Minute * time.Duration(timesplit)) if endat.Hour() != 0 || endat.Minute() != 0 { start := d.Add( time.Hour*time.Duration(endat.Hour()) + time.Minute*time.Duration(endat.Minute())) unavailable = append(unavailable, TimeSpan{ Start: gtime.NewFromTime(start), End: gtime.NewFromTime(d.Add(time.Hour * 24)), }) } } // 优先预约时间段 for _, i := range advanceTimeList { if i.Week == 0 { continue } startTime, err := time.Parse("15:04", i.StartTime) if err != nil { continue } endTime, err := time.Parse("15:04", i.EndTime) if err != nil { continue } d := days[i.Week-1] start := d.Add( time.Hour*time.Duration(startTime.Hour()) + time.Minute*time.Duration(startTime.Minute())) end := d.Add( time.Hour*time.Duration(endTime.Hour()) + time.Minute*time.Duration(endTime.Minute())) unavailable = append(unavailable, TimeSpan{ Start: gtime.NewFromTime(start), End: gtime.NewFromTime(end), }) } return map[string]interface{}{ "time_split": timesplit, "begin_at": instr.BeginAt.Time.Format("15:04:05"), "ent_at": instr.EndAt.Time.Format("15:04:05"), "unavailable": unavailable, "appoint": appointInfo, }, nil } // 默认可预约: 否表示只有加入预约资格设置可以预约,是表示预约资格设置失效,都可以预约 // 普通资格不可以预约周六周日的时间,资深资格无限制 // 优先预约权设置: 优先预约时段内只有添加到优先预约人员的用户才能预约 // SearchNoAppointment 查看不能预约时间段信息 func (s Service) SearchNoAppointment(req *equipment2.IdReq, info request.UserInfo) ([]equipment2.NoReservationInfo, error) { // 普通资格限制周末时间 var qualificationInfo []equipment2.BaseEquipmentQualification var noAppointmentInfos []equipment2.NoReservationInfo // 查询设备可预约时间段 和是否开启了默认可预约 var equipmentInfo equipment2.Instrument s.Dao.DB.Model("instrument").Fields("IsAppointAvailable,BeginAt, EndAt"). Where("Id = " + strconv.Itoa(req.EquipmentId)).Scan(&equipmentInfo) s.Dao.DB.Model("base_equipment_qualification").Where("EquipmentId = " + strconv.Itoa(req.EquipmentId) + " and UserId = " + strconv.Itoa(gconv.Int(info.Id))).Order("Qualification").Scan(&qualificationInfo) if len(qualificationInfo) >= 1 && qualificationInfo[0].Qualification == "1" && equipmentInfo.IsAppointAvailable != 1 { // 只有普通预约资格,限制周末预约时间段// 如果没有开启默认可预约 则进行时间段限制 startTime := equipmentInfo.BeginAt endTime := equipmentInfo.EndAt // 设备当天预约时间总长度h timeLong := endTime.Sub(startTime).Hours() saturdayTime := noReservationInfo(startTime, timeLong, req.Date, 6) sundayTime := noReservationInfo(startTime, timeLong, req.Date, 7) noAppointmentInfos = append(saturdayTime, sundayTime...) } if len(qualificationInfo) == 1 && qualificationInfo[0].Qualification != "3" { // 没有优先预约权,限制优先预约时间段 var advanceTimeList []equipment2.BaseEquipmentAdvanceTime s.Dao.DB.Model("base_equipment_advance_time"). Where("EquipmentId = " + strconv.Itoa(req.EquipmentId)).Scan(&advanceTimeList) for _, v := range advanceTimeList { // TODO 遍历获取不能预约时间段 startTime, _ := gtime.StrToTime(strings.Trim(v.StartTime, " "), "H:i") endTime, _ := gtime.StrToTime(strings.Trim(v.EndTime, " "), "H:i") timeLong := endTime.Sub(startTime).Hours() saturdayTime := noReservationInfo(startTime, timeLong, req.Date, v.Week) noAppointmentInfos = append(noAppointmentInfos, saturdayTime...) } } return noAppointmentInfos, nil } // ChangeInstrStauts 修改设备所属 func (s Service) ChangeBelongs(req *equipment2.IdReq) error { _, err := s.Dao.DB.Model("Instrument"). Update("Belongs = "+req.Belongs, "Id = "+strconv.Itoa(req.EquipmentId)) if err != nil { return err } return nil } // GetUnitCount 查询设备计费 func (s Service) GetUnitCount(instrumentId int) (rspInfo []equipment2.Instrument, err error) { err = s.Dao.DB.Model("Instrument").Where("Id = ?", instrumentId).Scan(&rspInfo) if err != nil { return rspInfo, err } return rspInfo, nil } // UpdateUnifPrice 更新计费价格 func (s Service) UpdateUnitPrice(instrumentId int, unitCount float64) error { _, err := s.Dao.DB.Model("Instrument").Update(fmt.Sprintf("unitCount=%v", unitCount), "Id = "+ strconv.Itoa(instrumentId)) if err != nil { return err } return nil } // RateChange 优惠比例更新 func (s Service) RateChange(InstrumentId, rate int) error { _, err := s.Dao.DB.Model("Instrument").Update("Rate = "+strconv.Itoa(rate), "Id = "+ strconv.Itoa(InstrumentId)) if err != nil { return err } return nil } // IsAdvance 是否有优先预约资格 func (s Service) IsAdvance(id int32, instrumentId int) (isAdvance int, err error) { equipmentQualification := equipment2.BaseEquipmentQualification{} err = s.Dao.DB.Model("base_equipment_qualification").Where("UserId", id). Where("Qualification", "3").Where("EquipmentId", instrumentId).Scan(&equipmentQualification) if err == sql.ErrNoRows { return 0, nil } return 1, nil } // noReservationInfo 不可预约时间段处理 startTime开始时间 timeLong 时间间隔 Date 前端传入日期 week 星期几 func noReservationInfo(startTime *gtime.Time, timeLong float64, Date string, week int) (noAppointmentInfo []equipment2.NoReservationInfo) { date, _ := gtime.StrToTime(Date, "Y-m-d") // 获取当前星期对应的日期 day := GetDate(date, week) grids := int(timeLong*2) + 1 for i := 0; i < grids; i++ { // 开始时间 start_time := startTime.Add(time.Duration(i) * 30 * time.Minute) //fmt.Println("day:", day, "week:", week, "start_time", fmt.Sprintf("%02d", start_time.Hour()) + ":"+fmt.Sprintf("%02d", start_time.Minute()), "status:", status) noAppointmentInfo = append(noAppointmentInfo, equipment2.NoReservationInfo{ Day: day, Week: week, StartTime: fmt.Sprintf("%02d", start_time.Hour()) + ":" + fmt.Sprintf("%02d", start_time.Minute()), Status: 3, }) } return noAppointmentInfo } // 获取当前星期对应的日期 func GetDate(Date *gtime.Time, week int) int { weekday := Date.Weekday().String() var targetDay *gtime.Time switch weekday { case "Monday": targetDay = Date.AddDate(0, 0, week-1) case "Tuesday": targetDay = Date.AddDate(0, 0, week-2) case "Wednesday": targetDay = Date.AddDate(0, 0, week-3) case "Thursday": targetDay = Date.AddDate(0, 0, week-4) case "Friday": targetDay = Date.AddDate(0, 0, week-5) case "Saturday": targetDay = Date.AddDate(0, 0, week-6) case "Sunday": targetDay = Date.AddDate(0, 0, week-7) } _, _, day := targetDay.Date() return day }