diff --git a/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs b/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs index d12c824..4aa71a0 100644 --- a/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs +++ b/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs @@ -17,6 +17,7 @@ using CoreCms.Net.Model.Entities; using CoreCms.Net.Model.Entities.Expression; using CoreCms.Net.Model.FromBody; using CoreCms.Net.Model.ViewModels.UI; +using CoreCms.Net.Model.ViewModels.SQ; using CoreCms.Net.Utility.Extensions; using CoreCms.Net.Utility.Helper; using CoreCms.Net.Web.Admin.Infrastructure; @@ -30,11 +31,14 @@ using NPOI.HSSF.UserModel; using SqlSugar; using System; +using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; +using NLog; +using AutoMapper; namespace CoreCms.Net.Web.Admin.Controllers { @@ -50,16 +54,31 @@ namespace CoreCms.Net.Web.Admin.Controllers { private readonly IWebHostEnvironment _webHostEnvironment; private readonly ISQRoomPricingServices _SQRoomPricingServices; + private readonly ISQRoomsServices _SQRoomsServices; + private readonly ISQReservationsServices _SQReservationsServices; + private readonly ISQReservationParticipantsServices _SQReservationParticipantsServices; + private readonly ICoreCmsUserServices _userServices; + private readonly IMapper _mapper; /// /// 构造函数 /// public SQRoomPricingController(IWebHostEnvironment webHostEnvironment , ISQRoomPricingServices SQRoomPricingServices + , ISQRoomsServices SQRoomsServices + , ISQReservationsServices SQReservationsServices + , ISQReservationParticipantsServices SQReservationParticipantsServices + , ICoreCmsUserServices userServices + , IMapper mapper ) { _webHostEnvironment = webHostEnvironment; _SQRoomPricingServices = SQRoomPricingServices; + _SQRoomsServices = SQRoomsServices; + _SQReservationsServices = SQReservationsServices; + _SQReservationParticipantsServices = SQReservationParticipantsServices; + _userServices = userServices; + _mapper = mapper; } #region 获取列表============================================================ @@ -820,6 +839,265 @@ namespace CoreCms.Net.Web.Admin.Controllers } #endregion + #region 获取房间时段状态============================================================ + // GET: Api/SQRoomPricing/GetRoomListWithSlots + /// + /// 获取房间列表及时段状态(用于日历视图) + /// + /// 日期 + /// 是否只显示可用房间 + /// 当前时段 + /// + [HttpGet] + [AllowAnonymous] + [Description("获取房间列表及时段状态")] + public async Task GetRoomListWithSlots([FromQuery] string date, [FromQuery] bool showOnlyAvailable = false, [FromQuery] int? currentTimeSlot = null) + { + var jm = new AdminUiCallBack(); + + // 验证日期参数 + if (string.IsNullOrEmpty(date)) + { + jm.msg = "请提供日期参数"; + return jm; + } + + if (!DateTime.TryParse(date, out DateTime dateValue)) + { + jm.msg = "日期格式不正确"; + return jm; + } + + // 调用服务获取数据 + var result = await _SQRoomsServices.GetRoomListWithSlotsAsync(dateValue, showOnlyAvailable, currentTimeSlot); + + jm.code = 0; + jm.msg = "获取成功"; + jm.data = result; + + return jm; + } + #endregion + + #region 获取日期详情============================================================ + // GET: Api/SQRoomPricing/GetDateDetails + /// + /// 获取指定日期和房间的详细信息(用于日历视图点击日期) + /// + /// 日期 + /// 房间ID + /// + [HttpGet] + [AllowAnonymous] + [Description("获取日期详情")] + public async Task GetDateDetails([FromQuery] string date, [FromQuery] int roomId) + { + var jm = new AdminUiCallBack(); + + try + { + // 验证参数 + if (string.IsNullOrEmpty(date)) + { + jm.msg = "请提供日期参数"; + return jm; + } + + if (roomId <= 0) + { + jm.msg = "请提供房间ID"; + return jm; + } + + if (!DateTime.TryParse(date, out DateTime dateValue)) + { + jm.msg = "日期格式不正确"; + return jm; + } + + // 获取房间信息 + var room = await _SQRoomsServices.QueryByIdAsync(roomId); + if (room == null) + { + jm.msg = "房间不存在"; + return jm; + } + + // 获取该日期该房间的时段状态 + var roomListWithSlots = await _SQRoomsServices.GetRoomListWithSlotsAsync(dateValue, false, null); + var roomData = roomListWithSlots?.FirstOrDefault(r => r.id == roomId); + + // 获取该日期该房间的预约列表 + var startTime = dateValue.Date; + var endTime = dateValue.Date.AddDays(1); + var reservations = await _SQReservationsServices.QueryListByClauseAsync( + p => p.room_id == roomId && + p.start_time >= startTime && + p.start_time < endTime && + p.status != 4, // 排除已取消的预约 + p => p.start_time, + OrderByType.Asc + ); + + // 查询所有预约的参与者 + var reservationIds = reservations.Select(r => r.id).ToList(); + List allParticipants = new List(); + List userList = new List(); + + if (reservationIds.Any()) + { + allParticipants = await _SQReservationParticipantsServices.QueryListByClauseAsync( + p => reservationIds.Contains(p.reservation_id), + p => p.role, + OrderByType.Desc, + true + ); + + // 查询所有参与者的用户信息 + var userIds = allParticipants.Select(p => p.user_id).Distinct().ToList(); + if (userIds.Any()) + { + userList = await _userServices.QueryListByClauseAsync( + u => userIds.Contains(u.id), + u => u.id, + OrderByType.Asc, + true + ); + } + } + + // 处理时段数据,添加参与者头像和数量 + var enhancedTimeSlots = new List(); + if (roomData?.time_slots != null) + { + foreach (var slot in roomData.time_slots) + { + // 获取该时段的所有预约 + var slotReservations = reservations.Where(r => + r.time_slot_type.HasValue && r.time_slot_type.Value == slot.slot_type + ).ToList(); + + // 获取该时段所有预约的参与者(正常状态) + var slotReservationIds = slotReservations.Select(r => r.id).ToList(); + var slotParticipants = allParticipants.Where(p => + slotReservationIds.Contains(p.reservation_id) && p.status == 0 + ).ToList(); + + // 提取头像列表 + var avatars = slotParticipants + .Select(p => userList.FirstOrDefault(u => u.id == p.user_id)?.avatarImage) + .Where(avatar => !string.IsNullOrEmpty(avatar)) + .Distinct() + .ToList(); + + enhancedTimeSlots.Add(new + { + slot_type = slot.slot_type, + slot_name = slot.slot_name, + status = slot.status, + price_desc_standard = slot.price_desc_standard, + price_desc_member = slot.price_desc_member, + reservation_count = slotParticipants.Count, + participant_avatars = avatars + }); + } + } + + // 按时段分组预约 + var reservationsBySlot = new Dictionary>(); + for (int i = 0; i <= 3; i++) + { + reservationsBySlot[i] = new List(); + } + + foreach (var reservation in reservations) + { + // 确定预约所属时段 + int slotType = reservation.time_slot_type ?? GetTimeSlotTypeFromTime(reservation.start_time); + + // 获取该预约的参与者 + var participants = allParticipants.Where(p => p.reservation_id == reservation.id) + .OrderBy(p => p.role == 1 ? 0 : 1) // 发起者优先 + .ThenBy(p => p.status) // 正常状态优先 + .ToList(); + + var participantsDto = _mapper.Map>(participants); + + // 填充用户信息 + foreach (var p in participantsDto) + { + var user = userList.FirstOrDefault(u => u.id == p.user_id); + if (user != null) + { + p.UserName = user.nickName; + p.AvatarImage = user.avatarImage; + } + } + + reservationsBySlot[slotType].Add(new + { + id = reservation.id, + title = reservation.title, + player_count = reservation.player_count, + deposit_fee = reservation.deposit_fee, + latest_arrival_time = reservation.latest_arrival_time?.ToString("yyyy-MM-dd HH:mm:ss"), + game_type = reservation.game_type, + game_rule = reservation.game_rule, + start_time = reservation.start_time.ToString("yyyy-MM-dd HH:mm:ss"), + end_time = reservation.end_time.ToString("yyyy-MM-dd HH:mm:ss"), + status = reservation.status, + participants = participantsDto.Select(p => new + { + id = p.id, + user_id = p.user_id, + user_name = p.UserName, + avatar_image = p.AvatarImage, + join_time = p.join_time.ToString("yyyy-MM-dd HH:mm:ss"), + role = p.role, + quit_time = p.quit_time?.ToString("yyyy-MM-dd HH:mm:ss"), + status = p.status, + is_refund = p.is_refund, + remarks = p.remarks + }).ToList() + }); + } + + // 构建返回数据 + var result = new + { + date = date, + room_id = roomId, + room_name = room.name, + time_slots = enhancedTimeSlots, + reservations_by_slot = reservationsBySlot + }; + + jm.code = 0; + jm.msg = "获取成功"; + jm.data = result; + } + catch (Exception ex) + { + jm.msg = "获取数据时发生错误:" + ex.Message; + NLogUtil.WriteAll(LogLevel.Error, LogType.Web, "获取日期详情", "GetDateDetails", ex); + } + + return jm; + } + + /// + /// 根据时间判断时段类型 + /// + private int GetTimeSlotTypeFromTime(DateTime time) + { + var hour = time.Hour; + if (hour >= 0 && hour < 6) return 0; // 凌晨 00:00-06:00 + if (hour >= 6 && hour < 12) return 1; // 上午 06:00-12:00 + if (hour >= 12 && hour < 18) return 2; // 下午 12:00-18:00 + return 3; // 晚上 18:00-24:00 + } + #endregion + } } diff --git a/server/CoreCms.Net.Web.Admin/Doc.xml b/server/CoreCms.Net.Web.Admin/Doc.xml index dcf3a70..a294bf3 100644 --- a/server/CoreCms.Net.Web.Admin/Doc.xml +++ b/server/CoreCms.Net.Web.Admin/Doc.xml @@ -4013,7 +4013,7 @@ - + 构造函数 @@ -4098,6 +4098,28 @@ + + + 获取房间列表及时段状态(用于日历视图) + + 日期 + 是否只显示可用房间 + 当前时段 + + + + + 获取指定日期和房间的详细信息(用于日历视图点击日期) + + 日期 + 房间ID + + + + + 根据时间判断时段类型 + + 房间表 diff --git a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqreservations/index.html b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqreservations/index.html index 6aa4ef1..b2bb2a5 100644 --- a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqreservations/index.html +++ b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqreservations/index.html @@ -749,6 +749,8 @@ } }); } + + //执行单个删除 function doDelete(obj) { coreHelper.Post("Api/SQReservations/DoDelete", { id: obj.data.id }, function (e) { diff --git a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html index 0a1a59c..bd113e7 100644 --- a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html +++ b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html @@ -9,30 +9,183 @@ -
-
-
-