321
This commit is contained in:
parent
7468f0df26
commit
2fe3facdce
|
|
@ -2796,5 +2796,33 @@ namespace CoreCms.Net.Configuration
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 房间不可用类型===============================================================
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 房间不可用类型
|
||||||
|
/// </summary>
|
||||||
|
public enum RoomUnavailableType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 禁用/维护
|
||||||
|
/// </summary>
|
||||||
|
[Description("禁用/维护")]
|
||||||
|
Disabled = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 后台预约
|
||||||
|
/// </summary>
|
||||||
|
[Description("后台预约")]
|
||||||
|
BackendReservation = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 线下预约
|
||||||
|
/// </summary>
|
||||||
|
[Description("线下预约")]
|
||||||
|
OfflineReservation = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,12 @@ namespace CoreCms.Net.Model.Entities
|
||||||
[Display(Name = "时段类型")]
|
[Display(Name = "时段类型")]
|
||||||
public System.Int32? time_slot_type { get; set; }
|
public System.Int32? time_slot_type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 不可用类型:1-禁用/维护, 2-后台预约, 3-线下预约
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "不可用类型")]
|
||||||
|
public System.Int32 type { get; set; } = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建人ID(管理员)
|
/// 创建人ID(管理员)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,11 @@ namespace CoreCms.Net.Model.ViewModels.SQ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string price_desc_member { get; set; }
|
public string price_desc_member { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 不可用类型(当status为unavailable时有效):1=禁用/维护,2=后台预约,3=线下预约
|
||||||
|
/// </summary>
|
||||||
|
public int? unavailable_type { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 该时段内的预约列表(仅详情接口返回)
|
/// 该时段内的预约列表(仅详情接口返回)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -243,14 +243,15 @@ namespace CoreCms.Net.Services
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 检查不可用时段
|
// 检查不可用时段,并获取禁用类型
|
||||||
bool isUnavailable = unavailableTimes?.Any(u =>
|
var unavailableRecord = unavailableTimes?.FirstOrDefault(u =>
|
||||||
(u.time_slot_type.HasValue && u.time_slot_type.Value == slotType) ||
|
(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.status = GlobalConstVars.RoomStatusUnavailable;
|
||||||
|
slotDto.unavailable_type = unavailableRecord.type; // 设置禁用类型
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ namespace CoreCms.Net.Web.Admin.Controllers
|
||||||
private readonly ISQRoomsServices _SQRoomsServices;
|
private readonly ISQRoomsServices _SQRoomsServices;
|
||||||
private readonly ISQReservationsServices _SQReservationsServices;
|
private readonly ISQReservationsServices _SQReservationsServices;
|
||||||
private readonly ISQReservationParticipantsServices _SQReservationParticipantsServices;
|
private readonly ISQReservationParticipantsServices _SQReservationParticipantsServices;
|
||||||
|
private readonly ISQRoomUnavailableTimesServices _SQRoomUnavailableTimesServices;
|
||||||
private readonly ICoreCmsUserServices _userServices;
|
private readonly ICoreCmsUserServices _userServices;
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
|
@ -68,6 +69,7 @@ namespace CoreCms.Net.Web.Admin.Controllers
|
||||||
, ISQRoomsServices SQRoomsServices
|
, ISQRoomsServices SQRoomsServices
|
||||||
, ISQReservationsServices SQReservationsServices
|
, ISQReservationsServices SQReservationsServices
|
||||||
, ISQReservationParticipantsServices SQReservationParticipantsServices
|
, ISQReservationParticipantsServices SQReservationParticipantsServices
|
||||||
|
, ISQRoomUnavailableTimesServices SQRoomUnavailableTimesServices
|
||||||
, ICoreCmsUserServices userServices
|
, ICoreCmsUserServices userServices
|
||||||
, IMapper mapper
|
, IMapper mapper
|
||||||
)
|
)
|
||||||
|
|
@ -77,6 +79,7 @@ namespace CoreCms.Net.Web.Admin.Controllers
|
||||||
_SQRoomsServices = SQRoomsServices;
|
_SQRoomsServices = SQRoomsServices;
|
||||||
_SQReservationsServices = SQReservationsServices;
|
_SQReservationsServices = SQReservationsServices;
|
||||||
_SQReservationParticipantsServices = SQReservationParticipantsServices;
|
_SQReservationParticipantsServices = SQReservationParticipantsServices;
|
||||||
|
_SQRoomUnavailableTimesServices = SQRoomUnavailableTimesServices;
|
||||||
_userServices = userServices;
|
_userServices = userServices;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
@ -1098,6 +1101,545 @@ namespace CoreCms.Net.Web.Admin.Controllers
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 设置房间时段不可用============================================================
|
||||||
|
// POST: Api/SQRoomPricing/SetRoomUnavailable
|
||||||
|
/// <summary>
|
||||||
|
/// 设置房间时段不可用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="roomId">房间ID</param>
|
||||||
|
/// <param name="date">日期</param>
|
||||||
|
/// <param name="timeSlotType">时段类型(0=凌晨,1=上午,2=下午,3=晚上)</param>
|
||||||
|
/// <param name="type">不可用类型(1=禁用/维护,2=后台预约,3=线下预约)</param>
|
||||||
|
/// <param name="reason">原因/备注</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Description("设置房间时段不可用")]
|
||||||
|
public async Task<AdminUiCallBack> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据时段类型获取时间范围
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
/// <summary>
|
||||||
|
/// 取消房间时段不可用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">不可用记录ID</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Description("取消房间时段不可用")]
|
||||||
|
public async Task<AdminUiCallBack> 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
|
||||||
|
/// <summary>
|
||||||
|
/// 取消房间整天不可用(删除该日期的所有禁用记录)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="roomId">房间ID</param>
|
||||||
|
/// <param name="date">日期</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Description("取消房间整天不可用")]
|
||||||
|
public async Task<AdminUiCallBack> 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
|
||||||
|
/// <summary>
|
||||||
|
/// 设置房间整天不可用(禁用所有时段,类型为维护)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="roomId">房间ID</param>
|
||||||
|
/// <param name="date">日期</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Description("设置房间整天不可用")]
|
||||||
|
public async Task<AdminUiCallBack> 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
|
||||||
|
/// <summary>
|
||||||
|
/// 获取房间某日期的禁用列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="roomId">房间ID</param>
|
||||||
|
/// <param name="date">日期</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
[Description("获取房间禁用列表")]
|
||||||
|
public async Task<AdminUiCallBack> 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<int, string>
|
||||||
|
{
|
||||||
|
{ 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 请求参数类
|
||||||
|
/// <summary>
|
||||||
|
/// 设置房间不可用请求参数
|
||||||
|
/// </summary>
|
||||||
|
public class SetRoomUnavailableRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 房间ID
|
||||||
|
/// </summary>
|
||||||
|
public int roomId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日期 (YYYY-MM-DD)
|
||||||
|
/// </summary>
|
||||||
|
public string date { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 时段类型(0=凌晨,1=上午,2=下午,3=晚上)
|
||||||
|
/// </summary>
|
||||||
|
public int timeSlotType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 不可用类型(1=禁用/维护,2=后台预约,3=线下预约)
|
||||||
|
/// </summary>
|
||||||
|
public int type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原因/备注
|
||||||
|
/// </summary>
|
||||||
|
public string reason { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取消房间不可用请求参数
|
||||||
|
/// </summary>
|
||||||
|
public class CancelRoomUnavailableRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 不可用记录ID数组
|
||||||
|
/// </summary>
|
||||||
|
public int[] ids { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置房间整天不可用请求参数
|
||||||
|
/// </summary>
|
||||||
|
public class SetRoomUnavailableAllDayRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 房间ID
|
||||||
|
/// </summary>
|
||||||
|
public int roomId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日期 (YYYY-MM-DD)
|
||||||
|
/// </summary>
|
||||||
|
public string date { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取消房间整天不可用请求参数
|
||||||
|
/// </summary>
|
||||||
|
public class CancelRoomUnavailableAllDayRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 房间ID
|
||||||
|
/// </summary>
|
||||||
|
public int roomId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日期 (YYYY-MM-DD)
|
||||||
|
/// </summary>
|
||||||
|
public string date { get; set; }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4013,7 +4013,7 @@
|
||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.#ctor(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,CoreCms.Net.IServices.ISQRoomPricingServices,CoreCms.Net.IServices.ISQRoomsServices,CoreCms.Net.IServices.ISQReservationsServices,CoreCms.Net.IServices.ISQReservationParticipantsServices,CoreCms.Net.IServices.ICoreCmsUserServices,AutoMapper.IMapper)">
|
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.#ctor(Microsoft.AspNetCore.Hosting.IWebHostEnvironment,CoreCms.Net.IServices.ISQRoomPricingServices,CoreCms.Net.IServices.ISQRoomsServices,CoreCms.Net.IServices.ISQReservationsServices,CoreCms.Net.IServices.ISQReservationParticipantsServices,CoreCms.Net.IServices.ISQRoomUnavailableTimesServices,CoreCms.Net.IServices.ICoreCmsUserServices,AutoMapper.IMapper)">
|
||||||
<summary>
|
<summary>
|
||||||
构造函数
|
构造函数
|
||||||
</summary>
|
</summary>
|
||||||
|
|
@ -4120,6 +4120,123 @@
|
||||||
根据时间判断时段类型
|
根据时间判断时段类型
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.SetRoomUnavailable(CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableRequest)">
|
||||||
|
<summary>
|
||||||
|
设置房间时段不可用
|
||||||
|
</summary>
|
||||||
|
<param name="roomId">房间ID</param>
|
||||||
|
<param name="date">日期</param>
|
||||||
|
<param name="timeSlotType">时段类型(0=凌晨,1=上午,2=下午,3=晚上)</param>
|
||||||
|
<param name="type">不可用类型(1=禁用/维护,2=后台预约,3=线下预约)</param>
|
||||||
|
<param name="reason">原因/备注</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.GetTimeSlotRange(System.DateTime,System.Int32)">
|
||||||
|
<summary>
|
||||||
|
根据时段类型获取时间范围
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.CancelRoomUnavailable(CoreCms.Net.Web.Admin.Controllers.CancelRoomUnavailableRequest)">
|
||||||
|
<summary>
|
||||||
|
取消房间时段不可用
|
||||||
|
</summary>
|
||||||
|
<param name="id">不可用记录ID</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.CancelRoomUnavailableAllDay(CoreCms.Net.Web.Admin.Controllers.CancelRoomUnavailableAllDayRequest)">
|
||||||
|
<summary>
|
||||||
|
取消房间整天不可用(删除该日期的所有禁用记录)
|
||||||
|
</summary>
|
||||||
|
<param name="roomId">房间ID</param>
|
||||||
|
<param name="date">日期</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.SetRoomUnavailableAllDay(CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableAllDayRequest)">
|
||||||
|
<summary>
|
||||||
|
设置房间整天不可用(禁用所有时段,类型为维护)
|
||||||
|
</summary>
|
||||||
|
<param name="roomId">房间ID</param>
|
||||||
|
<param name="date">日期</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQRoomPricingController.GetRoomUnavailableList(System.Int32,System.String)">
|
||||||
|
<summary>
|
||||||
|
获取房间某日期的禁用列表
|
||||||
|
</summary>
|
||||||
|
<param name="roomId">房间ID</param>
|
||||||
|
<param name="date">日期</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="T:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableRequest">
|
||||||
|
<summary>
|
||||||
|
设置房间不可用请求参数
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableRequest.roomId">
|
||||||
|
<summary>
|
||||||
|
房间ID
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableRequest.date">
|
||||||
|
<summary>
|
||||||
|
日期 (YYYY-MM-DD)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableRequest.timeSlotType">
|
||||||
|
<summary>
|
||||||
|
时段类型(0=凌晨,1=上午,2=下午,3=晚上)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableRequest.type">
|
||||||
|
<summary>
|
||||||
|
不可用类型(1=禁用/维护,2=后台预约,3=线下预约)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableRequest.reason">
|
||||||
|
<summary>
|
||||||
|
原因/备注
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:CoreCms.Net.Web.Admin.Controllers.CancelRoomUnavailableRequest">
|
||||||
|
<summary>
|
||||||
|
取消房间不可用请求参数
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.CancelRoomUnavailableRequest.ids">
|
||||||
|
<summary>
|
||||||
|
不可用记录ID数组
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableAllDayRequest">
|
||||||
|
<summary>
|
||||||
|
设置房间整天不可用请求参数
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableAllDayRequest.roomId">
|
||||||
|
<summary>
|
||||||
|
房间ID
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.SetRoomUnavailableAllDayRequest.date">
|
||||||
|
<summary>
|
||||||
|
日期 (YYYY-MM-DD)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:CoreCms.Net.Web.Admin.Controllers.CancelRoomUnavailableAllDayRequest">
|
||||||
|
<summary>
|
||||||
|
取消房间整天不可用请求参数
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.CancelRoomUnavailableAllDayRequest.roomId">
|
||||||
|
<summary>
|
||||||
|
房间ID
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:CoreCms.Net.Web.Admin.Controllers.CancelRoomUnavailableAllDayRequest.date">
|
||||||
|
<summary>
|
||||||
|
日期 (YYYY-MM-DD)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:CoreCms.Net.Web.Admin.Controllers.SQRoomsController">
|
<member name="T:CoreCms.Net.Web.Admin.Controllers.SQRoomsController">
|
||||||
<summary>
|
<summary>
|
||||||
房间表
|
房间表
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-day:hover {
|
.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);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,12 +139,17 @@
|
||||||
color: #ff9800;
|
color: #ff9800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.calendar-slot.backend-reservation {
|
||||||
|
background: #e65100;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* 右键菜单样式调整 */
|
/* 右键菜单样式调整 */
|
||||||
.context-menu-list {
|
.context-menu-list {
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border-radius: 4px;
|
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;
|
border: 1px solid #e6e6e6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +184,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-inline" id="table-view-search-btn" style="display: none;">
|
<div class="layui-inline" id="table-view-search-btn" style="display: none;">
|
||||||
<button class="layui-btn layui-btn-sm" lay-submit lay-filter="LAY-app-SQRoomPricing-search"><i class="layui-icon layui-icon-search"></i>筛选</button>
|
<button class="layui-btn layui-btn-sm" lay-submit lay-filter="LAY-app-SQRoomPricing-search"><i
|
||||||
|
class="layui-icon layui-icon-search"></i>筛选</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<button class="layui-btn layui-btn-sm layui-btn-normal" id="toggleViewBtn" type="button">
|
<button class="layui-btn layui-btn-sm layui-btn-normal" id="toggleViewBtn" type="button">
|
||||||
|
|
@ -247,7 +253,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var indexData;
|
var indexData;
|
||||||
var debug= layui.setter.debug;
|
var debug = layui.setter.debug;
|
||||||
var roomOptions = []; // 定义在外部作用域,供表格templet使用
|
var roomOptions = []; // 定义在外部作用域,供表格templet使用
|
||||||
var currentView = 'calendar'; // 当前视图:table 或 calendar
|
var currentView = 'calendar'; // 当前视图:table 或 calendar
|
||||||
var currentMonth = new Date(); // 当前显示的月份
|
var currentMonth = new Date(); // 当前显示的月份
|
||||||
|
|
@ -258,7 +264,7 @@
|
||||||
if (debug) { console.log(d); }
|
if (debug) { console.log(d); }
|
||||||
|
|
||||||
indexData = d.data;
|
indexData = d.data;
|
||||||
layui.use(['index', 'table', 'laydate', 'util', 'coredropdown', 'coreHelper'],
|
layui.use(['index', 'table', 'laydate', 'util', 'coredropdown', 'coreHelper', 'element'],
|
||||||
function () {
|
function () {
|
||||||
var $ = layui.$
|
var $ = layui.$
|
||||||
, admin = layui.admin
|
, admin = layui.admin
|
||||||
|
|
@ -268,7 +274,8 @@
|
||||||
, setter = layui.setter
|
, setter = layui.setter
|
||||||
, coreHelper = layui.coreHelper
|
, coreHelper = layui.coreHelper
|
||||||
, util = layui.util
|
, util = layui.util
|
||||||
, view = layui.view;
|
, view = layui.view
|
||||||
|
, element = layui.element;
|
||||||
|
|
||||||
var searchwhere;
|
var searchwhere;
|
||||||
|
|
||||||
|
|
@ -279,7 +286,7 @@
|
||||||
var roomSelect = $('#search_room_id');
|
var roomSelect = $('#search_room_id');
|
||||||
roomSelect.empty();
|
roomSelect.empty();
|
||||||
roomSelect.append('<option value="">请选择房间号</option>');
|
roomSelect.append('<option value="">请选择房间号</option>');
|
||||||
layui.each(roomOptions, function(index, item) {
|
layui.each(roomOptions, function (index, item) {
|
||||||
roomSelect.append('<option value="' + item.id + '">' + item.name + '</option>');
|
roomSelect.append('<option value="' + item.id + '">' + item.name + '</option>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -300,11 +307,11 @@
|
||||||
|
|
||||||
//监听搜索
|
//监听搜索
|
||||||
form.on('submit(LAY-app-SQRoomPricing-search)',
|
form.on('submit(LAY-app-SQRoomPricing-search)',
|
||||||
function(data) {
|
function (data) {
|
||||||
var field = data.field;
|
var field = data.field;
|
||||||
searchwhere = field;
|
searchwhere = field;
|
||||||
//执行重载
|
//执行重载
|
||||||
table.reloadData('LAY-app-SQRoomPricing-tableBox',{ where: field });
|
table.reloadData('LAY-app-SQRoomPricing-tableBox', { where: field });
|
||||||
});
|
});
|
||||||
//数据绑定
|
//数据绑定
|
||||||
table.render({
|
table.render({
|
||||||
|
|
@ -319,36 +326,40 @@
|
||||||
page: true,
|
page: true,
|
||||||
limit: 30,
|
limit: 30,
|
||||||
limits: [10, 15, 20, 25, 30, 50, 100, 200],
|
limits: [10, 15, 20, 25, 30, 50, 100, 200],
|
||||||
text: {none: '暂无相关数据'},
|
text: { none: '暂无相关数据' },
|
||||||
cols: [
|
cols: [
|
||||||
[
|
[
|
||||||
{ type: "checkbox", fixed: "left" },
|
{ type: "checkbox", fixed: "left" },
|
||||||
{ field: 'id', title: 'id', width: 60, sort: false},
|
{ field: 'id', title: 'id', width: 60, sort: false },
|
||||||
{ field: 'room_id', title: '房间号', sort: false, width: 150, templet: function(d) {
|
{
|
||||||
var room = roomOptions.find(function(item) { return item.id == d.room_id; });
|
field: 'room_id', title: '房间号', sort: false, width: 150, templet: function (d) {
|
||||||
|
var room = roomOptions.find(function (item) { return item.id == d.room_id; });
|
||||||
return room ? room.name : (d.room_id || '');
|
return room ? room.name : (d.room_id || '');
|
||||||
}},
|
}
|
||||||
{ field: 'time_slot_type', title: '时间段', sort: false, width: 105, templet: function(d) {
|
},
|
||||||
|
{
|
||||||
|
field: 'time_slot_type', title: '时间段', sort: false, width: 105, templet: function (d) {
|
||||||
if (d.time_slot_type === 0 || d.time_slot_type === '0') return '凌晨';
|
if (d.time_slot_type === 0 || d.time_slot_type === '0') return '凌晨';
|
||||||
if (d.time_slot_type === 1 || d.time_slot_type === '1') return '上午';
|
if (d.time_slot_type === 1 || d.time_slot_type === '1') return '上午';
|
||||||
if (d.time_slot_type === 2 || d.time_slot_type === '2') return '下午';
|
if (d.time_slot_type === 2 || d.time_slot_type === '2') return '下午';
|
||||||
if (d.time_slot_type === 3 || d.time_slot_type === '3') return '晚上';
|
if (d.time_slot_type === 3 || d.time_slot_type === '3') return '晚上';
|
||||||
return d.time_slot_type || '';
|
return d.time_slot_type || '';
|
||||||
}},
|
}
|
||||||
|
},
|
||||||
|
|
||||||
{ field: 'price_desc_standard', title: '普通价格描述', sort: false,width: 105 },
|
{ field: 'price_desc_standard', title: '普通价格描述', sort: false, width: 105 },
|
||||||
{ field: 'price_desc_member', title: '会员价格描述', sort: false,width: 105 },
|
{ field: 'price_desc_member', title: '会员价格描述', sort: false, width: 105 },
|
||||||
{ field: 'effective_date_start', title: '开始时间', sort: false,width: 105 },
|
{ field: 'effective_date_start', title: '开始时间', sort: false, width: 105 },
|
||||||
{ field: 'effective_date_end', title: '结束时间', sort: false,width: 105 },
|
{ field: 'effective_date_end', title: '结束时间', sort: false, width: 105 },
|
||||||
{ field: 'is_active', title: '是否启用', width: 95, templet: '#switch_is_active', sort: false , unresize: true},
|
{ field: 'is_active', title: '是否启用', width: 95, templet: '#switch_is_active', sort: false, unresize: true },
|
||||||
{ field: 'created_at', title: '创建时间', width: 130, sort: false},
|
{ field: 'created_at', title: '创建时间', width: 130, sort: false },
|
||||||
{ field: 'updated_at', title: '修改时间', width: 130, sort: false},
|
{ field: 'updated_at', title: '修改时间', width: 130, sort: false },
|
||||||
{ width: 162, align: 'center', title:'操作', fixed: 'right', toolbar: '#LAY-app-SQRoomPricing-tableBox-bar' }
|
{ width: 162, align: 'center', title: '操作', fixed: 'right', toolbar: '#LAY-app-SQRoomPricing-tableBox-bar' }
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
//监听排序事件
|
//监听排序事件
|
||||||
table.on('sort(LAY-app-SQRoomPricing-tableBox)', function(obj){
|
table.on('sort(LAY-app-SQRoomPricing-tableBox)', function (obj) {
|
||||||
table.reloadData('LAY-app-SQRoomPricing-tableBox', {
|
table.reloadData('LAY-app-SQRoomPricing-tableBox', {
|
||||||
initSort: obj, //记录初始排序,如果不设的话,将无法标记表头的排序状态。
|
initSort: obj, //记录初始排序,如果不设的话,将无法标记表头的排序状态。
|
||||||
where: { //请求参数(注意:这里面的参数可任意定义,并非下面固定的格式)
|
where: { //请求参数(注意:这里面的参数可任意定义,并非下面固定的格式)
|
||||||
|
|
@ -382,7 +393,7 @@
|
||||||
});
|
});
|
||||||
//监听工具条
|
//监听工具条
|
||||||
table.on('tool(LAY-app-SQRoomPricing-tableBox)',
|
table.on('tool(LAY-app-SQRoomPricing-tableBox)',
|
||||||
function(obj) {
|
function (obj) {
|
||||||
if (obj.event === 'detail') {
|
if (obj.event === 'detail') {
|
||||||
doDetails(obj);
|
doDetails(obj);
|
||||||
} else if (obj.event === 'del') {
|
} else if (obj.event === 'del') {
|
||||||
|
|
@ -392,7 +403,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//执行创建操作
|
//执行创建操作
|
||||||
function doCreate(){
|
function doCreate() {
|
||||||
coreHelper.Post("Api/SQRoomPricing/GetCreate", null, function (e) {
|
coreHelper.Post("Api/SQRoomPricing/GetCreate", null, function (e) {
|
||||||
if (e.code === 0) {
|
if (e.code === 0) {
|
||||||
admin.popup({
|
admin.popup({
|
||||||
|
|
@ -404,7 +415,7 @@
|
||||||
view(this.id).render('sq/sqroompricing/create', { data: e.data }).done(function () {
|
view(this.id).render('sq/sqroompricing/create', { data: e.data }).done(function () {
|
||||||
//监听提交
|
//监听提交
|
||||||
form.on('submit(LAY-app-SQRoomPricing-createForm-submit)',
|
form.on('submit(LAY-app-SQRoomPricing-createForm-submit)',
|
||||||
function(data) {
|
function (data) {
|
||||||
var field = data.field; //获取提交的字段
|
var field = data.field; //获取提交的字段
|
||||||
|
|
||||||
field.is_active = field.is_active == 'on';
|
field.is_active = field.is_active == 'on';
|
||||||
|
|
@ -437,8 +448,8 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//执行编辑操作
|
//执行编辑操作
|
||||||
function doEdit(obj){
|
function doEdit(obj) {
|
||||||
coreHelper.Post("Api/SQRoomPricing/GetEdit", {id:obj.data.id}, function (e) {
|
coreHelper.Post("Api/SQRoomPricing/GetEdit", { id: obj.data.id }, function (e) {
|
||||||
if (e.code === 0) {
|
if (e.code === 0) {
|
||||||
admin.popup({
|
admin.popup({
|
||||||
shadeClose: false,
|
shadeClose: false,
|
||||||
|
|
@ -449,7 +460,7 @@
|
||||||
view(this.id).render('sq/sqroompricing/edit', { data: e.data }).done(function () {
|
view(this.id).render('sq/sqroompricing/edit', { data: e.data }).done(function () {
|
||||||
//监听提交
|
//监听提交
|
||||||
form.on('submit(LAY-app-SQRoomPricing-editForm-submit)',
|
form.on('submit(LAY-app-SQRoomPricing-editForm-submit)',
|
||||||
function(data) {
|
function (data) {
|
||||||
var field = data.field; //获取提交的字段
|
var field = data.field; //获取提交的字段
|
||||||
|
|
||||||
field.is_active = field.is_active == 'on';
|
field.is_active = field.is_active == 'on';
|
||||||
|
|
@ -504,7 +515,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//执行单个删除
|
//执行单个删除
|
||||||
function doDelete(obj){
|
function doDelete(obj) {
|
||||||
coreHelper.Post("Api/SQRoomPricing/DoDelete", { id: obj.data.id }, function (e) {
|
coreHelper.Post("Api/SQRoomPricing/DoDelete", { id: obj.data.id }, function (e) {
|
||||||
if (debug) { console.log(e); } //开启调试返回数据
|
if (debug) { console.log(e); } //开启调试返回数据
|
||||||
table.reloadData('LAY-app-SQRoomPricing-tableBox');
|
table.reloadData('LAY-app-SQRoomPricing-tableBox');
|
||||||
|
|
@ -512,16 +523,16 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//执行批量删除
|
//执行批量删除
|
||||||
function doBatchDelete(checkStatus){
|
function doBatchDelete(checkStatus) {
|
||||||
var checkData = checkStatus.data;
|
var checkData = checkStatus.data;
|
||||||
if (checkData.length === 0) {
|
if (checkData.length === 0) {
|
||||||
return layer.msg('请选择要删除的数据');
|
return layer.msg('请选择要删除的数据');
|
||||||
}
|
}
|
||||||
layer.confirm('确定删除吗?删除后将无法恢复。',
|
layer.confirm('确定删除吗?删除后将无法恢复。',
|
||||||
function(index) {
|
function (index) {
|
||||||
var delidsStr = [];
|
var delidsStr = [];
|
||||||
layui.each(checkData,
|
layui.each(checkData,
|
||||||
function(index, item) {
|
function (index, item) {
|
||||||
delidsStr.push(item.id);
|
delidsStr.push(item.id);
|
||||||
});
|
});
|
||||||
coreHelper.Post("Api/SQRoomPricing/DoBatchDelete", { id: delidsStr }, function (e) {
|
coreHelper.Post("Api/SQRoomPricing/DoBatchDelete", { id: delidsStr }, function (e) {
|
||||||
|
|
@ -532,9 +543,9 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//执行查询条件导出excel
|
//执行查询条件导出excel
|
||||||
function doQueryExportexcel(){
|
function doQueryExportexcel() {
|
||||||
layer.confirm('确定根据当前的查询条件导出数据吗?',
|
layer.confirm('确定根据当前的查询条件导出数据吗?',
|
||||||
function(index) {
|
function (index) {
|
||||||
var field = searchwhere;
|
var field = searchwhere;
|
||||||
coreHelper.PostForm("Api/SQRoomPricing/QueryExportExcel", field, function (e) {
|
coreHelper.PostForm("Api/SQRoomPricing/QueryExportExcel", field, function (e) {
|
||||||
if (debug) { console.log(e); } //开启调试返回数据
|
if (debug) { console.log(e); } //开启调试返回数据
|
||||||
|
|
@ -547,16 +558,16 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//执行选择目录导出数据
|
//执行选择目录导出数据
|
||||||
function doSelectExportExcel(checkStatus){
|
function doSelectExportExcel(checkStatus) {
|
||||||
var checkData = checkStatus.data;
|
var checkData = checkStatus.data;
|
||||||
if (checkData.length === 0) {
|
if (checkData.length === 0) {
|
||||||
return layer.msg('请选择您要导出的数据');
|
return layer.msg('请选择您要导出的数据');
|
||||||
}
|
}
|
||||||
layer.confirm('确定导出选择的内容吗?',
|
layer.confirm('确定导出选择的内容吗?',
|
||||||
function(index) {
|
function (index) {
|
||||||
var delidsStr = [];
|
var delidsStr = [];
|
||||||
layui.each(checkData,
|
layui.each(checkData,
|
||||||
function(index, item) {
|
function (index, item) {
|
||||||
delidsStr.push(item.id);
|
delidsStr.push(item.id);
|
||||||
});
|
});
|
||||||
layer.close(index);
|
layer.close(index);
|
||||||
|
|
@ -584,7 +595,7 @@
|
||||||
|
|
||||||
|
|
||||||
// 视图切换功能
|
// 视图切换功能
|
||||||
$('#toggleViewBtn').on('click', function() {
|
$('#toggleViewBtn').on('click', function () {
|
||||||
if (currentView === 'table') {
|
if (currentView === 'table') {
|
||||||
// 切换到日历视图
|
// 切换到日历视图
|
||||||
currentView = 'calendar';
|
currentView = 'calendar';
|
||||||
|
|
@ -621,7 +632,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听房间选择变化(日历视图)
|
// 监听房间选择变化(日历视图)
|
||||||
form.on('select(search_room_id)', function(data) {
|
form.on('select(search_room_id)', function (data) {
|
||||||
if (currentView === 'calendar') {
|
if (currentView === 'calendar') {
|
||||||
selectedRoomId = data.value ? parseInt(data.value) : null;
|
selectedRoomId = data.value ? parseInt(data.value) : null;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
|
@ -634,13 +645,13 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// 上一月按钮
|
// 上一月按钮
|
||||||
$('#prevMonthBtn').on('click', function() {
|
$('#prevMonthBtn').on('click', function () {
|
||||||
currentMonth.setMonth(currentMonth.getMonth() - 1);
|
currentMonth.setMonth(currentMonth.getMonth() - 1);
|
||||||
renderCalendar();
|
renderCalendar();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 下一月按钮
|
// 下一月按钮
|
||||||
$('#nextMonthBtn').on('click', function() {
|
$('#nextMonthBtn').on('click', function () {
|
||||||
currentMonth.setMonth(currentMonth.getMonth() + 1);
|
currentMonth.setMonth(currentMonth.getMonth() + 1);
|
||||||
renderCalendar();
|
renderCalendar();
|
||||||
});
|
});
|
||||||
|
|
@ -670,7 +681,7 @@
|
||||||
|
|
||||||
// 添加星期标题
|
// 添加星期标题
|
||||||
var weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
var weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
||||||
weekdays.forEach(function(day) {
|
weekdays.forEach(function (day) {
|
||||||
calendarGrid.append('<div class="calendar-weekday">' + day + '</div>');
|
calendarGrid.append('<div class="calendar-weekday">' + day + '</div>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -693,7 +704,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定日期双击事件(查看详情)
|
// 绑定日期双击事件(查看详情)
|
||||||
$('#calendarGrid').off('dblclick', '.calendar-day').on('dblclick', '.calendar-day', function() {
|
$('#calendarGrid').off('dblclick', '.calendar-day').on('dblclick', '.calendar-day', function () {
|
||||||
var clickedDate = $(this).attr('data-date');
|
var clickedDate = $(this).attr('data-date');
|
||||||
if (clickedDate && !$(this).hasClass('empty')) {
|
if (clickedDate && !$(this).hasClass('empty')) {
|
||||||
showDateDetails(clickedDate);
|
showDateDetails(clickedDate);
|
||||||
|
|
@ -717,25 +728,323 @@
|
||||||
// 创建右键菜单
|
// 创建右键菜单
|
||||||
$.contextMenu({
|
$.contextMenu({
|
||||||
selector: '.calendar-day:not(.empty)',
|
selector: '.calendar-day:not(.empty)',
|
||||||
callback: function(key, options) {
|
callback: function (key, options) {
|
||||||
var dateStr = $(this).attr('data-date');
|
var dateStr = $(this).attr('data-date');
|
||||||
if (!dateStr) return;
|
if (!dateStr) return;
|
||||||
|
|
||||||
switch(key) {
|
switch (key) {
|
||||||
case 'view':
|
case 'view':
|
||||||
showDateDetails(dateStr);
|
showDateDetails(dateStr);
|
||||||
break;
|
break;
|
||||||
|
case 'setUnavailable':
|
||||||
|
showSetUnavailableDialog(dateStr);
|
||||||
|
break;
|
||||||
|
case 'cancelUnavailable':
|
||||||
|
showCancelUnavailableDialog(dateStr);
|
||||||
|
break;
|
||||||
|
case 'disableAllDay':
|
||||||
|
showDisableAllDayConfirm(dateStr);
|
||||||
|
break;
|
||||||
|
case 'cancelAllUnavailable':
|
||||||
|
showCancelAllUnavailableConfirm(dateStr);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items: {
|
items: {
|
||||||
"view": {
|
"view": {
|
||||||
name: "查看",
|
name: "查看",
|
||||||
icon: "fa-eye"
|
icon: "fa-eye"
|
||||||
|
},
|
||||||
|
"sep1": "---------",
|
||||||
|
"setUnavailable": {
|
||||||
|
name: "设置预约状态",
|
||||||
|
icon: "fa-ban"
|
||||||
|
},
|
||||||
|
"cancelUnavailable": {
|
||||||
|
name: "取消预约状态",
|
||||||
|
icon: "fa-check-circle"
|
||||||
|
},
|
||||||
|
"sep2": "---------",
|
||||||
|
"disableAllDay": {
|
||||||
|
name: "禁用整天",
|
||||||
|
icon: "fa-calendar-times"
|
||||||
|
},
|
||||||
|
"cancelAllUnavailable": {
|
||||||
|
name: "取消全部禁用",
|
||||||
|
icon: "fa-undo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 取消全部禁用确认
|
||||||
|
function showCancelAllUnavailableConfirm(dateStr) {
|
||||||
|
if (!selectedRoomId) {
|
||||||
|
layer.msg('请先选择房间');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedRoom = roomOptions.find(function (r) {
|
||||||
|
return r.id == selectedRoomId;
|
||||||
|
});
|
||||||
|
var roomName = selectedRoom ? selectedRoom.name : '未知房间';
|
||||||
|
|
||||||
|
layer.confirm('确定要取消 ' + roomName + ' 在 ' + dateStr + ' 的所有禁用吗?<br>这将取消该日期的所有时段禁用记录。', {
|
||||||
|
icon: 3,
|
||||||
|
title: '取消全部禁用确认'
|
||||||
|
}, function (confirmIndex) {
|
||||||
|
// 调用取消全部禁用接口
|
||||||
|
coreHelper.Post("Api/SQRoomPricing/CancelRoomUnavailableAllDay", {
|
||||||
|
roomId: selectedRoomId,
|
||||||
|
date: dateStr
|
||||||
|
}, function (e) {
|
||||||
|
layer.close(confirmIndex);
|
||||||
|
if (e.code === 0) {
|
||||||
|
layer.msg(e.msg);
|
||||||
|
refreshSingleDay(dateStr); // 只刷新当前日期
|
||||||
|
} else {
|
||||||
|
layer.msg(e.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 禁用整天确认
|
||||||
|
function showDisableAllDayConfirm(dateStr) {
|
||||||
|
if (!selectedRoomId) {
|
||||||
|
layer.msg('请先选择房间');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedRoom = roomOptions.find(function (r) {
|
||||||
|
return r.id == selectedRoomId;
|
||||||
|
});
|
||||||
|
var roomName = selectedRoom ? selectedRoom.name : '未知房间';
|
||||||
|
|
||||||
|
layer.confirm('确定要禁用 ' + roomName + ' 在 ' + dateStr + ' 的整天吗?<br>这将禁用该日期的所有时段(凌晨、上午、下午、晚上),类型为维护。', {
|
||||||
|
icon: 3,
|
||||||
|
title: '禁用整天确认'
|
||||||
|
}, function (confirmIndex) {
|
||||||
|
// 调用禁用整天接口
|
||||||
|
coreHelper.Post("Api/SQRoomPricing/SetRoomUnavailableAllDay", {
|
||||||
|
roomId: selectedRoomId,
|
||||||
|
date: dateStr
|
||||||
|
}, function (e) {
|
||||||
|
layer.close(confirmIndex);
|
||||||
|
if (e.code === 0) {
|
||||||
|
layer.msg(e.msg);
|
||||||
|
refreshSingleDay(dateStr); // 只刷新当前日期
|
||||||
|
} else {
|
||||||
|
layer.msg(e.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置禁用弹窗
|
||||||
|
function showSetUnavailableDialog(dateStr) {
|
||||||
|
if (!selectedRoomId) {
|
||||||
|
layer.msg('请先选择房间');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedRoom = roomOptions.find(function (r) {
|
||||||
|
return r.id == selectedRoomId;
|
||||||
|
});
|
||||||
|
var roomName = selectedRoom ? selectedRoom.name : '未知房间';
|
||||||
|
|
||||||
|
admin.popup({
|
||||||
|
shadeClose: false,
|
||||||
|
title: '设置禁用 - ' + roomName + ' - ' + dateStr,
|
||||||
|
area: ['1200px', '800px'],
|
||||||
|
id: 'LAY-popup-SQRoomPricing-unavailable',
|
||||||
|
btn: ['确定', '取消'],
|
||||||
|
success: function (layero, index) {
|
||||||
|
view(this.id).render('sq/sqroompricing/unavailable', {
|
||||||
|
data: {
|
||||||
|
dateStr: dateStr,
|
||||||
|
roomName: roomName,
|
||||||
|
selectedRoomId: selectedRoomId,
|
||||||
|
renderCalendar: renderCalendar,
|
||||||
|
refreshSingleDay: refreshSingleDay
|
||||||
|
}
|
||||||
|
}).done(function () {
|
||||||
|
form.render('radio', 'setUnavailableForm');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
yes: function (index, layero) {
|
||||||
|
// 调用模板中保存的提交处理函数
|
||||||
|
if (typeof window._setUnavailableSubmitHandler === 'function') {
|
||||||
|
window._setUnavailableSubmitHandler(layero, index);
|
||||||
|
} else {
|
||||||
|
layer.msg('提交处理函数未初始化');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消禁用弹窗
|
||||||
|
function showCancelUnavailableDialog(dateStr) {
|
||||||
|
if (!selectedRoomId) {
|
||||||
|
layer.msg('请先选择房间');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedRoom = roomOptions.find(function (r) {
|
||||||
|
return r.id == selectedRoomId;
|
||||||
|
});
|
||||||
|
var roomName = selectedRoom ? selectedRoom.name : '未知房间';
|
||||||
|
|
||||||
|
// 获取禁用列表
|
||||||
|
coreHelper.Get("Api/SQRoomPricing/GetRoomUnavailableList?roomId=" + selectedRoomId + "&date=" + encodeURIComponent(dateStr), function (e) {
|
||||||
|
if (e.code === 0) {
|
||||||
|
var list = e.data || [];
|
||||||
|
|
||||||
|
if (list.length === 0) {
|
||||||
|
layer.msg('该日期没有禁用记录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建弹窗内容
|
||||||
|
var content = '<div style="padding: 20px;">';
|
||||||
|
content += '<table id="unavailableListTable" lay-filter="unavailableListTable"></table>';
|
||||||
|
content += '</div>';
|
||||||
|
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: '取消禁用 - ' + roomName + ' - ' + dateStr,
|
||||||
|
area: ['700px', '400px'],
|
||||||
|
content: content,
|
||||||
|
btn: ['删除选中', '取消'],
|
||||||
|
success: function (layero, index) {
|
||||||
|
// 渲染表格
|
||||||
|
table.render({
|
||||||
|
elem: '#unavailableListTable',
|
||||||
|
data: list,
|
||||||
|
page: false,
|
||||||
|
cols: [[
|
||||||
|
{ type: 'checkbox', fixed: 'left' },
|
||||||
|
{ field: 'slot_name', title: '时段', width: 100 },
|
||||||
|
{ field: 'type_name', title: '类型', width: 100 },
|
||||||
|
{ field: 'reason', title: '原因', minWidth: 150 },
|
||||||
|
{ field: 'created_at', title: '创建时间', width: 160 }
|
||||||
|
]]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
yes: function (index, layero) {
|
||||||
|
var checkStatus = table.checkStatus('unavailableListTable');
|
||||||
|
var checkData = checkStatus.data;
|
||||||
|
|
||||||
|
if (checkData.length === 0) {
|
||||||
|
layer.msg('请选择要删除的记录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids = checkData.map(function (item) { return item.id; });
|
||||||
|
|
||||||
|
layer.confirm('确定要删除选中的禁用记录吗?', function (confirmIndex) {
|
||||||
|
coreHelper.Post("Api/SQRoomPricing/CancelRoomUnavailable", {
|
||||||
|
ids: ids
|
||||||
|
}, function (e) {
|
||||||
|
if (e.code === 0) {
|
||||||
|
layer.close(confirmIndex);
|
||||||
|
layer.close(index);
|
||||||
|
layer.msg(e.msg);
|
||||||
|
refreshSingleDay(dateStr); // 只刷新当前日期
|
||||||
|
} else {
|
||||||
|
layer.msg(e.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
layer.msg(e.msg || '获取数据失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新单个日期
|
||||||
|
function refreshSingleDay(dateStr) {
|
||||||
|
if (!selectedRoomId || !dateStr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dayElement = $('#calendarGrid').find('.calendar-day[data-date="' + dateStr + '"]');
|
||||||
|
if (dayElement.length === 0) {
|
||||||
|
if (debug) {
|
||||||
|
console.warn('未找到日期元素:', dateStr);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空加载提示(保留日期标题)
|
||||||
|
dayElement.find('div:not(.calendar-day-header)').remove();
|
||||||
|
|
||||||
|
// 显示加载中
|
||||||
|
dayElement.append('<div style="text-align:center;color:#999;padding:10px 0;">加载中...</div>');
|
||||||
|
|
||||||
|
coreHelper.Get("Api/SQRoomPricing/GetRoomListWithSlots?date=" + encodeURIComponent(dateStr) + "&showOnlyAvailable=false", function (e) {
|
||||||
|
// 再次清空内容(包括加载提示)
|
||||||
|
dayElement.find('div:not(.calendar-day-header)').remove();
|
||||||
|
|
||||||
|
if (e.code === 0 && e.data && Array.isArray(e.data)) {
|
||||||
|
// 注意:roomId 可能是字符串,需要类型转换比较
|
||||||
|
var roomData = e.data.find(function (r) {
|
||||||
|
return r.id == selectedRoomId || r.id == parseInt(selectedRoomId);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (roomData && roomData.time_slots && Array.isArray(roomData.time_slots)) {
|
||||||
|
var dayContentHtml = '';
|
||||||
|
|
||||||
|
// 显示价格信息
|
||||||
|
var firstSlot = roomData.time_slots[0];
|
||||||
|
if (firstSlot && firstSlot.price_desc_standard != '') {
|
||||||
|
dayContentHtml += '<div class="calendar-day-price">' + firstSlot.price_desc_standard + '</div>';
|
||||||
|
}
|
||||||
|
if (firstSlot && firstSlot.price_desc_member != '') {
|
||||||
|
dayContentHtml += '<div class="calendar-day-price">' + firstSlot.price_desc_member + '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示时段状态
|
||||||
|
dayContentHtml += '<div class="calendar-day-slots">';
|
||||||
|
roomData.time_slots.forEach(function (slot) {
|
||||||
|
var statusClass = 'unavailable';
|
||||||
|
var statusIcon = '✗';
|
||||||
|
|
||||||
|
// 检查该时段是否被后台预约禁用(unavailable_type=2)
|
||||||
|
if (slot.status === 'unavailable' && slot.unavailable_type === 2) {
|
||||||
|
// 后台预约:深橙色 + ✓
|
||||||
|
statusClass = 'backend-reservation';
|
||||||
|
statusIcon = '✓';
|
||||||
|
} else if (slot.status === 'available') {
|
||||||
|
statusClass = 'available';
|
||||||
|
statusIcon = '◯';
|
||||||
|
} else if (slot.status === 'reserved') {
|
||||||
|
statusClass = 'reserved';
|
||||||
|
statusIcon = '✓ ';
|
||||||
|
} else if (slot.status === 'using') {
|
||||||
|
statusClass = 'using';
|
||||||
|
statusIcon = '✗';
|
||||||
|
}
|
||||||
|
|
||||||
|
dayContentHtml += '<div class="calendar-slot ' + statusClass + '">' +
|
||||||
|
slot.slot_name + statusIcon + '</div>';
|
||||||
|
});
|
||||||
|
dayContentHtml += '</div>';
|
||||||
|
|
||||||
|
dayElement.append(dayContentHtml);
|
||||||
|
} else {
|
||||||
|
dayElement.append('<div style="text-align:center;color:#999;padding:10px 0;">无房间数据</div>');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var errorMsg = e.msg || '加载失败';
|
||||||
|
dayElement.append('<div style="text-align:center;color:#f44336;padding:10px 0;">' + errorMsg + '</div>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 加载月度数据
|
// 加载月度数据
|
||||||
function loadMonthData(roomId, startDate, endDate) {
|
function loadMonthData(roomId, startDate, endDate) {
|
||||||
var daysToLoad = [];
|
var daysToLoad = [];
|
||||||
|
|
@ -752,19 +1061,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量加载数据,每个日期加载完成后立即更新
|
// 批量加载数据,每个日期加载完成后立即更新
|
||||||
daysToLoad.forEach(function(date) {
|
daysToLoad.forEach(function (date) {
|
||||||
var dateStr = formatDate(date);
|
var dateStr = formatDate(date);
|
||||||
var url = layui.setter.apiUrl + "Api/SQRoomPricing/GetRoomListWithSlots?date=" + encodeURIComponent(dateStr) + "&showOnlyAvailable=false";
|
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
console.log('请求URL:', url);
|
console.log('请求日期:', dateStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
coreHelper.Get("Api/SQRoomPricing/GetRoomListWithSlots?date=" + encodeURIComponent(dateStr) + "&showOnlyAvailable=false", function (e) {
|
||||||
url: url,
|
|
||||||
type: 'GET',
|
|
||||||
dataType: 'json',
|
|
||||||
success: function(e) {
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
console.log('日期:', dateStr, '返回数据:', e);
|
console.log('日期:', dateStr, '返回数据:', e);
|
||||||
}
|
}
|
||||||
|
|
@ -785,7 +1089,7 @@
|
||||||
|
|
||||||
if (e.code === 0 && e.data && Array.isArray(e.data)) {
|
if (e.code === 0 && e.data && Array.isArray(e.data)) {
|
||||||
// 注意:roomId 可能是字符串,需要类型转换比较
|
// 注意:roomId 可能是字符串,需要类型转换比较
|
||||||
var roomData = e.data.find(function(r) {
|
var roomData = e.data.find(function (r) {
|
||||||
return r.id == roomId || r.id == parseInt(roomId);
|
return r.id == roomId || r.id == parseInt(roomId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -798,26 +1102,32 @@
|
||||||
|
|
||||||
// 显示价格信息
|
// 显示价格信息
|
||||||
var firstSlot = roomData.time_slots[0];
|
var firstSlot = roomData.time_slots[0];
|
||||||
if (firstSlot && firstSlot.standard_price) {
|
if (firstSlot && firstSlot.price_desc_standard != '') {
|
||||||
dayContentHtml += '<div class="calendar-day-price">' + firstSlot.standard_price + '元/时段</div>';
|
dayContentHtml += '<div class="calendar-day-price">' + firstSlot.price_desc_standard + '</div>';
|
||||||
}
|
}
|
||||||
if (firstSlot && firstSlot.member_price > 0) {
|
if (firstSlot && firstSlot.price_desc_member != '') {
|
||||||
dayContentHtml += '<div class="calendar-day-member">会员价</div>';
|
dayContentHtml += '<div class="calendar-day-price">' + firstSlot.price_desc_member + '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 显示时段状态
|
// 显示时段状态
|
||||||
dayContentHtml += '<div class="calendar-day-slots">';
|
dayContentHtml += '<div class="calendar-day-slots">';
|
||||||
roomData.time_slots.forEach(function(slot) {
|
roomData.time_slots.forEach(function (slot) {
|
||||||
var statusClass = 'unavailable';
|
var statusClass = 'unavailable';
|
||||||
var statusIcon = '✗';
|
var statusIcon = '✗';
|
||||||
|
|
||||||
if (slot.status === 'available') {
|
// 检查该时段是否被后台预约禁用(unavailable_type=2)
|
||||||
|
if (slot.status === 'unavailable' && slot.unavailable_type === 2) {
|
||||||
|
// 后台预约:深橙色 + ✓
|
||||||
|
statusClass = 'backend-reservation';
|
||||||
|
statusIcon = '✓';
|
||||||
|
} else if (slot.status === 'available') {
|
||||||
statusClass = 'available';
|
statusClass = 'available';
|
||||||
statusIcon = '◯';
|
statusIcon = '◯';
|
||||||
} else if (slot.status === 'reserved') {
|
} else if (slot.status === 'reserved') {
|
||||||
statusClass = 'reserved';
|
statusClass = 'reserved';
|
||||||
statusIcon = '✓ ';
|
statusIcon = '✓ ';
|
||||||
}else if( slot.status === 'using'){
|
} else if (slot.status === 'using') {
|
||||||
statusClass = 'using';
|
statusClass = 'using';
|
||||||
statusIcon = '✗';
|
statusIcon = '✗';
|
||||||
}
|
}
|
||||||
|
|
@ -835,16 +1145,8 @@
|
||||||
var errorMsg = e.msg || '加载失败';
|
var errorMsg = e.msg || '加载失败';
|
||||||
dayElement.append('<div style="text-align:center;color:#f44336;padding:10px 0;">' + errorMsg + '</div>');
|
dayElement.append('<div style="text-align:center;color:#f44336;padding:10px 0;">' + errorMsg + '</div>');
|
||||||
}
|
}
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
console.error('请求失败:', dateStr, status, error);
|
|
||||||
var dayElement = $('#calendarGrid').find('.calendar-day[data-date="' + dateStr + '"]');
|
|
||||||
if (dayElement.length > 0) {
|
|
||||||
dayElement.find('div:not(.calendar-day-header)').remove();
|
|
||||||
dayElement.append('<div style="text-align:center;color:#f44336;padding:10px 0;">网络错误</div>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -864,24 +1166,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找对应的房间名称
|
// 查找对应的房间名称
|
||||||
var selectedRoom = roomOptions.find(function(r) {
|
var selectedRoom = roomOptions.find(function (r) {
|
||||||
return r.id == selectedRoomId;
|
return r.id == selectedRoomId;
|
||||||
});
|
});
|
||||||
var roomName = selectedRoom ? selectedRoom.name : '未知房间';
|
var roomName = selectedRoom ? selectedRoom.name : '未知房间';
|
||||||
|
|
||||||
// 显示加载提示
|
|
||||||
var loadingIndex = layer.load(1, { shade: [0.1, '#fff'] });
|
|
||||||
|
|
||||||
// 请求详细数据
|
// 请求详细数据
|
||||||
var url = layui.setter.apiUrl + "Api/SQRoomPricing/GetDateDetails?date=" + encodeURIComponent(dateStr) + "&roomId=" + selectedRoomId;
|
coreHelper.Get("Api/SQRoomPricing/GetDateDetails?date=" + encodeURIComponent(dateStr) + "&roomId=" + selectedRoomId, function (e) {
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'GET',
|
|
||||||
dataType: 'json',
|
|
||||||
success: function(e) {
|
|
||||||
layer.close(loadingIndex);
|
|
||||||
|
|
||||||
if (e.code === 0 && e.data) {
|
if (e.code === 0 && e.data) {
|
||||||
var data = e.data;
|
var data = e.data;
|
||||||
|
|
||||||
|
|
@ -933,10 +1224,10 @@
|
||||||
title: roomName + ' - ' + dateStr + ' 详情',
|
title: roomName + ' - ' + dateStr + ' 详情',
|
||||||
area: ['1200px', '90%'],
|
area: ['1200px', '90%'],
|
||||||
content: content,
|
content: content,
|
||||||
success: function(layero, index) {
|
success: function (layero, index) {
|
||||||
// 渲染时段详情表格
|
// 渲染时段详情表格
|
||||||
if (data.time_slots && data.time_slots.length > 0) {
|
if (data.time_slots && data.time_slots.length > 0) {
|
||||||
var tableData = data.time_slots.map(function(slot) {
|
var tableData = data.time_slots.map(function (slot) {
|
||||||
return {
|
return {
|
||||||
slot_name: slot.slot_name || '',
|
slot_name: slot.slot_name || '',
|
||||||
status: slot.status || '',
|
status: slot.status || '',
|
||||||
|
|
@ -957,7 +1248,7 @@
|
||||||
field: 'status',
|
field: 'status',
|
||||||
title: '状态',
|
title: '状态',
|
||||||
width: 100,
|
width: 100,
|
||||||
templet: function(d) {
|
templet: function (d) {
|
||||||
var statusText = '';
|
var statusText = '';
|
||||||
var statusColor = '';
|
var statusColor = '';
|
||||||
if (d.status === 'available') {
|
if (d.status === 'available') {
|
||||||
|
|
@ -985,12 +1276,12 @@
|
||||||
field: 'participant_avatars',
|
field: 'participant_avatars',
|
||||||
title: '预约人头像',
|
title: '预约人头像',
|
||||||
width: 200,
|
width: 200,
|
||||||
templet: function(d) {
|
templet: function (d) {
|
||||||
if (!d.participant_avatars || d.participant_avatars.length === 0) {
|
if (!d.participant_avatars || d.participant_avatars.length === 0) {
|
||||||
return '<span style="color: #999;">无</span>';
|
return '<span style="color: #999;">无</span>';
|
||||||
}
|
}
|
||||||
var html = '<div style="display: flex; gap: 4px; flex-wrap: wrap;">';
|
var html = '<div style="display: flex; gap: 4px; flex-wrap: wrap;">';
|
||||||
d.participant_avatars.forEach(function(avatar) {
|
d.participant_avatars.forEach(function (avatar) {
|
||||||
html += '<img src="' + avatar + '" style="width:28px;height:28px;border-radius:50%;object-fit:cover;" onerror="this.src=\'/images/default-avatar.png\'" />';
|
html += '<img src="' + avatar + '" style="width:28px;height:28px;border-radius:50%;object-fit:cover;" onerror="this.src=\'/images/default-avatar.png\'" />';
|
||||||
});
|
});
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
@ -1017,7 +1308,7 @@
|
||||||
slotHtml += ' <h3 style="padding: 10px; background: #f8f8f8; border-left: 4px solid #009688;">预约详情列表(' + slotNames[slotType] + ')</h3>';
|
slotHtml += ' <h3 style="padding: 10px; background: #f8f8f8; border-left: 4px solid #009688;">预约详情列表(' + slotNames[slotType] + ')</h3>';
|
||||||
|
|
||||||
// 遍历该时段的每个预约
|
// 遍历该时段的每个预约
|
||||||
slotReservations.forEach(function(reservation, idx) {
|
slotReservations.forEach(function (reservation, idx) {
|
||||||
slotHtml += ' <div class="layui-card" style="margin-top: 10px;">';
|
slotHtml += ' <div class="layui-card" style="margin-top: 10px;">';
|
||||||
slotHtml += ' <div class="layui-card-header">';
|
slotHtml += ' <div class="layui-card-header">';
|
||||||
slotHtml += ' <div class="layui-row">';
|
slotHtml += ' <div class="layui-row">';
|
||||||
|
|
@ -1044,7 +1335,7 @@
|
||||||
reservationsBySlotContainer.append(slotHtml);
|
reservationsBySlotContainer.append(slotHtml);
|
||||||
|
|
||||||
// 渲染每个预约的参与者表格
|
// 渲染每个预约的参与者表格
|
||||||
slotReservations.forEach(function(reservation, idx) {
|
slotReservations.forEach(function (reservation, idx) {
|
||||||
var participants = reservation.participants || [];
|
var participants = reservation.participants || [];
|
||||||
|
|
||||||
table.render({
|
table.render({
|
||||||
|
|
@ -1059,7 +1350,7 @@
|
||||||
field: 'avatar_image',
|
field: 'avatar_image',
|
||||||
title: '用户头像',
|
title: '用户头像',
|
||||||
width: 80,
|
width: 80,
|
||||||
templet: function(d) {
|
templet: function (d) {
|
||||||
if (d.avatar_image) {
|
if (d.avatar_image) {
|
||||||
return '<img src="' + d.avatar_image + '" style="width:40px;height:40px;border-radius:50%;object-fit:cover;" onerror="this.src=\'/images/default-avatar.png\'" />';
|
return '<img src="' + d.avatar_image + '" style="width:40px;height:40px;border-radius:50%;object-fit:cover;" onerror="this.src=\'/images/default-avatar.png\'" />';
|
||||||
}
|
}
|
||||||
|
|
@ -1071,7 +1362,7 @@
|
||||||
field: 'role',
|
field: 'role',
|
||||||
title: '角色',
|
title: '角色',
|
||||||
width: 80,
|
width: 80,
|
||||||
templet: function(d) {
|
templet: function (d) {
|
||||||
return d.role === 1 ? '<span style="color: #ff5722;">发起者</span>' : '参与者';
|
return d.role === 1 ? '<span style="color: #ff5722;">发起者</span>' : '参与者';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1080,10 +1371,10 @@
|
||||||
field: 'is_refund',
|
field: 'is_refund',
|
||||||
title: '鸽子费状态',
|
title: '鸽子费状态',
|
||||||
width: 100,
|
width: 100,
|
||||||
templet: function(d) {
|
templet: function (d) {
|
||||||
var refundText = '';
|
var refundText = '';
|
||||||
var refundColor = '';
|
var refundColor = '';
|
||||||
switch(d.is_refund) {
|
switch (d.is_refund) {
|
||||||
case 0:
|
case 0:
|
||||||
refundText = '无需退款';
|
refundText = '无需退款';
|
||||||
refundColor = '#999';
|
refundColor = '#999';
|
||||||
|
|
@ -1127,12 +1418,6 @@
|
||||||
} else {
|
} else {
|
||||||
layer.msg(e.msg || '获取数据失败');
|
layer.msg(e.msg || '获取数据失败');
|
||||||
}
|
}
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
layer.close(loadingIndex);
|
|
||||||
console.error('请求失败:', status, error);
|
|
||||||
layer.msg('获取数据失败,请稍后重试');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1160,4 +1445,3 @@
|
||||||
<script type="text/html" id="switch_is_active">
|
<script type="text/html" id="switch_is_active">
|
||||||
<input type="checkbox" name="switch_is_active" value="{{d.id}}" lay-skin="switch" lay-text="开启|关闭" lay-filter="switch_is_active" {{ d.is_active ? 'checked' : '' }}>
|
<input type="checkbox" name="switch_is_active" value="{{d.id}}" lay-skin="switch" lay-text="开启|关闭" lay-filter="switch_is_active" {{ d.is_active ? 'checked' : '' }}>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,351 @@
|
||||||
|
<script type="text/html" template lay-done="layui.data.sendParams(d);">
|
||||||
|
<div class="layui-form" lay-filter="setUnavailableForm" style="padding: 20px;">
|
||||||
|
<!-- 日期和房间合并一行 -->
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">日期</label>
|
||||||
|
<div class="layui-input-inline" style="width: 200px;">
|
||||||
|
<input type="text" class="layui-input" value="{{d.params.data.dateStr || ''}}" readonly>
|
||||||
|
</div>
|
||||||
|
<label class="layui-form-label" style="margin-left: 20px;">房间</label>
|
||||||
|
<div class="layui-input-inline" style="width: 200px;">
|
||||||
|
<input type="text" class="layui-input" value="{{d.params.data.roomName || ''}}" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 时段列表 -->
|
||||||
|
<div class="time-slot-list" style="margin-top: 20px;">
|
||||||
|
<!-- 凌晨时段 -->
|
||||||
|
<div class="time-slot-item" data-slot="0" style="border: 1px solid #e6e6e6; border-radius: 4px; padding: 15px; margin-bottom: 15px; background: #fff;">
|
||||||
|
<div class="layui-form-item" style="margin-bottom: 10px;">
|
||||||
|
<label class="layui-form-label" style="width: 80px;">凌晨:</label>
|
||||||
|
<div class="layui-input-block" style="margin-left: 90px; display: flex; align-items: center; flex-wrap: wrap;">
|
||||||
|
<input type="checkbox" name="switch_0" lay-skin="switch" lay-text="开启|关闭" lay-filter="slot-switch">
|
||||||
|
<input type="hidden" name="slot_id_0" value="">
|
||||||
|
<div style="margin-left: 20px; flex: 1; min-width: 200px;">
|
||||||
|
<div style="display: inline-block; margin-right: 20px;">
|
||||||
|
<input type="radio" name="type_0" value="1" title="禁用/维护" checked disabled>
|
||||||
|
<input type="radio" name="type_0" value="2" title="后台预约" disabled>
|
||||||
|
<input type="radio" name="type_0" value="3" title="线下预约" disabled>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block; width: 300px;">
|
||||||
|
<input type="text" name="reason_0" placeholder="请输入原因/备注" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 上午时段 -->
|
||||||
|
<div class="time-slot-item" data-slot="1" style="border: 1px solid #e6e6e6; border-radius: 4px; padding: 15px; margin-bottom: 15px; background: #fff;">
|
||||||
|
<div class="layui-form-item" style="margin-bottom: 10px;">
|
||||||
|
<label class="layui-form-label" style="width: 80px;">上午:</label>
|
||||||
|
<div class="layui-input-block" style="margin-left: 90px; display: flex; align-items: center; flex-wrap: wrap;">
|
||||||
|
<input type="checkbox" name="switch_1" lay-skin="switch" lay-text="开启|关闭" lay-filter="slot-switch">
|
||||||
|
<input type="hidden" name="slot_id_1" value="">
|
||||||
|
<div style="margin-left: 20px; flex: 1; min-width: 200px;">
|
||||||
|
<div style="display: inline-block; margin-right: 20px;">
|
||||||
|
<input type="radio" name="type_1" value="1" title="禁用/维护" checked disabled>
|
||||||
|
<input type="radio" name="type_1" value="2" title="后台预约" disabled>
|
||||||
|
<input type="radio" name="type_1" value="3" title="线下预约" disabled>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block; width: 300px;">
|
||||||
|
<input type="text" name="reason_1" placeholder="请输入原因/备注" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 下午时段 -->
|
||||||
|
<div class="time-slot-item" data-slot="2" style="border: 1px solid #e6e6e6; border-radius: 4px; padding: 15px; margin-bottom: 15px; background: #fff;">
|
||||||
|
<div class="layui-form-item" style="margin-bottom: 10px;">
|
||||||
|
<label class="layui-form-label" style="width: 80px;">下午:</label>
|
||||||
|
<div class="layui-input-block" style="margin-left: 90px; display: flex; align-items: center; flex-wrap: wrap;">
|
||||||
|
<input type="checkbox" name="switch_2" lay-skin="switch" lay-text="开启|关闭" lay-filter="slot-switch">
|
||||||
|
<input type="hidden" name="slot_id_2" value="">
|
||||||
|
<div style="margin-left: 20px; flex: 1; min-width: 200px;">
|
||||||
|
<div style="display: inline-block; margin-right: 20px;">
|
||||||
|
<input type="radio" name="type_2" value="1" title="禁用/维护" checked disabled>
|
||||||
|
<input type="radio" name="type_2" value="2" title="后台预约" disabled>
|
||||||
|
<input type="radio" name="type_2" value="3" title="线下预约" disabled>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block; width: 300px;">
|
||||||
|
<input type="text" name="reason_2" placeholder="请输入原因/备注" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 晚上时段 -->
|
||||||
|
<div class="time-slot-item" data-slot="3" style="border: 1px solid #e6e6e6; border-radius: 4px; padding: 15px; margin-bottom: 15px; background: #fff;">
|
||||||
|
<div class="layui-form-item" style="margin-bottom: 10px;">
|
||||||
|
<label class="layui-form-label" style="width: 80px;">晚上:</label>
|
||||||
|
<div class="layui-input-block" style="margin-left: 90px; display: flex; align-items: center; flex-wrap: wrap;">
|
||||||
|
<input type="checkbox" name="switch_3" lay-skin="switch" lay-text="开启|关闭" lay-filter="slot-switch">
|
||||||
|
<input type="hidden" name="slot_id_3" value="">
|
||||||
|
<div style="margin-left: 20px; flex: 1; min-width: 200px;">
|
||||||
|
<div style="display: inline-block; margin-right: 20px;">
|
||||||
|
<input type="radio" name="type_3" value="1" title="禁用/维护" checked disabled>
|
||||||
|
<input type="radio" name="type_3" value="2" title="后台预约" disabled>
|
||||||
|
<input type="radio" name="type_3" value="3" title="线下预约" disabled>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block; width: 300px;">
|
||||||
|
<input type="text" name="reason_3" placeholder="请输入原因/备注" class="layui-input" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
var debug = layui.setter.debug;
|
||||||
|
layui.data.sendParams = function (d) {
|
||||||
|
//开启调试情况下获取接口赋值数据
|
||||||
|
if (debug) { console.log(d.params.data); }
|
||||||
|
layui.use(['admin', 'form', 'element', 'coreHelper', 'layer'],
|
||||||
|
function () {
|
||||||
|
var $ = layui.$
|
||||||
|
, form = layui.form
|
||||||
|
, element = layui.element
|
||||||
|
, admin = layui.admin
|
||||||
|
, coreHelper = layui.coreHelper
|
||||||
|
, layer = layui.layer;
|
||||||
|
|
||||||
|
var params = d.params.data;
|
||||||
|
var dateStr = params.dateStr;
|
||||||
|
var selectedRoomId = params.selectedRoomId;
|
||||||
|
var renderCalendar = params.renderCalendar;
|
||||||
|
var refreshSingleDay = params.refreshSingleDay; // 刷新单个日期的函数
|
||||||
|
|
||||||
|
// 存储已禁用的记录ID,用于取消禁用
|
||||||
|
var unavailableRecords = {};
|
||||||
|
// 存储原始数据,用于对比是否有变化
|
||||||
|
var originalData = {};
|
||||||
|
|
||||||
|
// 切换时段表单元素的启用/禁用状态
|
||||||
|
function toggleSlotForm(slotType, enabled) {
|
||||||
|
var slotItem = $('.time-slot-item[data-slot="' + slotType + '"]');
|
||||||
|
var typeRadios = slotItem.find('input[name="type_' + slotType + '"]');
|
||||||
|
var reasonInput = slotItem.find('input[name="reason_' + slotType + '"]');
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
typeRadios.prop('disabled', false);
|
||||||
|
reasonInput.prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
typeRadios.prop('disabled', true);
|
||||||
|
reasonInput.prop('disabled', true);
|
||||||
|
}
|
||||||
|
form.render('radio', 'setUnavailableForm');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新时段状态显示
|
||||||
|
function updateSlotStatus(slotType, item) {
|
||||||
|
var slotItem = $('.time-slot-item[data-slot="' + slotType + '"]');
|
||||||
|
var switchInput = slotItem.find('input[name="switch_' + slotType + '"]');
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
// 已禁用,打开开关
|
||||||
|
switchInput.prop('checked', true);
|
||||||
|
// 保存记录ID
|
||||||
|
slotItem.find('input[name="slot_id_' + slotType + '"]').val(item.id);
|
||||||
|
unavailableRecords[slotType] = item.id;
|
||||||
|
// 保存原始数据用于对比
|
||||||
|
originalData[slotType] = {
|
||||||
|
type: item.type,
|
||||||
|
reason: item.reason || '',
|
||||||
|
enabled: true
|
||||||
|
};
|
||||||
|
// 启用表单元素
|
||||||
|
toggleSlotForm(slotType, true);
|
||||||
|
} else {
|
||||||
|
// 未禁用,关闭开关
|
||||||
|
switchInput.prop('checked', false);
|
||||||
|
slotItem.find('input[name="slot_id_' + slotType + '"]').val('');
|
||||||
|
delete unavailableRecords[slotType];
|
||||||
|
originalData[slotType] = {
|
||||||
|
type: null,
|
||||||
|
reason: '',
|
||||||
|
enabled: false
|
||||||
|
};
|
||||||
|
// 禁用表单元素
|
||||||
|
toggleSlotForm(slotType, false);
|
||||||
|
}
|
||||||
|
form.render('checkbox', 'setUnavailableForm');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开关切换事件
|
||||||
|
form.on('switch(slot-switch)', function(data) {
|
||||||
|
var slotType = parseInt(data.elem.name.replace('switch_', ''));
|
||||||
|
var isChecked = data.elem.checked;
|
||||||
|
var slotItem = $('.time-slot-item[data-slot="' + slotType + '"]');
|
||||||
|
|
||||||
|
toggleSlotForm(slotType, isChecked);
|
||||||
|
|
||||||
|
// 如果关闭开关,清空类型和原因
|
||||||
|
if (!isChecked) {
|
||||||
|
slotItem.find('input[name="type_' + slotType + '"][value="1"]').prop('checked', true);
|
||||||
|
slotItem.find('input[name="reason_' + slotType + '"]').val('');
|
||||||
|
form.render('radio', 'setUnavailableForm');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载该日期的禁用记录
|
||||||
|
coreHelper.Get("Api/SQRoomPricing/GetRoomUnavailableList?roomId=" + selectedRoomId + "&date=" + encodeURIComponent(dateStr), function(e) {
|
||||||
|
if (e.code === 0 && e.data) {
|
||||||
|
// 初始化所有时段为未禁用状态
|
||||||
|
for (var i = 0; i <= 3; i++) {
|
||||||
|
updateSlotStatus(i, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历禁用记录,填充到对应的时段
|
||||||
|
if (e.data && e.data.length > 0) {
|
||||||
|
layui.each(e.data, function(index, item) {
|
||||||
|
var slotType = item.time_slot_type;
|
||||||
|
if (slotType !== null && slotType !== undefined && slotType >= 0 && slotType <= 3) {
|
||||||
|
// 设置类型单选框
|
||||||
|
var typeRadio = $('input[name="type_' + slotType + '"][value="' + item.type + '"]');
|
||||||
|
if (typeRadio.length > 0) {
|
||||||
|
typeRadio.prop('checked', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置原因
|
||||||
|
var reasonInput = $('input[name="reason_' + slotType + '"]');
|
||||||
|
if (reasonInput.length > 0) {
|
||||||
|
reasonInput.val(item.reason || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新状态显示
|
||||||
|
updateSlotStatus(slotType, item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//重载form
|
||||||
|
form.render('radio', 'setUnavailableForm');
|
||||||
|
form.render('checkbox', 'setUnavailableForm');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 保存提交处理函数到全局,供弹窗的确定按钮调用
|
||||||
|
window._setUnavailableSubmitHandler = function(layero, index) {
|
||||||
|
var saveTasks = [];
|
||||||
|
var cancelTasks = [];
|
||||||
|
var hasChanges = false;
|
||||||
|
|
||||||
|
// 遍历所有4个时段,收集需要保存或取消的数据
|
||||||
|
for (var slotType = 0; slotType <= 3; slotType++) {
|
||||||
|
var switchChecked = layero.find('input[name="switch_' + slotType + '"]').prop('checked');
|
||||||
|
var slotId = layero.find('input[name="slot_id_' + slotType + '"]').val();
|
||||||
|
var original = originalData[slotType] || { type: null, reason: '', enabled: false };
|
||||||
|
|
||||||
|
if (switchChecked) {
|
||||||
|
// 开关开启,需要设置禁用
|
||||||
|
var type = parseInt(layero.find('input[name="type_' + slotType + '"]:checked').val());
|
||||||
|
var reason = (layero.find('input[name="reason_' + slotType + '"]').val() || '').trim();
|
||||||
|
|
||||||
|
// 判断是否需要保存(新增或修改)
|
||||||
|
var needSave = false;
|
||||||
|
if (slotId) {
|
||||||
|
// 已禁用状态,检查是否有修改
|
||||||
|
if (original.type !== type || original.reason !== reason) {
|
||||||
|
needSave = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 未禁用状态,需要新增
|
||||||
|
needSave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needSave) {
|
||||||
|
hasChanges = true;
|
||||||
|
saveTasks.push({
|
||||||
|
slotType: slotType,
|
||||||
|
type: type,
|
||||||
|
reason: reason
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 开关关闭,需要取消禁用
|
||||||
|
if (slotId) {
|
||||||
|
hasChanges = true;
|
||||||
|
cancelTasks.push({
|
||||||
|
slotType: slotType,
|
||||||
|
slotId: parseInt(slotId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasChanges) {
|
||||||
|
layer.msg('没有需要保存的更改');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示加载提示
|
||||||
|
var loadIndex = layer.load(1, {shade: [0.1,'#fff']});
|
||||||
|
var completedCount = 0;
|
||||||
|
var totalTasks = saveTasks.length + cancelTasks.length;
|
||||||
|
var hasError = false;
|
||||||
|
var errorMsg = '';
|
||||||
|
|
||||||
|
// 依次执行保存和取消任务
|
||||||
|
function executeNext() {
|
||||||
|
if (completedCount >= totalTasks) {
|
||||||
|
layer.close(loadIndex);
|
||||||
|
if (hasError) {
|
||||||
|
layer.msg(errorMsg || '部分操作失败');
|
||||||
|
} else {
|
||||||
|
layer.close(index);
|
||||||
|
layer.msg('保存成功');
|
||||||
|
// 优先使用刷新单个日期,如果没有则刷新整个日历
|
||||||
|
if (refreshSingleDay && typeof refreshSingleDay === 'function') {
|
||||||
|
refreshSingleDay(dateStr); // 只刷新当前日期
|
||||||
|
} else if (renderCalendar && typeof renderCalendar === 'function') {
|
||||||
|
renderCalendar(); // 刷新整个日历(兼容旧逻辑)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先执行取消任务,再执行保存任务
|
||||||
|
if (completedCount < cancelTasks.length) {
|
||||||
|
var cancelTask = cancelTasks[completedCount];
|
||||||
|
coreHelper.Post("Api/SQRoomPricing/CancelRoomUnavailable", {
|
||||||
|
ids: [cancelTask.slotId]
|
||||||
|
}, function(e) {
|
||||||
|
completedCount++;
|
||||||
|
if (e.code !== 0) {
|
||||||
|
hasError = true;
|
||||||
|
errorMsg = e.msg || '取消失败';
|
||||||
|
}
|
||||||
|
executeNext();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var saveTask = saveTasks[completedCount - cancelTasks.length];
|
||||||
|
coreHelper.Post("Api/SQRoomPricing/SetRoomUnavailable", {
|
||||||
|
roomId: selectedRoomId,
|
||||||
|
date: dateStr,
|
||||||
|
timeSlotType: saveTask.slotType,
|
||||||
|
type: saveTask.type,
|
||||||
|
reason: saveTask.reason
|
||||||
|
}, function(e) {
|
||||||
|
completedCount++;
|
||||||
|
if (e.code !== 0) {
|
||||||
|
hasError = true;
|
||||||
|
errorMsg = e.msg || '保存失败';
|
||||||
|
}
|
||||||
|
executeNext();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始执行
|
||||||
|
executeNext();
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user