diff --git a/server/CoreCms.Net.Configuration/GlobalEnumVars.cs b/server/CoreCms.Net.Configuration/GlobalEnumVars.cs
index 0917a46..12452f7 100644
--- a/server/CoreCms.Net.Configuration/GlobalEnumVars.cs
+++ b/server/CoreCms.Net.Configuration/GlobalEnumVars.cs
@@ -2796,5 +2796,33 @@ namespace CoreCms.Net.Configuration
}
#endregion
+ #region 房间不可用类型===============================================================
+
+ ///
+ /// 房间不可用类型
+ ///
+ public enum RoomUnavailableType
+ {
+ ///
+ /// 禁用/维护
+ ///
+ [Description("禁用/维护")]
+ Disabled = 1,
+
+ ///
+ /// 后台预约
+ ///
+ [Description("后台预约")]
+ BackendReservation = 2,
+
+ ///
+ /// 线下预约
+ ///
+ [Description("线下预约")]
+ OfflineReservation = 3
+ }
+
+ #endregion
+
}
}
diff --git a/server/CoreCms.Net.Model/Entities/SQ/SQRoomUnavailableTimes.cs b/server/CoreCms.Net.Model/Entities/SQ/SQRoomUnavailableTimes.cs
index 12cfdb1..8a1994f 100644
--- a/server/CoreCms.Net.Model/Entities/SQ/SQRoomUnavailableTimes.cs
+++ b/server/CoreCms.Net.Model/Entities/SQ/SQRoomUnavailableTimes.cs
@@ -93,6 +93,12 @@ namespace CoreCms.Net.Model.Entities
[Display(Name = "时段类型")]
public System.Int32? time_slot_type { get; set; }
+ ///
+ /// 不可用类型:1-禁用/维护, 2-后台预约, 3-线下预约
+ ///
+ [Display(Name = "不可用类型")]
+ public System.Int32 type { get; set; } = 1;
+
///
/// 创建人ID(管理员)
///
diff --git a/server/CoreCms.Net.Model/ViewModels/SQ/SQReservationsDto.cs b/server/CoreCms.Net.Model/ViewModels/SQ/SQReservationsDto.cs
index 92c15dd..07176e4 100644
--- a/server/CoreCms.Net.Model/ViewModels/SQ/SQReservationsDto.cs
+++ b/server/CoreCms.Net.Model/ViewModels/SQ/SQReservationsDto.cs
@@ -380,6 +380,11 @@ namespace CoreCms.Net.Model.ViewModels.SQ
///
public string price_desc_member { get; set; }
+ ///
+ /// 不可用类型(当status为unavailable时有效):1=禁用/维护,2=后台预约,3=线下预约
+ ///
+ public int? unavailable_type { get; set; }
+
///
/// 该时段内的预约列表(仅详情接口返回)
///
diff --git a/server/CoreCms.Net.Services/SQ/SQRoomsServices.cs b/server/CoreCms.Net.Services/SQ/SQRoomsServices.cs
index d14cc05..6ae30b7 100644
--- a/server/CoreCms.Net.Services/SQ/SQRoomsServices.cs
+++ b/server/CoreCms.Net.Services/SQ/SQRoomsServices.cs
@@ -243,14 +243,15 @@ namespace CoreCms.Net.Services
}
else
{
- // 检查不可用时段
- bool isUnavailable = unavailableTimes?.Any(u =>
+ // 检查不可用时段,并获取禁用类型
+ var unavailableRecord = unavailableTimes?.FirstOrDefault(u =>
(u.time_slot_type.HasValue && u.time_slot_type.Value == slotType) ||
- (u.start_time < slotEnd && u.end_time > slotStart)) ?? false;
+ (u.start_time < slotEnd && u.end_time > slotStart));
- if (isUnavailable)
+ if (unavailableRecord != null)
{
slotDto.status = GlobalConstVars.RoomStatusUnavailable;
+ slotDto.unavailable_type = unavailableRecord.type; // 设置禁用类型
}
else
{
diff --git a/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs b/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs
index 4aa71a0..73f68e6 100644
--- a/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs
+++ b/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQRoomPricingController.cs
@@ -57,6 +57,7 @@ namespace CoreCms.Net.Web.Admin.Controllers
private readonly ISQRoomsServices _SQRoomsServices;
private readonly ISQReservationsServices _SQReservationsServices;
private readonly ISQReservationParticipantsServices _SQReservationParticipantsServices;
+ private readonly ISQRoomUnavailableTimesServices _SQRoomUnavailableTimesServices;
private readonly ICoreCmsUserServices _userServices;
private readonly IMapper _mapper;
@@ -68,6 +69,7 @@ namespace CoreCms.Net.Web.Admin.Controllers
, ISQRoomsServices SQRoomsServices
, ISQReservationsServices SQReservationsServices
, ISQReservationParticipantsServices SQReservationParticipantsServices
+ , ISQRoomUnavailableTimesServices SQRoomUnavailableTimesServices
, ICoreCmsUserServices userServices
, IMapper mapper
)
@@ -77,6 +79,7 @@ namespace CoreCms.Net.Web.Admin.Controllers
_SQRoomsServices = SQRoomsServices;
_SQReservationsServices = SQReservationsServices;
_SQReservationParticipantsServices = SQReservationParticipantsServices;
+ _SQRoomUnavailableTimesServices = SQRoomUnavailableTimesServices;
_userServices = userServices;
_mapper = mapper;
}
@@ -1098,6 +1101,545 @@ namespace CoreCms.Net.Web.Admin.Controllers
}
#endregion
+ #region 设置房间时段不可用============================================================
+ // POST: Api/SQRoomPricing/SetRoomUnavailable
+ ///
+ /// 设置房间时段不可用
+ ///
+ /// 房间ID
+ /// 日期
+ /// 时段类型(0=凌晨,1=上午,2=下午,3=晚上)
+ /// 不可用类型(1=禁用/维护,2=后台预约,3=线下预约)
+ /// 原因/备注
+ ///
+ [HttpPost]
+ [Description("设置房间时段不可用")]
+ public async Task SetRoomUnavailable([FromBody] SetRoomUnavailableRequest request)
+ {
+ var jm = new AdminUiCallBack();
+
+ try
+ {
+ // 参数验证
+ if (request.roomId <= 0)
+ {
+ jm.msg = "请选择房间";
+ return jm;
+ }
+
+ if (string.IsNullOrEmpty(request.date))
+ {
+ jm.msg = "请选择日期";
+ return jm;
+ }
+
+ if (!DateTime.TryParse(request.date, out DateTime dateValue))
+ {
+ jm.msg = "日期格式不正确";
+ return jm;
+ }
+
+ if (request.timeSlotType < 0 || request.timeSlotType > 3)
+ {
+ jm.msg = "时段类型不正确";
+ return jm;
+ }
+
+ if (request.type < 1 || request.type > 3)
+ {
+ jm.msg = "不可用类型不正确";
+ return jm;
+ }
+
+ // 检查房间是否存在
+ var room = await _SQRoomsServices.QueryByIdAsync(request.roomId);
+ if (room == null)
+ {
+ jm.msg = "房间不存在";
+ return jm;
+ }
+
+ // 根据时段类型计算开始和结束时间
+ var (startTime, endTime) = GetTimeSlotRange(dateValue, request.timeSlotType);
+
+ // 检查该时段是否已有用户预约
+ var hasReservation = await _SQReservationsServices.ExistsAsync(
+ r => r.room_id == request.roomId &&
+ r.status < 4 && // 排除已取消的预约
+ r.start_time < endTime &&
+ r.end_time > startTime
+ );
+
+ if (hasReservation)
+ {
+ jm.msg = "该时段已有用户预约,请先处理预约后再设置禁用";
+ return jm;
+ }
+
+ // 检查是否已存在禁用记录
+ var existingRecord = await _SQRoomUnavailableTimesServices.QueryByClauseAsync(
+ u => u.room_id == request.roomId &&
+ u.time_slot_type == request.timeSlotType &&
+ u.start_time == startTime &&
+ u.end_time == endTime,
+ u => u.id,
+ OrderByType.Asc
+ );
+
+ if (existingRecord != null)
+ {
+ // 更新现有记录
+ existingRecord.type = request.type;
+ existingRecord.reason = request.reason;
+ await _SQRoomUnavailableTimesServices.UpdateAsync(existingRecord);
+ jm.code = 0;
+ jm.msg = "更新成功";
+ }
+ else
+ {
+ // 新增记录
+ var newRecord = new SQRoomUnavailableTimes
+ {
+ room_id = request.roomId,
+ start_time = startTime,
+ end_time = endTime,
+ time_slot_type = request.timeSlotType,
+ type = request.type,
+ reason = request.reason,
+ created_at = DateTime.Now
+ };
+
+ await _SQRoomUnavailableTimesServices.InsertAsync(newRecord);
+ jm.code = 0;
+ jm.msg = "设置成功";
+ }
+ }
+ catch (Exception ex)
+ {
+ jm.msg = "设置失败:" + ex.Message;
+ NLogUtil.WriteAll(LogLevel.Error, LogType.Web, "设置房间不可用", "SetRoomUnavailable", ex);
+ }
+
+ return jm;
+ }
+
+ ///
+ /// 根据时段类型获取时间范围
+ ///
+ private (DateTime startTime, DateTime endTime) GetTimeSlotRange(DateTime date, int timeSlotType)
+ {
+ var baseDate = date.Date;
+ return timeSlotType switch
+ {
+ 0 => (baseDate, baseDate.AddHours(6)), // 凌晨 00:00-06:00
+ 1 => (baseDate.AddHours(6), baseDate.AddHours(12)), // 上午 06:00-12:00
+ 2 => (baseDate.AddHours(12), baseDate.AddHours(18)), // 下午 12:00-18:00
+ 3 => (baseDate.AddHours(18), baseDate.AddDays(1)), // 晚上 18:00-24:00
+ _ => (baseDate, baseDate.AddDays(1))
+ };
+ }
+ #endregion
+
+ #region 取消房间时段不可用============================================================
+ // POST: Api/SQRoomPricing/CancelRoomUnavailable
+ ///
+ /// 取消房间时段不可用
+ ///
+ /// 不可用记录ID
+ ///
+ [HttpPost]
+ [Description("取消房间时段不可用")]
+ public async Task CancelRoomUnavailable([FromBody] CancelRoomUnavailableRequest request)
+ {
+ var jm = new AdminUiCallBack();
+
+ try
+ {
+ if (request.ids == null || request.ids.Length == 0)
+ {
+ jm.msg = "请选择要取消的记录";
+ return jm;
+ }
+
+ await _SQRoomUnavailableTimesServices.DeleteByIdsAsync(request.ids);
+
+ jm.code = 0;
+ jm.msg = "取消成功";
+ }
+ catch (Exception ex)
+ {
+ jm.msg = "取消失败:" + ex.Message;
+ NLogUtil.WriteAll(LogLevel.Error, LogType.Web, "取消房间不可用", "CancelRoomUnavailable", ex);
+ }
+
+ return jm;
+ }
+ #endregion
+
+ #region 取消房间整天不可用============================================================
+ // POST: Api/SQRoomPricing/CancelRoomUnavailableAllDay
+ ///
+ /// 取消房间整天不可用(删除该日期的所有禁用记录)
+ ///
+ /// 房间ID
+ /// 日期
+ ///
+ [HttpPost]
+ [Description("取消房间整天不可用")]
+ public async Task CancelRoomUnavailableAllDay([FromBody] CancelRoomUnavailableAllDayRequest request)
+ {
+ var jm = new AdminUiCallBack();
+
+ try
+ {
+ // 参数验证
+ if (request.roomId <= 0)
+ {
+ jm.msg = "请选择房间";
+ return jm;
+ }
+
+ if (string.IsNullOrEmpty(request.date))
+ {
+ jm.msg = "请选择日期";
+ return jm;
+ }
+
+ if (!DateTime.TryParse(request.date, out DateTime dateValue))
+ {
+ jm.msg = "日期格式不正确";
+ return jm;
+ }
+
+ // 检查房间是否存在
+ var room = await _SQRoomsServices.QueryByIdAsync(request.roomId);
+ if (room == null)
+ {
+ jm.msg = "房间不存在";
+ return jm;
+ }
+
+ // 获取该日期的开始和结束时间
+ var startOfDay = dateValue.Date;
+ var endOfDay = dateValue.Date.AddDays(1);
+
+ // 查询该房间该日期的所有禁用记录
+ var unavailableRecords = await _SQRoomUnavailableTimesServices.QueryListByClauseAsync(
+ u => u.room_id == request.roomId &&
+ u.start_time >= startOfDay &&
+ u.start_time < endOfDay
+ );
+
+ if (unavailableRecords == null || unavailableRecords.Count == 0)
+ {
+ jm.msg = "该日期没有禁用记录";
+ return jm;
+ }
+
+ // 获取所有记录的ID
+ var ids = unavailableRecords.Select(r => r.id).ToArray();
+
+ // 批量删除
+ await _SQRoomUnavailableTimesServices.DeleteByIdsAsync(ids);
+
+ jm.code = 0;
+ jm.msg = $"取消成功,共删除 {ids.Length} 条禁用记录";
+ }
+ catch (Exception ex)
+ {
+ jm.msg = "取消失败:" + ex.Message;
+ NLogUtil.WriteAll(LogLevel.Error, LogType.Web, "取消房间整天不可用", "CancelRoomUnavailableAllDay", ex);
+ }
+
+ return jm;
+ }
+ #endregion
+
+ #region 设置房间整天不可用============================================================
+ // POST: Api/SQRoomPricing/SetRoomUnavailableAllDay
+ ///
+ /// 设置房间整天不可用(禁用所有时段,类型为维护)
+ ///
+ /// 房间ID
+ /// 日期
+ ///
+ [HttpPost]
+ [Description("设置房间整天不可用")]
+ public async Task SetRoomUnavailableAllDay([FromBody] SetRoomUnavailableAllDayRequest request)
+ {
+ var jm = new AdminUiCallBack();
+
+ try
+ {
+ // 参数验证
+ if (request.roomId <= 0)
+ {
+ jm.msg = "请选择房间";
+ return jm;
+ }
+
+ if (string.IsNullOrEmpty(request.date))
+ {
+ jm.msg = "请选择日期";
+ return jm;
+ }
+
+ if (!DateTime.TryParse(request.date, out DateTime dateValue))
+ {
+ jm.msg = "日期格式不正确";
+ return jm;
+ }
+
+ // 检查房间是否存在
+ var room = await _SQRoomsServices.QueryByIdAsync(request.roomId);
+ if (room == null)
+ {
+ jm.msg = "房间不存在";
+ return jm;
+ }
+
+ // 检查该日期是否已有用户预约
+ var startOfDay = dateValue.Date;
+ var endOfDay = dateValue.Date.AddDays(1);
+ var hasReservation = await _SQReservationsServices.ExistsAsync(
+ r => r.room_id == request.roomId &&
+ r.status < 4 && // 排除已取消的预约
+ r.start_time < endOfDay &&
+ r.end_time > startOfDay
+ );
+
+ if (hasReservation)
+ {
+ jm.msg = "该日期已有用户预约,请先处理预约后再设置禁用";
+ return jm;
+ }
+
+ // 禁用类型为维护(type=1),原因默认为"整天维护"
+ var maintenanceType = 1;
+ var defaultReason = "整天维护";
+
+ // 遍历所有4个时段,设置禁用
+ var successCount = 0;
+ var updateCount = 0;
+ var insertCount = 0;
+
+ for (int timeSlotType = 0; timeSlotType <= 3; timeSlotType++)
+ {
+ var (startTime, endTime) = GetTimeSlotRange(dateValue, timeSlotType);
+
+ // 检查是否已存在禁用记录
+ var existingRecord = await _SQRoomUnavailableTimesServices.QueryByClauseAsync(
+ u => u.room_id == request.roomId &&
+ u.time_slot_type == timeSlotType &&
+ u.start_time == startTime &&
+ u.end_time == endTime,
+ u => u.id,
+ OrderByType.Asc
+ );
+
+ if (existingRecord != null)
+ {
+ // 更新现有记录为维护类型
+ existingRecord.type = maintenanceType;
+ existingRecord.reason = defaultReason;
+ await _SQRoomUnavailableTimesServices.UpdateAsync(existingRecord);
+ updateCount++;
+ }
+ else
+ {
+ // 新增记录
+ var newRecord = new SQRoomUnavailableTimes
+ {
+ room_id = request.roomId,
+ start_time = startTime,
+ end_time = endTime,
+ time_slot_type = timeSlotType,
+ type = maintenanceType,
+ reason = defaultReason,
+ created_at = DateTime.Now
+ };
+
+ await _SQRoomUnavailableTimesServices.InsertAsync(newRecord);
+ insertCount++;
+ }
+ successCount++;
+ }
+
+ jm.code = 0;
+ jm.msg = $"禁用成功,共设置 {successCount} 个时段(新增 {insertCount} 条,更新 {updateCount} 条)";
+ }
+ catch (Exception ex)
+ {
+ jm.msg = "禁用失败:" + ex.Message;
+ NLogUtil.WriteAll(LogLevel.Error, LogType.Web, "设置房间整天不可用", "SetRoomUnavailableAllDay", ex);
+ }
+
+ return jm;
+ }
+ #endregion
+
+ #region 获取房间某日期的禁用列表============================================================
+ // GET: Api/SQRoomPricing/GetRoomUnavailableList
+ ///
+ /// 获取房间某日期的禁用列表
+ ///
+ /// 房间ID
+ /// 日期
+ ///
+ [HttpGet]
+ [Description("获取房间禁用列表")]
+ public async Task GetRoomUnavailableList([FromQuery] int roomId, [FromQuery] string date)
+ {
+ var jm = new AdminUiCallBack();
+
+ try
+ {
+ if (roomId <= 0)
+ {
+ jm.msg = "请选择房间";
+ return jm;
+ }
+
+ if (string.IsNullOrEmpty(date))
+ {
+ jm.msg = "请选择日期";
+ return jm;
+ }
+
+ if (!DateTime.TryParse(date, out DateTime dateValue))
+ {
+ jm.msg = "日期格式不正确";
+ return jm;
+ }
+
+ // 获取该日期的开始和结束时间
+ var startOfDay = dateValue.Date;
+ var endOfDay = dateValue.Date.AddDays(1);
+
+ // 查询该房间该日期的所有禁用记录
+ var list = await _SQRoomUnavailableTimesServices.QueryListByClauseAsync(
+ u => u.room_id == roomId &&
+ u.start_time >= startOfDay &&
+ u.start_time < endOfDay,
+ u => u.time_slot_type,
+ OrderByType.Asc
+ );
+
+ // 时段名称映射
+ var slotNames = new[] { "凌晨", "上午", "下午", "晚上" };
+ var typeNames = new Dictionary
+ {
+ { 1, "禁用/维护" },
+ { 2, "后台预约" },
+ { 3, "线下预约" }
+ };
+
+ var result = list.Select(item => new
+ {
+ item.id,
+ item.room_id,
+ item.time_slot_type,
+ slot_name = item.time_slot_type.HasValue && item.time_slot_type.Value >= 0 && item.time_slot_type.Value <= 3
+ ? slotNames[item.time_slot_type.Value]
+ : "未知",
+ item.type,
+ type_name = typeNames.ContainsKey(item.type) ? typeNames[item.type] : "未知",
+ item.reason,
+ start_time = item.start_time.ToString("yyyy-MM-dd HH:mm:ss"),
+ end_time = item.end_time.ToString("yyyy-MM-dd HH:mm:ss"),
+ created_at = item.created_at.ToString("yyyy-MM-dd HH:mm:ss")
+ }).ToList();
+
+ jm.code = 0;
+ jm.msg = "获取成功";
+ jm.data = result;
+ }
+ catch (Exception ex)
+ {
+ jm.msg = "获取失败:" + ex.Message;
+ NLogUtil.WriteAll(LogLevel.Error, LogType.Web, "获取房间禁用列表", "GetRoomUnavailableList", ex);
+ }
+
+ return jm;
+ }
+ #endregion
+
}
+
+ #region 请求参数类
+ ///
+ /// 设置房间不可用请求参数
+ ///
+ public class SetRoomUnavailableRequest
+ {
+ ///
+ /// 房间ID
+ ///
+ public int roomId { get; set; }
+
+ ///
+ /// 日期 (YYYY-MM-DD)
+ ///
+ public string date { get; set; }
+
+ ///
+ /// 时段类型(0=凌晨,1=上午,2=下午,3=晚上)
+ ///
+ public int timeSlotType { get; set; }
+
+ ///
+ /// 不可用类型(1=禁用/维护,2=后台预约,3=线下预约)
+ ///
+ public int type { get; set; }
+
+ ///
+ /// 原因/备注
+ ///
+ public string reason { get; set; }
+ }
+
+ ///
+ /// 取消房间不可用请求参数
+ ///
+ public class CancelRoomUnavailableRequest
+ {
+ ///
+ /// 不可用记录ID数组
+ ///
+ public int[] ids { get; set; }
+ }
+
+ ///
+ /// 设置房间整天不可用请求参数
+ ///
+ public class SetRoomUnavailableAllDayRequest
+ {
+ ///
+ /// 房间ID
+ ///
+ public int roomId { get; set; }
+
+ ///
+ /// 日期 (YYYY-MM-DD)
+ ///
+ public string date { get; set; }
+ }
+
+ ///
+ /// 取消房间整天不可用请求参数
+ ///
+ public class CancelRoomUnavailableAllDayRequest
+ {
+ ///
+ /// 房间ID
+ ///
+ public int roomId { get; set; }
+
+ ///
+ /// 日期 (YYYY-MM-DD)
+ ///
+ public string date { get; set; }
+ }
+ #endregion
}
diff --git a/server/CoreCms.Net.Web.Admin/Doc.xml b/server/CoreCms.Net.Web.Admin/Doc.xml
index a294bf3..cd9bb01 100644
--- a/server/CoreCms.Net.Web.Admin/Doc.xml
+++ b/server/CoreCms.Net.Web.Admin/Doc.xml
@@ -4013,7 +4013,7 @@
-
+
构造函数
@@ -4120,6 +4120,123 @@
根据时间判断时段类型
+
+
+ 设置房间时段不可用
+
+ 房间ID
+ 日期
+ 时段类型(0=凌晨,1=上午,2=下午,3=晚上)
+ 不可用类型(1=禁用/维护,2=后台预约,3=线下预约)
+ 原因/备注
+
+
+
+
+ 根据时段类型获取时间范围
+
+
+
+
+ 取消房间时段不可用
+
+ 不可用记录ID
+
+
+
+
+ 取消房间整天不可用(删除该日期的所有禁用记录)
+
+ 房间ID
+ 日期
+
+
+
+
+ 设置房间整天不可用(禁用所有时段,类型为维护)
+
+ 房间ID
+ 日期
+
+
+
+
+ 获取房间某日期的禁用列表
+
+ 房间ID
+ 日期
+
+
+
+
+ 设置房间不可用请求参数
+
+
+
+
+ 房间ID
+
+
+
+
+ 日期 (YYYY-MM-DD)
+
+
+
+
+ 时段类型(0=凌晨,1=上午,2=下午,3=晚上)
+
+
+
+
+ 不可用类型(1=禁用/维护,2=后台预约,3=线下预约)
+
+
+
+
+ 原因/备注
+
+
+
+
+ 取消房间不可用请求参数
+
+
+
+
+ 不可用记录ID数组
+
+
+
+
+ 设置房间整天不可用请求参数
+
+
+
+
+ 房间ID
+
+
+
+
+ 日期 (YYYY-MM-DD)
+
+
+
+
+ 取消房间整天不可用请求参数
+
+
+
+
+ 房间ID
+
+
+
+
+ 日期 (YYYY-MM-DD)
+
+
房间表
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 baf275b..1ecaa65 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
@@ -18,11 +18,11 @@
padding: 20px;
background: #fff;
}
-
+
.table-body {
display: none;
}
-
+
.calendar-header {
display: flex;
justify-content: space-between;
@@ -32,24 +32,24 @@
background: #f8f8f8;
border-radius: 4px;
}
-
+
.calendar-header h3 {
margin: 0;
font-size: 18px;
font-weight: bold;
}
-
+
.calendar-nav button {
margin: 0 5px;
}
-
+
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 10px;
margin-top: 20px;
}
-
+
.calendar-weekday {
text-align: center;
font-weight: bold;
@@ -57,7 +57,7 @@
background: #f0f0f0;
border-radius: 4px;
}
-
+
.calendar-day {
border: 1px solid #e6e6e6;
border-radius: 4px;
@@ -66,35 +66,35 @@
background: #fff;
transition: all 0.3s;
}
-
+
.calendar-day:hover {
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
-
+
.calendar-day.empty {
background: #fafafa;
border-color: #f0f0f0;
}
-
+
.calendar-day.today {
border-color: #009688;
background: #f0fffe;
}
-
+
.calendar-day-header {
font-weight: bold;
margin-bottom: 8px;
font-size: 16px;
color: #333;
}
-
+
.calendar-day-price {
font-size: 12px;
color: #666;
margin-bottom: 4px;
}
-
+
.calendar-day-member {
display: inline-block;
background: #ff5722;
@@ -104,65 +104,70 @@
font-size: 11px;
margin-bottom: 6px;
}
-
+
.calendar-day-slots {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4px;
margin-top: 8px;
}
-
+
.calendar-slot {
font-size: 11px;
padding: 3px 5px;
border-radius: 3px;
text-align: center;
}
-
+
.calendar-slot.available {
background: #e8f5e9;
color: #4caf50;
}
-
+
.calendar-slot.unavailable {
background: #ffebee;
color: #f44336;
}
-
+
.calendar-slot.reserved {
background: #fff3e0;
color: #ff9800;
}
-
+
.calendar-slot.using {
background: #a3a9ac1e;
color: #ff9800;
}
-
+
+ .calendar-slot.backend-reservation {
+ background: #e65100;
+ color: #fff;
+ }
+
/* 右键菜单样式调整 */
.context-menu-list {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
border-radius: 4px;
- box-shadow: 0 2px 12px rgba(0,0,0,0.15);
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
border: 1px solid #e6e6e6;
}
-
+
.context-menu-item {
padding: 8px 20px;
}
-
+
.context-menu-item:hover {
background: #009688;
color: #fff;
}
-
+
.context-menu-icon {
margin-right: 8px;
}
@@ -179,7 +184,8 @@
-
+
@@ -209,7 +215,7 @@
-
+
@@ -247,18 +253,18 @@
-
+
\ No newline at end of file
diff --git a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/unavailable.html b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/unavailable.html
new file mode 100644
index 0000000..e69e0aa
--- /dev/null
+++ b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/unavailable.html
@@ -0,0 +1,351 @@
+
+
+