diff --git a/web/App_Code/GuaDanStatusCode.cs b/web/App_Code/GuaDanStatusCode.cs new file mode 100644 index 0000000..3cbcd0b --- /dev/null +++ b/web/App_Code/GuaDanStatusCode.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +/// +/// GuaDanStatusCode 的摘要描述 +/// +public static class GuaDanStatusCode +{ + public static class Bed + { + public const string Empty = "101"; // 空床:床位可分配 + public const string Occupied = "102"; // 占用中:床位已有人使用 + public const string Repair = "103"; // 維修停用:床位維修或不可使用 + } + + public static class Room + { + public const string Empty = "301"; // 空房:房間所有床位皆為空 + public const string Partly = "302"; // 部分入住:房間有人,但仍有空床 + public const string Full = "303"; // 已滿:房間所有床位皆已入住 + public const string Repair = "304"; // 維修停用:房間維修或不可使用 + } + + public static class Guadan + { + public const string Booked = "401"; // 預訂成功:默認就是預訂成功狀態 + public const string CheckedIn = "402"; // 已入住:已辦理入住 + public const string CheckedOut = "403"; // 已退房 + public const string Cancelled = "404"; // 已取消:取消後的狀態,不是取消的動作 + } +} diff --git a/web/App_Code/api/HandleBedInUsedController.cs b/web/App_Code/api/HandleBedInUsedController.cs new file mode 100644 index 0000000..dfa841a --- /dev/null +++ b/web/App_Code/api/HandleBedInUsedController.cs @@ -0,0 +1,184 @@ +using Model; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Web; +using System.Web.Http; +using System.Web.Http.Results; +using static GuaDanStatusCode; + +/// +/// HandleBedInUsedController 的摘要描述 +/// +public class HandleBedInUsedController : ApiController +{ + private Model.ezEntities _db = new Model.ezEntities(); + public HandleBedInUsedController() + { + // + // TODO: 在這裡新增建構函式邏輯 + // + } + [HttpPost] + [Route("api/bed/inuse/list")] + public IHttpActionResult Get([FromBody] UuidModel uuidModel) + { + //獲取已被預約或者正在入住的床位,如果有指定就會查詢指定條件,如果沒有指定就會返回所有 + var query = _db.GuaDanOrderGuest + .Where(gd => gd.StatusCode == GuaDanStatusCode.Guadan.CheckedIn + || gd.StatusCode == GuaDanStatusCode.Guadan.Booked).ToList(); + if (uuidModel.bedUuid.HasValue) + { + // 優先按床位查詢 + query = query.Where(g => g.BedUuid == uuidModel.bedUuid.Value).ToList(); + } + else if (uuidModel.roomUuid.HasValue) + { + // 如果沒有 bed,但有 room + query = query.Where(g => g.RoomUuid == uuidModel.roomUuid.Value).ToList(); + } + else if (uuidModel.regionUuid.HasValue) + { + // 如果只有 region + //query = query.Where(g => g.Room.RegionUuid == uuidModel.regionUuid.Value); + query = query.Where(g => IsRegionOrAncestor(g.Room, uuidModel.regionUuid.Value)).ToList(); + + } + var data = query.Select(g => new + { + g.BedUuid, + g.RoomUuid, + g.Room.RegionUuid, + g.GuaDanOrderNo, + g.RegionRoomBed.Name, + fullName = GetFullBedName(g.BedUuid.Value), + g.followers.u_name, + guadan_during = new { g.CheckInAt, g.CheckOutAt }, + status = new { g.StatusCode, g.RegionRoomBedStatus.Name } + }); + return Ok(data.ToList()); + } + + [HttpPost] + [Route("api/bed/inuse/cancel/singlebed/booking")] + public IHttpActionResult CancelSingleBedBooking([FromBody] UuidModel uuidModel) + { + if (uuidModel?.bedUuid == null) + return BadRequest("床位ID不能為空"); + + using (var transaction = _db.Database.BeginTransaction()) + { + try + { + // 查詢符合條件的訂單 + var orders = _db.GuaDanOrderGuest + .Where(g => g.BedUuid == uuidModel.bedUuid) + .Where(g => g.StatusCode == GuaDanStatusCode.Guadan.Booked || g.StatusCode == GuaDanStatusCode.Guadan.CheckedIn) + .ToList(); + + if (!orders.Any()) + return NotFound(); + + // 更新狀態 + foreach (var order in orders) + { + if (!StatusTransitionManager.CanTransition(order.StatusCode, GuaDanStatusCode.Guadan.Cancelled)) + { + return BadRequest("當前狀態不能被取消"); + } + + + order.StatusCode = GuaDanStatusCode.Guadan.Cancelled; // 假設Cancelled是取消狀態 + } + var schedules = _db.RegionAndRoomAndBedSchedule + .Where(s => s.TargetUuid == uuidModel.bedUuid) + .Where(s => s.GuaDanOrderGuest.StatusCode == GuaDanStatusCode.Guadan.Booked + || s.GuaDanOrderGuest.StatusCode == GuaDanStatusCode.Guadan.CheckedIn) + .ToList(); + foreach (var schedule in schedules) + { + schedule.IsCancel = true; + } + _db.SaveChanges(); + transaction.Commit(); + + return Ok(new { message = "取消成功", cancelledCount = orders.Count }); + } + catch (Exception ex) + { + transaction.Rollback(); + return InternalServerError(ex); + } + } + } + [HttpGet] + [Route("api/bed/inuse/region/list")] + public IHttpActionResult GetRegionList() + { + var regions = _db.Region + .Select(r => new + { + r.Uuid, + r.Name, + }) + .ToList(); + return Ok(regions); + } + [HttpGet] + [Route("api/bed/inuse/room/list")] + public IHttpActionResult GetRoomList([FromUri] Guid? regionUuid = null) + { + var room = _db.Room.Where(r => !r.IsDeleted && r.IsActive.Value).ToList(); + if (regionUuid != null) + { + room = room.Where(r => IsRegionOrAncestor(r, regionUuid.Value)).ToList(); + } + var data = room.Select(r => new + { + r.Uuid, + r.Name, + fullName = r.Region.Name + "/" + r.Name, + }).ToList(); + return Ok(data); + } + public string GetFullBedName(Guid bedUuid) + { + var bed = _db.RegionRoomBed.Find(bedUuid); + if (bed == null) + return ""; + var name = bed.Name; + var room = bed.Room; + if (room == null) + return name; + name = room.Name + "/" + name; + + var region = room?.Region; + while (region != null) + { + name = region.Name + "/" + name; + region = region.Region2; // 遞迴向上 + } + + return name; + } + bool IsRegionOrAncestor(Model.Room room, Guid regionUuid) + { + //判斷傳入的regionuuid是否是room的祖先 + if (room.RegionUuid == regionUuid) + return true; + var region = room.Region; + while (region != null) + { + if (region.Uuid == regionUuid) return true; + region = region.Region2; + } + return false; + } + public class UuidModel + { + public Guid? regionUuid = null; + public Guid? roomUuid = null; + public Guid? bedUuid = null; + } +} \ No newline at end of file diff --git a/web/App_Code/api/guadanGuestQueryController.cs b/web/App_Code/api/guadanGuestQueryController.cs index e86a447..0abc658 100644 --- a/web/App_Code/api/guadanGuestQueryController.cs +++ b/web/App_Code/api/guadanGuestQueryController.cs @@ -80,9 +80,9 @@ public class guadanGuestQueryController: ApiController { var today = DateTime.Now.Date; var data = await _db.GuaDanOrderGuest - .Where(guest => guest.StatusCode == "402") + .Where(guest => guest.StatusCode == "402" || guest.StatusCode == "403") .Where(guest => guest.RegionAndRoomAndBedSchedule - .Any(s => s.ScheduleDate == date.Date && s.ScheduleDate == today) == true) + .Any(s => s.ScheduleDate == date.Date && s.ScheduleDate <= today) == true) .Select(guest => new { name = guest.followers.u_name, @@ -96,7 +96,7 @@ public class guadanGuestQueryController: ApiController public async Task GetBookingGuest([FromUri] DateTime date) { var data = await _db.GuaDanOrderGuest - .Where(guest => guest.StatusCode == "402" || guest.StatusCode == "401") + .Where(guest => guest.StatusCode == "402" || guest.StatusCode == "401" || guest.StatusCode == "403") .Where(guest => guest.RegionAndRoomAndBedSchedule.Any(s => s.ScheduleDate == date.Date) == true) .Select(guest => new { diff --git a/web/App_Code/api/guadanOrderController.cs b/web/App_Code/api/guadanOrderController.cs index 07b63f8..b3966af 100644 --- a/web/App_Code/api/guadanOrderController.cs +++ b/web/App_Code/api/guadanOrderController.cs @@ -24,12 +24,12 @@ public class guadanOrderController : ApiController var query = _db.GuaDanOrder .Where(a => a.IsCancel == false) .Where(a => a.IsDeleted == false); - if(search.guadanUser != null) + if (search.guadanUser != null) { query = query.Where(order => order.BookerName == search.guadanUser); } if (search.startDate != null && search.endDate != null) - { + { query = query.Where(order => order.StartDate >= search.startDate) .Where(order => order.EndDate <= search.endDate); } @@ -56,11 +56,28 @@ public class guadanOrderController : ApiController created_at = a.CreatedAt, updated_at = a.UpdatedAt, notes = a.Notes, + activity = _db.activities + .Where(act => act.num == a.ActivityNum) + .Select(act => new + { + subject = act.subject + }) + .FirstOrDefault(), bookerName = a.BookerName, guest_count = _db.GuaDanOrderGuest .Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false) .Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED) .Count(), + statusName = _db.GuaDanOrderGuest + .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo) + .All(g => g.StatusCode == "404") ? "預約" : + _db.GuaDanOrderGuest + .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo) + .All(g => g.StatusCode == "403") ? "全部退房" : + _db.GuaDanOrderGuest + .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo) + .Any(g => g.StatusCode == "401") ? "正在入住" : + "混合狀態" }) .Skip((search.page - 1) * search.pageSize) .Take(search.pageSize) @@ -81,7 +98,7 @@ public class guadanOrderController : ApiController .FirstOrDefaultAsync(); if (order == null) { - return BadRequest("未找到对应订单"); + return BadRequest("未找到對應訂單"); } var result = new { @@ -115,7 +132,7 @@ public class guadanOrderController : ApiController } if (model.Uuid.HasValue) { - return BadRequest("已存在对应挂单资料"); + return BadRequest("已存在對應掛單資料"); } try { @@ -174,7 +191,7 @@ public class guadanOrderController : ApiController var order = await _db.GuaDanOrder.FindAsync(model.Uuid.Value); if (order == null) { - return BadRequest("未找到对应挂单资料"); + return BadRequest("未找到對應掛單資料"); } order.StartDate = model.startdate; order.EndDate = model.enddate; @@ -194,9 +211,9 @@ public class guadanOrderController : ApiController { return NotFound(); } - if(_db.GuaDanOrderGuest.Any(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo) ) + if (_db.GuaDanOrderGuest.Any(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)) { - return BadRequest($"该挂单已经存在挂单莲友,不能取消!"); + return BadRequest($"該掛單已經存在掛單蓮友,不能取消!"); } using (var transaction = _db.Database.BeginTransaction()) { diff --git a/web/App_Code/api/guadanOrderGuestController.cs b/web/App_Code/api/guadanOrderGuestController.cs index fac10e7..67eefec 100644 --- a/web/App_Code/api/guadanOrderGuestController.cs +++ b/web/App_Code/api/guadanOrderGuestController.cs @@ -46,12 +46,13 @@ public class guadanOrderGuestController : ApiController checkoutat = a.CheckOutAt.HasValue ? a.CheckOutAt.Value.ToString("yyyy-MM-dd") : null, phone = null, roomName = a.Room.Name, - bedName = a.RegionRoomBed.Name, + bedName = GetBedString(a.RegionRoomBed), orderNo = a.GuaDanOrderNo, follower = a.followers == null ? null : new FollowerDto { num = a.followers.num, - u_name = a.followers.u_name + u_name = a.followers.u_name, + sex = a.followers.sex }, statuscode = a.StatusCode, statusName = a.RegionRoomBedStatus?.Name, @@ -59,7 +60,22 @@ public class guadanOrderGuestController : ApiController return Ok(data); } - + public string GetBedString(RegionRoomBed bed) + { + if (bed == null) + return ""; + var room = bed.Room; + var name = room.Name + "/" + bed.Name; + var region = room.Region; + name = region.Name + "/" + name; + var parentRegion = region.Region2; + while(parentRegion != null) + { + name = parentRegion.Name + "/" + name; + parentRegion = parentRegion.Region2; + } + return name; + } [HttpPost] [Route("api/guadanorderguest/create")] public async Task create([FromBody] guadan_order_guest_dto model) @@ -650,6 +666,7 @@ public class guadanOrderGuestController : ApiController { public int num { get; set; } public string u_name { get; set; } + public string sex { get; set; } } public class XuZhuModel { diff --git a/web/App_Code/api/regionController.cs b/web/App_Code/api/regionController.cs index d830ffb..3e81908 100644 --- a/web/App_Code/api/regionController.cs +++ b/web/App_Code/api/regionController.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Drawing.Drawing2D; using System.Linq; +using System.Net; using System.Web; using System.Web.Http; using System.Web.Routing; @@ -39,7 +40,7 @@ public class regionController : ApiController var startDate = filter.StartDate.Date; var endDate = filter.EndDate.Date; - var query = _db.Region//区域状态是否启用这里只设置了过滤了有客房的区域,是否要过滤所有 + var query = _db.Region//區域狀態是否啟用這裡只設置了過濾了有客房的區域,是否要過濾所有 .Where(r => !r.IsDeleted) .Where(r => r.IsActive) .Where(r => r.Room.Any()); @@ -68,6 +69,7 @@ public class regionController : ApiController r.Uuid, r.Name, regionPath = r.Name, + isStop = !IsRegionAvailable(r.Uuid), Room = r.Room .Where(room => filter.Gender == null || room.Gender == filter.Gender) .Where(room => @@ -149,6 +151,30 @@ public class regionController : ApiController Summary = summary, }); } + public bool IsRegionAvailable(Guid regionUuid) + { + var current = _db.Region.FirstOrDefault(r => r.Uuid == regionUuid); + while (current != null) + { + // 當前區域不可用就直接返回 false + if (!current.IsActive || current.IsDeleted) + { + return false; + } + + // 沒有父區域了,說明一路上都可用 + if (!current.ParentUuid.HasValue) + { + return true; + } + + // 繼續往父區域走 + current = _db.Region.FirstOrDefault(r => r.Uuid == current.ParentUuid.Value); + } + + // 沒查到(極端情況,比如資料庫被改了) + return false; + } /// /// 遞迴生成區域完整路徑 @@ -228,25 +254,25 @@ public class regionController : ApiController { var allRegions = _db.Region.ToList(); - // 根区域 + // 根區域 var rootRegions = allRegions .Where(r => r.ParentUuid == null) .OrderBy(r => r.SortOrder) .ToList(); - // 生成树并按性别过滤 + // 生成樹並按性別過濾 var tree = rootRegions .Select(r => BuildRegionDtoByGender(r, allRegions, request.IsMale)) - .Where(r => r != null) // 去掉没有房间的区域 + .Where(r => r != null) // 去掉沒有房間的區域 .ToList(); return Ok(tree); } - // 根据性别过滤房间的 BuildRegionDto + // 根據性別過濾房間的 BuildRegionDto private RegionDto BuildRegionDtoByGender(Region region, List allRegions, bool? gender) { - // 过滤房间按性别 + // 過濾房間按性別 var rooms = region.Room? .Where(a => !gender.HasValue || a.Gender == gender.Value) .Select(a => new RoomDto @@ -268,14 +294,14 @@ public class regionController : ApiController }) .ToList(); - // 递归生成子区域 + // 遞迴生成子區域 var children = allRegions .Where(r => r.ParentUuid == region.Uuid) .Select(child => BuildRegionDtoByGender(child, allRegions, gender)) - .Where(c => c != null) // 去掉没有房间的子区域 + .Where(c => c != null) // 去掉沒有房間的子區域 .ToList(); - // 如果这个区域既没有房间也没有子区域,则返回 null + // 如果這個區域既沒有房間也沒有子區域,則返回 null if (!rooms.Any() && !children.Any()) return null; @@ -297,10 +323,10 @@ public class regionController : ApiController }; } - // 请求模型 + // 請求模型 public class GenderRequest { - public bool? IsMale { get; set; } // true = 男, false = 女, null = 不过滤 + public bool? IsMale { get; set; } // true = 男, false = 女, null = 不過濾 } public class RoomDto @@ -374,10 +400,28 @@ public class regionController : ApiController var region = _db.Region.FirstOrDefault(r => r.Uuid == dto.Uuid); if (region == null) return NotFound(); - if(dto.RoomCount < region.Room.Count()) + if (dto.RoomCount < region.Room.Count()) { return BadRequest("客房數量小於已存在的客房數量"); } + if (dto.IsActive == false) + { + var regionIds = GetAllRegionIds(region.Uuid); + var hasPendingBeds = _db.RegionRoomBed + .Where(b => regionIds.Contains(b.Room.RegionUuid)) + .SelectMany(b => b.GuaDanOrderGuest) + .Any(g => !g.IsDeleted && + (g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_BOOKED || // 預約中 + g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_CHECKED_IN)); // 已入住 + if (hasPendingBeds) + { + return Content(HttpStatusCode.BadRequest, new + { + code = "BED_IS_USED", + message = "該區域有床位正在掛單中,請先處理" + }); + } + } region.Name = dto.Name; region.Description = dto.Description; region.SortOrder = dto.SortOrder; @@ -416,6 +460,25 @@ public class regionController : ApiController return Ok(new { message = "刪除成功" }); } + public List GetAllRegionIds(Guid regionUuid) + { + var regionIds = new List { regionUuid }; + + var children = _db.Region + .Where(r => r.ParentUuid == regionUuid) + .Select(r => r.Uuid) + .ToList(); + + foreach (var childId in children) + { + regionIds.AddRange(GetAllRegionIds(childId)); + } + + return regionIds; + } + + + // 遞迴刪除子節點 private void DeleteRegionRecursive(Region region) { @@ -438,7 +501,7 @@ public class regionController : ApiController [Route("api/region/regionwithroom")] public IHttpActionResult GetRegionWithRoom() { - //返回有房间的region + //返回有房間的region var data = _db.Region.Where(a => a.Room.Count() > 0) .Select(r => new { @@ -459,7 +522,7 @@ public class regionController : ApiController [Route("api/room/roomwithbed")] public IHttpActionResult GetRoomWithBed(Guid? RegionUuid = null) { - //获取所有有床位的房间 + //獲取所有有床位的房間 var query = _db.Room .Select(r => new { diff --git a/web/App_Code/api/regionRoomBedController.cs b/web/App_Code/api/regionRoomBedController.cs index eecd783..77edcff 100644 --- a/web/App_Code/api/regionRoomBedController.cs +++ b/web/App_Code/api/regionRoomBedController.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; +using System.Net; using System.Threading.Tasks; using System.Web; using System.Web.Http; @@ -66,7 +67,7 @@ public class regionRoomBedController : ApiController .ToList(); bool canUsed = !bedSchedules.Any(); - + bool bedIsStop = IsBedStopped(a); return new { a.Uuid, @@ -76,6 +77,7 @@ public class regionRoomBedController : ApiController a.StatusCode, a.RoomUuid, canUsed, + bedIsStop, schedule = bedSchedules }; }); @@ -83,6 +85,33 @@ public class regionRoomBedController : ApiController return Ok(data); } + public bool IsBedStopped(RegionRoomBed bed) + { + // 1️⃣ 床位本身不可用 + if (!bed.IsActive || bed.IsDeleted) + return true; + + // 2️⃣ 所属房间不可用 + var room = bed.Room; + if (room == null || !room.IsActive.Value || room.IsDeleted) + return true; + + // 3️⃣ 所属区域不可用 + var region = room.Region; + while (region != null) + { + if (!region.IsActive || region.IsDeleted) + return true; // 有任意一级区域不可用就返回 true + + if (!region.ParentUuid.HasValue) + break; // 到顶层了 + + region = _db.Region.FirstOrDefault(r => r.Uuid == region.ParentUuid.Value); + } + + // 4️⃣ 全部检查通过 → 床位可用 + return false; + } [HttpPost] [Route("api/region/bed/create")] @@ -147,6 +176,20 @@ public class regionRoomBedController : ApiController { return BadRequest("床為性別和房間性別必須一致"); } + if (bed.IsActive == false) + { + var hasPendingBeds = oldBed.GuaDanOrderGuest.Any(g => !g.IsDeleted && + (g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_BOOKED || // 预约中 + g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_CHECKED_IN)); + if (hasPendingBeds) + { + return Content(HttpStatusCode.BadRequest, new + { + code = "BED_IS_USED", + message = "該床位正在掛單中,請先處理" + }); + } + } oldBed.StatusCode = bed.StatusCode; oldBed.IsActive = bed.IsActive; oldBed.Name = bed.Name; @@ -158,18 +201,38 @@ public class regionRoomBedController : ApiController } [HttpPost] [Route("api/region/bed/delete")] - public IHttpActionResult delete([FromUri] Guid uuid) + public IHttpActionResult Delete([FromUri] Guid uuid) { var bed = _db.RegionRoomBed.Find(uuid); if (bed == null) { return BadRequest("未找到床位"); } - _db.RegionRoomBed.Remove(bed); - _db.SaveChanges(); - return Ok(new { message = "刪除成功" }); + + try + { + _db.RegionRoomBed.Remove(bed); + _db.SaveChanges(); + return Ok(new { message = "刪除成功" }); + } + catch (System.Data.Entity.Infrastructure.DbUpdateException ex) + { + // 判斷是否為外鍵關聯錯誤 + if (ex.InnerException?.InnerException is System.Data.SqlClient.SqlException sqlEx && + (sqlEx.Number == 547)) // 547 = SQL Server 外鍵違反錯誤碼 + { + return BadRequest("刪除失敗:該床位已被使用或存在關聯資料,無法刪除。"); + } + + return InternalServerError(ex); // 其他資料庫錯誤 + } + catch (Exception ex) + { + return InternalServerError(ex); // 其他未預期錯誤 + } } + [HttpGet] [Route("api/region/bed/getavailablebedcountbytime")] public async Task GetCanUseBedCountByTime(DateTime startTime, DateTime endTime) @@ -192,6 +255,7 @@ public class regionRoomBedController : ApiController // 可用床位 = 所有床位 - 忙碌床位 var availableBeds = _db.RegionRoomBed + .Where(b => b.IsActive) .Where(b => !busyBedUuids.Contains(b.Uuid)); var result = await availableBeds diff --git a/web/App_Code/api/regionRoomController.cs b/web/App_Code/api/regionRoomController.cs index 33cc4f5..7067d54 100644 --- a/web/App_Code/api/regionRoomController.cs +++ b/web/App_Code/api/regionRoomController.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Data.Entity; using System.Drawing; using System.Linq; +using System.Net; using System.ServiceModel.Channels; using System.Threading.Tasks; using System.Web; @@ -99,6 +100,23 @@ public class regionRoomController : ApiController { return BadRequest("請輸入床位數量"); } + if (room.IsActive == false) + { + var hasPendingBeds = oldRoom.RegionRoomBed + .SelectMany(b => b.GuaDanOrderGuest) + .Any(g => !g.IsDeleted && + (g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_BOOKED || // 预约中 + g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_CHECKED_IN)); // 已入住 + if (hasPendingBeds) + { + return Content(HttpStatusCode.BadRequest, new + { + code = "BED_IS_USED", + message = "該房间有床位正在掛單中,請先處理" + }); + } + } + oldRoom.Name = room.Name; oldRoom.BedCount = room.BedCount; oldRoom.Gender = room.Gender; diff --git a/web/admin/guadan/create.aspx b/web/admin/guadan/create.aspx index e6fc61c..d4ee875 100644 --- a/web/admin/guadan/create.aspx +++ b/web/admin/guadan/create.aspx @@ -94,6 +94,10 @@ + + + @@ -114,7 +117,7 @@ { text: '掛單人數', value: 'guest_count' }, { text: '狀態', value: 'statusName', align: 'center' }, { text: '建立時間', value: 'created_at', align: 'center' }, - { text: '備註', value: 'notes', align: 'center' }, + { text: '關聯活動', value: 'activity', align: 'center' }, { text: '操作', value: 'actions', align: 'center' } ], options: { diff --git a/web/admin/region/bed/index.aspx b/web/admin/region/bed/index.aspx index a39820c..d514e38 100644 --- a/web/admin/region/bed/index.aspx +++ b/web/admin/region/bed/index.aspx @@ -108,8 +108,9 @@ -
-

