using Model; 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; /// /// regionController 的摘要描述 /// [ezAuthorize] public class regionController : ApiController { private Model.ezEntities _db = new Model.ezEntities(); public regionController() { // // TODO: 在這裡新增建構函式邏輯 // } public class RoomFilter { public DateTime StartDate { get; set; } = DateTime.Now.Date; public DateTime EndDate { get; set; } = DateTime.Today.AddDays(1); public Guid? AreaId { get; set; } = null; public Guid? RoomId { get; set; } = null; public bool Occupied { get; set; } public bool Unoccupied { get; set; } public bool? Gender { get; set; } = null; } [HttpPost] [Route("api/region/list")] public IHttpActionResult GetList([FromBody] RoomFilter filter) { var startDate = filter.StartDate.Date; var endDate = filter.EndDate.Date; var query = _db.Region//區域狀態是否啟用這裡只設置了過濾了有客房的區域,是否要過濾所有 .Where(r => !r.IsDeleted) .Where(r => r.IsActive) .Where(r => r.Room.Any()); if (filter.Gender != null) { query = query.Where(a => a.Gender == filter.Gender || a.Gender == null); } // 區域過濾 if (filter.AreaId.HasValue && filter.AreaId.Value != Guid.Empty) { query = query.Where(r => r.Uuid == filter.AreaId.Value); } // 房間過濾 if (filter.RoomId.HasValue && filter.RoomId.Value != Guid.Empty) { query = query.Where(r => r.Room.Any(room => room.Uuid == filter.RoomId.Value)); } var data = query .ToList() .Select(r => new { 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 => !filter.Unoccupied || room.RegionRoomBed.Any(bed => bed.IsAvailableDuring(startDate, endDate, _db)) ) .Where(room => !filter.RoomId.HasValue || room.Uuid == filter.RoomId.Value) .Select(room => new { gender = room.Gender, room.Uuid, room.Name, Stats = new { BedCount = room.RegionRoomBed.Count(), AvailableCount = room.RegionRoomBed.Count(b => b.IsAvailableDuring(startDate, endDate, _db)), }, beds = room.RegionRoomBed .ToList() .Where(bed => (!filter.Occupied || !bed.IsAvailableDuring(startDate, endDate, _db)) && (!filter.Unoccupied || bed.IsAvailableDuring(startDate, endDate, _db)) ) .Select(bed => new { bed.Uuid, bed.Name, bed.Gender, bed.RoomUuid, bed.StatusCode, bed.IsActive, bed.IsDeleted, canuse = bed.IsAvailableDuring(startDate, endDate, _db), statusname = bed.RegionRoomBedStatus.Name, schedules = _db.RegionAndRoomAndBedSchedule .Where(s => s.IsCancel == false) .Where(s => s.TargetUuid == bed.Uuid && s.IsDeleted == false && (s.ScheduleDate == null || (s.ScheduleDate >= startDate))) .Where(s => s.GuaDanOrderGuest.StatusCode != "403" && s.GuaDanOrderGuest.StatusCode != "404") .OrderBy(a => a.ScheduleDate) .Select(s => new { s.Uuid, scheduledate = s.ScheduleDate, s.UseType, s.Title, s.Description, s.GuaDanOrderNo, s.TargetUuid, usename = _db.GuaDanOrderGuest .Where(guest => guest.GuaDanOrderNo == s.GuaDanOrderNo) .Where(guest => guest.BedUuid == s.TargetUuid) .Select(guest => guest.followers.u_name) .FirstOrDefault() }) .ToList() }), }).ToList() }) .ToList(); // 過濾掉沒有房間的區域 data = data.Where(a => a.Room.Count() > 0).ToList(); var summary = new { TotalBeds = _db.RegionRoomBed.Count(a => !a.IsDeleted), TotalMaleBeds = _db.RegionRoomBed.Count(a => !a.IsDeleted && a.Gender == true), TotalRooms = _db.Room.Count(a => !a.IsDeleted), TotalMaleRooms = _db.Room.Count(a => !a.IsDeleted && a.Gender == true), }; return Ok(new { Regions = data, 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; } /// /// 遞迴生成區域完整路徑 /// private string BuildRegionPath(Region region) { string path = region.Name; var parent = region.Region2; // 假設 Region2 是父區域導航屬性 while (parent != null) { path = parent.Name + " > " + path; parent = parent.Region2; } return path; } [HttpPost] [Route("api/region/getRegionList")] public IHttpActionResult getRegionList() { var allRegions = _db.Region.ToList(); var rootRegions = allRegions .Where(r => r.ParentUuid == null) .OrderBy(r => r.SortOrder) .ToList(); var tree = rootRegions .Select(r => BuildRegionDto(r, allRegions)) .ToList(); return Ok(tree); } private RegionDto BuildRegionDto(Region region, List allRegions) { return new RegionDto { Uuid = region.Uuid, Name = region.Name, Description = region.Description, SortOrder = region.SortOrder, ParentUuid = region.ParentUuid, RegionTypeUuid = region.RegionTypeUuid, IsActive = region.IsActive, RoomCount = region.RoomCount, BedDto = new List(), Rooms = region.Room.Select(a => new RoomDto { Uuid = a.Uuid, Name = a.Name, RegionUuid = a.RegionUuid, Gender = a.Gender, BedCount = a.BedCount, IsActive = a.IsActive, beds = a.RegionRoomBed.Select(c => new BedDto { Uuid = c.Uuid, name = c.Name, roomUuid = c.RoomUuid, isactive = c.IsActive, statuscode = c.StatusCode, Gender = c.Gender, }).ToList(), }).ToList(), Children = allRegions .Where(r => r.ParentUuid == region.Uuid) .OrderBy(r => r.SortOrder) .Select(child => BuildRegionDto(child, allRegions)) .ToList(), Gender = region.Gender, }; } [HttpPost] [Route("api/region/getRegionListByGender")] public IHttpActionResult getRegionListByGender([FromBody] GenderRequest request) { 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) // 去掉沒有房間的區域 .ToList(); return Ok(tree); } // 根據性別過濾房間的 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 { Uuid = a.Uuid, Name = a.Name, RegionUuid = a.RegionUuid, Gender = a.Gender, BedCount = a.BedCount, IsActive = a.IsActive, beds = a.RegionRoomBed.Select(c => new BedDto { Uuid = c.Uuid, name = c.Name, roomUuid = c.RoomUuid, isactive = c.IsActive, statuscode = c.StatusCode, }).ToList() }) .ToList(); // 遞迴生成子區域 var children = allRegions .Where(r => r.ParentUuid == region.Uuid) .Select(child => BuildRegionDtoByGender(child, allRegions, gender)) .Where(c => c != null) // 去掉沒有房間的子區域 .ToList(); // 如果這個區域既沒有房間也沒有子區域,則返回 null if (!rooms.Any() && !children.Any()) return null; return new RegionDto { Uuid = region.Uuid, Name = region.Name, Description = region.Description, SortOrder = region.SortOrder, ParentUuid = region.ParentUuid, RegionTypeUuid = region.RegionTypeUuid, IsActive = region.IsActive, RoomCount = rooms.Count, Rooms = rooms, BedDto = new List(), Children = children, Gender = region.Gender, }; } // 請求模型 public class GenderRequest { public bool? IsMale { get; set; } // true = 男, false = 女, null = 不過濾 } public class RoomDto { public Guid Uuid { get; set; } public Guid RegionUuid { get; set; } public string Name { get; set; } public bool Gender { get; set; } public Nullable BedCount { get; set; } public Nullable IsActive { get; set; } public Nullable CreatedAt { get; set; } public Nullable UpdatedAt { get; set; } public List beds { get; set; } } public class BedDto { public Guid Uuid { get; set; } public Guid? roomUuid { get; set; } public string name { get; set; } public string statuscode { get; set; } public bool isactive { get; set; } public bool Gender { get; set; } } public class RegionDto { public Guid Uuid { get; set; } = Guid.NewGuid(); public string Name { get; set; } public string Description { get; set; } public int? SortOrder { get; set; } public Guid? ParentUuid { get; set; } public List Children { get; set; } public Guid? RegionTypeUuid { get; set; } public bool IsActive { get; set; } = true; public int? RoomCount { get; set; } public List Rooms { get; set; } public List BedDto { get; set; } public bool? Gender { get; set; } } [HttpPost] [Route("api/region/create")] public IHttpActionResult createRegion([FromBody] RegionDto dto) { if (string.IsNullOrWhiteSpace(dto.Name)) return BadRequest("區域名稱為必填"); var region = new Region { Name = dto.Name, Description = dto.Description, SortOrder = dto.SortOrder, ParentUuid = dto.ParentUuid, RegionTypeUuid = dto.RegionTypeUuid, IsActive = dto.IsActive, RoomCount = dto.RoomCount, Uuid = Guid.NewGuid(), }; _db.Region.Add(region); _db.SaveChanges(); return Ok(new { message = "新增成功", id = region.Uuid }); } [HttpPost] [Route("api/region/update")] public IHttpActionResult updateRegion([FromBody] RegionDto dto) { if (dto == null || dto.Uuid == Guid.Empty) return BadRequest("無效的區域資料"); if (string.IsNullOrWhiteSpace(dto.Name)) return BadRequest("區域名稱為必填"); var region = _db.Region.FirstOrDefault(r => r.Uuid == dto.Uuid); if (region == null) return NotFound(); 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; region.ParentUuid = dto.ParentUuid; region.UpdatedAt = DateTime.Now; region.RegionTypeUuid = dto.RegionTypeUuid; region.IsActive = dto.IsActive; region.RoomCount = dto.RoomCount; _db.SaveChanges(); return Ok(new { message = "更新成功", id = region.Uuid }); } [HttpPost] [Route("api/region/delete")] public IHttpActionResult deleteRegion([FromBody] RegionDto dto) { if (dto == null || dto.Uuid == Guid.Empty) return BadRequest("無效的區域ID"); var region = _db.Region.Find(dto.Uuid); if (region == null) return NotFound(); // 先找出所有子節點(直屬) var childRegions = _db.Region.Where(r => r.ParentUuid == region.Uuid).ToList(); // 如果你要遞迴刪除,需實作遞迴刪除所有子節點 foreach (var child in childRegions) { DeleteRegionRecursive(child); } // 最後刪除自己 _db.Region.Remove(region); _db.SaveChanges(); 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) { var children = _db.Region.Where(r => r.ParentUuid == region.Uuid).ToList(); foreach (var child in children) { DeleteRegionRecursive(child); } _db.Region.Remove(region); } [HttpPost] [Route("api/region/getRegionType")] public IHttpActionResult getRegionType() { var data = _db.RegionType.Where(a => a.IsActive == true).ToList(); return Ok(data); } [HttpGet] [Route("api/region/regionwithroom")] public IHttpActionResult GetRegionWithRoom() { //返回有房間的region var data = _db.Region.Where(a => a.Room.Count() > 0) .Select(r => new { r.Uuid, r.Name, r.ParentUuid, r.Gender, rooms = r.Room.Select(room => new { room.Uuid, room.Name, room.RegionUuid }).ToList() }).ToList(); return Ok(data); } [HttpGet] [Route("api/room/roomwithbed")] public IHttpActionResult GetRoomWithBed(Guid? RegionUuid = null) { //獲取所有有床位的房間 var query = _db.Room .Select(r => new { r.Uuid, r.Name, r.RegionUuid }); if (RegionUuid.HasValue) { query = query.Where(r => r.RegionUuid == RegionUuid.Value); } var rooms = query.ToList(); return Ok(rooms); } }