reservation.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  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. "begin_at": m.BeginAt.Time.Format("15:04:05"),
  282. "ent_at": m.EndAt.Time.Format("15:04:05"),
  283. "time_split": timesplit,
  284. "unavailable": unavailable,
  285. "appoint": appointInfo,
  286. }, nil
  287. }
  288. // OverviewListByDay 按天预约概况
  289. func (s Service) OverviewListByDay(ctx context.Context, req meeting3.OverviewReq) (g.Map, error) {
  290. beginAt := g.Cfg().GetString("reservation.begin")
  291. endAt := g.Cfg().GetString("reservation.end")
  292. defaultPeriod := s.getCurrentPeriod(beginAt, endAt)
  293. dates := getCurrentWeekDay(req.Date)
  294. meetingList, err := meeting.NewSrv(s.Tenant).ShortList()
  295. if err != nil {
  296. return nil, err
  297. }
  298. reservationList, err := s.getCurrentDayReservation(ctx, meetingList, req.Date)
  299. if err != nil {
  300. return nil, err
  301. }
  302. // for i := range meetingList {
  303. // begin, end := beginAt, endAt
  304. // if meetingList[i].BeginAt != nil && meetingList[i].EndAt != nil {
  305. // begin = meetingList[i].BeginAt.Time.Format("15:04:05")
  306. // end = meetingList[i].EndAt.Time.Format("15:04:05")
  307. // }
  308. // fmt.Println(meetingList[i].Id, meetingList[i].Name)
  309. // period := s.getCurrentPeriod(begin, end)
  310. // meetingList[i].Period = period
  311. // }
  312. return g.Map{
  313. "period": defaultPeriod,
  314. "dates": dates,
  315. "meeting": meetingList,
  316. "reservation": reservationList,
  317. }, nil
  318. }
  319. // ReserveInfo 预约信息
  320. func (s Service) ReserveInfo(ctx context.Context, req meeting3.ReserveReq) (g.Map, error) {
  321. // 常规信息
  322. beginAt := g.Cfg().GetString("reservation.begin_at")
  323. endAt := g.Cfg().GetString("reservation.end_at")
  324. period := s.getCurrentPeriod(beginAt, endAt)
  325. dates := getCurrentWeekDay(req.Date)
  326. weekday := g.Cfg().GetString("reservation.weekday")
  327. // 预约信息
  328. list, err := s.getCurrentWeekReservation(ctx, req)
  329. if err != nil {
  330. return nil, err
  331. }
  332. return g.Map{
  333. "period": period,
  334. "dates": dates,
  335. "weekday": weekday,
  336. "reservation": list,
  337. }, nil
  338. }
  339. // Ending 结束会议
  340. func (s Service) Ending(ctx context.Context, req meeting3.EndingReq) error {
  341. // 先查询预约记录
  342. entity, err := s.Dao.WherePri(req.Id).FindOne()
  343. if err != nil {
  344. return err
  345. }
  346. if entity == nil {
  347. return errors.New("未找到当前预约信息")
  348. }
  349. if entity.SignOutTime.String() != "" {
  350. return errors.New("当前预约已提前结束")
  351. }
  352. // 校验日期是不是同一天(24:00除外) 校验日期是不是在预约开始时间之后
  353. if req.Date.Sub(entity.StartTime) <= 0 {
  354. return errors.New("结束时间不能早于会议预约时间")
  355. }
  356. if req.Date.Format("Y-m-d") != entity.StartTime.Format("Y-m-d") &&
  357. req.Date.Hour() != 0 && req.Date.Minute() != 0 {
  358. return errors.New("结束时间必须为当天时间")
  359. }
  360. if (req.Date.Day()-1) != entity.StartTime.Day() && req.Date.Hour() == 0 && req.Date.Minute() == 0 {
  361. return errors.New("当前结束时间错误,请重试")
  362. }
  363. if req.Date.Sub(entity.EndTime) > 0 {
  364. return errors.New("预约时间正常结束的会议无需再次结束")
  365. }
  366. userInfo, err := micro_srv.GetUserInfo(ctx)
  367. if err != nil {
  368. return err
  369. }
  370. if userInfo.Id != int32(entity.UserId) {
  371. return errors.New("当前预约只能由本人结束")
  372. }
  373. // 更新实际结束时间
  374. updatedMap := service.SetUpdatedMap(&userInfo)
  375. updatedMap[s.Dao.Columns.SignOutTime] = req.Date
  376. updatedMap[s.Dao.Columns.RealEndTimeNode] = common.GetNextTimeNode(req.Date)
  377. _, err = s.Dao.M.WherePri(req.Id).Update(updatedMap)
  378. if err != nil {
  379. return err
  380. }
  381. return nil
  382. }
  383. func (s Service) AutoEnding(id int) error {
  384. entity, err := s.Dao.WherePri(id).FindOne()
  385. if err != nil {
  386. return err
  387. }
  388. if entity == nil {
  389. return nil
  390. }
  391. if entity.SignOutTime != nil && entity.SignOutTime.String() != "" {
  392. return nil
  393. }
  394. _, err = s.Dao.WherePri(id).Update(g.Map{s.Dao.Columns.SignOutTime: entity.EndTime})
  395. if err != nil {
  396. return err
  397. }
  398. return nil
  399. }
  400. // Check 预约校验
  401. func (s Service) check(req meeting3.ReservationReq) error {
  402. // 校验开始结束时间不能跨天
  403. if req.StartTime.Format("Y-m-d") != req.EndTime.Format("Y-m-d") &&
  404. req.EndTime.Hour() != 0 && req.EndTime.Minute() != 0 {
  405. return errors.New("预约时间必须是同一天")
  406. }
  407. // 校验开始时间是否小于结束时间
  408. if req.EndTime.Sub(req.StartTime) <= 0 {
  409. return errors.New("预约结束时候必须大于开始时间")
  410. }
  411. // 时间间隔不能小于30分钟 todo:可以加到配置参数中
  412. if req.EndTime.Sub(req.StartTime).Minutes() < 30 {
  413. return errors.New("预约时间最小为30分钟")
  414. }
  415. // 校验是否是过期时间
  416. if req.StartTime.Sub(gtime.Now()) < 0 {
  417. return errors.New("当前预约时间已过期")
  418. }
  419. // 校验时间内是否有 预约
  420. entityModel := s.Dao.M.
  421. Where(s.Dao.Columns.EntityId, req.EntityId).
  422. Where(s.Dao.Columns.Status, 1).
  423. Where(s.Dao.Columns.StartTime+">= ? AND "+s.Dao.Columns.StartTime+"< ?", req.StartTime, req.EndTime)
  424. entityModel = entityModel.
  425. WhereOr(s.Dao.Columns.EntityId+"= ? AND "+s.Dao.Columns.Status+" = 1 AND "+
  426. s.Dao.Columns.RealEndTimeNode+"> ? AND "+s.Dao.Columns.RealEndTimeNode+"<= ?",
  427. req.EntityId, req.StartTime, req.EndTime)
  428. entityModel = entityModel.
  429. WhereOr(s.Dao.Columns.EntityId+"= ? AND "+s.Dao.Columns.Status+" = 1 AND "+
  430. s.Dao.Columns.RealEndTimeNode+">= ? AND "+s.Dao.Columns.StartTime+"<= ?",
  431. req.EntityId, req.EndTime, req.StartTime)
  432. exist, err := entityModel.Count()
  433. if err != nil {
  434. return err
  435. }
  436. if exist > 0 {
  437. return errors.New("当前时间段内已有预约记录,请刷新后重试")
  438. }
  439. // 校验会议室是否存在
  440. err = meeting.NewSrv(s.Tenant).Exists(req.EntityId)
  441. if err != nil {
  442. return err
  443. }
  444. return nil
  445. }
  446. // getCurrentWeekDay 返回当前日期的周信息
  447. func getCurrentWeekDay(current *gtime.Time) []meeting3.CurrentDate {
  448. startOfWeek := common.GetCNStartOfWeek(current)
  449. dates := make([]meeting3.CurrentDate, 0)
  450. for i := 0; i <= 6; i++ {
  451. times := startOfWeek.AddDate(0, 0, 1*i)
  452. dates = append(dates, meeting3.CurrentDate{
  453. Date: times.Format("Y-m-d"),
  454. Day: times.Day(),
  455. })
  456. }
  457. return dates
  458. }
  459. func (s Service) shortList(date *gtime.Time) ([]meeting3.ShortList, error) {
  460. sTime := common.GetCNStartOfWeek(date)
  461. eTime := common.GetCNEndOfWeek(date)
  462. list := make([]meeting3.ShortList, 0)
  463. res, err := s.Dao.M.WhereBetween(s.Dao.Columns.StartTime, sTime, eTime).
  464. Where(s.Dao.Columns.Status, 1).FindAll()
  465. if err != nil {
  466. return nil, err
  467. }
  468. if res.IsEmpty() {
  469. return nil, nil
  470. }
  471. res.Structs(&list)
  472. for k, _ := range list {
  473. // 当签退时间小于预约结束时间,使用签退时间
  474. if list[k].SignOutTime.String() != "" && list[k].EndTime.Sub(list[k].SignOutTime) > 0 {
  475. list[k].EndTime = common.GetNextTimeNode(list[k].SignOutTime)
  476. }
  477. }
  478. return list, nil
  479. }
  480. // getCurrentDayTimeQuantum 获取当前的时间段
  481. func (s Service) getCurrentPeriod(entityBeginAt, entityEndAt string) [][]string {
  482. now := gtime.Now()
  483. startTime, _ := gtime.StrToTime(entityBeginAt)
  484. //endTime, _ := gtime.StrToTime(entityEndAt)
  485. startAtStr := fmt.Sprintf("%v-%.2v-%.2v %.2v:%.2v:%.2v",
  486. now.Year(), int(now.Month()), now.Day(),
  487. startTime.Hour(), startTime.Minute(), startTime.Second())
  488. startAt, _ := gtime.StrToTime(startAtStr)
  489. endAtStr := fmt.Sprintf("%v-%.2v-%.2v %s",
  490. now.Year(), int(now.Month()), now.Day(), entityEndAt)
  491. endAt, _ := gtime.StrToTime(endAtStr)
  492. timeLong := endAt.Sub(startAt).Hours()
  493. grids := int(timeLong * 2)
  494. fmt.Println(startAt, endAt)
  495. var timeQuantum [][]string
  496. for i := 0; i < grids; i++ {
  497. times := make([]string, 0)
  498. timeSplit := g.Cfg().GetInt("reservation.time_split")
  499. // 开始时间
  500. startAt := startAt.Add(time.Duration(i*timeSplit) * time.Minute)
  501. startTime := startAt.Format("H:i")
  502. // 结束时间
  503. endAt := startAt.Add(time.Duration(timeSplit) * time.Minute).Format("H:i")
  504. if startAt.Hour() == 23 && startAt.Minute() == 30 {
  505. endAt = "24:00"
  506. }
  507. times = append(times, startTime, endAt)
  508. timeQuantum = append(timeQuantum, times)
  509. }
  510. return timeQuantum
  511. }
  512. // getCurrentWeekReservation 返回本周预约信息
  513. func (s Service) getCurrentWeekReservation(ctx context.Context, req meeting3.ReserveReq) ([]meeting3.ReservationList, error) {
  514. // 获取符合条件的预约信息
  515. list, err := s.Dao.Where(s.Dao.Columns.EntityId, req.EntityId).
  516. Where(s.Dao.Columns.Status, 1).
  517. Where(s.Dao.Columns.StartTime+">=", common.GetCNStartOfWeek(req.Date)).
  518. Where(s.Dao.Columns.StartTime+"<=", common.GetCNEndOfWeek(req.Date)).
  519. FindAll()
  520. if err != nil {
  521. return nil, err
  522. }
  523. if len(list) == 0 {
  524. return nil, nil
  525. }
  526. uIds := make([]int64, 0)
  527. uMap := make(map[int]struct{})
  528. for _, v := range list {
  529. if _, ok := uMap[v.UserId]; !ok {
  530. uIds = append(uIds, int64(v.UserId))
  531. uMap[v.UserId] = struct{}{}
  532. }
  533. }
  534. // 获取用户信息
  535. userList, err := srv.GetUserList(ctx, uIds, s.Tenant)
  536. usersMap := make(map[int]user_def.UserInfoList)
  537. for _, v := range userList {
  538. usersMap[v.Id] = v
  539. }
  540. resultList := make([]meeting3.ReservationList, 0)
  541. for _, v := range list {
  542. timeLong := v.EndTime.Sub(v.StartTime).Hours()
  543. if v.SignOutTime.String() != "" && v.EndTime.Sub(v.SignOutTime) > 0 {
  544. timeLong = common.GetNextTimeNode(v.SignOutTime).Sub(v.StartTime).Hours()
  545. }
  546. grid := timeLong * 2
  547. for i := 0; i < int(grid); i++ {
  548. startAt := v.StartTime.Add(time.Duration(i) * 30 * time.Minute)
  549. resultList = append(resultList, meeting3.ReservationList{
  550. ReservationId: int(v.Id),
  551. Day: v.StartTime.Day(),
  552. Dept: usersMap[v.UserId].DepartmentName,
  553. StartTime: fmt.Sprintf("%.2v:%.2v", startAt.Hour(), startAt.Minute()),
  554. Tel: usersMap[v.UserId].Mobile,
  555. Uid: v.UserId,
  556. Uname: usersMap[v.UserId].Realname,
  557. Week: common.GetCNWeekday(v.StartTime),
  558. })
  559. }
  560. }
  561. return resultList, nil
  562. }
  563. // getCurrentWeekReservation 返回本周预约信息
  564. func (s Service) getCurrentDayReservation(ctx context.Context, meetingList []meeting3.ShortMeeting, reqDate *gtime.Time) ([]meeting3.ReservationList, error) {
  565. // 获取符合条件的预约信息
  566. resultList := make([]meeting3.ReservationList, 0)
  567. for _, value := range meetingList {
  568. list, err := s.Dao.Where(s.Dao.Columns.EntityId, value.Id).
  569. Where(s.Dao.Columns.Status, 1).
  570. Where(s.Dao.Columns.StartTime+">=", reqDate).
  571. Where(s.Dao.Columns.EndTime+"<=", reqDate.AddDate(0, 0, 1)).
  572. FindAll()
  573. if err != nil {
  574. g.Log().Info("getCurrentDayReservation err:", err)
  575. return nil, err
  576. }
  577. if len(list) == 0 {
  578. continue
  579. }
  580. uIds := make([]int64, 0)
  581. uMap := make(map[int]struct{})
  582. for _, v := range list {
  583. if _, ok := uMap[v.UserId]; !ok {
  584. uIds = append(uIds, int64(v.UserId))
  585. uMap[v.UserId] = struct{}{}
  586. }
  587. }
  588. // 获取用户信息
  589. userList, err := srv.GetUserList(ctx, uIds, s.Tenant)
  590. usersMap := make(map[int]user_def.UserInfoList)
  591. for _, v := range userList {
  592. usersMap[v.Id] = v
  593. }
  594. for _, v := range list {
  595. timeLong := v.EndTime.Sub(v.StartTime).Hours()
  596. if v.SignOutTime.String() != "" && v.EndTime.Sub(v.SignOutTime) > 0 {
  597. timeLong = common.GetNextTimeNode(v.SignOutTime).Sub(v.StartTime).Hours()
  598. }
  599. grid := timeLong * 2
  600. for i := 0; i < int(grid); i++ {
  601. startAt := v.StartTime.Add(time.Duration(i) * 30 * time.Minute)
  602. resultList = append(resultList, meeting3.ReservationList{
  603. EntityId: value.Id,
  604. ReservationId: int(v.Id),
  605. Title: v.Title,
  606. Day: v.StartTime.Day(),
  607. Dept: usersMap[v.UserId].DepartmentName,
  608. StartTime: fmt.Sprintf("%.2v:%.2v", startAt.Hour(), startAt.Minute()),
  609. Tel: usersMap[v.UserId].Mobile,
  610. Uid: v.UserId,
  611. Uname: usersMap[v.UserId].Realname,
  612. Week: common.GetCNWeekday(v.StartTime),
  613. ReservationStartTime: v.StartTime.String(),
  614. ReservationEndTime: v.EndTime.String(),
  615. })
  616. }
  617. }
  618. }
  619. return resultList, nil
  620. }