修改挂单功能
This commit is contained in:
57
web/App_Code/Model/Partial/GuaDanOrderGuest.cs
Normal file
57
web/App_Code/Model/Partial/GuaDanOrderGuest.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GuaDanOrderGuest 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
public partial class GuaDanOrderGuest
|
||||||
|
{
|
||||||
|
// 状态常量定义
|
||||||
|
public const string STATUS_BOOKED = "401"; // 预订成功
|
||||||
|
public const string STATUS_CHECKED_IN = "402"; // 已入住
|
||||||
|
public const string STATUS_CHECKED_OUT = "403"; // 已退房
|
||||||
|
public const string STATUS_CANCELLED = "404"; // 已取消
|
||||||
|
|
||||||
|
public static bool IsStatusTransitionValid(ezEntities db, string targetStatus, Guid guestId)
|
||||||
|
{
|
||||||
|
// 获取当前客人对象
|
||||||
|
GuaDanOrderGuest currentGuest = db.GuaDanOrderGuest.Find(guestId);
|
||||||
|
if (currentGuest == null)
|
||||||
|
{
|
||||||
|
// 如果没有客人对象,只能创建新的预订
|
||||||
|
return targetStatus == STATUS_BOOKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全获取当前状态(处理null情况)
|
||||||
|
string currentStatus = currentGuest.RegionRoomBedStatus?.Code;
|
||||||
|
|
||||||
|
// 如果当前状态为空,只能进入预订成功状态
|
||||||
|
if (string.IsNullOrEmpty(currentStatus))
|
||||||
|
{
|
||||||
|
return targetStatus == STATUS_BOOKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义有效的状态转换规则
|
||||||
|
var validTransitions = new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{ STATUS_BOOKED, new List<string> { STATUS_CHECKED_IN, STATUS_CANCELLED } },
|
||||||
|
{ STATUS_CHECKED_IN, new List<string> { STATUS_CHECKED_OUT } },
|
||||||
|
{ STATUS_CHECKED_OUT, new List<string> { } }, // 终态,不能再转换
|
||||||
|
{ STATUS_CANCELLED, new List<string> { } } // 终态,不能再转换
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检查转换是否有效
|
||||||
|
if (validTransitions.ContainsKey(currentStatus))
|
||||||
|
{
|
||||||
|
return validTransitions[currentStatus].Contains(targetStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // 未知的当前状态
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@ namespace Model
|
|||||||
|
|
||||||
// 找出在日期範圍內被占用的床位 Uuid(包括長期占用 ScheduleDate = null)
|
// 找出在日期範圍內被占用的床位 Uuid(包括長期占用 ScheduleDate = null)
|
||||||
var busyBedUuidsQuery = db.RegionAndRoomAndBedSchedule
|
var busyBedUuidsQuery = db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.IsDeleted == false && s.IsActive
|
.Where(s => s.IsDeleted == false && !s.IsCancel
|
||||||
&& (s.ScheduleDate == null
|
&& (s.ScheduleDate == null
|
||||||
|| (end.HasValue
|
|| (end.HasValue
|
||||||
&& s.ScheduleDate >= start
|
&& s.ScheduleDate >= start
|
||||||
@@ -79,25 +79,28 @@ namespace Model
|
|||||||
public static async Task<bool> IsBedAvailableAsync(ezEntities db, Guid targetUuid, DateTime start, DateTime? end)
|
public static async Task<bool> IsBedAvailableAsync(ezEntities db, Guid targetUuid, DateTime start, DateTime? end)
|
||||||
{
|
{
|
||||||
// 如果 end 為 null,表示長期占用,直接判斷是否已有長期占用
|
// 如果 end 為 null,表示長期占用,直接判斷是否已有長期占用
|
||||||
|
//不包含结束时间那一天
|
||||||
if (end == null)
|
if (end == null)
|
||||||
{
|
{
|
||||||
var hasLongTerm = await db.RegionAndRoomAndBedSchedule
|
var hasLongTerm = await db.RegionAndRoomAndBedSchedule
|
||||||
.AnyAsync(s => s.IsDeleted == false
|
.AnyAsync(s => s.IsDeleted == false
|
||||||
&& s.IsActive
|
&& !s.IsCancel
|
||||||
&& s.TargetUuid == targetUuid
|
&& s.TargetUuid == targetUuid
|
||||||
&& s.ScheduleDate == null);
|
&& s.ScheduleDate == null);
|
||||||
return !hasLongTerm;
|
return !hasLongTerm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 短期占用,查詢每日排程中有無衝突
|
// 短期占用,查詢每日排程中有無衝突
|
||||||
var totalDays = (end.Value.Date - start.Date).Days + 1;
|
var totalDays = (end.Value.Date - start.Date).Days;
|
||||||
for (int i = 0; i < totalDays; i++)
|
for (int i = 0; i < totalDays; i++)
|
||||||
{
|
{
|
||||||
var date = start.Date.AddDays(i);
|
var date = start.Date.AddDays(i);
|
||||||
|
|
||||||
var conflict = await db.RegionAndRoomAndBedSchedule
|
var conflict = await db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != GuaDanOrderGuest.STATUS_CHECKED_OUT)
|
||||||
.AnyAsync(s => s.IsDeleted == false
|
.AnyAsync(s => s.IsDeleted == false
|
||||||
&& s.IsActive
|
&& !s.IsCancel
|
||||||
&& s.TargetUuid == targetUuid
|
&& s.TargetUuid == targetUuid
|
||||||
&& s.ScheduleDate == date);
|
&& s.ScheduleDate == date);
|
||||||
|
|
||||||
@@ -114,7 +117,10 @@ namespace Model
|
|||||||
|
|
||||||
// 找出所有在日期範圍內被占用的床位
|
// 找出所有在日期範圍內被占用的床位
|
||||||
var busyBedUuids = await db.RegionAndRoomAndBedSchedule
|
var busyBedUuids = await db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.IsDeleted == false && s.IsActive
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403")
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
|
.Where(a => a.IsCancel == false)
|
||||||
|
.Where(s => s.IsDeleted == false
|
||||||
&& (s.ScheduleDate == null // 長期占用
|
&& (s.ScheduleDate == null // 長期占用
|
||||||
|| (s.ScheduleDate >= start && s.ScheduleDate <= end)))
|
|| (s.ScheduleDate >= start && s.ScheduleDate <= end)))
|
||||||
.Select(s => s.TargetUuid)
|
.Select(s => s.TargetUuid)
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ namespace Model
|
|||||||
{
|
{
|
||||||
public partial class RegionRoomBed
|
public partial class RegionRoomBed
|
||||||
{
|
{
|
||||||
|
public const string STATUS_BED_FREE = "101"; // 空閒,可使用
|
||||||
|
public const string STATUS_BED_OCCUPIED = "102"; // 已佔用
|
||||||
|
public const string STATUS_BED_MAINTENANCE = "103"; // 維護中,不可使用
|
||||||
public bool IsAvailable()
|
public bool IsAvailable()
|
||||||
{
|
{
|
||||||
//判断床位是否可用:自身是否启用
|
//判断床位是否可用:自身是否启用
|
||||||
@@ -34,7 +37,9 @@ namespace Model
|
|||||||
// 如果資料庫 ScheduleDate 是 date 型別,本身沒有時間部分,可以直接比較
|
// 如果資料庫 ScheduleDate 是 date 型別,本身沒有時間部分,可以直接比較
|
||||||
var conflict = _db.RegionAndRoomAndBedSchedule.Any(s =>
|
var conflict = _db.RegionAndRoomAndBedSchedule.Any(s =>
|
||||||
s.TargetUuid == this.Uuid &&
|
s.TargetUuid == this.Uuid &&
|
||||||
s.IsActive &&
|
s.GuaDanOrderGuest.StatusCode != "403" &&
|
||||||
|
s.GuaDanOrderGuest.StatusCode != "404" &&
|
||||||
|
!s.IsCancel &&
|
||||||
!s.IsDeleted &&
|
!s.IsDeleted &&
|
||||||
(
|
(
|
||||||
s.ScheduleDate == null || // 長期占用
|
s.ScheduleDate == null || // 長期占用
|
||||||
@@ -46,5 +51,6 @@ namespace Model
|
|||||||
|
|
||||||
return !conflict;
|
return !conflict;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,5 +19,6 @@ public class GuaDanOrderView
|
|||||||
public string bookerName { get; set; }
|
public string bookerName { get; set; }
|
||||||
public string bookerPhone { get; set; }
|
public string bookerPhone { get; set; }
|
||||||
public int? bookerFollowerNum { get; set; }
|
public int? bookerFollowerNum { get; set; }
|
||||||
|
public int? activityNum { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
34
web/App_Code/StatusTransitionManager.cs
Normal file
34
web/App_Code/StatusTransitionManager.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
public static class StatusTransitionManager
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, List<string>> transitions =
|
||||||
|
new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
// 掛單狀態
|
||||||
|
{ "401", new List<string> { "402", "404" } },
|
||||||
|
{ "402", new List<string> { "403" } },
|
||||||
|
{ "403", new List<string>() },
|
||||||
|
{ "404", new List<string>() },
|
||||||
|
|
||||||
|
// 床位狀態
|
||||||
|
{ "101", new List<string> {"101", "102","103"} },
|
||||||
|
{ "102", new List<string> { "101" } },
|
||||||
|
{ "103", new List<string> { "101" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static bool CanTransition(string currentCode, string targetCode)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(currentCode))
|
||||||
|
{
|
||||||
|
return targetCode == "401" || targetCode == "402" || targetCode == "101";
|
||||||
|
}
|
||||||
|
if(string.IsNullOrEmpty(targetCode))
|
||||||
|
{ return false; }
|
||||||
|
return transitions.ContainsKey(currentCode) &&
|
||||||
|
transitions[currentCode].Contains(targetCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,14 +12,16 @@ using static regionController;
|
|||||||
/// guadanOderController 的摘要描述
|
/// guadanOderController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class guadanOrderController: ApiController
|
public class guadanOrderController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/guadan/list")]
|
[Route("api/guadan/list")]
|
||||||
public async Task<IHttpActionResult> getGuadanList()
|
public async Task<IHttpActionResult> getGuadanList()
|
||||||
{
|
{
|
||||||
var data = await _db.GuaDanOrder.OrderByDescending(b => b.CreatedAt)
|
var data = await _db.GuaDanOrder
|
||||||
|
.Where(a => a.IsCancel == false)
|
||||||
|
.OrderByDescending(b => b.CreatedAt)
|
||||||
.Select(a => new
|
.Select(a => new
|
||||||
{
|
{
|
||||||
uuid = a.Uuid,
|
uuid = a.Uuid,
|
||||||
@@ -30,7 +32,10 @@ public class guadanOrderController: ApiController
|
|||||||
updated_at = a.UpdatedAt,
|
updated_at = a.UpdatedAt,
|
||||||
notes = a.Notes,
|
notes = a.Notes,
|
||||||
bookerName = a.BookerName,
|
bookerName = a.BookerName,
|
||||||
guest_count = _db.GuaDanOrderGuest.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo).Count(),
|
guest_count = _db.GuaDanOrderGuest
|
||||||
|
.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false)
|
||||||
|
.Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
|
.Count(),
|
||||||
}).ToListAsync();
|
}).ToListAsync();
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
@@ -38,7 +43,10 @@ public class guadanOrderController: ApiController
|
|||||||
[Route("api/guadan/getorderbyid")]
|
[Route("api/guadan/getorderbyid")]
|
||||||
public async Task<IHttpActionResult> getGuadanOrderById(string orderId)
|
public async Task<IHttpActionResult> getGuadanOrderById(string orderId)
|
||||||
{
|
{
|
||||||
var order = await _db.GuaDanOrder.Where(a => a.GuaDanOrderNo == orderId).FirstOrDefaultAsync();
|
var order = await _db.GuaDanOrder
|
||||||
|
.Where(a => a.GuaDanOrderNo == orderId)
|
||||||
|
.Where(a => a.IsCancel == false && a.IsDeleted == false)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
if (order == null)
|
if (order == null)
|
||||||
{
|
{
|
||||||
return BadRequest("未找到对应订单");
|
return BadRequest("未找到对应订单");
|
||||||
@@ -46,7 +54,7 @@ public class guadanOrderController: ApiController
|
|||||||
var result = new
|
var result = new
|
||||||
{
|
{
|
||||||
order.admin,
|
order.admin,
|
||||||
order.follower,
|
order.followers,
|
||||||
StartDate = order.StartDate?.ToString("yyyy-MM-dd"),
|
StartDate = order.StartDate?.ToString("yyyy-MM-dd"),
|
||||||
EndDate = order.EndDate?.ToString("yyyy-MM-dd"),
|
EndDate = order.EndDate?.ToString("yyyy-MM-dd"),
|
||||||
order.CreateUser,
|
order.CreateUser,
|
||||||
@@ -59,6 +67,8 @@ public class guadanOrderController: ApiController
|
|||||||
order.BookerPhone,
|
order.BookerPhone,
|
||||||
order.IsDeleted,
|
order.IsDeleted,
|
||||||
order.Uuid,
|
order.Uuid,
|
||||||
|
order.ActivityNum,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@@ -71,7 +81,7 @@ public class guadanOrderController: ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("掛單資料不可為空");
|
return BadRequest("掛單資料不可為空");
|
||||||
}
|
}
|
||||||
if(model.Uuid.HasValue)
|
if (model.Uuid.HasValue)
|
||||||
{
|
{
|
||||||
return BadRequest("已存在对应挂单资料");
|
return BadRequest("已存在对应挂单资料");
|
||||||
}
|
}
|
||||||
@@ -99,6 +109,7 @@ public class guadanOrderController: ApiController
|
|||||||
BookerName = model.bookerName,
|
BookerName = model.bookerName,
|
||||||
BookerPhone = model.bookerPhone,
|
BookerPhone = model.bookerPhone,
|
||||||
Uuid = Guid.NewGuid(),
|
Uuid = Guid.NewGuid(),
|
||||||
|
ActivityNum = model.activityNum,
|
||||||
};
|
};
|
||||||
_db.GuaDanOrder.Add(guadanorder);
|
_db.GuaDanOrder.Add(guadanorder);
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
@@ -138,12 +149,13 @@ public class guadanOrderController: ApiController
|
|||||||
order.Notes = model.note;
|
order.Notes = model.note;
|
||||||
order.BookerName = model.bookerName;
|
order.BookerName = model.bookerName;
|
||||||
order.BookerPhone = model.bookerPhone;
|
order.BookerPhone = model.bookerPhone;
|
||||||
|
order.ActivityNum = model.activityNum;
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
return Ok(model);
|
return Ok(model);
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/guadan/delete")]
|
[Route("api/guadan/cancel")]
|
||||||
public async Task<IHttpActionResult> deleteGuadanOrder([FromUri] Guid uuid)
|
public async Task<IHttpActionResult> CancelGuadanOrder([FromUri] Guid uuid)
|
||||||
{
|
{
|
||||||
var guadan = await _db.GuaDanOrder.FindAsync(uuid);
|
var guadan = await _db.GuaDanOrder.FindAsync(uuid);
|
||||||
if (guadan == null)
|
if (guadan == null)
|
||||||
@@ -158,31 +170,27 @@ public class guadanOrderController: ApiController
|
|||||||
var guadanGuests = await _db.GuaDanOrderGuest
|
var guadanGuests = await _db.GuaDanOrderGuest
|
||||||
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var scheduleIds = _db.RegionAndRoomAndBedSchedule
|
|
||||||
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
|
||||||
.Where( b => b.IsActive == true)
|
|
||||||
.Select(c => c.GuaDanOrderNo)
|
|
||||||
.ToList();
|
|
||||||
if (guadanGuests.Any())
|
if (guadanGuests.Any())
|
||||||
{
|
{
|
||||||
_db.GuaDanOrderGuest.RemoveRange(guadanGuests);
|
foreach (var guest in guadanGuests)
|
||||||
|
{
|
||||||
|
guest.StatusCode = "404";
|
||||||
|
// 取消所有相關的排程
|
||||||
|
if (guest.RegionAndRoomAndBedSchedule != null && guest.RegionAndRoomAndBedSchedule.Any())
|
||||||
|
{
|
||||||
|
foreach (var schedule in guest.RegionAndRoomAndBedSchedule)
|
||||||
|
{
|
||||||
|
schedule.IsCancel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
guadan.IsCancel = true;
|
||||||
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();
|
await _db.SaveChangesAsync();
|
||||||
transaction.Commit();
|
transaction.Commit();
|
||||||
|
|
||||||
return Ok(new { message = "删除成功" });
|
return Ok(new { message = "取消成功" });
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -200,7 +208,6 @@ public class guadanOrderController: ApiController
|
|||||||
public int guest_id { get; set; }
|
public int guest_id { get; set; }
|
||||||
public DateTime start_date { get; set; }
|
public DateTime start_date { get; set; }
|
||||||
public DateTime? end_date { get; set; }
|
public DateTime? end_date { get; set; }
|
||||||
public Guid? statusUuid { get; set; }
|
|
||||||
public int? create_user { get; set; }
|
public int? create_user { get; set; }
|
||||||
public DateTime created_at { get; set; }
|
public DateTime created_at { get; set; }
|
||||||
public DateTime updated_at { get; set; }
|
public DateTime updated_at { get; set; }
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
using Model;
|
using DocumentFormat.OpenXml.Drawing;
|
||||||
|
using Model;
|
||||||
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
|
using System.Data.Entity.Infrastructure;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
@@ -11,7 +15,7 @@ using System.Web.Http;
|
|||||||
/// guadanOrderGuest 的摘要描述
|
/// guadanOrderGuest 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class guadanOrderGuestController: ApiController
|
public class guadanOrderGuestController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -25,12 +29,12 @@ public class guadanOrderGuestController: ApiController
|
|||||||
[Route("api/guadanorderguest/getbyorderno")]
|
[Route("api/guadanorderguest/getbyorderno")]
|
||||||
public async Task<IHttpActionResult> getByOrderNo(string orderNo)
|
public async Task<IHttpActionResult> getByOrderNo(string orderNo)
|
||||||
{
|
{
|
||||||
// 先查数据库,不做格式化
|
// 先查資料庫,不做格式化
|
||||||
var qry = await _db.GuaDanOrderGuest
|
var qry = await _db.GuaDanOrderGuest
|
||||||
.Where(a => a.GuaDanOrderNo == orderNo && a.IsDeleted == false)
|
.Where(a => a.GuaDanOrderNo == orderNo && a.IsDeleted == false && a.RegionRoomBedStatus.Code != "404")
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
// 拉到内存后再处理日期
|
// 拉到記憶體後再處理日期
|
||||||
var data = qry.Select(a => new guadan_order_guest_display_dto
|
var data = qry.Select(a => new guadan_order_guest_display_dto
|
||||||
{
|
{
|
||||||
Uuid = a.Uuid,
|
Uuid = a.Uuid,
|
||||||
@@ -44,8 +48,12 @@ public class guadanOrderGuestController: ApiController
|
|||||||
roomName = a.Room.Name,
|
roomName = a.Room.Name,
|
||||||
bedName = a.RegionRoomBed.Name,
|
bedName = a.RegionRoomBed.Name,
|
||||||
orderNo = a.GuaDanOrderNo,
|
orderNo = a.GuaDanOrderNo,
|
||||||
follower = a.follower,
|
follower = a.followers == null ? null : new FollowerDto
|
||||||
statusUuid = a.statusUuid,
|
{
|
||||||
|
num = a.followers.num,
|
||||||
|
u_name = a.followers.u_name
|
||||||
|
},
|
||||||
|
statuscode = a.StatusCode,
|
||||||
statusName = a.RegionRoomBedStatus?.Name,
|
statusName = a.RegionRoomBedStatus?.Name,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
@@ -58,11 +66,14 @@ public class guadanOrderGuestController: ApiController
|
|||||||
{
|
{
|
||||||
if (model == null)
|
if (model == null)
|
||||||
return BadRequest("");
|
return BadRequest("");
|
||||||
|
/*if(model.statuscode == null)
|
||||||
|
{
|
||||||
|
return BadRequest("狀態不能為空");
|
||||||
|
}*/
|
||||||
// 驗證床位與蓮友
|
// 驗證床位與蓮友
|
||||||
|
var bed = _db.RegionRoomBed.Find(model.bedUuid.Value);
|
||||||
if (model.followerNum.HasValue && model.bedUuid.HasValue)
|
if (model.followerNum.HasValue && model.bedUuid.HasValue)
|
||||||
{
|
{
|
||||||
var bed = _db.RegionRoomBed.Find(model.bedUuid.Value);
|
|
||||||
var follower = _db.followers.Find(model.followerNum.Value);
|
var follower = _db.followers.Find(model.followerNum.Value);
|
||||||
|
|
||||||
if (bed == null || follower == null)
|
if (bed == null || follower == null)
|
||||||
@@ -81,16 +92,16 @@ public class guadanOrderGuestController: ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!model.bedUuid.HasValue)
|
if (!model.bedUuid.HasValue)
|
||||||
return BadRequest("床位 UUID 不能为空");
|
return BadRequest("床位 UUID 不能為空");
|
||||||
if (!model.checkInAt.HasValue)
|
if (!model.checkInAt.HasValue)
|
||||||
return BadRequest("入住时间不能为空");
|
return BadRequest("入住時間不能為空");
|
||||||
|
|
||||||
// 長期占用處理:checkOutAt 可為 null
|
// 長期占用處理:checkOutAt 可為 null
|
||||||
DateTime? checkOut = model.checkOutAt.Value.Date;
|
DateTime? checkOut = model.checkOutAt.Value.Date;
|
||||||
|
|
||||||
if (checkOut.HasValue && model.checkInAt > checkOut)
|
if (checkOut.HasValue && model.checkInAt > checkOut)
|
||||||
return BadRequest("掛單結束時間不能再開始時間之前");
|
return BadRequest("掛單結束時間不能再開始時間之前");
|
||||||
if(model.checkInAt == model.checkOutAt)
|
if (model.checkInAt == model.checkOutAt)
|
||||||
{
|
{
|
||||||
return BadRequest("掛單結束時間和開始時間不能是同一天");
|
return BadRequest("掛單結束時間和開始時間不能是同一天");
|
||||||
}
|
}
|
||||||
@@ -103,8 +114,22 @@ public class guadanOrderGuestController: ApiController
|
|||||||
);
|
);
|
||||||
if (!bedIsCanUse)
|
if (!bedIsCanUse)
|
||||||
return BadRequest("床位在該時間段內已被占用");
|
return BadRequest("床位在該時間段內已被占用");
|
||||||
|
if (model.followerNum.HasValue)
|
||||||
|
{
|
||||||
|
if (_db.GuaDanOrderGuest.Any(a => a.FollowerNum == model.followerNum
|
||||||
|
&& a.GuaDanOrderNo == model.orderNo
|
||||||
|
&& a.StatusCode != "404"
|
||||||
|
))
|
||||||
|
return BadRequest("該蓮友已經在該掛單中");
|
||||||
|
}
|
||||||
|
//建立訂單的的時候,狀態只能是401或者402
|
||||||
|
var targetStatus = _db.RegionRoomBedStatus.Where(a => a.Code == GuaDanOrderGuest.STATUS_BOOKED).FirstOrDefault();
|
||||||
|
|
||||||
|
if (targetStatus == null)
|
||||||
|
{
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到目標狀態,請先建立對應狀態");
|
||||||
|
}
|
||||||
|
|
||||||
// 建立掛單
|
|
||||||
var guest = new GuaDanOrderGuest
|
var guest = new GuaDanOrderGuest
|
||||||
{
|
{
|
||||||
GuaDanOrderNo = model.orderNo,
|
GuaDanOrderNo = model.orderNo,
|
||||||
@@ -114,14 +139,9 @@ public class guadanOrderGuestController: ApiController
|
|||||||
CheckInAt = model.checkInAt?.Date,
|
CheckInAt = model.checkInAt?.Date,
|
||||||
CheckOutAt = checkOut,
|
CheckOutAt = checkOut,
|
||||||
Uuid = Guid.NewGuid(),
|
Uuid = Guid.NewGuid(),
|
||||||
statusUuid = model.statusUuid,
|
StatusCode = GuaDanOrderGuest.STATUS_BOOKED,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (model.followerNum.HasValue)
|
|
||||||
{
|
|
||||||
if (_db.GuaDanOrderGuest.Any(a => a.FollowerNum == model.followerNum && a.GuaDanOrderNo == model.orderNo))
|
|
||||||
return BadRequest("該蓮友已經在該掛單中");
|
|
||||||
}
|
|
||||||
|
|
||||||
_db.GuaDanOrderGuest.Add(guest);
|
_db.GuaDanOrderGuest.Add(guest);
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
@@ -140,12 +160,13 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單",
|
Description = "床位掛單",
|
||||||
ScheduleDate = scheduleDate,
|
ScheduleDate = scheduleDate,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
@@ -159,17 +180,17 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單(長期占用)",
|
Description = "床位掛單(長期占用)",
|
||||||
ScheduleDate = null,
|
ScheduleDate = null,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
await _db.SaveChangesAsync();
|
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
@@ -201,10 +222,10 @@ public class guadanOrderGuestController: ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!model.bedUuid.HasValue)
|
if (!model.bedUuid.HasValue)
|
||||||
return BadRequest("床位 UUID 不能为空");
|
return BadRequest("床位 UUID 不能為空");
|
||||||
|
|
||||||
if (!model.checkInAt.HasValue)
|
if (!model.checkInAt.HasValue)
|
||||||
return BadRequest("入住时间不能为空");
|
return BadRequest("入住時間不能為空");
|
||||||
|
|
||||||
// 長期占用處理
|
// 長期占用處理
|
||||||
DateTime? checkOut = model.checkOutAt?.Date;
|
DateTime? checkOut = model.checkOutAt?.Date;
|
||||||
@@ -234,18 +255,27 @@ public class guadanOrderGuestController: ApiController
|
|||||||
.AnyAsync();
|
.AnyAsync();
|
||||||
if (exists) return BadRequest("該蓮友已經在該掛單中");
|
if (exists) return BadRequest("該蓮友已經在該掛單中");
|
||||||
}
|
}
|
||||||
|
/*var targetStatus = _db.RegionRoomBedStatus.Find(model.statuscode);
|
||||||
|
if (targetStatus == null)
|
||||||
|
{
|
||||||
|
return BadRequest("目標狀態不存在");
|
||||||
|
}
|
||||||
|
if(!StatusTransitionManager.CanTransition(guest.StatusCode,targetStatus.Code))
|
||||||
|
{
|
||||||
|
return BadRequest("狀態的變化不合法");
|
||||||
|
}*/
|
||||||
// 更新掛單基本資料
|
// 更新掛單基本資料
|
||||||
guest.FollowerNum = model.followerNum;
|
guest.FollowerNum = model.followerNum;
|
||||||
guest.RoomUuid = model.roomUuid;
|
guest.RoomUuid = model.roomUuid;
|
||||||
guest.BedUuid = model.bedUuid;
|
guest.BedUuid = model.bedUuid;
|
||||||
guest.CheckInAt = model.checkInAt?.Date;
|
guest.CheckInAt = model.checkInAt?.Date;
|
||||||
guest.CheckOutAt = checkOut;
|
guest.CheckOutAt = checkOut;
|
||||||
guest.statusUuid = model.statusUuid;
|
//guest.StatusCode = model.statuscode;
|
||||||
|
//更新的時候不能更新狀態,狀態都用單獨的操作api控制
|
||||||
|
|
||||||
// 刪除原有每日排程
|
// 刪除原有每日排程
|
||||||
var oldSchedules = _db.RegionAndRoomAndBedSchedule
|
var oldSchedules = _db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo)
|
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo && s.TargetUuid == guest.BedUuid)
|
||||||
.ToList();
|
.ToList();
|
||||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(oldSchedules);
|
_db.RegionAndRoomAndBedSchedule.RemoveRange(oldSchedules);
|
||||||
|
|
||||||
@@ -262,12 +292,13 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單",
|
Description = "床位掛單",
|
||||||
ScheduleDate = date,
|
ScheduleDate = date,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
@@ -281,12 +312,13 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單(長期占用)",
|
Description = "床位掛單(長期占用)",
|
||||||
ScheduleDate = null,
|
ScheduleDate = null,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
@@ -298,25 +330,231 @@ public class guadanOrderGuestController: ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/guadanorderguest/delete")]
|
[Route("api/guadanorderguest/cancel")]
|
||||||
public async Task<IHttpActionResult> deleteGuadanGuest([FromUri] Guid uuid)
|
public async Task<IHttpActionResult> CancelGuadanGuest([FromUri] Guid uuid)
|
||||||
{
|
{
|
||||||
var guest = await _db.GuaDanOrderGuest.FindAsync(uuid);
|
var guest = await _db.GuaDanOrderGuest.FindAsync(uuid);
|
||||||
if (guest == null)
|
if (guest == null)
|
||||||
return BadRequest("未找到指定挂单资料");
|
return NotFound();
|
||||||
|
|
||||||
// 删除所有与该 guest 相关的排程(每日排程或長期占用)
|
if (guest.StatusCode == "404")
|
||||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
return BadRequest("該掛單已取消,無需再取消");
|
||||||
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (schedules.Any())
|
if (!StatusTransitionManager.CanTransition(guest.StatusCode, "404"))
|
||||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(schedules);
|
{
|
||||||
|
return BadRequest("當前狀態不能取消");
|
||||||
|
}
|
||||||
|
var cancelStatus = await _db.RegionRoomBedStatus
|
||||||
|
.FirstOrDefaultAsync(a => a.Code == "404");
|
||||||
|
if (cancelStatus == null)
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到取消狀態(Code=404),請先建立對應狀態");
|
||||||
|
//把狀態設置為取消
|
||||||
|
using (var tx = _db.Database.BeginTransaction())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 1) 更新 guest
|
||||||
|
guest.StatusCode = "404";
|
||||||
|
|
||||||
_db.GuaDanOrderGuest.Remove(guest);
|
// 2) 取消相關排程(常見做法:只取消未來&未取消的)
|
||||||
await _db.SaveChangesAsync();
|
var today = DateTime.Today;
|
||||||
|
|
||||||
return Ok(new { message = "删除成功" });
|
var schedules = await _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuestUuid == guest.Uuid
|
||||||
|
&& s.IsCancel == false
|
||||||
|
//&& s.ScheduleDate >= today
|
||||||
|
)
|
||||||
|
// ✅ 只取消今天與未來的,能取消就代表未入住,
|
||||||
|
// 未入住就要全部取消,如果是入住後提前退房,
|
||||||
|
// 就要取消未來的,取消未來的時候要注意今日是否包含的問題
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var s in schedules)
|
||||||
|
{
|
||||||
|
s.IsCancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) 釋放占用資源(若有床位/房間占用紀錄)
|
||||||
|
if (guest.BedUuid != null)
|
||||||
|
{
|
||||||
|
// 先抓到目標狀態
|
||||||
|
var freeStatus = await _db.RegionRoomBedStatus
|
||||||
|
.FirstOrDefaultAsync(a => a.Code == "101");
|
||||||
|
|
||||||
|
if (freeStatus == null)
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到床位狀態 Code=101");
|
||||||
|
if (guest.RegionRoomBed != null)
|
||||||
|
{
|
||||||
|
guest.RegionRoomBed.StatusCode = freeStatus.Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
tx.Commit();
|
||||||
|
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
message = "取消成功",
|
||||||
|
guestUuid = guest.Uuid,
|
||||||
|
canceledSchedules = schedules.Count
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException)
|
||||||
|
{
|
||||||
|
tx.Rollback();
|
||||||
|
return StatusCode(HttpStatusCode.PreconditionFailed); // 或自訂訊息
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
tx.Rollback();
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/guadanorderguest/checkout")]
|
||||||
|
public IHttpActionResult CheckoutGuadanOrderGuest(Guid uuid)
|
||||||
|
{
|
||||||
|
DbContextTransaction transaction = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transaction = _db.Database.BeginTransaction(); // 開啟事務
|
||||||
|
|
||||||
|
// 1️⃣ 取得該筆掛單
|
||||||
|
var guest = _db.GuaDanOrderGuest
|
||||||
|
.Where(a => a.Uuid == uuid)
|
||||||
|
.Where(a => !a.IsDeleted && a.StatusCode != "404")
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (guest == null)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
// 2️⃣ 標記為已退房
|
||||||
|
var targetStatus = _db.RegionRoomBedStatus
|
||||||
|
.Where(a => a.Code == "403")
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (targetStatus == null)
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到退房狀態(Code=403),請先建立對應狀態");
|
||||||
|
|
||||||
|
if (!StatusTransitionManager.CanTransition(guest.StatusCode, targetStatus.Code))
|
||||||
|
return BadRequest("掛單狀態轉換不對");
|
||||||
|
|
||||||
|
if (!StatusTransitionManager.CanTransition(guest.RegionRoomBed.StatusCode, "101"))
|
||||||
|
return BadRequest("床位掛單狀態轉換不對");
|
||||||
|
|
||||||
|
guest.StatusCode = targetStatus.Code;
|
||||||
|
guest.RegionRoomBed.StatusCode = "101";
|
||||||
|
|
||||||
|
//更新未來排程為取消
|
||||||
|
var latestCheckoutStr = _db.GuadanTimeSetting
|
||||||
|
.Select(a => a.LatestCheckOut) // 字符串 "HH:mm"
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
TimeSpan? latestCheckoutTime = null;
|
||||||
|
if (!string.IsNullOrEmpty(latestCheckoutStr))
|
||||||
|
{
|
||||||
|
// 尝试解析字符串
|
||||||
|
if (TimeSpan.TryParse(latestCheckoutStr, out var ts))
|
||||||
|
{
|
||||||
|
latestCheckoutTime = ts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var futureSchedules = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuestUuid == guest.Uuid);
|
||||||
|
if (latestCheckoutTime == null || DateTime.Now.TimeOfDay > latestCheckoutTime)
|
||||||
|
{
|
||||||
|
// 包含今天
|
||||||
|
futureSchedules = futureSchedules.Where(s => s.ScheduleDate > DateTime.Today);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 不包含今天
|
||||||
|
futureSchedules = futureSchedules.Where(s => s.ScheduleDate >= DateTime.Today);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var schedule in futureSchedules)
|
||||||
|
{
|
||||||
|
schedule.IsCancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4️⃣ 保存所有變更
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
// 5️⃣ 提交事務
|
||||||
|
transaction.Commit();
|
||||||
|
|
||||||
|
return Ok(new { message = "退房完成", guestUuid = guest.Uuid });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
transaction.Rollback(); // 回滾事務
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
transaction.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/guadanorderguest/checkin")]
|
||||||
|
public IHttpActionResult CheckinGuadanGuest([FromUri] Guid uuid)
|
||||||
|
{
|
||||||
|
if (uuid == Guid.Empty)
|
||||||
|
return BadRequest("uuid不能為空");
|
||||||
|
|
||||||
|
// 獲取掛單客人
|
||||||
|
var guest = _db.GuaDanOrderGuest
|
||||||
|
.Include(g => g.RegionRoomBedStatus) // 包含導航屬性
|
||||||
|
.FirstOrDefault(g => g.Uuid == uuid);
|
||||||
|
|
||||||
|
if (guest == null)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
string currentStatus = guest.StatusCode;
|
||||||
|
|
||||||
|
// 判斷狀態流轉是否合法
|
||||||
|
if (!StatusTransitionManager.CanTransition(currentStatus, GuaDanOrderGuest.STATUS_CHECKED_IN))
|
||||||
|
{
|
||||||
|
return BadRequest("當前狀態不允許入住");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 新增:檢查今天是否在排程表 ----------
|
||||||
|
var today = DateTime.Today;
|
||||||
|
bool hasScheduleToday = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Any(s => s.GuaDanOrderGuestUuid == guest.Uuid && s.ScheduleDate == today);
|
||||||
|
|
||||||
|
if (!hasScheduleToday)
|
||||||
|
{
|
||||||
|
return BadRequest("不在入住時間段內,無法入住");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 更新狀態
|
||||||
|
guest.StatusCode = GuaDanOrderGuest.STATUS_CHECKED_IN;
|
||||||
|
|
||||||
|
// 如果需要,更新床位狀態,比如變為占用
|
||||||
|
if (guest.BedUuid != null)
|
||||||
|
{
|
||||||
|
var bed = _db.RegionRoomBed.FirstOrDefault(b => b.Uuid == guest.BedUuid);
|
||||||
|
if (bed != null && StatusTransitionManager.CanTransition(bed.StatusCode, "102")) // 102 = 占用
|
||||||
|
{
|
||||||
|
bed.StatusCode = "102";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok(new { message = "入住成功", statusCode = guest.StatusCode });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class guadan_order_guest_dto
|
public class guadan_order_guest_dto
|
||||||
@@ -328,7 +566,7 @@ public class guadanOrderGuestController: ApiController
|
|||||||
public Guid? bedUuid { get; set; }
|
public Guid? bedUuid { get; set; }
|
||||||
public DateTime? checkInAt { get; set; }
|
public DateTime? checkInAt { get; set; }
|
||||||
public DateTime? checkOutAt { get; set; }
|
public DateTime? checkOutAt { get; set; }
|
||||||
public Guid? statusUuid { get; set; }
|
public string statuscode { get; set; }
|
||||||
}
|
}
|
||||||
public class guadan_order_guest_display_dto
|
public class guadan_order_guest_display_dto
|
||||||
{
|
{
|
||||||
@@ -337,17 +575,23 @@ public class guadanOrderGuestController: ApiController
|
|||||||
public string orderNo { get; set; }
|
public string orderNo { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public Guid? roomUuid { get; set; }
|
public Guid? roomUuid { get; set; }
|
||||||
public Guid? bedUuid { get;set; }
|
public Guid? bedUuid { get; set; }
|
||||||
public string checkinat { get;set; }
|
public string checkinat { get; set; }
|
||||||
public string checkoutat { get;set; }
|
public string checkoutat { get; set; }
|
||||||
public int? gender { get; set; }
|
public int? gender { get; set; }
|
||||||
public Guid? statusUuid { get; set; }
|
public string statuscode { get; set; }
|
||||||
public string statusName { get; set; }
|
public string statusName { get; set; }
|
||||||
public string phone { get; set; }
|
public string phone { get; set; }
|
||||||
public string note { get; set; }
|
public string note { get; set; }
|
||||||
public string roomName { get; set; }
|
public string roomName { get; set; }
|
||||||
public string bedName { get; set; }
|
public string bedName { get; set; }
|
||||||
public follower follower { get; set; }
|
public bool iscancel { get; set; }
|
||||||
|
public FollowerDto follower { get; set; }
|
||||||
|
}
|
||||||
|
public class FollowerDto
|
||||||
|
{
|
||||||
|
public int num { get; set; }
|
||||||
|
public string u_name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -33,13 +33,13 @@ public class guadanStatisticsController: ApiController
|
|||||||
|
|
||||||
var guadanTotalCount = await _db.GuaDanOrder.Where(a => a.IsDeleted == 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 guadanPeopleTotal = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false).CountAsync();
|
||||||
var guadanPeopleMale = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false && a.follower.sex == "男眾").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.follower.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);
|
dynamic bedCounts = await RegionAndRoomAndBedSchedule.GetAvailableBedCountsAsync(_db, DateTime.Now, DateTime.Now);
|
||||||
var guadanCurrentCount = await _db.GuaDanOrder.Where(a => now < a.EndDate).CountAsync();
|
var guadanCurrentCount = await _db.GuaDanOrder.Where(a => now < a.EndDate).CountAsync();
|
||||||
var guadanPeopleCurrent = await _db.GuaDanOrderGuest.Where( a => a.CheckOutAt > now).CountAsync();
|
var guadanPeopleCurrent = await _db.GuaDanOrderGuest.Where( a => a.CheckOutAt > now).CountAsync();
|
||||||
var guadanPeopleCurrentMale = await _db.GuaDanOrderGuest.Where(a => a.CheckOutAt > now && a.follower.sex == "男眾").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.follower.sex == "女眾").CountAsync();
|
var guadanPeopleCurrentFemale = await _db.GuaDanOrderGuest.Where(a => a.CheckOutAt > now && a.followers.sex == "女眾").CountAsync();
|
||||||
|
|
||||||
var result = new
|
var result = new
|
||||||
{
|
{
|
||||||
|
|||||||
96
web/App_Code/api/guadanStatisticsTableController.cs
Normal file
96
web/App_Code/api/guadanStatisticsTableController.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// guadanStatisticsTable 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[ezAuthorize]
|
||||||
|
public class guadanStatisticsTableController: ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
public guadanStatisticsTableController()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/guadan/guadanstatisticstable/list")]
|
||||||
|
public IHttpActionResult Get([FromUri] DateTime? start, [FromUri] DateTime? end)
|
||||||
|
{
|
||||||
|
// 如果兩個都為空,設定 start = 今天,end = 一個月後
|
||||||
|
if (!start.HasValue && !end.HasValue)
|
||||||
|
{
|
||||||
|
start = DateTime.Today;
|
||||||
|
end = DateTime.Today.AddMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有 start 沒有 end,就給 end 預設一個月後
|
||||||
|
if (start.HasValue && !end.HasValue)
|
||||||
|
{
|
||||||
|
end = start.Value.Date.AddMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有 end 沒有 start,就給 start 預設 end 的前一個月
|
||||||
|
if (!start.HasValue && end.HasValue)
|
||||||
|
{
|
||||||
|
start = end.Value.Date.AddMonths(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最後確保只取 date 部分
|
||||||
|
var startDate = start.Value.Date;
|
||||||
|
var endDate = end.Value.Date;
|
||||||
|
|
||||||
|
// 查詢資料庫時就用 date 型別對應
|
||||||
|
var statistics = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.IsCancel == false)
|
||||||
|
.Where(s => s.ScheduleDate >= startDate && s.ScheduleDate <= endDate)
|
||||||
|
.GroupBy(s => s.ScheduleDate)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
date = g.Key,
|
||||||
|
todaytotalbookers = g.Count(), // 该日期的总记录数
|
||||||
|
checkin = g.Key <= DateTime.Today
|
||||||
|
? g.Count(x => x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "402"
|
||||||
|
|| x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "403")
|
||||||
|
: 0,
|
||||||
|
})
|
||||||
|
.OrderBy(x => x.date)
|
||||||
|
.ToList();
|
||||||
|
var todayDate = DateTime.Today;
|
||||||
|
dynamic today = statistics.FirstOrDefault(x => x.date == todayDate);
|
||||||
|
|
||||||
|
if (today == null)
|
||||||
|
{
|
||||||
|
var todayCount = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.ScheduleDate == todayDate && !s.IsCancel)
|
||||||
|
.Count();
|
||||||
|
|
||||||
|
today = new { date = todayDate, todaytotalbookers = todayCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
var bedcount = _db.RegionRoomBed
|
||||||
|
.Where(a => a.IsDeleted == false)
|
||||||
|
.Count();
|
||||||
|
var roomcount = _db.Room.Count();
|
||||||
|
var result = new
|
||||||
|
{
|
||||||
|
bedcount,
|
||||||
|
roomcount,
|
||||||
|
statistics,
|
||||||
|
today,
|
||||||
|
totalbookers = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.IsCancel == false)
|
||||||
|
.Where(s => s.ScheduleDate >= DateTime.Today)
|
||||||
|
.Count(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ using System.Web.Http;
|
|||||||
/// lianyouController 的摘要描述
|
/// lianyouController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class lianyouController: ApiController
|
public class lianyouController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
|
||||||
@@ -19,13 +19,34 @@ public class lianyouController: ApiController
|
|||||||
[Route("api/lianyou/getfollowers")]
|
[Route("api/lianyou/getfollowers")]
|
||||||
public async Task<IHttpActionResult> GetGuadanFollowers(int page, int pageSize, string searchName = null)
|
public async Task<IHttpActionResult> GetGuadanFollowers(int page, int pageSize, string searchName = null)
|
||||||
{
|
{
|
||||||
var qry = _db.followers.AsEnumerable();
|
// IQueryable 可讓 EF 在資料庫層面執行過濾和投影
|
||||||
if(searchName != null)
|
var qry = _db.followers.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(searchName))
|
||||||
{
|
{
|
||||||
qry = qry.Where(a => (a.u_name ?? "").Contains(searchName) || (a.phone ?? "").Contains(searchName));
|
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);
|
var count = await qry.CountAsync();
|
||||||
return Ok(new {data = data, count = count});
|
|
||||||
|
// 投影到只需要的欄位
|
||||||
|
var projected = qry
|
||||||
|
.OrderBy(a => a.f_number)
|
||||||
|
.Select(a => new
|
||||||
|
{
|
||||||
|
num = a.num,
|
||||||
|
u_name = a.u_name,
|
||||||
|
phone = a.phone,
|
||||||
|
sex = a.sex,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 分頁
|
||||||
|
var data = projected
|
||||||
|
.Skip((page - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToList(); // 如果使用 EF Core 可用 ToListAsync()
|
||||||
|
|
||||||
|
return Ok(new { data = data, count = count });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ using System.Web.Routing;
|
|||||||
/// regionController 的摘要描述
|
/// regionController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class regionController: ApiController
|
public class regionController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
public regionController()
|
public regionController()
|
||||||
@@ -95,17 +95,18 @@ public class regionController: ApiController
|
|||||||
bed.Name,
|
bed.Name,
|
||||||
bed.Gender,
|
bed.Gender,
|
||||||
bed.RoomUuid,
|
bed.RoomUuid,
|
||||||
bed.StatusUuid,
|
bed.StatusCode,
|
||||||
bed.IsActive,
|
bed.IsActive,
|
||||||
bed.IsDeleted,
|
bed.IsDeleted,
|
||||||
canuse = bed.IsAvailableDuring(startDate, endDate, _db),
|
canuse = bed.IsAvailableDuring(startDate, endDate, _db),
|
||||||
statusname = bed.RegionRoomBedStatus.Name,
|
statusname = bed.RegionRoomBedStatus.Name,
|
||||||
schedules = _db.RegionAndRoomAndBedSchedule
|
schedules = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.IsCancel == false)
|
||||||
.Where(s => s.TargetUuid == bed.Uuid
|
.Where(s => s.TargetUuid == bed.Uuid
|
||||||
&& s.IsDeleted == false
|
&& s.IsDeleted == false
|
||||||
&& s.IsActive
|
|
||||||
&& (s.ScheduleDate == null
|
&& (s.ScheduleDate == null
|
||||||
|| (s.ScheduleDate >= startDate && s.ScheduleDate <= endDate)))
|
|| (s.ScheduleDate >= startDate && s.ScheduleDate <= endDate)))
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403" && s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
.Select(s => new
|
.Select(s => new
|
||||||
{
|
{
|
||||||
s.Uuid,
|
s.Uuid,
|
||||||
@@ -113,7 +114,15 @@ public class regionController: ApiController
|
|||||||
s.UseType,
|
s.UseType,
|
||||||
s.Title,
|
s.Title,
|
||||||
s.Description,
|
s.Description,
|
||||||
s.GuaDanOrderNo
|
s.GuaDanOrderNo,
|
||||||
|
s.TargetUuid,
|
||||||
|
usename = _db.GuaDanOrderGuest
|
||||||
|
.Where(guest => guest.GuaDanOrderNo == s.GuaDanOrderNo)
|
||||||
|
.Where(guest => guest.BedUuid == s.TargetUuid)
|
||||||
|
.Select(guest => guest.followers.u_name)
|
||||||
|
.FirstOrDefault()
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.ToList()
|
.ToList()
|
||||||
}),
|
}),
|
||||||
@@ -183,7 +192,8 @@ public class regionController: ApiController
|
|||||||
IsActive = region.IsActive,
|
IsActive = region.IsActive,
|
||||||
RoomCount = region.RoomCount,
|
RoomCount = region.RoomCount,
|
||||||
BedDto = new List<BedDto>(),
|
BedDto = new List<BedDto>(),
|
||||||
Rooms = region.Room.Select(a => new RoomDto {
|
Rooms = region.Room.Select(a => new RoomDto
|
||||||
|
{
|
||||||
Uuid = a.Uuid,
|
Uuid = a.Uuid,
|
||||||
Name = a.Name,
|
Name = a.Name,
|
||||||
RegionUuid = a.RegionUuid,
|
RegionUuid = a.RegionUuid,
|
||||||
@@ -194,13 +204,13 @@ public class regionController: ApiController
|
|||||||
{
|
{
|
||||||
Uuid = c.Uuid,
|
Uuid = c.Uuid,
|
||||||
name = c.Name,
|
name = c.Name,
|
||||||
roomUuid = c.RoomUuid,
|
roomUuid = c.RoomUuid,
|
||||||
isactive = c.IsActive,
|
isactive = c.IsActive,
|
||||||
statusuuid = c.StatusUuid,
|
statuscode = c.StatusCode,
|
||||||
Gender = c.Gender,
|
Gender = c.Gender,
|
||||||
|
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
|
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
Children = allRegions
|
Children = allRegions
|
||||||
.Where(r => r.ParentUuid == region.Uuid)
|
.Where(r => r.ParentUuid == region.Uuid)
|
||||||
@@ -251,7 +261,7 @@ public class regionController: ApiController
|
|||||||
name = c.Name,
|
name = c.Name,
|
||||||
roomUuid = c.RoomUuid,
|
roomUuid = c.RoomUuid,
|
||||||
isactive = c.IsActive,
|
isactive = c.IsActive,
|
||||||
statusuuid = c.StatusUuid
|
statuscode = c.StatusCode,
|
||||||
}).ToList()
|
}).ToList()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -281,7 +291,7 @@ public class regionController: ApiController
|
|||||||
BedDto = new List<BedDto>(),
|
BedDto = new List<BedDto>(),
|
||||||
Children = children,
|
Children = children,
|
||||||
Gender = region.Gender,
|
Gender = region.Gender,
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,11 +313,12 @@ public class regionController: ApiController
|
|||||||
public Nullable<System.DateTime> UpdatedAt { get; set; }
|
public Nullable<System.DateTime> UpdatedAt { get; set; }
|
||||||
public List<BedDto> beds { get; set; }
|
public List<BedDto> beds { get; set; }
|
||||||
}
|
}
|
||||||
public class BedDto {
|
public class BedDto
|
||||||
|
{
|
||||||
public Guid Uuid { get; set; }
|
public Guid Uuid { get; set; }
|
||||||
public Guid? roomUuid { get; set; }
|
public Guid? roomUuid { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public Guid? statusuuid { get; set; }
|
public string statuscode { get; set; }
|
||||||
public bool isactive { get; set; }
|
public bool isactive { get; set; }
|
||||||
public bool Gender { get; set; }
|
public bool Gender { get; set; }
|
||||||
}
|
}
|
||||||
@@ -324,13 +335,13 @@ public class regionController: ApiController
|
|||||||
public bool IsActive { get; set; } = true;
|
public bool IsActive { get; set; } = true;
|
||||||
public int? RoomCount { get; set; }
|
public int? RoomCount { get; set; }
|
||||||
public List<RoomDto> Rooms { get; set; }
|
public List<RoomDto> Rooms { get; set; }
|
||||||
public List<BedDto> BedDto { get; set; }
|
public List<BedDto> BedDto { get; set; }
|
||||||
public bool? Gender { get; set; }
|
public bool? Gender { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/create")]
|
[Route("api/region/create")]
|
||||||
public IHttpActionResult createRegion([FromBody] RegionDto dto)
|
public IHttpActionResult createRegion([FromBody] RegionDto dto)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(dto.Name))
|
if (string.IsNullOrWhiteSpace(dto.Name))
|
||||||
return BadRequest("區域名稱為必填");
|
return BadRequest("區域名稱為必填");
|
||||||
@@ -412,7 +423,7 @@ public class regionController: ApiController
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/getRegionType")]
|
[Route("api/region/getRegionType")]
|
||||||
public IHttpActionResult getRegionType()
|
public IHttpActionResult getRegionType()
|
||||||
{
|
{
|
||||||
var data = _db.RegionType.Where(a => a.IsActive == true).ToList();
|
var data = _db.RegionType.Where(a => a.IsActive == true).ToList();
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
@@ -431,7 +442,9 @@ public class regionController: ApiController
|
|||||||
r.Gender,
|
r.Gender,
|
||||||
rooms = r.Room.Select(room => new
|
rooms = r.Room.Select(room => new
|
||||||
{
|
{
|
||||||
room.Uuid, room.Name, room.RegionUuid
|
room.Uuid,
|
||||||
|
room.Name,
|
||||||
|
room.RegionUuid
|
||||||
}).ToList()
|
}).ToList()
|
||||||
}).ToList();
|
}).ToList();
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
|
|||||||
@@ -40,24 +40,23 @@ public class regionRoomBedController : ApiController
|
|||||||
.Where(a => a.RoomUuid == roomUuid)
|
.Where(a => a.RoomUuid == roomUuid)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// 取出所有相关排程
|
StartTime = StartTime.Date;
|
||||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
EndTime = EndTime?.Date;
|
||||||
.Where(b => b.IsDeleted == false && b.IsActive)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var data = beds.Select(a =>
|
var data = beds.Select(a =>
|
||||||
{
|
{
|
||||||
// 在内存中处理日期比较
|
var bedSchedules = _db.RegionAndRoomAndBedSchedule
|
||||||
var bedSchedules = schedules
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403")
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
.Where(b => b.TargetUuid == a.Uuid
|
.Where(b => b.TargetUuid == a.Uuid
|
||||||
&& (b.ScheduleDate == null // 长期占用
|
&& (b.ScheduleDate == null
|
||||||
|| (b.ScheduleDate >= StartTime.Date && b.ScheduleDate <= EndTime.Value.Date)))
|
|| (b.ScheduleDate >= StartTime && b.ScheduleDate < EndTime)))
|
||||||
|
.ToList()
|
||||||
.Select(c => new
|
.Select(c => new
|
||||||
{
|
{
|
||||||
c.Uuid,
|
c.Uuid,
|
||||||
c.Description,
|
c.Description,
|
||||||
c.IsDeleted,
|
c.IsDeleted,
|
||||||
c.IsActive,
|
|
||||||
c.GuaDanOrderNo,
|
c.GuaDanOrderNo,
|
||||||
c.UseType,
|
c.UseType,
|
||||||
c.Title,
|
c.Title,
|
||||||
@@ -74,13 +73,14 @@ public class regionRoomBedController : ApiController
|
|||||||
a.Name,
|
a.Name,
|
||||||
a.Gender,
|
a.Gender,
|
||||||
a.IsActive,
|
a.IsActive,
|
||||||
a.StatusUuid,
|
a.StatusCode,
|
||||||
a.RoomUuid,
|
a.RoomUuid,
|
||||||
canUsed,
|
canUsed,
|
||||||
schedule = bedSchedules
|
schedule = bedSchedules
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("當前客房不存在");
|
return BadRequest("當前客房不存在");
|
||||||
}
|
}
|
||||||
if(room.Gender != bed.Gender)
|
if (room.Gender != bed.Gender)
|
||||||
{
|
{
|
||||||
return BadRequest("床為性別和房間性別必須一致");
|
return BadRequest("床為性別和房間性別必須一致");
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
Name = bed.Name,
|
Name = bed.Name,
|
||||||
RoomUuid = bed.RoomUuid,
|
RoomUuid = bed.RoomUuid,
|
||||||
StatusUuid = bed.StatusUuid,
|
StatusCode = bed.StatusCode,
|
||||||
IsActive = bed.IsActive,
|
IsActive = bed.IsActive,
|
||||||
Gender = bed.Gender,
|
Gender = bed.Gender,
|
||||||
Uuid = Guid.NewGuid(),
|
Uuid = Guid.NewGuid(),
|
||||||
@@ -114,10 +114,11 @@ public class regionRoomBedController : ApiController
|
|||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
|
||||||
//創建床位
|
//創建床位
|
||||||
return Ok(new {
|
return Ok(new
|
||||||
|
{
|
||||||
uuid = regionBed.Uuid,
|
uuid = regionBed.Uuid,
|
||||||
roomUuid = regionBed.RoomUuid,
|
roomUuid = regionBed.RoomUuid,
|
||||||
statusuuid = regionBed.StatusUuid,
|
statuscode = regionBed.StatusCode,
|
||||||
isactive = regionBed.IsActive,
|
isactive = regionBed.IsActive,
|
||||||
gender = regionBed.Gender,
|
gender = regionBed.Gender,
|
||||||
name = regionBed.Name,
|
name = regionBed.Name,
|
||||||
@@ -146,7 +147,7 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("床為性別和房間性別必須一致");
|
return BadRequest("床為性別和房間性別必須一致");
|
||||||
}
|
}
|
||||||
oldBed.StatusUuid = bed.StatusUuid;
|
oldBed.StatusCode = bed.StatusCode;
|
||||||
oldBed.IsActive = bed.IsActive;
|
oldBed.IsActive = bed.IsActive;
|
||||||
oldBed.Name = bed.Name;
|
oldBed.Name = bed.Name;
|
||||||
oldBed.Gender = bed.Gender;
|
oldBed.Gender = bed.Gender;
|
||||||
@@ -174,8 +175,37 @@ public class regionRoomBedController : ApiController
|
|||||||
public async Task<IHttpActionResult> GetCanUseBedCountByTime(DateTime startTime, DateTime endTime)
|
public async Task<IHttpActionResult> GetCanUseBedCountByTime(DateTime startTime, DateTime endTime)
|
||||||
{
|
{
|
||||||
//获取某个时间段内可用床位数量
|
//获取某个时间段内可用床位数量
|
||||||
var counts = await RegionAndRoomAndBedSchedule.GetAvailableBedCountsAsync(_db, startTime, endTime);
|
var start = startTime.Date;
|
||||||
return Ok(counts);
|
var end = endTime.Date;
|
||||||
|
|
||||||
|
// 找出所有在日期範圍內被占用的床位
|
||||||
|
var busyBedUuids = await _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403")
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
|
.Where(a => a.IsCancel == false)
|
||||||
|
.Where(s => s.IsDeleted == false
|
||||||
|
&& (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 Ok(new {male, female});
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
@@ -260,7 +290,7 @@ public class regionRoomBedController : ApiController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index < followers.Count)
|
if (index < followers.Count)
|
||||||
{
|
{
|
||||||
isAllallocation = false;
|
isAllallocation = false;
|
||||||
return;
|
return;
|
||||||
@@ -313,7 +343,7 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
// 先拉出床位相關排程到內存,避免 EF 不支援 .Date
|
// 先拉出床位相關排程到內存,避免 EF 不支援 .Date
|
||||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
var schedules = _db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.IsDeleted == false && s.IsActive && s.TargetUuid == req.bedUuid)
|
.Where(s => s.IsDeleted == false && !s.IsCancel && s.TargetUuid == req.bedUuid)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
bool conflictExists = schedules.Any(s =>
|
bool conflictExists = schedules.Any(s =>
|
||||||
@@ -364,7 +394,6 @@ public class regionRoomBedController : ApiController
|
|||||||
ScheduleDate = date,
|
ScheduleDate = date,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
|
||||||
CreatedBy = "系统自动分配",
|
CreatedBy = "系统自动分配",
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
GuaDanOrderNo = guest.GuaDanOrderNo
|
||||||
@@ -382,7 +411,6 @@ public class regionRoomBedController : ApiController
|
|||||||
ScheduleDate = null,
|
ScheduleDate = null,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
|
||||||
CreatedBy = "系统自动分配",
|
CreatedBy = "系统自动分配",
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
GuaDanOrderNo = guest.GuaDanOrderNo
|
||||||
@@ -406,7 +434,7 @@ public class regionRoomBedController : ApiController
|
|||||||
|
|
||||||
private bool BedIsCanUsed(RegionRoomBed bed, DateTime? StartTime, DateTime? EndTime)
|
private bool BedIsCanUsed(RegionRoomBed bed, DateTime? StartTime, DateTime? EndTime)
|
||||||
{
|
{
|
||||||
if(!bed.IsActive)
|
if (!bed.IsActive)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using System.Web.Http;
|
|||||||
/// regionRoomBedStatusController 的摘要描述
|
/// regionRoomBedStatusController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class regionRoomBedStatusController: ApiController
|
public class regionRoomBedStatusController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
public regionRoomBedStatusController()
|
public regionRoomBedStatusController()
|
||||||
@@ -34,7 +34,6 @@ public class regionRoomBedStatusController: ApiController
|
|||||||
s.Code,
|
s.Code,
|
||||||
s.Name,
|
s.Name,
|
||||||
s.Description,
|
s.Description,
|
||||||
s.Uuid,
|
|
||||||
s.CategoryName
|
s.CategoryName
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -53,9 +52,9 @@ public class regionRoomBedStatusController: ApiController
|
|||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/bed/status/delete")]
|
[Route("api/region/bed/status/delete")]
|
||||||
public IHttpActionResult DeleteBedStatus([FromUri]Guid id)
|
public IHttpActionResult DeleteBedStatus([FromUri] string code)
|
||||||
{
|
{
|
||||||
var rt = _db.RegionRoomBedStatus.Find(id);
|
var rt = _db.RegionRoomBedStatus.Find(code);
|
||||||
if (rt == null)
|
if (rt == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ using static regionController;
|
|||||||
/// regionRoomController 的摘要描述
|
/// regionRoomController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class regionRoomController: ApiController
|
public class regionRoomController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
public regionRoomController()
|
public regionRoomController()
|
||||||
@@ -62,7 +62,7 @@ public class regionRoomController: ApiController
|
|||||||
name = c.Name,
|
name = c.Name,
|
||||||
roomUuid = c.RoomUuid,
|
roomUuid = c.RoomUuid,
|
||||||
isactive = c.IsActive,
|
isactive = c.IsActive,
|
||||||
statusuuid = c.StatusUuid,
|
statuscode = c.StatusCode,
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -86,7 +86,7 @@ public class regionRoomController: ApiController
|
|||||||
// 如果有不符合性別的床位,不能繼續操作
|
// 如果有不符合性別的床位,不能繼續操作
|
||||||
return BadRequest("房間中已有與房間性別不符的床位,無法操作");
|
return BadRequest("房間中已有與房間性別不符的床位,無法操作");
|
||||||
}
|
}
|
||||||
if(!room.BedCount.HasValue)
|
if (!room.BedCount.HasValue)
|
||||||
{
|
{
|
||||||
return BadRequest("請輸入床位數量");
|
return BadRequest("請輸入床位數量");
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ public class regionRoomController: ApiController
|
|||||||
oldRoom.IsActive = room.IsActive;
|
oldRoom.IsActive = room.IsActive;
|
||||||
oldRoom.RegionUuid = room.RegionUuid;
|
oldRoom.RegionUuid = room.RegionUuid;
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
return Ok(new { message = "更新成功"});
|
return Ok(new { message = "更新成功" });
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/room/delete")]
|
[Route("api/region/room/delete")]
|
||||||
|
|||||||
@@ -15,6 +15,15 @@
|
|||||||
<div class="col-sm-4 text-left">
|
<div class="col-sm-4 text-left">
|
||||||
<input class="form-control" v-model="guadanorder.order_form.orderNo" readonly />
|
<input class="form-control" v-model="guadanorder.order_form.orderNo" readonly />
|
||||||
</div>
|
</div>
|
||||||
|
<label class="col-sm-2 col-form-label text-center">關聯活動</label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-control" v-model="guadanorder.order_form.activityNum" >
|
||||||
|
<option :value="null">未關聯</option>
|
||||||
|
<option v-for="activity in activityList" :key="activity.num" :value="activity.num">
|
||||||
|
{{activity.subject}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mt-3">
|
<div class="form-group row mt-3">
|
||||||
<label class="col-sm-2 col-form-label text-center">
|
<label class="col-sm-2 col-form-label text-center">
|
||||||
@@ -86,14 +95,51 @@
|
|||||||
{{item.follower?.u_name}}
|
{{item.follower?.u_name}}
|
||||||
</template>
|
</template>
|
||||||
<template #item.actions="{ item }">
|
<template #item.actions="{ item }">
|
||||||
<v-btn color="red" variant="outlined" size="small" class="me-2" @click="confirmDeleteGuadanOrderGuest(item)">
|
<div>
|
||||||
取消
|
<!-- 取消預訂 -->
|
||||||
</v-btn>
|
<v-btn
|
||||||
<v-btn color="primary" variant="outlined" size="small" @click="editGuadanOrderGuest(item)">
|
color="red"
|
||||||
<v-icon start>mdi-pencil</v-icon>
|
variant="outlined"
|
||||||
編輯
|
size="small"
|
||||||
</v-btn>
|
class="me-2"
|
||||||
</template>
|
:disabled="item.statuscode !== '401'"
|
||||||
|
@click="confirmDeleteGuadanOrderGuest(item)"
|
||||||
|
>
|
||||||
|
取消預訂
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="red"
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
class="me-2"
|
||||||
|
:disabled="item.statuscode !== '401'"
|
||||||
|
@click="checkinGuadanGuest(item)"
|
||||||
|
>
|
||||||
|
入住
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="red"
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
class="me-2"
|
||||||
|
:disabled="item.statuscode !== '402'">
|
||||||
|
續住
|
||||||
|
</v-btn>
|
||||||
|
<!-- 退房 -->
|
||||||
|
<v-btn
|
||||||
|
color="primary"
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
:disabled="item.statuscode !== '402'"
|
||||||
|
@click="checkoutGuadanOrderGuest(item)"
|
||||||
|
>
|
||||||
|
<v-icon start>mdi-exit-run</v-icon>
|
||||||
|
退房
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
@@ -174,21 +220,6 @@
|
|||||||
<div class="text-info text-xs mt-1">請從床位清單中選擇</div>
|
<div class="text-info text-xs mt-1">請從床位清單中選擇</div>
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12" sm="6">
|
|
||||||
<div class="d-flex flex-column justify-center" style="height: 100%;">
|
|
||||||
<v-select
|
|
||||||
v-model="checkInGuest.inGuest.statusUuid"
|
|
||||||
:items="checkInGuest.status"
|
|
||||||
item-value="uuid"
|
|
||||||
item-text="name"
|
|
||||||
label="选择個人挂单状态"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
></v-select>
|
|
||||||
</div>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
|
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
@@ -768,6 +799,7 @@
|
|||||||
vuetify: new Vuetify(vuetify_options),
|
vuetify: new Vuetify(vuetify_options),
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
activityList: [],
|
||||||
availableBedCount: {
|
availableBedCount: {
|
||||||
male: 0,
|
male: 0,
|
||||||
female: 0,
|
female: 0,
|
||||||
@@ -782,6 +814,7 @@
|
|||||||
bookerName: null,
|
bookerName: null,
|
||||||
bookerPhone: null,
|
bookerPhone: null,
|
||||||
bookerFollowerNum: null,
|
bookerFollowerNum: null,
|
||||||
|
activityNum: null,
|
||||||
},
|
},
|
||||||
status_items: [],
|
status_items: [],
|
||||||
},
|
},
|
||||||
@@ -848,7 +881,7 @@
|
|||||||
bedUuid: null,
|
bedUuid: null,
|
||||||
checkInAt: null,
|
checkInAt: null,
|
||||||
checkOutAt: null,
|
checkOutAt: null,
|
||||||
statusUuid: null,
|
statuscode: null,
|
||||||
},
|
},
|
||||||
status: [],
|
status: [],
|
||||||
},
|
},
|
||||||
@@ -938,8 +971,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getActivityList() {
|
||||||
|
axios.post('/api/activity/GetList?page=1&pageSize=500', { kind: 0, subject: "" })
|
||||||
|
.then((res) => {
|
||||||
|
this.activityList = res.data.list
|
||||||
|
})
|
||||||
|
},
|
||||||
getavailablebedcountbytime(startTime, endTime) {
|
getavailablebedcountbytime(startTime, endTime) {
|
||||||
axios.get('/api/region/bed/getavailablebedcountbytime',{
|
axios.get('/api/region/bed/getavailablebedcountbytime', {
|
||||||
params: {
|
params: {
|
||||||
startTime: startTime,
|
startTime: startTime,
|
||||||
endTime: endTime
|
endTime: endTime
|
||||||
@@ -1117,6 +1156,7 @@
|
|||||||
this.guadanorder.order_form.bookerPhone = res.data.bookerPhone;
|
this.guadanorder.order_form.bookerPhone = res.data.bookerPhone;
|
||||||
this.guadanorder.order_form.bookerFollowerNum = res.data.bookerFollowerNum;
|
this.guadanorder.order_form.bookerFollowerNum = res.data.bookerFollowerNum;
|
||||||
this.guadanorder.order_form.uuid = res.data.uuid;
|
this.guadanorder.order_form.uuid = res.data.uuid;
|
||||||
|
this.guadanorder.order_form.activityNum = res.data.activityNum;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1203,6 +1243,40 @@
|
|||||||
//掛單相關方法-------------------end
|
//掛單相關方法-------------------end
|
||||||
|
|
||||||
//增加蓮友方法-------------------start
|
//增加蓮友方法-------------------start
|
||||||
|
checkoutGuadanOrderGuest(guest) {
|
||||||
|
this.$refs.confirmModal.open({
|
||||||
|
message: `確定要將 ${guest.follower.u_name || ''} 退房嗎?`,
|
||||||
|
onConfirm: async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`/api/guadanorderguest/checkout`, null, {
|
||||||
|
params: { uuid: guest.uuid }
|
||||||
|
});
|
||||||
|
|
||||||
|
// 成功提示
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
title: '操作成功',
|
||||||
|
message: '退房成功!',
|
||||||
|
status: 'success'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新狀態並刷新資料
|
||||||
|
guest.statusCode = "403"; // 已退房
|
||||||
|
this.getGuadanOrderGuestByOrderNo();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
// 失敗提示
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
title: '操作失敗',
|
||||||
|
message: error.response?.data?.message || '退房過程中發生錯誤!',
|
||||||
|
status: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
resetInGuest() {
|
resetInGuest() {
|
||||||
this.checkInGuest.inGuest = {
|
this.checkInGuest.inGuest = {
|
||||||
uuid: null,
|
uuid: null,
|
||||||
@@ -1212,7 +1286,7 @@
|
|||||||
bedUuid: null,
|
bedUuid: null,
|
||||||
checkInAt: null,
|
checkInAt: null,
|
||||||
checkOutAt: null,
|
checkOutAt: null,
|
||||||
statusUuid: null,
|
statuscode: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
setInGuest() {
|
setInGuest() {
|
||||||
@@ -1284,8 +1358,7 @@
|
|||||||
getGuadanGuestStatus() {
|
getGuadanGuestStatus() {
|
||||||
axios.get('/api/region/bed/status/list')
|
axios.get('/api/region/bed/status/list')
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.checkInGuest.status = res.data.filter(item => item.category === 4);
|
this.checkInGuest.status = res.data.filter(item => item.category === 4 && item.code != '404');
|
||||||
console.log(this.checkInGuest.status);
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
//增加蓮友方法-------------------end
|
//增加蓮友方法-------------------end
|
||||||
@@ -1318,7 +1391,7 @@
|
|||||||
},
|
},
|
||||||
selectGuadanOrderGuest(guest) {
|
selectGuadanOrderGuest(guest) {
|
||||||
this.selectGuestModal.currentSelectedGuest = guest;
|
this.selectGuestModal.currentSelectedGuest = guest;
|
||||||
console.log('----------'+ guest)
|
console.log('----------' + guest)
|
||||||
this.selectGuestModal.fullNameText = guest.u_name;
|
this.selectGuestModal.fullNameText = guest.u_name;
|
||||||
this.checkInGuest.inGuest.followerNum = guest.num;
|
this.checkInGuest.inGuest.followerNum = guest.num;
|
||||||
this.selectGuestModal.showSelectGuestModal = false;
|
this.selectGuestModal.showSelectGuestModal = false;
|
||||||
@@ -1336,7 +1409,7 @@
|
|||||||
this.getCurrentSelectBedTextByBedId(guest.bedUuid);
|
this.getCurrentSelectBedTextByBedId(guest.bedUuid);
|
||||||
this.selectGuestModal.fullNameText = guest.follower?.u_name;
|
this.selectGuestModal.fullNameText = guest.follower?.u_name;
|
||||||
this.selectGuestModal.currentSelectedGuest = guest.follower;
|
this.selectGuestModal.currentSelectedGuest = guest.follower;
|
||||||
this.checkInGuest.inGuest.statusUuid = guest.statusUuid;
|
this.checkInGuest.inGuest.statuscode = guest.statuscode;
|
||||||
|
|
||||||
},
|
},
|
||||||
async saveEditGuadanOrderGuest() {
|
async saveEditGuadanOrderGuest() {
|
||||||
@@ -1352,9 +1425,14 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
deleteGuadanOrderGuest(guest) {
|
deleteGuadanOrderGuest(guest) {
|
||||||
axios.post('/api/guadanorderguest/delete?uuid=' + guest.uuid).then((res) => {
|
axios.post('/api/guadanorderguest/cancel?uuid=' + guest.uuid)
|
||||||
this.guadanguest.items = this.guadanguest.items.filter(i => i.uuid != guest.uuid);
|
.then((res) => {
|
||||||
})
|
this.guadanguest.items = this.guadanguest.items.filter(i => i.uuid != guest.uuid);
|
||||||
|
}).catch((error) => {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: (error.response?.data?.message || error.message)
|
||||||
|
})
|
||||||
|
});
|
||||||
},
|
},
|
||||||
confirmDeleteGuadanOrderGuest(guest) {
|
confirmDeleteGuadanOrderGuest(guest) {
|
||||||
this.$refs.confirmModal.open({
|
this.$refs.confirmModal.open({
|
||||||
@@ -1364,6 +1442,43 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
async checkinGuadanGuest(guest) {
|
||||||
|
// 先確認操作
|
||||||
|
this.$refs.confirmModal.open({
|
||||||
|
message: '確認入住?',
|
||||||
|
onConfirm: async () => {
|
||||||
|
try {
|
||||||
|
// 發送請求到後端 API
|
||||||
|
const response = await axios.post(`/api/guadanorderguest/checkin`, null, {
|
||||||
|
params: { uuid: guest.uuid }
|
||||||
|
});
|
||||||
|
|
||||||
|
// 成功提示
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
title: '操作成功',
|
||||||
|
message: '入住成功!',
|
||||||
|
status: 'success'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新本地列表,修改狀態為已入住 (402)
|
||||||
|
guest.statusCode = "402";
|
||||||
|
|
||||||
|
// 如果需要刷新整個列表,也可以調用
|
||||||
|
this.getGuadanOrderGuestByOrderNo();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
// 失敗提示
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
title: '操作失敗',
|
||||||
|
message: error.response?.data?.message || '入住過程中發生錯誤!',
|
||||||
|
status: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
//蓮友選擇相關方法---------------end
|
//蓮友選擇相關方法---------------end
|
||||||
|
|
||||||
//床位選擇相關方法----------------start
|
//床位選擇相關方法----------------start
|
||||||
@@ -1532,6 +1647,7 @@
|
|||||||
this.loadRegions();
|
this.loadRegions();
|
||||||
this.getGuadanOrderStatus();
|
this.getGuadanOrderStatus();
|
||||||
this.getGuadanGuestStatus();
|
this.getGuadanGuestStatus();
|
||||||
|
this.getActivityList();
|
||||||
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
return {
|
return {
|
||||||
items: [],
|
items: [],
|
||||||
headers: [
|
headers: [
|
||||||
{ text: '登记挂单莲友', value: 'bookerName'},
|
{ text: '登记挂单莲友', value: 'bookerName' },
|
||||||
{ text: '起始日期', value: 'start_date', align: 'center' },
|
{ text: '起始日期', value: 'start_date', align: 'center' },
|
||||||
{ text: '結束日期', value: 'end_date', align: 'center' },
|
{ text: '結束日期', value: 'end_date', align: 'center' },
|
||||||
{ text: '掛單人數', value: 'guest_count' },
|
{ text: '掛單人數', value: 'guest_count' },
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
this.$refs.confirmModal.open({
|
this.$refs.confirmModal.open({
|
||||||
message: '確認取消掛單?',
|
message: '確認取消掛單?',
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
axios.post('/api/guadan/delete', null, {
|
axios.post('/api/guadan/cancel', null, {
|
||||||
params: {
|
params: {
|
||||||
uuid: order.uuid
|
uuid: order.uuid
|
||||||
}
|
}
|
||||||
|
|||||||
193
web/admin/guadan/statistics_table.aspx
Normal file
193
web/admin/guadan/statistics_table.aspx
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="statistics_table.aspx.cs" Inherits="admin_guadan_statistics_table" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<!-- 今日使用情況 -->
|
||||||
|
<div class="section mb-6">
|
||||||
|
<v-card outlined class="pa-1">
|
||||||
|
<v-card-title class="headline grey--text text--darken-2">
|
||||||
|
今日使用情况
|
||||||
|
</v-card-title>
|
||||||
|
<v-divider class="mb-4"></v-divider>
|
||||||
|
<v-card-text>
|
||||||
|
<div class="d-flex flex-wrap justify-space-around">
|
||||||
|
<v-card class="ma-2 pa-3 text-center" color="#e3f2fd" outlined>
|
||||||
|
<div class="subtitle-1 font-weight-bold">总预订人数</div>
|
||||||
|
<div class="headline">{{totalbookers }}</div>
|
||||||
|
</v-card>
|
||||||
|
<v-card class="ma-2 pa-3 text-center" color="#e3f2fd" outlined>
|
||||||
|
<div class="subtitle-1 font-weight-bold">今日预订人数</div>
|
||||||
|
<div class="headline">{{today.todaytotalbookers }}</div>
|
||||||
|
</v-card>
|
||||||
|
<v-card class="ma-2 pa-3 text-center" color="#e3f2fd" outlined>
|
||||||
|
<div class="subtitle-1 font-weight-bold">今日已入住人数</div>
|
||||||
|
<div class="headline">{{today.checkin }}</div>
|
||||||
|
</v-card>
|
||||||
|
<v-card class="ma-2 pa-3 text-center" color="#e3f2fd" outlined>
|
||||||
|
<div class="subtitle-1 font-weight-bold">今日待入住人数</div>
|
||||||
|
<div class="headline">{{today.todaytotalbookers - today.checkin }}</div>
|
||||||
|
</v-card>
|
||||||
|
<v-card class="ma-2 pa-3 text-center" color="#fce4ec" outlined>
|
||||||
|
<div class="subtitle-1 font-weight-bold">空床數</div>
|
||||||
|
<div class="headline">{{ bedcount - today.todaytotalbookers}}</div>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 近期床位使用統計 -->
|
||||||
|
<div class="section container">
|
||||||
|
|
||||||
|
<!-- 日期筛选区 -->
|
||||||
|
<div class="d-flex align-center flex-wrap" style="gap: 12px;">
|
||||||
|
<!-- 开始日期 -->
|
||||||
|
<v-menu
|
||||||
|
ref="menu1"
|
||||||
|
v-model="menu1"
|
||||||
|
:close-on-content-click="false"
|
||||||
|
transition="scale-transition"
|
||||||
|
offset-y
|
||||||
|
min-width="auto"
|
||||||
|
>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-text-field
|
||||||
|
v-model="startDate"
|
||||||
|
label="開始日期"
|
||||||
|
prepend-icon="mdi-calendar"
|
||||||
|
readonly
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
></v-text-field>
|
||||||
|
</template>
|
||||||
|
<v-date-picker v-model="startDate" @input="menu1 = false"></v-date-picker>
|
||||||
|
</v-menu>
|
||||||
|
|
||||||
|
<!-- 结束日期 -->
|
||||||
|
<v-menu
|
||||||
|
ref="menu2"
|
||||||
|
v-model="menu2"
|
||||||
|
:close-on-content-click="false"
|
||||||
|
transition="scale-transition"
|
||||||
|
offset-y
|
||||||
|
min-width="auto"
|
||||||
|
>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-text-field
|
||||||
|
v-model="endDate"
|
||||||
|
label="結束日期"
|
||||||
|
prepend-icon="mdi-calendar"
|
||||||
|
readonly
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
></v-text-field>
|
||||||
|
</template>
|
||||||
|
<v-date-picker v-model="endDate" @input="menu2 = false"></v-date-picker>
|
||||||
|
</v-menu>
|
||||||
|
|
||||||
|
<!-- 查询按钮 -->
|
||||||
|
<v-btn
|
||||||
|
color="primary"
|
||||||
|
@click="getList"
|
||||||
|
style="align-self: stretch;"
|
||||||
|
>
|
||||||
|
查詢
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<v-divider class="mb-4"></v-divider>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<!-- 表格 -->
|
||||||
|
<v-data-table
|
||||||
|
:items="items"
|
||||||
|
:headers="headers"
|
||||||
|
class="elevation-2"
|
||||||
|
dense
|
||||||
|
hide-default-footer
|
||||||
|
:items-per-page="10"
|
||||||
|
>
|
||||||
|
<template #item.date="{ item }">
|
||||||
|
<span>{{ item.date | timeString('YYYY-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
<template #item.bedusagerate="{ item }">
|
||||||
|
{{ ((item.todaytotalbookers / bedcount) * 100).toFixed(2) + '%' }}
|
||||||
|
</template>
|
||||||
|
<template #item.roomcount="{item}">
|
||||||
|
{{roomcount}}
|
||||||
|
</template>
|
||||||
|
<template #item.bedcount="{item}">
|
||||||
|
{{bedcount}}
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
</div>
|
||||||
|
</asp:Content>
|
||||||
|
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
Vue.filter('timeString', function (value, myFormat) {
|
||||||
|
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
||||||
|
});
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
items: [],
|
||||||
|
headers: [
|
||||||
|
{ text: '日期', value: 'date' },
|
||||||
|
{ text: '房间数量', value: 'roomcount' },
|
||||||
|
{ text: '床位数量', value: 'bedcount' },
|
||||||
|
{ text: '预约人数', value: 'todaytotalbookers' },
|
||||||
|
{ text: '已入住人数', value: 'checkin'},
|
||||||
|
{ text: '可用床位', value: 'availableBeds' },
|
||||||
|
{ text: '床位利用率', value: 'bedusagerate' }
|
||||||
|
],
|
||||||
|
today: {},
|
||||||
|
totalbookers: 0,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
menu1: false,
|
||||||
|
menu2: false,
|
||||||
|
bedcount: 0,
|
||||||
|
roomcount: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
const res = await axios.get('/api/guadan/guadanstatisticstable/list', {
|
||||||
|
params: {
|
||||||
|
start: this.startDate || '',
|
||||||
|
end: this.endDate || ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.items = res.data.statistics;
|
||||||
|
this.roomcount = res.data.roomcount;
|
||||||
|
this.bedcount = res.data.bedcount;
|
||||||
|
this.today = res.data.today;
|
||||||
|
this.totalbookers = res.data.totalbookers;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</asp:Content>
|
||||||
|
|
||||||
14
web/admin/guadan/statistics_table.aspx.cs
Normal file
14
web/admin/guadan/statistics_table.aspx.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_guadan_statistics_table : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<asp:Literal ID="L_msg" runat="server" />
|
<asp:Literal ID="L_msg" runat="server" />
|
||||||
<asp:HiddenField ID="HF_Id" runat="server" />
|
<asp:HiddenField ID="HF_Code" runat="server" />
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
<div class="form-group mb-3">
|
||||||
<label for="TB_Name">名稱</label>
|
<label for="TB_Name">名稱</label>
|
||||||
|
|||||||
@@ -1,35 +1,36 @@
|
|||||||
using Model;
|
using Model;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web;
|
|
||||||
using System.Web.UI;
|
using System.Web.UI;
|
||||||
using System.Web.UI.WebControls;
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
public partial class admin_region_bed_bedstatus_create : MyWeb.config
|
public partial class admin_region_bed_bedstatus_create : MyWeb.config
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
|
||||||
protected void Page_Load(object sender, EventArgs e)
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (!IsPostBack) // 加這行
|
if (!IsPostBack)
|
||||||
{
|
{
|
||||||
if (Guid.TryParse(Request.QueryString["statusid"], out Guid id))
|
var code = Request.QueryString["code"];
|
||||||
|
if (!string.IsNullOrEmpty(code))
|
||||||
{
|
{
|
||||||
LoadData(id);
|
LoadData(code);
|
||||||
L_title.Text = "編輯區域類型";
|
L_title.Text = "編輯區域類型";
|
||||||
}
|
}
|
||||||
|
|
||||||
var categoryList = RegionRoomBedStatus.GetCategoryList();
|
var categoryList = RegionRoomBedStatus.GetCategoryList();
|
||||||
// 假设你的下拉控件ID叫 ddlCategory
|
|
||||||
TB_Category.DataSource = categoryList;
|
TB_Category.DataSource = categoryList;
|
||||||
TB_Category.DataTextField = "Text"; // 显示文字
|
TB_Category.DataTextField = "Text"; // 顯示文字
|
||||||
TB_Category.DataValueField = "Value"; // 选项值
|
TB_Category.DataValueField = "Value"; // 選項值
|
||||||
TB_Category.DataBind();
|
TB_Category.DataBind();
|
||||||
TB_Category.Items.Insert(0, new ListItem("--请选择分类--", ""));
|
TB_Category.Items.Insert(0, new ListItem("--請選擇分類--", ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void LoadData(Guid id)
|
|
||||||
|
private void LoadData(string code)
|
||||||
{
|
{
|
||||||
var rt = _db.RegionRoomBedStatus.FirstOrDefault(r => r.Uuid == id);
|
var rt = _db.RegionRoomBedStatus.FirstOrDefault(r => r.Code == code);
|
||||||
if (rt == null)
|
if (rt == null)
|
||||||
{
|
{
|
||||||
L_msg.Text = "<div class='alert alert-danger'>找不到資料</div>";
|
L_msg.Text = "<div class='alert alert-danger'>找不到資料</div>";
|
||||||
@@ -37,22 +38,24 @@ public partial class admin_region_bed_bedstatus_create : MyWeb.config
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HF_Id.Value = rt.Uuid.ToString();
|
HF_Code.Value = rt.Code; // ✅ 以 Code 為唯一識別
|
||||||
TB_Name.Text = rt.Name;
|
TB_Name.Text = rt.Name;
|
||||||
TB_Code.Text = rt.Code;
|
TB_Code.Text = rt.Code;
|
||||||
TB_Category.SelectedValue = rt.Category?.ToString();
|
TB_Category.SelectedValue = rt.Category?.ToString();
|
||||||
Description.Text = rt.Description;
|
Description.Text = rt.Description;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void BTN_Save_Click(object sender, EventArgs e)
|
protected void BTN_Save_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RegionRoomBedStatus rt;
|
RegionRoomBedStatus rt;
|
||||||
if (Guid.TryParse(HF_Id.Value, out Guid id))
|
var code = HF_Code.Value; // ✅ 用隱藏欄位的 Code 判斷
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(code))
|
||||||
{
|
{
|
||||||
// 更新
|
// 更新
|
||||||
rt = _db.RegionRoomBedStatus.FirstOrDefault(r => r.Uuid == id);
|
rt = _db.RegionRoomBedStatus.FirstOrDefault(r => r.Code == code);
|
||||||
if (rt == null)
|
if (rt == null)
|
||||||
{
|
{
|
||||||
L_msg.Text = "<div class='alert alert-danger'>資料不存在</div>";
|
L_msg.Text = "<div class='alert alert-danger'>資料不存在</div>";
|
||||||
@@ -63,19 +66,20 @@ public partial class admin_region_bed_bedstatus_create : MyWeb.config
|
|||||||
{
|
{
|
||||||
// 新增
|
// 新增
|
||||||
rt = new RegionRoomBedStatus();
|
rt = new RegionRoomBedStatus();
|
||||||
rt.Uuid = Guid.NewGuid();
|
rt.Code = TB_Code.Text.Trim(); // ✅ 以 Code 當主鍵
|
||||||
_db.RegionRoomBedStatus.Add(rt);
|
_db.RegionRoomBedStatus.Add(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt.Name = TB_Name.Text.Trim();
|
rt.Name = TB_Name.Text.Trim();
|
||||||
if (rt.Name.Length == 0)
|
if (string.IsNullOrEmpty(rt.Name))
|
||||||
{
|
{
|
||||||
L_msg.Text = "<div class='alert alert-danger'>名稱不能为空</div>";
|
L_msg.Text = "<div class='alert alert-danger'>名稱不能為空</div>";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rt.Code = TB_Code.Text.Trim();
|
|
||||||
rt.Description = Description.Text.Trim();
|
rt.Description = Description.Text.Trim();
|
||||||
if(int.TryParse(TB_Category.SelectedValue, out int category))
|
|
||||||
|
if (int.TryParse(TB_Category.SelectedValue, out int category))
|
||||||
{
|
{
|
||||||
rt.Category = category;
|
rt.Category = category;
|
||||||
}
|
}
|
||||||
@@ -83,16 +87,18 @@ public partial class admin_region_bed_bedstatus_create : MyWeb.config
|
|||||||
{
|
{
|
||||||
rt.Category = null;
|
rt.Category = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
|
||||||
L_msg.Text = "<div class='alert alert-success'>儲存成功</div>";
|
L_msg.Text = "<div class='alert alert-success'>儲存成功</div>";
|
||||||
|
|
||||||
// 如果是新增,更新隱藏欄位並切換標題為編輯
|
// ✅ 如果是新增,更新隱藏欄位並切換標題
|
||||||
if (HF_Id.Value == "")
|
if (string.IsNullOrEmpty(HF_Code.Value))
|
||||||
{
|
{
|
||||||
HF_Id.Value = rt.Uuid.ToString();
|
HF_Code.Value = rt.Code;
|
||||||
L_title.Text = "編輯區域類型";
|
L_title.Text = "編輯區域類型";
|
||||||
}
|
}
|
||||||
|
|
||||||
Response.Redirect("index.aspx");
|
Response.Redirect("index.aspx");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -100,4 +106,4 @@ public partial class admin_region_bed_bedstatus_create : MyWeb.config
|
|||||||
L_msg.Text = $"<div class='alert alert-danger'>錯誤:{ex.Message}</div>";
|
L_msg.Text = $"<div class='alert alert-danger'>錯誤:{ex.Message}</div>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
<template #item.actions="{item}">
|
<template #item.actions="{item}">
|
||||||
<a :href="'create.aspx?statusid='+item.uuid" class="btn btn-primary"><i class="mdi mdi-pencil"></i>修改</a>
|
<a :href="'create.aspx?code='+item.code" class="btn btn-primary"><i class="mdi mdi-pencil"></i>修改</a>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-outline-danger"
|
class="btn btn-outline-danger"
|
||||||
@@ -46,11 +46,10 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
headers: [
|
headers: [
|
||||||
{ text: 'Id', value: 'id' },
|
|
||||||
{ text: '狀態名稱', value: 'name' },
|
{ text: '狀態名稱', value: 'name' },
|
||||||
{ text: '狀態代碼', value: 'code' },
|
{ text: '狀態代碼', value: 'code' },
|
||||||
{ text: '描述', value: 'description' },
|
{ text: '描述', value: 'description' },
|
||||||
{ text: '状态分类', value: 'categoryName'},
|
{ text: '状态分类', value: 'categoryName' },
|
||||||
{ text: '', value: 'actions' }
|
{ text: '', value: 'actions' }
|
||||||
],
|
],
|
||||||
items: [],
|
items: [],
|
||||||
@@ -75,10 +74,10 @@
|
|||||||
},
|
},
|
||||||
deleteStatus(item) {
|
deleteStatus(item) {
|
||||||
axios.post('/api/region/bed/status/delete', null, {
|
axios.post('/api/region/bed/status/delete', null, {
|
||||||
params: { id: item.uuid }
|
params: { code: item.code }
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.items = this.items.filter(i => i.uuid != item.uuid);
|
this.items = this.items.filter(i => i.code != item.code);
|
||||||
this.$refs.messageModal.open({
|
this.$refs.messageModal.open({
|
||||||
title: '操作成功',
|
title: '操作成功',
|
||||||
message: '刪除成功!',
|
message: '刪除成功!',
|
||||||
|
|||||||
@@ -112,7 +112,7 @@
|
|||||||
<h2 class="region-title mb-3">{{ region.regionPath }}</h2>
|
<h2 class="region-title mb-3">{{ region.regionPath }}</h2>
|
||||||
|
|
||||||
<div class="row g-3 justify-content-start">
|
<div class="row g-3 justify-content-start">
|
||||||
<div v-for="room in region.room" :key="room.ruid" class="col-12 col-md-6 col-lg-4">
|
<div v-for="room in region.room" :key="room.ruid" class="col-12 col-md-6 col-lg-6">
|
||||||
|
|
||||||
<div class="card h-100 shadow-sm" style="min-height: 300px; max-height: 400px; overflow-y: auto; border-radius: 0.5rem;">
|
<div class="card h-100 shadow-sm" style="min-height: 300px; max-height: 400px; overflow-y: auto; border-radius: 0.5rem;">
|
||||||
<!-- 上部:房間名稱 -->
|
<!-- 上部:房間名稱 -->
|
||||||
@@ -138,20 +138,26 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">床位名稱</th>
|
<th scope="col">床位名稱</th>
|
||||||
<th scope="col">是否可用</th>
|
|
||||||
<th scope="col">使用明細</th>
|
<th scope="col">使用明細</th>
|
||||||
|
<th scope="col">掛單</th>
|
||||||
|
<th scope="col">當前狀態</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="bed in room.beds" :key="bed.uuid"
|
<tr v-for="bed in room.beds" :key="bed.uuid"
|
||||||
:class="bed.canuse ? 'table-success' : 'table-danger'">
|
:class="bed.canuse ? 'table-success' : 'table-danger'">
|
||||||
<td>{{ bed.name }}</td>
|
<td>{{ bed.name }}</td>
|
||||||
<td :class="!bed.canuse ? 'text-danger' : 'text-success'">
|
|
||||||
{{ bed.canuse ? '是' : '否' }}
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="btn btn-primary" @click="showBedSchedule(bed)">查看明細</button>
|
<button type="button" class="btn btn-primary" @click="showBedSchedule(bed)">查看明細</button>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-primary">
|
||||||
|
快速掛單
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{bed.statusname}}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -251,6 +257,7 @@
|
|||||||
{ text: '使用日期', value: 'scheduledate' },
|
{ text: '使用日期', value: 'scheduledate' },
|
||||||
{ text: '掛單單號', value: 'guaDanOrderNo' },
|
{ text: '掛單單號', value: 'guaDanOrderNo' },
|
||||||
{ text: '標題', value: 'title' },
|
{ text: '標題', value: 'title' },
|
||||||
|
{ text: '掛單人', value: 'usename' },
|
||||||
{ text: '查看掛單', value: 'actions' },
|
{ text: '查看掛單', value: 'actions' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -381,9 +388,6 @@
|
|||||||
return { maleBeds, femaleBeds };
|
return { maleBeds, femaleBeds };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
|
|||||||
@@ -217,8 +217,8 @@
|
|||||||
<template #item.isactive="{item}">
|
<template #item.isactive="{item}">
|
||||||
{{item.isactive ? '啟用' : '停用'}}
|
{{item.isactive ? '啟用' : '停用'}}
|
||||||
</template>
|
</template>
|
||||||
<template #item.statusuuid="{item}">
|
<template #item.statuscode="{item}">
|
||||||
{{getBedStatusNameById(item.statusuuid)}}
|
{{getBedStatusNameById(item.statuscode)}}
|
||||||
</template>
|
</template>
|
||||||
<template #item.action ="{item}">
|
<template #item.action ="{item}">
|
||||||
<button type="button" class="btn btn-primary" @click="editBed(item)">
|
<button type="button" class="btn btn-primary" @click="editBed(item)">
|
||||||
@@ -252,8 +252,8 @@
|
|||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">狀態</label>
|
<label class="form-label">狀態</label>
|
||||||
<select class="form-control" v-model="room_bed.newBedForm.statusuuid">
|
<select class="form-control" v-model="room_bed.newBedForm.statuscode">
|
||||||
<option v-for="status in room_bed.bed_status" :value="status.uuid">
|
<option v-for="status in room_bed.bed_status" :value="status.code">
|
||||||
{{status.name}}
|
{{status.name}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -528,7 +528,7 @@
|
|||||||
bed_headers: [
|
bed_headers: [
|
||||||
{ text: '床位編號', value: 'uuid' },
|
{ text: '床位編號', value: 'uuid' },
|
||||||
{ text: '床位名稱', value: 'name' },
|
{ text: '床位名稱', value: 'name' },
|
||||||
{ text: '床位狀態', value: 'statusuuid' },
|
{ text: '床位狀態', value: 'statuscode' },
|
||||||
{ text: '是否啟用', value: 'isactive' },
|
{ text: '是否啟用', value: 'isactive' },
|
||||||
{ text: '', value: 'action' },
|
{ text: '', value: 'action' },
|
||||||
],
|
],
|
||||||
@@ -536,7 +536,7 @@
|
|||||||
uuid: null,
|
uuid: null,
|
||||||
RegionUuid: null,
|
RegionUuid: null,
|
||||||
Name: '',
|
Name: '',
|
||||||
statusuuid: null,
|
statuscode: null,
|
||||||
IsActive: true,
|
IsActive: true,
|
||||||
Gender: null,
|
Gender: null,
|
||||||
},
|
},
|
||||||
@@ -664,7 +664,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
confirmDeleteRegion() {
|
confirmDeleteRegion() {
|
||||||
axios.post('/api/region/delete', { uuid: this.form.uuid })
|
axios.post('/api/region/delete', { statuscode: this.form.statuscode })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.showDeleteModal = false;
|
this.showDeleteModal = false;
|
||||||
this.$refs.messageModal.open({
|
this.$refs.messageModal.open({
|
||||||
@@ -716,7 +716,7 @@
|
|||||||
uuid: null,
|
uuid: null,
|
||||||
RoomUuid: this.currentSelectRoom.uuid,
|
RoomUuid: this.currentSelectRoom.uuid,
|
||||||
Name: '',
|
Name: '',
|
||||||
statusuuid: null,
|
statuscode: null,
|
||||||
IsActive: true,
|
IsActive: true,
|
||||||
Gender: this.currentSelectRoom.gender, // 不設預設值,強制選擇
|
Gender: this.currentSelectRoom.gender, // 不設預設值,強制選擇
|
||||||
};
|
};
|
||||||
@@ -791,7 +791,7 @@
|
|||||||
RegionUuid: bed.regionUuid,
|
RegionUuid: bed.regionUuid,
|
||||||
RoomUuid: bed.roomUuid,
|
RoomUuid: bed.roomUuid,
|
||||||
Name: bed.name,
|
Name: bed.name,
|
||||||
statusuuid: bed.statusuuid,
|
statuscode: bed.statuscode,
|
||||||
IsActive: bed.isactive,
|
IsActive: bed.isactive,
|
||||||
Gender: bed.gender,
|
Gender: bed.gender,
|
||||||
};
|
};
|
||||||
@@ -811,7 +811,7 @@
|
|||||||
...this.room_bed.bed_items[index], // 保留原本未更新欄位
|
...this.room_bed.bed_items[index], // 保留原本未更新欄位
|
||||||
roomUuid: updated.RoomUuid,
|
roomUuid: updated.RoomUuid,
|
||||||
name: updated.Name,
|
name: updated.Name,
|
||||||
statusuuid: updated.statusuuid,
|
statuscode: updated.statuscode,
|
||||||
isactive: updated.IsActive
|
isactive: updated.IsActive
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -839,10 +839,8 @@
|
|||||||
this.room_bed.bed_status = res.data;
|
this.room_bed.bed_status = res.data;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getBedStatusNameById(id) {
|
getBedStatusNameById(statuscode) {
|
||||||
console.log(id)
|
const status = this.room_bed.bed_status.find(i => i.code == statuscode);
|
||||||
//傳入一個Id,獲取該Id對應的名稱
|
|
||||||
const status = this.room_bed.bed_status.find(i => i.uuid == id);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
return status.name;
|
return status.name;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user