reservation.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. package reservation
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "lims_adapter/common"
  8. meeting2 "lims_adapter/dao/meeting"
  9. "lims_adapter/model"
  10. meeting3 "lims_adapter/model/meeting"
  11. "lims_adapter/service"
  12. "lims_adapter/service/meeting"
  13. "lims_adapter/service/srv"
  14. "strconv"
  15. "strings"
  16. "time"
  17. "dashoo.cn/common_definition/admin/user_def"
  18. "dashoo.cn/micro_libary/micro_srv"
  19. "dashoo.cn/micro_libary/myerrors"
  20. "dashoo.cn/micro_libary/request"
  21. "github.com/gogf/gf/frame/g"
  22. "github.com/gogf/gf/os/gtime"
  23. "github.com/gogf/gf/util/gconv"
  24. )
  25. // Service ReservationService 预约
  26. type Service struct {
  27. Dao *meeting2.MeetingReservationDao
  28. Tenant string
  29. }
  30. // NewSrv 服务初始化
  31. func NewSrv(tenant string) Service {
  32. return Service{Dao: meeting2.NewMeetingReservationDao(tenant), Tenant: tenant}
  33. }
  34. // List 预约列表
  35. func (s Service) List(req model.ListReq) ([]meeting3.List, int, error) {
  36. entityModel := s.Dao.M
  37. if req.Entity != nil {
  38. entity := new(meeting3.ReservationReq)
  39. gconv.Struct(req.Entity, entity)
  40. tableSql := s.Dao.Table + "."
  41. if entity.Title != "" {
  42. entityModel = entityModel.WhereLike(tableSql+s.Dao.Columns.Title, "%"+entity.Title+"%")
  43. }
  44. if entity.EntityId != 0 {
  45. entityModel = entityModel.Where(tableSql+s.Dao.Columns.EntityId, entity.EntityId)
  46. }
  47. if entity.UserName != "" {
  48. entityModel = entityModel.WhereLike(tableSql+s.Dao.Columns.UserName, "%"+entity.UserName+"%")
  49. }
  50. // 预约状态(1:预定 2:取消)
  51. if entity.Status != 0 {
  52. entityModel = entityModel.Where(tableSql+s.Dao.Columns.Status, entity.Status)
  53. }
  54. // 预约时间
  55. if len(entity.TimeSplit) == 2 {
  56. entityModel = entityModel.WhereBetween(tableSql+s.Dao.Columns.StartTime, entity.TimeSplit[0], entity.TimeSplit[1])
  57. }
  58. }
  59. total, err := entityModel.Count()
  60. if err != nil {
  61. return nil, 0, err
  62. }
  63. if total == 0 {
  64. return nil, 0, nil
  65. }
  66. if req.Value != "" {
  67. entityModel = entityModel.Order(s.Dao.Table+"."+common.Snake2Orm(meeting3.MeetingReservation{}, req.Value), req.Type)
  68. } else {
  69. entityModel = entityModel.Order(s.Dao.Table+"."+s.Dao.Columns.CreatedAt, "DESC")
  70. }
  71. res, err := entityModel.Page(req.Current, req.Size).
  72. Fields("meeting_reservation.*", "meeting.Name", "base_user.DepartmentName").
  73. LeftJoin("meeting", "meeting.Id = meeting_reservation.EntityId").
  74. LeftJoin("base_user", "base_user.Id = meeting_reservation.UserId").
  75. FindAll()
  76. if err != nil {
  77. return nil, 0, err
  78. }
  79. if res.IsEmpty() {
  80. return nil, 0, nil
  81. }
  82. list := make([]meeting3.List, 0)
  83. res.Structs(&list)
  84. return list, total, nil
  85. }
  86. // Add 添加预约
  87. func (s Service) Add(userInfo request.UserInfo, req meeting3.ReservationReq) error {
  88. entity := new(meeting3.MeetingReservation)
  89. err := s.check(req)
  90. if err != nil {
  91. return err
  92. }
  93. gconv.Struct(req, entity)
  94. service.SetCreate(&userInfo, entity)
  95. entity.UserName = userInfo.RealName
  96. entity.UserId = int(userInfo.Id)
  97. entity.DepartmentId = gconv.Int(userInfo.DeptId)
  98. entity.RealEndTimeNode = req.EndTime
  99. res, err := s.Dao.M.Insert(entity)
  100. if err != nil {
  101. return err
  102. }
  103. id, _ := res.LastInsertId()
  104. // 延迟消息
  105. go AutoProcess(int(id), s.Tenant, req.EndTime.Sub(gtime.Now()))
  106. return nil
  107. }
  108. const PermissionCancelAnyMeetingReservation = "meeting:cancel:any"
  109. // Cancel 取消预约 预约状态(1:预定 2:取消)
  110. func (s Service) Cancel(userInfo request.UserInfo, id int) error {
  111. // 判断当前用户是否是预约人
  112. entity, err := s.Dao.WherePri(id).FindOne()
  113. if err != nil {
  114. return err
  115. }
  116. if entity == nil {
  117. return errors.New("未找到当前预约信息,请重试")
  118. }
  119. allow, err := common.Allow(s.Tenant, userInfo.Uuid, PermissionCancelAnyMeetingReservation)
  120. if err != nil {
  121. return err
  122. }
  123. if allow {
  124. updatedMap := service.SetUpdatedMap(&userInfo)
  125. updatedMap["Status"] = 2
  126. _, err = s.Dao.M.Data(updatedMap).WherePri(id).Update()
  127. if err != nil {
  128. return err
  129. }
  130. return nil
  131. }
  132. if int32(entity.UserId) != userInfo.Id {
  133. return errors.New("当前预约只能由预约人取消")
  134. }
  135. if entity.StartTime.Sub(gtime.Now()) <= 0 {
  136. return errors.New("预约开始不允许取消")
  137. }
  138. updatedMap := service.SetUpdatedMap(&userInfo)
  139. updatedMap["Status"] = 2
  140. _, err = s.Dao.M.Data(updatedMap).WherePri(id).Update()
  141. if err != nil {
  142. return err
  143. }
  144. return nil
  145. }
  146. // OverviewList 预约概况
  147. func (s Service) OverviewList(req meeting3.OverviewReq) (g.Map, error) {
  148. dates := getCurrentWeekDay(req.Date)
  149. meetingList, err := meeting.NewSrv(s.Tenant).ShortList()
  150. if err != nil {
  151. return nil, err
  152. }
  153. reservationList, err := s.shortList(req.Date)
  154. if err != nil {
  155. return nil, err
  156. }
  157. return g.Map{
  158. "dates": dates,
  159. "meeting": meetingList,
  160. "reservation": reservationList,
  161. }, nil
  162. }
  163. func (s Service) AppointTimeSplit() int {
  164. return g.Cfg().GetInt("reservation.time_split", 30)
  165. }
  166. type AppointTimeInfoAppoint struct {
  167. Id int `json:"id"`
  168. Title string `json:"title"`
  169. Start string `json:"start"`
  170. End string `json:"end"`
  171. Status int `json:"status"`
  172. Uid int `json:"uid"`
  173. Uname string `json:"uname"`
  174. Tel string `json:"tel"`
  175. Dept string `json:"dept"`
  176. }
  177. type AppointTimeInfoInstrument struct {
  178. Id int
  179. Weekday string
  180. BeginAt *gtime.Time
  181. EndAt *gtime.Time
  182. IsAppointAvailable int // 是否默认可预约 1是 2否
  183. }
  184. type TimeSpan struct {
  185. Start *gtime.Time `json:"start"`
  186. End *gtime.Time `json:"end"`
  187. }
  188. // 获取指定仪器预约信息
  189. func (s Service) AppointTimeInfo(req *meeting3.AppointTimeInfoReq, userinfo request.UserInfo) (map[string]interface{}, error) {
  190. if req.MeetingId == 0 {
  191. return nil, myerrors.NewMsgError(nil, "会议室 Id 不能为空")
  192. }
  193. if req.Date == nil {
  194. return nil, myerrors.NewMsgError(nil, "日期不能为空")
  195. }
  196. timesplit := s.AppointTimeSplit()
  197. days := common.Weekday(req.Date.Time)
  198. mettingSrv := meeting.NewSrv(s.Tenant)
  199. m, err := mettingSrv.Dao.Where("Id = ?", req.MeetingId).One()
  200. if err != nil {
  201. return nil, err
  202. }
  203. var appointInfo []AppointTimeInfoAppoint
  204. err = s.Dao.DB.Table("meeting_reservation a").LeftJoin("base_user b", "a.UserId=b.Id").Unscoped().
  205. Where("a.DeletedAt IS NULL").
  206. Where("a.EntityId", req.MeetingId).
  207. WherePri("a.Status", 1).
  208. Where("a.EndTime > ?", days[0]).
  209. Where("a.EndTime <= ?", days[6].Add(time.Hour*24)).
  210. Fields("a.Id, a.Title, 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").
  211. Structs(&appointInfo)
  212. if err == sql.ErrNoRows {
  213. err = nil
  214. }
  215. if err != nil {
  216. return nil, err
  217. }
  218. reservationBeginStr := g.Cfg().GetString("reservation.begin", 30)
  219. reservationEndStr := g.Cfg().GetString("reservation.end", 30)
  220. reservationWeekdayStr := g.Cfg().GetString("reservation.weekday", 30)
  221. instrWeekStr := strings.Split(reservationWeekdayStr, ",")
  222. instrWeek := []int{}
  223. for _, i := range instrWeekStr {
  224. d, err := strconv.Atoi(i)
  225. if err != nil {
  226. continue
  227. }
  228. instrWeek = append(instrWeek, d)
  229. }
  230. toRemoveDay := []int{}
  231. for i := 1; i <= 7; i++ {
  232. if !common.SliceIntcontains(instrWeek, i) {
  233. toRemoveDay = append(toRemoveDay, i)
  234. }
  235. }
  236. reservationBegin, err := time.Parse("15:04:05", reservationBeginStr)
  237. if err != nil {
  238. return nil, err
  239. }
  240. reservationEnd, err := time.Parse("15:04:05", reservationEndStr)
  241. if err != nil {
  242. return nil, err
  243. }
  244. if m.BeginAt == nil {
  245. m.BeginAt = gtime.NewFromTime(reservationBegin)
  246. }
  247. if m.EndAt == nil {
  248. m.EndAt = gtime.NewFromTime(reservationEnd)
  249. }
  250. unavailable := []TimeSpan{}
  251. // 仪器设置的可预约范围外
  252. for i, d := range days {
  253. if common.SliceIntcontains(toRemoveDay, i+1) {
  254. unavailable = append(unavailable, TimeSpan{
  255. Start: gtime.NewFromTime(d),
  256. End: gtime.NewFromTime(d.Add(24 * time.Hour)),
  257. })
  258. continue
  259. }
  260. if m.BeginAt.Hour() != 0 || m.BeginAt.Minute() != 0 {
  261. end := d.Add(
  262. time.Hour*time.Duration(m.BeginAt.Hour()) +
  263. time.Minute*time.Duration(m.BeginAt.Minute()))
  264. unavailable = append(unavailable, TimeSpan{
  265. Start: gtime.NewFromTime(d),
  266. End: gtime.NewFromTime(end),
  267. })
  268. }
  269. endat := m.EndAt.Add(time.Minute * time.Duration(timesplit))
  270. if endat.Hour() != 0 || endat.Minute() != 0 {
  271. start := d.Add(
  272. time.Hour*time.Duration(endat.Hour()) +
  273. time.Minute*time.Duration(endat.Minute()))
  274. unavailable = append(unavailable, TimeSpan{
  275. Start: gtime.NewFromTime(start),
  276. End: gtime.NewFromTime(d.Add(time.Hour * 24)),
  277. })
  278. }
  279. }
  280. return map[string]interface{}{
  281. "time_split": timesplit,
  282. "unavailable": unavailable,
  283. "appoint": appointInfo,
  284. }, nil
  285. }
  286. // OverviewListByDay 按天预约概况
  287. func (s Service) OverviewListByDay(ctx context.Context, req meeting3.OverviewReq) (g.Map, error) {
  288. beginAt := g.Cfg().GetString("reservation.begin")
  289. endAt := g.Cfg().GetString("reservation.end")
  290. defaultPeriod := s.getCurrentPeriod(beginAt, endAt)
  291. dates := getCurrentWeekDay(req.Date)
  292. meetingList, err := meeting.NewSrv(s.Tenant).ShortList()
  293. if err != nil {
  294. return nil, err
  295. }
  296. reservationList, err := s.getCurrentDayReservation(ctx, meetingList, req.Date)
  297. if err != nil {
  298. return nil, err
  299. }
  300. // for i := range meetingList {
  301. // begin, end := beginAt, endAt
  302. // if meetingList[i].BeginAt != nil && meetingList[i].EndAt != nil {
  303. // begin = meetingList[i].BeginAt.Time.Format("15:04:05")
  304. // end = meetingList[i].EndAt.Time.Format("15:04:05")
  305. // }
  306. // fmt.Println(meetingList[i].Id, meetingList[i].Name)
  307. // period := s.getCurrentPeriod(begin, end)
  308. // meetingList[i].Period = period
  309. // }
  310. return g.Map{
  311. "period": defaultPeriod,
  312. "dates": dates,
  313. "meeting": meetingList,
  314. "reservation": reservationList,
  315. }, nil
  316. }
  317. // ReserveInfo 预约信息
  318. func (s Service) ReserveInfo(ctx context.Context, req meeting3.ReserveReq) (g.Map, error) {
  319. // 常规信息
  320. beginAt := g.Cfg().GetString("reservation.begin_at")
  321. endAt := g.Cfg().GetString("reservation.end_at")
  322. period := s.getCurrentPeriod(beginAt, endAt)
  323. dates := getCurrentWeekDay(req.Date)
  324. weekday := g.Cfg().GetString("reservation.weekday")
  325. // 预约信息
  326. list, err := s.getCurrentWeekReservation(ctx, req)
  327. if err != nil {
  328. return nil, err
  329. }
  330. return g.Map{
  331. "period": period,
  332. "dates": dates,
  333. "weekday": weekday,
  334. "reservation": list,
  335. }, nil
  336. }
  337. // Ending 结束会议
  338. func (s Service) Ending(ctx context.Context, req meeting3.EndingReq) error {
  339. // 先查询预约记录
  340. entity, err := s.Dao.WherePri(req.Id).FindOne()
  341. if err != nil {
  342. return err
  343. }
  344. if entity == nil {
  345. return errors.New("未找到当前预约信息")
  346. }
  347. if entity.SignOutTime.String() != "" {
  348. return errors.New("当前预约已提前结束")
  349. }
  350. // 校验日期是不是同一天(24:00除外) 校验日期是不是在预约开始时间之后
  351. if req.Date.Sub(entity.StartTime) <= 0 {
  352. return errors.New("结束时间不能早于会议预约时间")
  353. }
  354. if req.Date.Format("Y-m-d") != entity.StartTime.Format("Y-m-d") &&
  355. req.Date.Hour() != 0 && req.Date.Minute() != 0 {
  356. return errors.New("结束时间必须为当天时间")
  357. }
  358. if (req.Date.Day()-1) != entity.StartTime.Day() && req.Date.Hour() == 0 && req.Date.Minute() == 0 {
  359. return errors.New("当前结束时间错误,请重试")
  360. }
  361. if req.Date.Sub(entity.EndTime) > 0 {
  362. return errors.New("预约时间正常结束的会议无需再次结束")
  363. }
  364. userInfo, err := micro_srv.GetUserInfo(ctx)
  365. if err != nil {
  366. return err
  367. }
  368. if userInfo.Id != int32(entity.UserId) {
  369. return errors.New("当前预约只能由本人结束")
  370. }
  371. // 更新实际结束时间
  372. updatedMap := service.SetUpdatedMap(&userInfo)
  373. updatedMap[s.Dao.Columns.SignOutTime] = req.Date
  374. updatedMap[s.Dao.Columns.RealEndTimeNode] = common.GetNextTimeNode(req.Date)
  375. _, err = s.Dao.M.WherePri(req.Id).Update(updatedMap)
  376. if err != nil {
  377. return err
  378. }
  379. return nil
  380. }
  381. func (s Service) AutoEnding(id int) error {
  382. entity, err := s.Dao.WherePri(id).FindOne()
  383. if err != nil {
  384. return err
  385. }
  386. if entity == nil {
  387. return nil
  388. }
  389. if entity.SignOutTime != nil && entity.SignOutTime.String() != "" {
  390. return nil
  391. }
  392. _, err = s.Dao.WherePri(id).Update(g.Map{s.Dao.Columns.SignOutTime: entity.EndTime})
  393. if err != nil {
  394. return err
  395. }
  396. return nil
  397. }
  398. // Check 预约校验
  399. func (s Service) check(req meeting3.ReservationReq) error {
  400. // 校验开始结束时间不能跨天
  401. if req.StartTime.Format("Y-m-d") != req.EndTime.Format("Y-m-d") &&
  402. req.EndTime.Hour() != 0 && req.EndTime.Minute() != 0 {
  403. return errors.New("预约时间必须是同一天")
  404. }
  405. // 校验开始时间是否小于结束时间
  406. if req.EndTime.Sub(req.StartTime) <= 0 {
  407. return errors.New("预约结束时候必须大于开始时间")
  408. }
  409. // 时间间隔不能小于30分钟 todo:可以加到配置参数中
  410. if req.EndTime.Sub(req.StartTime).Minutes() < 30 {
  411. return errors.New("预约时间最小为30分钟")
  412. }
  413. // 校验是否是过期时间
  414. if req.StartTime.Sub(gtime.Now()) < 0 {
  415. return errors.New("当前预约时间已过期")
  416. }
  417. // 校验时间内是否有 预约
  418. entityModel := s.Dao.M.
  419. Where(s.Dao.Columns.EntityId, req.EntityId).
  420. Where(s.Dao.Columns.Status, 1).
  421. Where(s.Dao.Columns.StartTime+">= ? AND "+s.Dao.Columns.StartTime+"< ?", req.StartTime, req.EndTime)
  422. entityModel = entityModel.
  423. WhereOr(s.Dao.Columns.EntityId+"= ? AND "+s.Dao.Columns.Status+" = 1 AND "+
  424. s.Dao.Columns.RealEndTimeNode+"> ? AND "+s.Dao.Columns.RealEndTimeNode+"<= ?",
  425. req.EntityId, req.StartTime, req.EndTime)
  426. entityModel = entityModel.
  427. WhereOr(s.Dao.Columns.EntityId+"= ? AND "+s.Dao.Columns.Status+" = 1 AND "+
  428. s.Dao.Columns.RealEndTimeNode+">= ? AND "+s.Dao.Columns.StartTime+"<= ?",
  429. req.EntityId, req.EndTime, req.StartTime)
  430. exist, err := entityModel.Count()
  431. if err != nil {
  432. return err
  433. }
  434. if exist > 0 {
  435. return errors.New("当前时间段内已有预约记录,请刷新后重试")
  436. }
  437. // 校验会议室是否存在
  438. err = meeting.NewSrv(s.Tenant).Exists(req.EntityId)
  439. if err != nil {
  440. return err
  441. }
  442. return nil
  443. }
  444. // getCurrentWeekDay 返回当前日期的周信息
  445. func getCurrentWeekDay(current *gtime.Time) []meeting3.CurrentDate {
  446. startOfWeek := common.GetCNStartOfWeek(current)
  447. dates := make([]meeting3.CurrentDate, 0)
  448. for i := 0; i <= 6; i++ {
  449. times := startOfWeek.AddDate(0, 0, 1*i)
  450. dates = append(dates, meeting3.CurrentDate{
  451. Date: times.Format("Y-m-d"),
  452. Day: times.Day(),
  453. })
  454. }
  455. return dates
  456. }
  457. func (s Service) shortList(date *gtime.Time) ([]meeting3.ShortList, error) {
  458. sTime := common.GetCNStartOfWeek(date)
  459. eTime := common.GetCNEndOfWeek(date)
  460. list := make([]meeting3.ShortList, 0)
  461. res, err := s.Dao.M.WhereBetween(s.Dao.Columns.StartTime, sTime, eTime).
  462. Where(s.Dao.Columns.Status, 1).FindAll()
  463. if err != nil {
  464. return nil, err
  465. }
  466. if res.IsEmpty() {
  467. return nil, nil
  468. }
  469. res.Structs(&list)
  470. for k, _ := range list {
  471. // 当签退时间小于预约结束时间,使用签退时间
  472. if list[k].SignOutTime.String() != "" && list[k].EndTime.Sub(list[k].SignOutTime) > 0 {
  473. list[k].EndTime = common.GetNextTimeNode(list[k].SignOutTime)
  474. }
  475. }
  476. return list, nil
  477. }
  478. // getCurrentDayTimeQuantum 获取当前的时间段
  479. func (s Service) getCurrentPeriod(entityBeginAt, entityEndAt string) [][]string {
  480. now := gtime.Now()
  481. startTime, _ := gtime.StrToTime(entityBeginAt)
  482. //endTime, _ := gtime.StrToTime(entityEndAt)
  483. startAtStr := fmt.Sprintf("%v-%.2v-%.2v %.2v:%.2v:%.2v",
  484. now.Year(), int(now.Month()), now.Day(),
  485. startTime.Hour(), startTime.Minute(), startTime.Second())
  486. startAt, _ := gtime.StrToTime(startAtStr)
  487. endAtStr := fmt.Sprintf("%v-%.2v-%.2v %s",
  488. now.Year(), int(now.Month()), now.Day(), entityEndAt)
  489. endAt, _ := gtime.StrToTime(endAtStr)
  490. timeLong := endAt.Sub(startAt).Hours()
  491. grids := int(timeLong * 2)
  492. fmt.Println(startAt, endAt)
  493. var timeQuantum [][]string
  494. for i := 0; i < grids; i++ {
  495. times := make([]string, 0)
  496. timeSplit := g.Cfg().GetInt("reservation.time_split")
  497. // 开始时间
  498. startAt := startAt.Add(time.Duration(i*timeSplit) * time.Minute)
  499. startTime := startAt.Format("H:i")
  500. // 结束时间
  501. endAt := startAt.Add(time.Duration(timeSplit) * time.Minute).Format("H:i")
  502. if startAt.Hour() == 23 && startAt.Minute() == 30 {
  503. endAt = "24:00"
  504. }
  505. times = append(times, startTime, endAt)
  506. timeQuantum = append(timeQuantum, times)
  507. }
  508. return timeQuantum
  509. }
  510. // getCurrentWeekReservation 返回本周预约信息
  511. func (s Service) getCurrentWeekReservation(ctx context.Context, req meeting3.ReserveReq) ([]meeting3.ReservationList, error) {
  512. // 获取符合条件的预约信息
  513. list, err := s.Dao.Where(s.Dao.Columns.EntityId, req.EntityId).
  514. Where(s.Dao.Columns.Status, 1).
  515. Where(s.Dao.Columns.StartTime+">=", common.GetCNStartOfWeek(req.Date)).
  516. Where(s.Dao.Columns.StartTime+"<=", common.GetCNEndOfWeek(req.Date)).
  517. FindAll()
  518. if err != nil {
  519. return nil, err
  520. }
  521. if len(list) == 0 {
  522. return nil, nil
  523. }
  524. uIds := make([]int64, 0)
  525. uMap := make(map[int]struct{})
  526. for _, v := range list {
  527. if _, ok := uMap[v.UserId]; !ok {
  528. uIds = append(uIds, int64(v.UserId))
  529. uMap[v.UserId] = struct{}{}
  530. }
  531. }
  532. // 获取用户信息
  533. userList, err := srv.GetUserList(ctx, uIds, s.Tenant)
  534. usersMap := make(map[int]user_def.UserInfoList)
  535. for _, v := range userList {
  536. usersMap[v.Id] = v
  537. }
  538. resultList := make([]meeting3.ReservationList, 0)
  539. for _, v := range list {
  540. timeLong := v.EndTime.Sub(v.StartTime).Hours()
  541. if v.SignOutTime.String() != "" && v.EndTime.Sub(v.SignOutTime) > 0 {
  542. timeLong = common.GetNextTimeNode(v.SignOutTime).Sub(v.StartTime).Hours()
  543. }
  544. grid := timeLong * 2
  545. for i := 0; i < int(grid); i++ {
  546. startAt := v.StartTime.Add(time.Duration(i) * 30 * time.Minute)
  547. resultList = append(resultList, meeting3.ReservationList{
  548. ReservationId: int(v.Id),
  549. Day: v.StartTime.Day(),
  550. Dept: usersMap[v.UserId].DepartmentName,
  551. StartTime: fmt.Sprintf("%.2v:%.2v", startAt.Hour(), startAt.Minute()),
  552. Tel: usersMap[v.UserId].Mobile,
  553. Uid: v.UserId,
  554. Uname: usersMap[v.UserId].Realname,
  555. Week: common.GetCNWeekday(v.StartTime),
  556. })
  557. }
  558. }
  559. return resultList, nil
  560. }
  561. // getCurrentWeekReservation 返回本周预约信息
  562. func (s Service) getCurrentDayReservation(ctx context.Context, meetingList []meeting3.ShortMeeting, reqDate *gtime.Time) ([]meeting3.ReservationList, error) {
  563. // 获取符合条件的预约信息
  564. resultList := make([]meeting3.ReservationList, 0)
  565. for _, value := range meetingList {
  566. list, err := s.Dao.Where(s.Dao.Columns.EntityId, value.Id).
  567. Where(s.Dao.Columns.Status, 1).
  568. Where(s.Dao.Columns.StartTime+">=", reqDate).
  569. Where(s.Dao.Columns.EndTime+"<=", reqDate.AddDate(0, 0, 1)).
  570. FindAll()
  571. if err != nil {
  572. g.Log().Info("getCurrentDayReservation err:", err)
  573. return nil, err
  574. }
  575. if len(list) == 0 {
  576. continue
  577. }
  578. uIds := make([]int64, 0)
  579. uMap := make(map[int]struct{})
  580. for _, v := range list {
  581. if _, ok := uMap[v.UserId]; !ok {
  582. uIds = append(uIds, int64(v.UserId))
  583. uMap[v.UserId] = struct{}{}
  584. }
  585. }
  586. // 获取用户信息
  587. userList, err := srv.GetUserList(ctx, uIds, s.Tenant)
  588. usersMap := make(map[int]user_def.UserInfoList)
  589. for _, v := range userList {
  590. usersMap[v.Id] = v
  591. }
  592. for _, v := range list {
  593. timeLong := v.EndTime.Sub(v.StartTime).Hours()
  594. if v.SignOutTime.String() != "" && v.EndTime.Sub(v.SignOutTime) > 0 {
  595. timeLong = common.GetNextTimeNode(v.SignOutTime).Sub(v.StartTime).Hours()
  596. }
  597. grid := timeLong * 2
  598. for i := 0; i < int(grid); i++ {
  599. startAt := v.StartTime.Add(time.Duration(i) * 30 * time.Minute)
  600. resultList = append(resultList, meeting3.ReservationList{
  601. EntityId: value.Id,
  602. ReservationId: int(v.Id),
  603. Title: v.Title,
  604. Day: v.StartTime.Day(),
  605. Dept: usersMap[v.UserId].DepartmentName,
  606. StartTime: fmt.Sprintf("%.2v:%.2v", startAt.Hour(), startAt.Minute()),
  607. Tel: usersMap[v.UserId].Mobile,
  608. Uid: v.UserId,
  609. Uname: usersMap[v.UserId].Realname,
  610. Week: common.GetCNWeekday(v.StartTime),
  611. ReservationStartTime: v.StartTime.String(),
  612. ReservationEndTime: v.EndTime.String(),
  613. })
  614. }
  615. }
  616. }
  617. return resultList, nil
  618. }