update from old git
This commit is contained in:
21
web/App_Code/Model/Partial/GuaDanOrder.cs
Normal file
21
web/App_Code/Model/Partial/GuaDanOrder.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
/// <summary>
|
||||
/// GuaDanOrder 的摘要描述
|
||||
/// </summary>
|
||||
namespace Model
|
||||
{
|
||||
public partial class GuaDanOrder
|
||||
{
|
||||
public static string GenerateStatusCode()
|
||||
{
|
||||
string prefix = "GD";
|
||||
string datePart = DateTime.Now.ToString("yyyyMMdd");
|
||||
string randomPart = Guid.NewGuid().ToString("N").Substring(0, 4).ToUpper();
|
||||
return $"{prefix}{datePart}-{randomPart}";
|
||||
}
|
||||
}
|
||||
}
|
||||
49
web/App_Code/Model/Partial/Region.cs
Normal file
49
web/App_Code/Model/Partial/Region.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
/// <summary>
|
||||
/// Region 的摘要描述
|
||||
/// </summary>
|
||||
namespace Model
|
||||
{
|
||||
public partial class Region
|
||||
{
|
||||
public bool IsAvailable()
|
||||
{
|
||||
//判断当前区域是否可用,需要判断父区域是否可用,如果父区域不可用,则所有字区域都不可用
|
||||
if (!this.IsActive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Region region = this.Region2;
|
||||
while (region != null) {
|
||||
if (!region.IsActive) {
|
||||
return false;
|
||||
}
|
||||
region = region.Region2;
|
||||
}
|
||||
return true;
|
||||
//这里增加根据区域排程判定在指定时间段内区域是否可用
|
||||
}
|
||||
|
||||
public bool? IsMaleOrFemale()
|
||||
{
|
||||
if (this.Gender.HasValue)
|
||||
return this.Gender.Value;
|
||||
Region currentRegion = this.Region2;
|
||||
while (currentRegion != null)
|
||||
{
|
||||
if (currentRegion.Gender.HasValue)
|
||||
return currentRegion.Gender.Value;
|
||||
|
||||
currentRegion = currentRegion.Region2; // 上级区域
|
||||
}
|
||||
|
||||
// 都没有定义性别
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
144
web/App_Code/Model/Partial/RegionAndRoomAndBedSchedule.cs
Normal file
144
web/App_Code/Model/Partial/RegionAndRoomAndBedSchedule.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
/// <summary>
|
||||
/// RegionAndRoomAndBedSchedule 的摘要描述
|
||||
/// </summary>
|
||||
namespace Model
|
||||
{
|
||||
public partial class RegionAndRoomAndBedSchedule
|
||||
{
|
||||
public enum SchedulePurpose
|
||||
{
|
||||
None = -1, // 無特定用途
|
||||
|
||||
// 區域相關
|
||||
Region_Repair = 10, // 區域修繕
|
||||
Region_Cleaning = 11, // 區域清潔
|
||||
// 客房相關
|
||||
Room_Reservation = 20, // 客房預訂
|
||||
Room_Cleaning = 21, // 客房清潔
|
||||
Room_Disinfection = 22, // 客房消毒
|
||||
Room_Repair = 23, // 客房維修
|
||||
|
||||
// 床位相關
|
||||
Bed_Reservation = 30, // 床位預訂
|
||||
Bed_Cleaning = 31, // 床位清潔
|
||||
Bed_Repair = 32, // 床位維修
|
||||
Bed_Disinfection = 33, // 床位消毒
|
||||
|
||||
// 其他用途
|
||||
Event_Use = 90, // 活動使用
|
||||
Other = 99 // 其他
|
||||
}
|
||||
|
||||
public enum StatusEnum
|
||||
{
|
||||
None = 0,
|
||||
Normal = 1,
|
||||
Cancel = 2,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找指定时间段内可用床位(无排程占用)
|
||||
/// </summary>
|
||||
/// <param name="db">数据库上下文</param>
|
||||
/// <param name="start">查询开始时间</param>
|
||||
/// <param name="end">查询结束时间</param>
|
||||
/// <returns>可用床位列表</returns>
|
||||
public static async Task<List<RegionRoomBed>> GetAvailableBedsAsync(ezEntities db, DateTime start, DateTime? end)
|
||||
{
|
||||
start = start.Date;
|
||||
end = end?.Date;
|
||||
|
||||
// 找出在日期範圍內被占用的床位 Uuid(包括長期占用 ScheduleDate = null)
|
||||
var busyBedUuidsQuery = db.RegionAndRoomAndBedSchedule
|
||||
.Where(s => s.IsDeleted == false && s.IsActive
|
||||
&& (s.ScheduleDate == null
|
||||
|| (end.HasValue
|
||||
&& s.ScheduleDate >= start
|
||||
&& s.ScheduleDate <= end.Value)));
|
||||
|
||||
var busyBedUuids = await busyBedUuidsQuery
|
||||
.Select(s => s.TargetUuid)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
// 空閒床位 = 所有床位 - 忙碌床位
|
||||
var availableBeds = await db.RegionRoomBed
|
||||
.Where(b => !busyBedUuids.Contains(b.Uuid))
|
||||
.ToListAsync();
|
||||
|
||||
return availableBeds;
|
||||
}
|
||||
public static async Task<bool> IsBedAvailableAsync(ezEntities db, Guid targetUuid, DateTime start, DateTime? end)
|
||||
{
|
||||
// 如果 end 為 null,表示長期占用,直接判斷是否已有長期占用
|
||||
if (end == null)
|
||||
{
|
||||
var hasLongTerm = await db.RegionAndRoomAndBedSchedule
|
||||
.AnyAsync(s => s.IsDeleted == false
|
||||
&& s.IsActive
|
||||
&& s.TargetUuid == targetUuid
|
||||
&& s.ScheduleDate == null);
|
||||
return !hasLongTerm;
|
||||
}
|
||||
|
||||
// 短期占用,查詢每日排程中有無衝突
|
||||
var totalDays = (end.Value.Date - start.Date).Days + 1;
|
||||
for (int i = 0; i < totalDays; i++)
|
||||
{
|
||||
var date = start.Date.AddDays(i);
|
||||
|
||||
var conflict = await db.RegionAndRoomAndBedSchedule
|
||||
.AnyAsync(s => s.IsDeleted == false
|
||||
&& s.IsActive
|
||||
&& s.TargetUuid == targetUuid
|
||||
&& s.ScheduleDate == date);
|
||||
|
||||
if (conflict)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static async Task<object> GetAvailableBedCountsAsync(ezEntities db, DateTime start, DateTime end)
|
||||
{
|
||||
start = start.Date;
|
||||
end = end.Date;
|
||||
|
||||
// 找出所有在日期範圍內被占用的床位
|
||||
var busyBedUuids = await db.RegionAndRoomAndBedSchedule
|
||||
.Where(s => s.IsDeleted == false && s.IsActive
|
||||
&& (s.ScheduleDate == null // 長期占用
|
||||
|| (s.ScheduleDate >= start && s.ScheduleDate <= end)))
|
||||
.Select(s => s.TargetUuid)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
// 可用床位 = 所有床位 - 忙碌床位
|
||||
var availableBeds = db.RegionRoomBed
|
||||
.Where(b => !busyBedUuids.Contains(b.Uuid));
|
||||
|
||||
var result = await availableBeds
|
||||
.GroupBy(b => b.Gender)
|
||||
.Select(g => new
|
||||
{
|
||||
Gender = g.Key,
|
||||
Count = g.Count()
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
var male = result.Where(r => r.Gender == true).Select(r => r.Count).FirstOrDefault();
|
||||
var female = result.Where(r => r.Gender == false).Select(r => r.Count).FirstOrDefault();
|
||||
|
||||
return new { male, female };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
50
web/App_Code/Model/Partial/RegionRoomBed.cs
Normal file
50
web/App_Code/Model/Partial/RegionRoomBed.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
/// <summary>
|
||||
/// RegionRoomBed 的摘要描述
|
||||
/// </summary>
|
||||
namespace Model
|
||||
{
|
||||
public partial class RegionRoomBed
|
||||
{
|
||||
public bool IsAvailable()
|
||||
{
|
||||
//判断床位是否可用:自身是否启用
|
||||
//床位使用排程是否可用
|
||||
//是否需要传入时间?指定时间间隔内
|
||||
if (!this.IsActive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.Room.IsAvailable();
|
||||
//根据床位排程判定床位是否可用
|
||||
}
|
||||
public bool IsAvailableDuring(DateTime checkInAt, DateTime? checkOutAt, ezEntities _db)
|
||||
{
|
||||
// 床位本身不可用,直接返回 false
|
||||
if (!this.IsActive || !this.Room.IsAvailable())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 如果資料庫 ScheduleDate 是 date 型別,本身沒有時間部分,可以直接比較
|
||||
var conflict = _db.RegionAndRoomAndBedSchedule.Any(s =>
|
||||
s.TargetUuid == this.Uuid &&
|
||||
s.IsActive &&
|
||||
!s.IsDeleted &&
|
||||
(
|
||||
s.ScheduleDate == null || // 長期占用
|
||||
(checkOutAt.HasValue
|
||||
? (s.ScheduleDate >= checkInAt && s.ScheduleDate <= checkOutAt.Value)
|
||||
: s.ScheduleDate >= checkInAt)
|
||||
)
|
||||
);
|
||||
|
||||
return !conflict;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
web/App_Code/Model/Partial/RegionRoomBedStatus.cs
Normal file
55
web/App_Code/Model/Partial/RegionRoomBedStatus.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Model;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Model
|
||||
{
|
||||
[MetadataType(typeof(RegionRoomBedStatusMetadata))]
|
||||
public partial class RegionRoomBedStatus
|
||||
{
|
||||
private class RegionRoomBedStatusMetadata
|
||||
{
|
||||
//[JsonIgnore]
|
||||
//public virtual ICollection<RegionRoomBed> RegionRoomBed { get; set; }
|
||||
|
||||
//[JsonIgnore]
|
||||
//public virtual ICollection<GuaDanOrder> GuaDanOrder { get; set; }
|
||||
}
|
||||
|
||||
public enum CategoryEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
BedStatus = 1,
|
||||
GuaDanStatus = 2,
|
||||
RoomStatus = 3,
|
||||
GuadanLianyouStatus = 4,
|
||||
}
|
||||
[JsonProperty("CategoryName")]
|
||||
public string CategoryName => GetCategoryName(this.Category);
|
||||
public static string GetCategoryName(int? category)
|
||||
{
|
||||
if (category == null) return "";
|
||||
switch ((CategoryEnum)category)
|
||||
{
|
||||
case CategoryEnum.BedStatus: return "床位狀態";
|
||||
case CategoryEnum.GuaDanStatus: return "掛單狀態";
|
||||
case CategoryEnum.RoomStatus: return "房間狀態";
|
||||
case CategoryEnum.GuadanLianyouStatus: return "個人掛單狀態";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable GetCategoryList()
|
||||
{
|
||||
var list = new ArrayList();
|
||||
list.Add(new { Value = (int)CategoryEnum.BedStatus, Text = "床位狀態" });
|
||||
list.Add(new { Value = (int)CategoryEnum.GuaDanStatus, Text = "掛單狀態" });
|
||||
list.Add(new { Value = (int)CategoryEnum.RoomStatus, Text = "房間狀態" });
|
||||
list.Add(new { Value = (int)CategoryEnum.GuadanLianyouStatus, Text = "個人掛單狀態" });
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
web/App_Code/Model/Partial/Room.cs
Normal file
23
web/App_Code/Model/Partial/Room.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Model
|
||||
{
|
||||
public partial class Room
|
||||
{
|
||||
public bool IsAvailable()
|
||||
{
|
||||
//判断当前房间是否可用,需要判断父区域是否可用,如果父区域不可用,则所有子区域都不可用
|
||||
// 有值且是 false,表示不可用
|
||||
if (this.IsActive.HasValue && this.IsActive.Value == false)
|
||||
return false;
|
||||
return this.Region.IsAvailable();
|
||||
//这里增加根据房间排程判定在指定时间段内房间是否可用
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Room 的摘要描述
|
||||
/// </summary>
|
||||
32
web/App_Code/Model/ViewModel/GuaDanGuestView.cs
Normal file
32
web/App_Code/Model/ViewModel/GuaDanGuestView.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
/// <summary>
|
||||
/// GuaDanGuestView 的摘要描述
|
||||
/// </summary>
|
||||
public class GuaDanGuestView
|
||||
{
|
||||
public GuaDanGuestView()
|
||||
{
|
||||
//
|
||||
// TODO: 在這裡新增建構函式邏輯
|
||||
//
|
||||
}
|
||||
public int? Id { get; set; }
|
||||
[Required]
|
||||
[StringLength(100, MinimumLength = 1)]
|
||||
public string FullName { get; set; }
|
||||
public Nullable<int> Gender { get; set; }
|
||||
public string Phone { get; set; }
|
||||
public string IDNumber { get; set; }
|
||||
public Nullable<System.DateTime> Birthday { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string EmergencyContact { get; set; }
|
||||
public string EmergencyPhone { get; set; }
|
||||
public Nullable<int> Status { get; set; }
|
||||
public string Notes { get; set; }
|
||||
}
|
||||
23
web/App_Code/Model/ViewModel/GuaDanOrderView.cs
Normal file
23
web/App_Code/Model/ViewModel/GuaDanOrderView.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
/// <summary>
|
||||
/// GuaDanOrderView 的摘要描述
|
||||
/// </summary>
|
||||
public class GuaDanOrderView
|
||||
{
|
||||
public Guid? Uuid { get; set; } = null;
|
||||
public System.DateTime startdate { get; set; }
|
||||
public Nullable<System.DateTime> enddate { get; set; }
|
||||
public Guid? statusUuid { get; set; } = null;
|
||||
public Nullable<int> createuser { get; set; }
|
||||
public System.DateTime createdat { get; set; }
|
||||
public System.DateTime updatedat { get; set; }
|
||||
public string note { get; set; }
|
||||
public string bookerName { get; set; }
|
||||
public string bookerPhone { get; set; }
|
||||
public int? bookerFollowerNum { get; set; }
|
||||
|
||||
}
|
||||
214
web/App_Code/api/guadanOrderController.cs
Normal file
214
web/App_Code/api/guadanOrderController.cs
Normal file
@@ -0,0 +1,214 @@
|
||||
using Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using static regionController;
|
||||
|
||||
/// <summary>
|
||||
/// guadanOderController 的摘要描述
|
||||
/// </summary>
|
||||
[ezAuthorize]
|
||||
public class guadanOrderController: ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
[HttpGet]
|
||||
[Route("api/guadan/list")]
|
||||
public async Task<IHttpActionResult> getGuadanList()
|
||||
{
|
||||
var data = await _db.GuaDanOrder.OrderByDescending(b => b.CreatedAt)
|
||||
.Select(a => new
|
||||
{
|
||||
uuid = a.Uuid,
|
||||
guaDanOrderNo = a.GuaDanOrderNo,
|
||||
start_date = a.StartDate,
|
||||
end_date = a.EndDate,
|
||||
created_at = a.CreatedAt,
|
||||
updated_at = a.UpdatedAt,
|
||||
notes = a.Notes,
|
||||
bookerName = a.BookerName,
|
||||
guest_count = _db.GuaDanOrderGuest.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo).Count(),
|
||||
}).ToListAsync();
|
||||
return Ok(data);
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("api/guadan/getorderbyid")]
|
||||
public async Task<IHttpActionResult> getGuadanOrderById(string orderId)
|
||||
{
|
||||
var order = await _db.GuaDanOrder.Where(a => a.GuaDanOrderNo == orderId).FirstOrDefaultAsync();
|
||||
if (order == null)
|
||||
{
|
||||
return BadRequest("未找到对应订单");
|
||||
}
|
||||
var result = new
|
||||
{
|
||||
order.admin,
|
||||
order.followers,
|
||||
StartDate = order.StartDate?.ToString("yyyy-MM-dd"),
|
||||
EndDate = order.EndDate?.ToString("yyyy-MM-dd"),
|
||||
order.CreateUser,
|
||||
order.CreatedAt,
|
||||
order.UpdatedAt,
|
||||
order.Notes,
|
||||
order.GuaDanOrderNo,
|
||||
order.BookerFollowerNum,
|
||||
order.BookerName,
|
||||
order.BookerPhone,
|
||||
order.IsDeleted,
|
||||
order.Uuid,
|
||||
};
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/guadan/create")]
|
||||
public async Task<IHttpActionResult> createGuadanOrder(GuaDanOrderView model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return BadRequest("掛單資料不可為空");
|
||||
}
|
||||
if(model.Uuid.HasValue)
|
||||
{
|
||||
return BadRequest("已存在对应挂单资料");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (model.startdate > model.enddate)
|
||||
{
|
||||
return BadRequest("掛單結束時間不能再開始時間之前");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
var guadanorder = new GuaDanOrder
|
||||
{
|
||||
StartDate = model.startdate,
|
||||
EndDate = model.enddate,
|
||||
CreateUser = model.createuser,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
Notes = model.note,
|
||||
GuaDanOrderNo = GuaDanOrder.GenerateStatusCode(),
|
||||
BookerName = model.bookerName,
|
||||
BookerPhone = model.bookerPhone,
|
||||
Uuid = Guid.NewGuid(),
|
||||
};
|
||||
_db.GuaDanOrder.Add(guadanorder);
|
||||
await _db.SaveChangesAsync();
|
||||
return Ok(guadanorder);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/guadan/update")]
|
||||
public async Task<IHttpActionResult> updateGuadanOrder(GuaDanOrderView model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return BadRequest("掛單資料不可為空");
|
||||
}
|
||||
if (!model.Uuid.HasValue)
|
||||
{
|
||||
return BadRequest("");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (model.startdate > model.enddate)
|
||||
{
|
||||
return BadRequest("掛單結束時間不能再開始時間之前");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
var order = await _db.GuaDanOrder.FindAsync(model.Uuid.Value);
|
||||
if (order == null)
|
||||
{
|
||||
return BadRequest("未找到对应挂单资料");
|
||||
}
|
||||
order.StartDate = model.startdate;
|
||||
order.EndDate = model.enddate;
|
||||
order.Notes = model.note;
|
||||
order.BookerName = model.bookerName;
|
||||
order.BookerPhone = model.bookerPhone;
|
||||
await _db.SaveChangesAsync();
|
||||
return Ok(model);
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/guadan/delete")]
|
||||
public async Task<IHttpActionResult> deleteGuadanOrder([FromUri] Guid uuid)
|
||||
{
|
||||
var guadan = await _db.GuaDanOrder.FindAsync(uuid);
|
||||
if (guadan == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
using (var transaction = _db.Database.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
var guadanGuests = await _db.GuaDanOrderGuest
|
||||
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
||||
.ToListAsync();
|
||||
var scheduleIds = _db.RegionAndRoomAndBedSchedule
|
||||
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
||||
.Where( b => b.IsActive == true)
|
||||
.Select(c => c.GuaDanOrderNo)
|
||||
.ToList();
|
||||
if (guadanGuests.Any())
|
||||
{
|
||||
_db.GuaDanOrderGuest.RemoveRange(guadanGuests);
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (scheduleIds.Any())
|
||||
{
|
||||
var schedules = await _db.RegionAndRoomAndBedSchedule
|
||||
.Where(a => scheduleIds.Contains(a.GuaDanOrderNo))
|
||||
.ToListAsync();
|
||||
|
||||
if (schedules.Any())
|
||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(schedules);
|
||||
}
|
||||
_db.GuaDanOrder.Remove(guadan);
|
||||
await _db.SaveChangesAsync();
|
||||
transaction.Commit();
|
||||
|
||||
return Ok(new { message = "删除成功" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
transaction.Rollback();
|
||||
return InternalServerError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class guadan_order_dto
|
||||
{
|
||||
public int id { get; set; }
|
||||
public int room_id { get; set; }
|
||||
public int bed_id { get; set; }
|
||||
public int guest_id { get; set; }
|
||||
public DateTime start_date { get; set; }
|
||||
public DateTime? end_date { get; set; }
|
||||
public Guid? statusUuid { get; set; }
|
||||
public int? create_user { get; set; }
|
||||
public DateTime created_at { get; set; }
|
||||
public DateTime updated_at { get; set; }
|
||||
public string notes { get; set; }
|
||||
public int? follower_num { get; set; }
|
||||
|
||||
public Room room { get; set; } = null;
|
||||
public RegionRoomBed bed { get; set; } = null;
|
||||
}
|
||||
|
||||
}
|
||||
353
web/App_Code/api/guadanOrderGuestController.cs
Normal file
353
web/App_Code/api/guadanOrderGuestController.cs
Normal file
@@ -0,0 +1,353 @@
|
||||
using Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
/// <summary>
|
||||
/// guadanOrderGuest 的摘要描述
|
||||
/// </summary>
|
||||
[ezAuthorize]
|
||||
public class guadanOrderGuestController: ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
[HttpGet]
|
||||
[Route("api/guadanorderguest/get")]
|
||||
public async Task<IHttpActionResult> Get()
|
||||
{
|
||||
var data = await _db.GuaDanOrderGuest.ToListAsync();
|
||||
return Ok(data);
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("api/guadanorderguest/getbyorderno")]
|
||||
public async Task<IHttpActionResult> getByOrderNo(string orderNo)
|
||||
{
|
||||
// 先查数据库,不做格式化
|
||||
var qry = await _db.GuaDanOrderGuest
|
||||
.Where(a => a.GuaDanOrderNo == orderNo && a.IsDeleted == false)
|
||||
.ToListAsync();
|
||||
|
||||
// 拉到内存后再处理日期
|
||||
var data = qry.Select(a => new guadan_order_guest_display_dto
|
||||
{
|
||||
Uuid = a.Uuid,
|
||||
name = null,
|
||||
followerNum = a.FollowerNum,
|
||||
roomUuid = a.RoomUuid,
|
||||
bedUuid = a.BedUuid,
|
||||
checkinat = a.CheckInAt.HasValue ? a.CheckInAt.Value.ToString("yyyy-MM-dd") : null,
|
||||
checkoutat = a.CheckOutAt.HasValue ? a.CheckOutAt.Value.ToString("yyyy-MM-dd") : null,
|
||||
phone = null,
|
||||
roomName = a.Room.Name,
|
||||
bedName = a.RegionRoomBed.Name,
|
||||
orderNo = a.GuaDanOrderNo,
|
||||
follower = a.followers,
|
||||
statusUuid = a.statusUuid,
|
||||
statusName = a.RegionRoomBedStatus?.Name,
|
||||
}).ToList();
|
||||
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/guadanorderguest/create")]
|
||||
public async Task<IHttpActionResult> create([FromBody] guadan_order_guest_dto model)
|
||||
{
|
||||
if (model == null)
|
||||
return BadRequest("");
|
||||
|
||||
// 驗證床位與蓮友
|
||||
if (model.followerNum.HasValue && model.bedUuid.HasValue)
|
||||
{
|
||||
var bed = _db.RegionRoomBed.Find(model.bedUuid.Value);
|
||||
var follower = _db.followers.Find(model.followerNum.Value);
|
||||
|
||||
if (bed == null || follower == null)
|
||||
return BadRequest("床位或蓮友不存在");
|
||||
|
||||
bool isMaleFollower;
|
||||
if (follower.sex == "男眾")
|
||||
isMaleFollower = true;
|
||||
else if (follower.sex == "女眾")
|
||||
isMaleFollower = false;
|
||||
else
|
||||
return BadRequest("蓮友性別未知");
|
||||
|
||||
if (bed.Gender != isMaleFollower)
|
||||
return BadRequest("床位性別與蓮友性別不同");
|
||||
}
|
||||
|
||||
if (!model.bedUuid.HasValue)
|
||||
return BadRequest("床位 UUID 不能为空");
|
||||
if (!model.checkInAt.HasValue)
|
||||
return BadRequest("入住时间不能为空");
|
||||
|
||||
// 長期占用處理:checkOutAt 可為 null
|
||||
DateTime? checkOut = model.checkOutAt.Value.Date;
|
||||
|
||||
if (checkOut.HasValue && model.checkInAt > checkOut)
|
||||
return BadRequest("掛單結束時間不能再開始時間之前");
|
||||
if(model.checkInAt == model.checkOutAt)
|
||||
{
|
||||
return BadRequest("掛單結束時間和開始時間不能是同一天");
|
||||
}
|
||||
// 檢查床位可用性
|
||||
var bedIsCanUse = await RegionAndRoomAndBedSchedule.IsBedAvailableAsync(
|
||||
_db,
|
||||
model.bedUuid.Value,
|
||||
model.checkInAt.Value.Date,
|
||||
checkOut
|
||||
);
|
||||
if (!bedIsCanUse)
|
||||
return BadRequest("床位在該時間段內已被占用");
|
||||
|
||||
// 建立掛單
|
||||
var guest = new GuaDanOrderGuest
|
||||
{
|
||||
GuaDanOrderNo = model.orderNo,
|
||||
FollowerNum = model.followerNum,
|
||||
RoomUuid = model.roomUuid,
|
||||
BedUuid = model.bedUuid,
|
||||
CheckInAt = model.checkInAt?.Date,
|
||||
CheckOutAt = checkOut,
|
||||
Uuid = Guid.NewGuid(),
|
||||
statusUuid = model.statusUuid,
|
||||
};
|
||||
|
||||
if (model.followerNum.HasValue)
|
||||
{
|
||||
if (_db.GuaDanOrderGuest.Any(a => a.FollowerNum == model.followerNum && a.GuaDanOrderNo == model.orderNo))
|
||||
return BadRequest("該蓮友已經在該掛單中");
|
||||
}
|
||||
|
||||
_db.GuaDanOrderGuest.Add(guest);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
// 生成每日排程
|
||||
if (checkOut.HasValue)
|
||||
{
|
||||
int totalDays = (checkOut.Value - model.checkInAt.Value.Date).Days;
|
||||
for (int i = 0; i < totalDays; i++)
|
||||
{
|
||||
var scheduleDate = model.checkInAt.Value.Date.AddDays(i);
|
||||
|
||||
var schedul = new RegionAndRoomAndBedSchedule
|
||||
{
|
||||
Title = "掛單",
|
||||
Description = "床位掛單",
|
||||
ScheduleDate = scheduleDate,
|
||||
IsDeleted = false,
|
||||
IsActive = true,
|
||||
TargetUuid = guest.BedUuid,
|
||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||
CreatedAt = DateTime.Now,
|
||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||
Uuid = Guid.NewGuid()
|
||||
};
|
||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 長期占用,ScheduleDate = null
|
||||
var schedul = new RegionAndRoomAndBedSchedule
|
||||
{
|
||||
Title = "掛單",
|
||||
Description = "床位掛單(長期占用)",
|
||||
ScheduleDate = null,
|
||||
IsDeleted = false,
|
||||
IsActive = true,
|
||||
TargetUuid = guest.BedUuid,
|
||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||
CreatedAt = DateTime.Now,
|
||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||
Uuid = Guid.NewGuid()
|
||||
};
|
||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||
}
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/guadanorderguest/update")]
|
||||
public async Task<IHttpActionResult> update([FromBody] guadan_order_guest_dto model)
|
||||
{
|
||||
if (model == null)
|
||||
return BadRequest("");
|
||||
|
||||
// 驗證床位與蓮友
|
||||
if (model.followerNum.HasValue && model.bedUuid.HasValue)
|
||||
{
|
||||
var bed = _db.RegionRoomBed.Find(model.bedUuid.Value);
|
||||
var follower = _db.followers.Find(model.followerNum.Value);
|
||||
|
||||
if (bed == null || follower == null)
|
||||
return BadRequest("床位或蓮友不存在");
|
||||
|
||||
bool isMaleFollower;
|
||||
if (follower.sex == "男眾") isMaleFollower = true;
|
||||
else if (follower.sex == "女眾") isMaleFollower = false;
|
||||
else return BadRequest("蓮友性別未知");
|
||||
|
||||
if (bed.Gender != isMaleFollower)
|
||||
return BadRequest("床位性別與蓮友性別不同");
|
||||
}
|
||||
|
||||
if (!model.bedUuid.HasValue)
|
||||
return BadRequest("床位 UUID 不能为空");
|
||||
|
||||
if (!model.checkInAt.HasValue)
|
||||
return BadRequest("入住时间不能为空");
|
||||
|
||||
// 長期占用處理
|
||||
DateTime? checkOut = model.checkOutAt?.Date;
|
||||
if (checkOut.HasValue && model.checkInAt > checkOut)
|
||||
return BadRequest("掛單結束時間不能再開始時間之前");
|
||||
|
||||
var guest = await _db.GuaDanOrderGuest.FindAsync(model.Uuid);
|
||||
if (guest == null) return BadRequest();
|
||||
|
||||
// 檢查床位可用性
|
||||
var bedIsCanUse = await RegionAndRoomAndBedSchedule.IsBedAvailableAsync(
|
||||
_db,
|
||||
model.bedUuid.Value,
|
||||
model.checkInAt.Value.Date,
|
||||
checkOut
|
||||
);
|
||||
|
||||
if (!bedIsCanUse && guest.BedUuid != model.bedUuid)
|
||||
return BadRequest("床位在該時間段內已被占用");
|
||||
|
||||
if (model.followerNum.HasValue)
|
||||
{
|
||||
bool exists = await _db.GuaDanOrderGuest
|
||||
.Where(a => a.FollowerNum == model.followerNum
|
||||
&& a.GuaDanOrderNo == model.orderNo
|
||||
&& a.Uuid != model.Uuid)
|
||||
.AnyAsync();
|
||||
if (exists) return BadRequest("該蓮友已經在該掛單中");
|
||||
}
|
||||
|
||||
// 更新掛單基本資料
|
||||
guest.FollowerNum = model.followerNum;
|
||||
guest.RoomUuid = model.roomUuid;
|
||||
guest.BedUuid = model.bedUuid;
|
||||
guest.CheckInAt = model.checkInAt?.Date;
|
||||
guest.CheckOutAt = checkOut;
|
||||
guest.statusUuid = model.statusUuid;
|
||||
|
||||
// 刪除原有每日排程
|
||||
var oldSchedules = _db.RegionAndRoomAndBedSchedule
|
||||
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo)
|
||||
.ToList();
|
||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(oldSchedules);
|
||||
|
||||
// 重新生成每日排程
|
||||
if (checkOut.HasValue)
|
||||
{
|
||||
int totalDays = (checkOut.Value - model.checkInAt.Value.Date).Days;
|
||||
for (int i = 0; i < totalDays; i++)
|
||||
{
|
||||
var date = model.checkInAt.Value.Date.AddDays(i);
|
||||
var schedul = new RegionAndRoomAndBedSchedule
|
||||
{
|
||||
Title = "掛單",
|
||||
Description = "床位掛單",
|
||||
ScheduleDate = date,
|
||||
IsDeleted = false,
|
||||
IsActive = true,
|
||||
TargetUuid = guest.BedUuid,
|
||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||
CreatedAt = DateTime.Now,
|
||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||
Uuid = Guid.NewGuid()
|
||||
};
|
||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 長期占用
|
||||
var schedul = new RegionAndRoomAndBedSchedule
|
||||
{
|
||||
Title = "掛單",
|
||||
Description = "床位掛單(長期占用)",
|
||||
ScheduleDate = null,
|
||||
IsDeleted = false,
|
||||
IsActive = true,
|
||||
TargetUuid = guest.BedUuid,
|
||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||
CreatedAt = DateTime.Now,
|
||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||
Uuid = Guid.NewGuid()
|
||||
};
|
||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||
}
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/guadanorderguest/delete")]
|
||||
public async Task<IHttpActionResult> deleteGuadanGuest([FromUri] Guid uuid)
|
||||
{
|
||||
var guest = await _db.GuaDanOrderGuest.FindAsync(uuid);
|
||||
if (guest == null)
|
||||
return BadRequest("未找到指定挂单资料");
|
||||
|
||||
// 删除所有与该 guest 相关的排程(每日排程或長期占用)
|
||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
||||
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo)
|
||||
.ToList();
|
||||
|
||||
if (schedules.Any())
|
||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(schedules);
|
||||
|
||||
_db.GuaDanOrderGuest.Remove(guest);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok(new { message = "删除成功" });
|
||||
}
|
||||
|
||||
public class guadan_order_guest_dto
|
||||
{
|
||||
public Guid? Uuid { get; set; }
|
||||
public int? followerNum { get; set; }
|
||||
public string orderNo { get; set; }
|
||||
public Guid? roomUuid { get; set; }
|
||||
public Guid? bedUuid { get; set; }
|
||||
public DateTime? checkInAt { get; set; }
|
||||
public DateTime? checkOutAt { get; set; }
|
||||
public Guid? statusUuid { get; set; }
|
||||
}
|
||||
public class guadan_order_guest_display_dto
|
||||
{
|
||||
public Guid? Uuid { get; set; }
|
||||
public int? followerNum { get; set; }
|
||||
public string orderNo { get; set; }
|
||||
public string name { get; set; }
|
||||
public Guid? roomUuid { get; set; }
|
||||
public Guid? bedUuid { get;set; }
|
||||
public string checkinat { get;set; }
|
||||
public string checkoutat { get;set; }
|
||||
public int? gender { get; set; }
|
||||
public Guid? statusUuid { get; set; }
|
||||
public string statusName { get; set; }
|
||||
public string phone { get; set; }
|
||||
public string note { get; set; }
|
||||
public string roomName { get; set; }
|
||||
public string bedName { get; set; }
|
||||
public follower follower { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
72
web/App_Code/api/guadanStatisticsController.cs
Normal file
72
web/App_Code/api/guadanStatisticsController.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
/// <summary>
|
||||
/// guadanStatisticsController 的摘要描述
|
||||
/// </summary>
|
||||
public class guadanStatisticsController: ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
|
||||
[HttpGet]
|
||||
[Route("api/guadanStatistics/GetGuadanStatistics")]
|
||||
public async Task<IHttpActionResult> GetGuadanStatistics()
|
||||
{
|
||||
//挂单统计:房间,床位,挂单笔数,挂单人数的统计
|
||||
|
||||
var now = DateTime.Now;
|
||||
var roomCount = await _db.Room.Where(a => a.IsDeleted == false).CountAsync();
|
||||
var rooms = await _db.Room.Include(r => r.RegionRoomBed).ToListAsync();
|
||||
|
||||
var emptyRoomCount = rooms
|
||||
.Where(r => r.RegionRoomBed.All(b => b.IsAvailableDuring(now, now, _db))) // 這裡就能用方法
|
||||
.Count();
|
||||
var bedCount = await _db.RegionRoomBed.Where(a => a.IsDeleted == false).CountAsync();
|
||||
var maleBedCount = await _db.RegionRoomBed.Where(a => a.IsDeleted == false && a.Gender == true).CountAsync();
|
||||
var femaleBedCount = await _db.RegionRoomBed.Where(a => a.IsDeleted == false && a.Gender == false).CountAsync();
|
||||
|
||||
var guadanTotalCount = await _db.GuaDanOrder.Where(a => a.IsDeleted == false).CountAsync();
|
||||
var guadanPeopleTotal = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false).CountAsync();
|
||||
var guadanPeopleMale = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false && a.followers.sex == "男眾").CountAsync();
|
||||
var guadanPeopleFemale = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false && a.followers.sex == "女眾").CountAsync();
|
||||
dynamic bedCounts = await RegionAndRoomAndBedSchedule.GetAvailableBedCountsAsync(_db, DateTime.Now, DateTime.Now);
|
||||
var guadanCurrentCount = await _db.GuaDanOrder.Where(a => now < a.EndDate).CountAsync();
|
||||
var guadanPeopleCurrent = await _db.GuaDanOrderGuest.Where( a => a.CheckOutAt > now).CountAsync();
|
||||
var guadanPeopleCurrentMale = await _db.GuaDanOrderGuest.Where(a => a.CheckOutAt > now && a.followers.sex == "男眾").CountAsync();
|
||||
var guadanPeopleCurrentFemale = await _db.GuaDanOrderGuest.Where(a => a.CheckOutAt > now && a.followers.sex == "女眾").CountAsync();
|
||||
|
||||
var result = new
|
||||
{
|
||||
roomStatistics = new
|
||||
{
|
||||
roomCount = roomCount,
|
||||
emptyRoomCount = emptyRoomCount,
|
||||
bedCount = bedCount,
|
||||
maleBedCount = maleBedCount,
|
||||
femaleBedCount = femaleBedCount,
|
||||
emptyBedCount = bedCounts.male + bedCounts.female,
|
||||
emptyMaleBedCount = bedCounts.male,
|
||||
emptyFemaleBedCount = bedCounts.female
|
||||
},
|
||||
guadanStatistics = new
|
||||
{
|
||||
guadanTotalCount = guadanTotalCount, // 总挂单次数
|
||||
guadanCurrentCount = guadanCurrentCount, // 当前挂单数量
|
||||
guadanPeopleTotal = guadanPeopleTotal, // 总挂单人数
|
||||
guadanPeopleMale = guadanPeopleMale,
|
||||
guadanPeopleFemale = guadanPeopleFemale,
|
||||
guadanPeopleCurrent = guadanPeopleCurrent, // 当前挂单人数
|
||||
guadanPeopleCurrentMale = guadanPeopleCurrentMale,
|
||||
guadanPeopleCurrentFemale = guadanPeopleCurrentFemale
|
||||
}
|
||||
};
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
31
web/App_Code/api/lianyouController.cs
Normal file
31
web/App_Code/api/lianyouController.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using PagedList;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
/// <summary>
|
||||
/// lianyouController 的摘要描述
|
||||
/// </summary>
|
||||
[ezAuthorize]
|
||||
public class lianyouController: ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/lianyou/getfollowers")]
|
||||
public async Task<IHttpActionResult> GetGuadanFollowers(int page, int pageSize, string searchName = null)
|
||||
{
|
||||
var qry = _db.followers.AsEnumerable();
|
||||
if(searchName != null)
|
||||
{
|
||||
qry = qry.Where(a => (a.u_name ?? "").Contains(searchName) || (a.phone ?? "").Contains(searchName));
|
||||
}
|
||||
var count = qry.Count();
|
||||
var data = qry.OrderBy(a => a.f_number).ToPagedList(page, pageSize);
|
||||
return Ok(new {data = data, count = count});
|
||||
}
|
||||
}
|
||||
460
web/App_Code/api/regionController.cs
Normal file
460
web/App_Code/api/regionController.cs
Normal file
@@ -0,0 +1,460 @@
|
||||
using Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Routing;
|
||||
|
||||
/// <summary>
|
||||
/// regionController 的摘要描述
|
||||
/// </summary>
|
||||
[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.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,
|
||||
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.StatusUuid,
|
||||
bed.IsActive,
|
||||
bed.IsDeleted,
|
||||
canuse = bed.IsAvailableDuring(startDate, endDate, _db),
|
||||
statusname = bed.RegionRoomBedStatus.Name,
|
||||
schedules = _db.RegionAndRoomAndBedSchedule
|
||||
.Where(s => s.TargetUuid == bed.Uuid
|
||||
&& s.IsDeleted == false
|
||||
&& s.IsActive
|
||||
&& (s.ScheduleDate == null
|
||||
|| (s.ScheduleDate >= startDate && s.ScheduleDate <= endDate)))
|
||||
.Select(s => new
|
||||
{
|
||||
s.Uuid,
|
||||
scheduledate = s.ScheduleDate,
|
||||
s.UseType,
|
||||
s.Title,
|
||||
s.Description,
|
||||
s.GuaDanOrderNo
|
||||
})
|
||||
.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,
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 遞迴生成區域完整路徑
|
||||
/// </summary>
|
||||
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<Region> 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<BedDto>(),
|
||||
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,
|
||||
statusuuid = c.StatusUuid,
|
||||
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<Region> 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,
|
||||
statusuuid = c.StatusUuid
|
||||
}).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<BedDto>(),
|
||||
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<int> BedCount { get; set; }
|
||||
public Nullable<bool> IsActive { get; set; }
|
||||
public Nullable<System.DateTime> CreatedAt { get; set; }
|
||||
public Nullable<System.DateTime> UpdatedAt { get; set; }
|
||||
public List<BedDto> beds { get; set; }
|
||||
}
|
||||
public class BedDto {
|
||||
public Guid Uuid { get; set; }
|
||||
public Guid? roomUuid { get; set; }
|
||||
public string name { get; set; }
|
||||
public Guid? statusuuid { 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<RegionDto> Children { get; set; }
|
||||
public Guid? RegionTypeUuid { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public int? RoomCount { get; set; }
|
||||
public List<RoomDto> Rooms { get; set; }
|
||||
public List<BedDto> 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();
|
||||
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 = "刪除成功" });
|
||||
}
|
||||
|
||||
// 遞迴刪除子節點
|
||||
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);
|
||||
}
|
||||
}
|
||||
435
web/App_Code/api/regionRoomBedController.cs
Normal file
435
web/App_Code/api/regionRoomBedController.cs
Normal file
@@ -0,0 +1,435 @@
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using DocumentFormat.OpenXml.Office.CustomUI;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using Microsoft.AspNet.SignalR;
|
||||
using Model;
|
||||
using Org.BouncyCastle.Asn1.Ocsp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
/// <summary>
|
||||
/// regionRoomBedController 的摘要描述
|
||||
/// </summary>
|
||||
[ezAuthorize]
|
||||
public class regionRoomBedController : ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
public regionRoomBedController()
|
||||
{
|
||||
//
|
||||
// TODO: 在這裡新增建構函式邏輯
|
||||
//
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("api/region/room/bed/list")]
|
||||
public IHttpActionResult GetRegionRoomBedListByRoomId(Guid? roomUuid, DateTime StartTime, DateTime? EndTime)
|
||||
{
|
||||
if (StartTime == null || EndTime == null)
|
||||
return BadRequest("时间不能为空");
|
||||
|
||||
if (roomUuid == null)
|
||||
return BadRequest("roomId不能为空");
|
||||
|
||||
// 先取出床位
|
||||
var beds = _db.RegionRoomBed
|
||||
.Where(a => a.RoomUuid == roomUuid)
|
||||
.ToList();
|
||||
|
||||
// 取出所有相关排程
|
||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
||||
.Where(b => b.IsDeleted == false && b.IsActive)
|
||||
.ToList();
|
||||
|
||||
var data = beds.Select(a =>
|
||||
{
|
||||
// 在内存中处理日期比较
|
||||
var bedSchedules = schedules
|
||||
.Where(b => b.TargetUuid == a.Uuid
|
||||
&& (b.ScheduleDate == null // 长期占用
|
||||
|| (b.ScheduleDate >= StartTime.Date && b.ScheduleDate <= EndTime.Value.Date)))
|
||||
.Select(c => new
|
||||
{
|
||||
c.Uuid,
|
||||
c.Description,
|
||||
c.IsDeleted,
|
||||
c.IsActive,
|
||||
c.GuaDanOrderNo,
|
||||
c.UseType,
|
||||
c.Title,
|
||||
c.TargetUuid,
|
||||
scheduledate = c.ScheduleDate,
|
||||
})
|
||||
.ToList();
|
||||
|
||||
bool canUsed = !bedSchedules.Any();
|
||||
|
||||
return new
|
||||
{
|
||||
a.Uuid,
|
||||
a.Name,
|
||||
a.Gender,
|
||||
a.IsActive,
|
||||
a.StatusUuid,
|
||||
a.RoomUuid,
|
||||
canUsed,
|
||||
schedule = bedSchedules
|
||||
};
|
||||
});
|
||||
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/region/bed/create")]
|
||||
public IHttpActionResult CreateBed([FromBody] RegionRoomBed bed)
|
||||
{
|
||||
var room = _db.Room.Find(bed.RoomUuid);
|
||||
if (room == null)
|
||||
{
|
||||
return BadRequest("當前客房不存在");
|
||||
}
|
||||
if(room.Gender != bed.Gender)
|
||||
{
|
||||
return BadRequest("床為性別和房間性別必須一致");
|
||||
}
|
||||
if (room.BedCount != null && room.BedCount < room.RegionRoomBed.Count() + 1)
|
||||
{
|
||||
return BadRequest("該客房床位已滿");
|
||||
}
|
||||
var regionBed = new RegionRoomBed
|
||||
{
|
||||
Name = bed.Name,
|
||||
RoomUuid = bed.RoomUuid,
|
||||
StatusUuid = bed.StatusUuid,
|
||||
IsActive = bed.IsActive,
|
||||
Gender = bed.Gender,
|
||||
Uuid = Guid.NewGuid(),
|
||||
};
|
||||
_db.RegionRoomBed.Add(regionBed);
|
||||
_db.SaveChanges();
|
||||
|
||||
//創建床位
|
||||
return Ok(new {
|
||||
uuid = regionBed.Uuid,
|
||||
roomUuid = regionBed.RoomUuid,
|
||||
statusuuid = regionBed.StatusUuid,
|
||||
isactive = regionBed.IsActive,
|
||||
gender = regionBed.Gender,
|
||||
name = regionBed.Name,
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/region/bed/update")]
|
||||
public IHttpActionResult UpdateBed([FromBody] RegionRoomBed bed)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(bed.Name))
|
||||
{
|
||||
return BadRequest("床位名稱不可為空");
|
||||
}
|
||||
var oldBed = _db.RegionRoomBed.Find(bed.Uuid);
|
||||
if (oldBed == null)
|
||||
{
|
||||
return BadRequest("更新失敗,床位不存在");
|
||||
}
|
||||
var room = _db.Room.Find(bed.RoomUuid);
|
||||
if (room == null)
|
||||
{
|
||||
return BadRequest("當前客房不存在");
|
||||
}
|
||||
if (room.Gender != bed.Gender)
|
||||
{
|
||||
return BadRequest("床為性別和房間性別必須一致");
|
||||
}
|
||||
oldBed.StatusUuid = bed.StatusUuid;
|
||||
oldBed.IsActive = bed.IsActive;
|
||||
oldBed.Name = bed.Name;
|
||||
oldBed.Gender = bed.Gender;
|
||||
_db.SaveChanges();
|
||||
|
||||
//創建床位
|
||||
return Ok(new { message = "床位更新成功" });
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/region/bed/delete")]
|
||||
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 = "刪除成功" });
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("api/region/bed/getavailablebedcountbytime")]
|
||||
public async Task<IHttpActionResult> GetCanUseBedCountByTime(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
//获取某个时间段内可用床位数量
|
||||
var counts = await RegionAndRoomAndBedSchedule.GetAvailableBedCountsAsync(_db, startTime, endTime);
|
||||
return Ok(counts);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/region/bed/preallocation")]
|
||||
public async Task<IHttpActionResult> PreAutoAllocationBed([FromBody] ConfirmAllocationRequest request)
|
||||
{
|
||||
DateTime allocationStart = request.CheckInAt;
|
||||
DateTime? allocationEnd = request.CheckOutAt;
|
||||
bool isAllallocation = true; //是否全部分配完毕
|
||||
// 获取可用床位列表
|
||||
var availableBeds = await RegionAndRoomAndBedSchedule.GetAvailableBedsAsync(_db, allocationStart, allocationEnd);
|
||||
|
||||
// 将床位按房间分组
|
||||
var roomGroups = availableBeds
|
||||
.GroupBy(b => b.RoomUuid)
|
||||
.Select(g => new
|
||||
{
|
||||
RoomUuid = g.Key,
|
||||
Beds = g.ToList(),
|
||||
Gender = g.First().Room.Gender // bool,不可空
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var data = new List<FollowerBedResponse>();
|
||||
|
||||
// 按性别分组请求
|
||||
var maleFollowers = request.PreBeds.Where(f => f.sex == "M").ToList();
|
||||
var femaleFollowers = request.PreBeds.Where(f => f.sex == "F").ToList();
|
||||
|
||||
void AllocateByGender(List<FollowerBedResponse> followers, bool isMale)
|
||||
{
|
||||
var rooms = roomGroups.Where(r => r.Gender == isMale).ToList();
|
||||
int remaining = followers.Count;
|
||||
int index = 0;
|
||||
|
||||
while (remaining > 0 && rooms.Any(r => r.Beds.Count > 0))
|
||||
{
|
||||
// 找能容纳所有人的房间
|
||||
var fullRoom = rooms
|
||||
.Where(r => r.Beds.Count >= remaining)
|
||||
.OrderBy(r => r.Beds.Count - remaining) // 分配后剩余床位最少优先
|
||||
.FirstOrDefault();
|
||||
|
||||
if (fullRoom != null)
|
||||
{
|
||||
// 分配所有剩余人员
|
||||
for (int i = index; i < followers.Count; i++)
|
||||
{
|
||||
var follower = followers[i];
|
||||
var bed = fullRoom.Beds.First();
|
||||
data.Add(new FollowerBedResponse
|
||||
{
|
||||
num = follower.num,
|
||||
sex = follower.sex,
|
||||
bedUuid = bed.Uuid
|
||||
});
|
||||
fullRoom.Beds.Remove(bed);
|
||||
remaining--;
|
||||
index++;
|
||||
}
|
||||
break; // 全部分配完
|
||||
}
|
||||
else
|
||||
{
|
||||
// 找剩余床位最多的房间
|
||||
var room = rooms.OrderByDescending(r => r.Beds.Count).First();
|
||||
int toAssign = Math.Min(remaining, room.Beds.Count);
|
||||
|
||||
for (int i = 0; i < toAssign; i++)
|
||||
{
|
||||
var follower = followers[index++];
|
||||
var bed = room.Beds.First();
|
||||
data.Add(new FollowerBedResponse
|
||||
{
|
||||
num = follower.num,
|
||||
sex = follower.sex,
|
||||
bedUuid = bed.Uuid
|
||||
});
|
||||
room.Beds.Remove(bed);
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(index < followers.Count)
|
||||
{
|
||||
isAllallocation = false;
|
||||
return;
|
||||
}
|
||||
// 剩余无法分配的人员
|
||||
for (int i = index; i < followers.Count; i++)
|
||||
{
|
||||
|
||||
data.Add(new FollowerBedResponse
|
||||
{
|
||||
num = followers[i].num,
|
||||
sex = followers[i].sex,
|
||||
bedUuid = null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 先分配男生,再分配女生
|
||||
AllocateByGender(maleFollowers, true);
|
||||
if (!isAllallocation)
|
||||
{
|
||||
return BadRequest("分配失敗,床位不足");
|
||||
}
|
||||
AllocateByGender(femaleFollowers, false);
|
||||
if (!isAllallocation)
|
||||
{
|
||||
return BadRequest("分配失敗,床位不足");
|
||||
}
|
||||
|
||||
return Ok(new { message = "預分配成功", data });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/region/bed/confirmallocation")]
|
||||
public async Task<IHttpActionResult> ConfirmAutoAllocationBed([FromBody] ConfirmAllocationRequest request)
|
||||
{
|
||||
if (request?.PreBeds == null || !request.PreBeds.Any())
|
||||
return BadRequest("请求床位不能为空");
|
||||
|
||||
using (var transaction = _db.Database.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
DateTime allocationStart = request.CheckInAt.Date; // 保證時間清零
|
||||
DateTime? allocationEnd = request.CheckOutAt?.Date;
|
||||
|
||||
foreach (var req in request.PreBeds)
|
||||
{
|
||||
if (req.bedUuid != null)
|
||||
{
|
||||
// 先拉出床位相關排程到內存,避免 EF 不支援 .Date
|
||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
||||
.Where(s => s.IsDeleted == false && s.IsActive && s.TargetUuid == req.bedUuid)
|
||||
.ToList();
|
||||
|
||||
bool conflictExists = schedules.Any(s =>
|
||||
s.ScheduleDate == null // 長期占用
|
||||
|| (allocationEnd.HasValue
|
||||
? (s.ScheduleDate >= allocationStart && s.ScheduleDate <= allocationEnd.Value)
|
||||
: s.ScheduleDate >= allocationStart)
|
||||
);
|
||||
|
||||
if (conflictExists)
|
||||
{
|
||||
transaction.Rollback();
|
||||
return BadRequest($"床位 {req.bedUuid} 在时间段内已被占用,分配失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 找到房間 UUID
|
||||
Guid? roomUuid = null;
|
||||
if (req.bedUuid != null)
|
||||
{
|
||||
var bed = _db.RegionRoomBed.Find(req.bedUuid);
|
||||
if (bed != null)
|
||||
roomUuid = bed.RoomUuid;
|
||||
}
|
||||
|
||||
// 新增挂单入住客人记录
|
||||
var guest = new GuaDanOrderGuest
|
||||
{
|
||||
GuaDanOrderNo = request.OrderNo,
|
||||
FollowerNum = req.num,
|
||||
BedUuid = req.bedUuid,
|
||||
Uuid = Guid.NewGuid(),
|
||||
RoomUuid = roomUuid,
|
||||
CheckInAt = allocationStart,
|
||||
CheckOutAt = allocationEnd,
|
||||
};
|
||||
_db.GuaDanOrderGuest.Add(guest);
|
||||
|
||||
// 新增每日排程
|
||||
if (allocationEnd.HasValue)
|
||||
{
|
||||
for (var date = allocationStart; date <= allocationEnd.Value; date = date.AddDays(1))
|
||||
{
|
||||
var newSchedule = new RegionAndRoomAndBedSchedule
|
||||
{
|
||||
Uuid = Guid.NewGuid(),
|
||||
TargetUuid = req.bedUuid,
|
||||
ScheduleDate = date,
|
||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||
IsDeleted = false,
|
||||
IsActive = true,
|
||||
CreatedBy = "系统自动分配",
|
||||
CreatedAt = DateTime.Now,
|
||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
||||
};
|
||||
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 長期占用
|
||||
var newSchedule = new RegionAndRoomAndBedSchedule
|
||||
{
|
||||
Uuid = Guid.NewGuid(),
|
||||
TargetUuid = req.bedUuid,
|
||||
ScheduleDate = null,
|
||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||
IsDeleted = false,
|
||||
IsActive = true,
|
||||
CreatedBy = "系统自动分配",
|
||||
CreatedAt = DateTime.Now,
|
||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
||||
};
|
||||
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
||||
}
|
||||
}
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
transaction.Commit();
|
||||
|
||||
return Ok(new { message = "分配成功" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
transaction.Rollback();
|
||||
return InternalServerError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool BedIsCanUsed(RegionRoomBed bed, DateTime? StartTime, DateTime? EndTime)
|
||||
{
|
||||
if(!bed.IsActive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public class FollowerBedRequest
|
||||
{
|
||||
public int num { get; set; }
|
||||
public string sex { get; set; }
|
||||
}
|
||||
|
||||
public class FollowerBedResponse
|
||||
{
|
||||
public int num { get; set; }
|
||||
public string sex { get; set; }
|
||||
public Guid? bedUuid { get; set; } = null;
|
||||
public string bedName { get; set; }
|
||||
}
|
||||
public class ConfirmAllocationRequest
|
||||
{
|
||||
public List<FollowerBedResponse> PreBeds { get; set; }
|
||||
public string OrderNo { get; set; }
|
||||
public DateTime CheckInAt { get; set; }
|
||||
public DateTime? CheckOutAt { get; set; }
|
||||
}
|
||||
}
|
||||
67
web/App_Code/api/regionRoomBedStatusController.cs
Normal file
67
web/App_Code/api/regionRoomBedStatusController.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
/// <summary>
|
||||
/// regionRoomBedStatusController 的摘要描述
|
||||
/// </summary>
|
||||
[ezAuthorize]
|
||||
public class regionRoomBedStatusController: ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
public regionRoomBedStatusController()
|
||||
{
|
||||
//
|
||||
// TODO: 在這裡新增建構函式邏輯
|
||||
//
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("api/region/bed/status/list")]
|
||||
public IHttpActionResult getStatusList()
|
||||
{
|
||||
//返回所有状态
|
||||
var data = _db.RegionRoomBedStatus
|
||||
.Where(a => !a.IsDeleted)
|
||||
.OrderBy(a => a.Category)
|
||||
.ThenBy(a => a.Code)
|
||||
.ToList()
|
||||
.Select(s => new
|
||||
{
|
||||
s.Category,
|
||||
s.Code,
|
||||
s.Name,
|
||||
s.Description,
|
||||
s.Uuid,
|
||||
s.CategoryName
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return Ok(data);
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("api/region/guadan/status/list")]
|
||||
public IHttpActionResult getGuadanStatusList()
|
||||
{
|
||||
//获取挂单状态
|
||||
var data = _db.RegionRoomBedStatus
|
||||
.Where(a => a.Category == (int)RegionRoomBedStatus.CategoryEnum.GuaDanStatus)
|
||||
.ToList();
|
||||
return Ok(data);
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/region/bed/status/delete")]
|
||||
public IHttpActionResult DeleteBedStatus([FromUri]Guid id)
|
||||
{
|
||||
var rt = _db.RegionRoomBedStatus.Find(id);
|
||||
if (rt == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
_db.RegionRoomBedStatus.Remove(rt);
|
||||
_db.SaveChanges();
|
||||
return Ok(new { message = "刪除成功" });
|
||||
}
|
||||
}
|
||||
117
web/App_Code/api/regionRoomController.cs
Normal file
117
web/App_Code/api/regionRoomController.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using static regionController;
|
||||
|
||||
/// <summary>
|
||||
/// regionRoomController 的摘要描述
|
||||
/// </summary>
|
||||
[ezAuthorize]
|
||||
public class regionRoomController: ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
public regionRoomController()
|
||||
{
|
||||
//
|
||||
// TODO: 在這裡新增建構函式邏輯
|
||||
//
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("api/region/room/get")]
|
||||
public async Task<IHttpActionResult> getRoomList()
|
||||
{
|
||||
var rooms = await _db.Room.ToListAsync();
|
||||
return Ok(rooms);
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/region/room/create")]
|
||||
public async Task<IHttpActionResult> createRoom([FromBody] Room room)
|
||||
{
|
||||
if (!room.BedCount.HasValue)
|
||||
{
|
||||
return BadRequest("請輸入床位數量");
|
||||
}
|
||||
var newRoom = new Room();
|
||||
newRoom.Name = room.Name;
|
||||
newRoom.RegionUuid = room.RegionUuid;
|
||||
newRoom.BedCount = room.BedCount;
|
||||
newRoom.CreatedAt = room.CreatedAt;
|
||||
newRoom.Gender = room.Gender;
|
||||
newRoom.IsActive = room.IsActive;
|
||||
newRoom.Uuid = Guid.NewGuid();
|
||||
_db.Room.Add(newRoom);
|
||||
await _db.SaveChangesAsync();
|
||||
var Rooms = new
|
||||
{
|
||||
uuid = newRoom.Uuid,
|
||||
Name = newRoom.Name,
|
||||
regionUuid = newRoom.RegionUuid,
|
||||
Gender = newRoom.Gender,
|
||||
BedCount = newRoom.BedCount,
|
||||
IsActive = newRoom.IsActive,
|
||||
beds = newRoom.RegionRoomBed.Select(c => new BedDto
|
||||
{
|
||||
Uuid = c.Uuid,
|
||||
name = c.Name,
|
||||
roomUuid = c.RoomUuid,
|
||||
isactive = c.IsActive,
|
||||
statusuuid = c.StatusUuid,
|
||||
}).ToList(),
|
||||
|
||||
};
|
||||
return Ok(Rooms);
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/region/room/update")]
|
||||
public async Task<IHttpActionResult> updateRoom([FromBody] Room room)
|
||||
{
|
||||
var oldRoom = await _db.Room.FindAsync(room.Uuid);
|
||||
if (oldRoom == null)
|
||||
{
|
||||
return BadRequest("未找到该房间信息,更新失败");
|
||||
}
|
||||
// 判斷房間中是否存在與房間性別不符的床位
|
||||
bool canProceed = !_db.RegionRoomBed
|
||||
.Any(a => a.RoomUuid == room.Uuid && a.Gender != room.Gender);
|
||||
|
||||
if (!canProceed)
|
||||
{
|
||||
// 如果有不符合性別的床位,不能繼續操作
|
||||
return BadRequest("房間中已有與房間性別不符的床位,無法操作");
|
||||
}
|
||||
if(!room.BedCount.HasValue)
|
||||
{
|
||||
return BadRequest("請輸入床位數量");
|
||||
}
|
||||
oldRoom.Name = room.Name;
|
||||
oldRoom.BedCount = room.BedCount;
|
||||
oldRoom.Gender = room.Gender;
|
||||
oldRoom.UpdatedAt = DateTime.Now;
|
||||
oldRoom.IsActive = room.IsActive;
|
||||
oldRoom.RegionUuid = room.RegionUuid;
|
||||
await _db.SaveChangesAsync();
|
||||
return Ok(new { message = "更新成功"});
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/region/room/delete")]
|
||||
public async Task<IHttpActionResult> deleteRoom([FromBody] Room rm)
|
||||
{
|
||||
var room = await _db.Room.FindAsync(rm.Uuid);
|
||||
if (room == null) return BadRequest("房間不存在");
|
||||
|
||||
var beds = _db.RegionRoomBed.Where(b => b.RoomUuid == room.Uuid);
|
||||
_db.RegionRoomBed.RemoveRange(beds);
|
||||
|
||||
_db.Room.Remove(room);
|
||||
await _db.SaveChangesAsync();
|
||||
return Ok(new { message = "刪除成功" });
|
||||
}
|
||||
|
||||
}
|
||||
48
web/App_Code/api/regiontypeController.cs
Normal file
48
web/App_Code/api/regiontypeController.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
/// <summary>
|
||||
/// regiontypeController 的摘要描述
|
||||
/// </summary>
|
||||
[ezAuthorize]
|
||||
public class regiontypeController: ApiController
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
public regiontypeController()
|
||||
{
|
||||
//
|
||||
// TODO: 在這裡新增建構函式邏輯
|
||||
//
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/regiontype/getreiontypelist")]
|
||||
public IHttpActionResult getRegionTypeList()
|
||||
{
|
||||
var data = _db.RegionType
|
||||
.Select(region => new
|
||||
{
|
||||
region.Uuid,
|
||||
region.Name,
|
||||
region.Code,
|
||||
isactive = region.IsActive,
|
||||
})
|
||||
.ToList();
|
||||
return Ok(data);
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("api/regiontype/delete")]
|
||||
public IHttpActionResult deleteRegionType([FromUri] Guid uuid)
|
||||
{
|
||||
var rt = _db.RegionType.Find(uuid);
|
||||
if (rt == null) {
|
||||
return NotFound();
|
||||
}
|
||||
_db.RegionType.Remove(rt);
|
||||
_db.SaveChanges();
|
||||
return Ok( new { message = "刪除成功" });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user