update from old git

This commit is contained in:
2025-09-04 18:30:54 +08:00
parent af2c152ef6
commit 61502cb3bd
46 changed files with 6420 additions and 0 deletions

View 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}";
}
}
}

View 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;
}
}
}

View 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 };
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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>

View 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; }
}

View 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; }
}

View 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;
}
}

View 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; }
}
}

View 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);
}
}

View 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});
}
}

View 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);
}
}

View 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; }
}
}

View 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 = "刪除成功" });
}
}

View 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 = "刪除成功" });
}
}

View 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 = "刪除成功" });
}
}