{{ region.regionPath }}

+
+

{{region.isStop?(region.regionPath + '(已停用)'): region.regionPath }}

@@ -319,6 +320,14 @@ .then((res) => { this.regions = res.data.regions; this.summary = res.data.summary; // 保存後端統計 + try { + this.regions.sort((a, b) => { + return Number(a.isStop) - Number(b.isStop); + }); + } + catch (error) { + console.log(error) + } }) .catch((err) => { console.error('API 錯誤', err); diff --git a/web/admin/region/handle_bed_in_used.aspx b/web/admin/region/handle_bed_in_used.aspx new file mode 100644 index 0000000..0ca87b0 --- /dev/null +++ b/web/admin/region/handle_bed_in_used.aspx @@ -0,0 +1,217 @@ +<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="handle_bed_in_used.aspx.cs" Inherits="admin_region_handle_bed_in_used" %> + + + + + + + + +
+ + + + + +
+ + + + +
+ + + + + \ No newline at end of file diff --git a/web/admin/region/handle_bed_in_used.aspx.cs b/web/admin/region/handle_bed_in_used.aspx.cs new file mode 100644 index 0000000..a01c9d2 --- /dev/null +++ b/web/admin/region/handle_bed_in_used.aspx.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; + +public partial class admin_region_handle_bed_in_used : MyWeb.config +{ + protected void Page_Load(object sender, EventArgs e) + { + + } +} \ No newline at end of file diff --git a/web/admin/region/index.aspx b/web/admin/region/index.aspx index a308af3..37975a6 100644 --- a/web/admin/region/index.aspx +++ b/web/admin/region/index.aspx @@ -252,7 +252,7 @@
- @@ -349,6 +349,23 @@ + + +
+
+

{{bed_is_used_modal_message}}

+
+ + + 前往处理 + +
+
+
+ @@ -477,13 +494,14 @@
` }); - - new Vue({ el: '#app', vuetify: new Vuetify(vuetify_options), data() { return { + bed_is_used_modal: false, + bed_is_used_modal_message: null, + bed_is_used_modal_link: "handle_bed_in_used.aspx", // 默认链接 selectedId: null, // 被選中項目ID selectedType: null, // 'region' 或 'room' expandAllFlag: false, // 控制全部展開 @@ -546,6 +564,11 @@ }; }, methods: { + closeBedInUsedModal() { + this.bed_is_used_modal = false; + this.bed_is_used_modal_message = null; + this.bed_is_used_modal_link = "handle_bed_in_used.aspx"; // 默认链接 + }, expandAll() { this.expandAllFlag = true; this.collapseAllFlag = false; @@ -634,7 +657,10 @@ }); return; } - const url = this.form.uuid ? '/api/region/update' : '/api/region/create'; + const url = this.form.uuid + ? HTTP_HOST + '/api/region/update' + : HTTP_HOST + '/api/region/create'; + axios.post(url, this.form) .then((res) => { //alert('儲存成功'); @@ -649,10 +675,20 @@ }); }) .catch((error) => { - this.$refs.messageModal.open({ - title: '更新提示', - message: error.response?.data?.message || "儲存失敗,請稍後再試。", - }); + console.error('更新失敗', error); + const code = error.response?.data?.code; + const message = error.response?.data?.message || error.message || + "未知錯誤,請稍後再試"; + if (code === "BED_IS_USED") { + this.bed_is_used_modal = true; + this.bed_is_used_modal_message = message + this.bed_is_used_modal_link = this.bed_is_used_modal_link + '?region=' + this.form.uuid + + } else { + this.$refs.messageModal.open({ + message: (message) + }); + } }); }, deleteRegion() { @@ -665,7 +701,7 @@ }); }, confirmDeleteRegion() { - axios.post('/api/region/delete', { Uuid: this.form.uuid }) + axios.post(HTTP_HOST + 'api/region/delete', { Uuid: this.form.uuid }) .then(() => { this.showDeleteModal = false; this.$refs.messageModal.open({ @@ -717,7 +753,7 @@ uuid: null, RoomUuid: this.currentSelectRoom.uuid, Name: '', - statuscode: null, + statuscode: "101", IsActive: true, Gender: this.currentSelectRoom.gender, // 不設預設值,強制選擇 }; @@ -732,7 +768,7 @@ return; } try { - var res = await axios.post('/api/region/bed/create', this.room_bed.newBedForm); + var res = await axios.post(HTTP_HOST + 'api/region/bed/create', this.room_bed.newBedForm); this.room_bed.showBedModal = false; this.$refs.messageModal.open({ title: '成功', @@ -825,12 +861,20 @@ await this.loadRegions(); this.room_bed.bed_items = this.currentSelectRoom.beds; //this.selectRegion(this.findRegionById(this.regions, this.form.id)); - } catch (err) { - console.log(err) - this.$refs.messageModal.open({ - title: '錯誤', - message: err.response?.data?.message || '更新失敗' - }); + } catch (error) { + console.error('更新失敗', error); + const code = error.response?.data?.code; + const message = error.response?.data?.message || error.message || + "未知錯誤,請稍後再試"; + if (code === "BED_IS_USED") { + this.bed_is_used_modal = true; + this.bed_is_used_modal_message = message; + this.bed_is_used_modal_link = this.bed_is_used_modal_link + '?bed=' + this.room_bed.newBedForm.uuid + } else { + this.$refs.messageModal.open({ + message: (message) + }); + } } }, getBedStatus() { @@ -887,9 +931,18 @@ }; } catch (error) { console.error('更新失敗', error); - this.$refs.messageModal.open({ - message: (error.response?.data?.message || error.message) - }); + const code = error.response?.data?.code; + const message = error.response?.data?.message || error.message || + "未知錯誤,請稍後再試"; + if (code === "BED_IS_USED") { + this.bed_is_used_modal = true; + this.bed_is_used_modal_message = message; + this.bed_is_used_modal_link = this.bed_is_used_modal_link + '?room=' + this.room.room_form.uuid + } else { + this.$refs.messageModal.open({ + message: (message) + }); + } } },