处理挂单测试问题
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using Model;
|
using Model;
|
||||||
|
using PagedList;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
@@ -15,12 +16,36 @@ using static regionController;
|
|||||||
public class guadanOrderController : ApiController
|
public class guadanOrderController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
[HttpGet]
|
[HttpPost]
|
||||||
[Route("api/guadan/list")]
|
[Route("api/guadan/list")]
|
||||||
public async Task<IHttpActionResult> getGuadanList()
|
public async Task<IHttpActionResult> getGuadanList([FromBody] guadan_order_search_dto search)
|
||||||
{
|
{
|
||||||
var data = await _db.GuaDanOrder
|
|
||||||
|
var query = _db.GuaDanOrder
|
||||||
.Where(a => a.IsCancel == false)
|
.Where(a => a.IsCancel == false)
|
||||||
|
.Where(a => a.IsDeleted == false);
|
||||||
|
if(search.guadanUser != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.BookerName == search.guadanUser);
|
||||||
|
}
|
||||||
|
if (search.startDate != null && search.endDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.StartDate >= search.startDate)
|
||||||
|
.Where(order => order.EndDate <= search.endDate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (search.startDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.StartDate == search.startDate);
|
||||||
|
}
|
||||||
|
else if (search.endDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.EndDate == search.endDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var total = query.Count();
|
||||||
|
var data = await query
|
||||||
.OrderByDescending(b => b.CreatedAt)
|
.OrderByDescending(b => b.CreatedAt)
|
||||||
.Select(a => new
|
.Select(a => new
|
||||||
{
|
{
|
||||||
@@ -36,8 +61,15 @@ public class guadanOrderController : ApiController
|
|||||||
.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false)
|
.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false)
|
||||||
.Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED)
|
.Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
.Count(),
|
.Count(),
|
||||||
}).ToListAsync();
|
})
|
||||||
return Ok(data);
|
.Skip((search.page - 1) * search.pageSize)
|
||||||
|
.Take(search.pageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
total,
|
||||||
|
data
|
||||||
|
});
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/guadan/getorderbyid")]
|
[Route("api/guadan/getorderbyid")]
|
||||||
@@ -221,4 +253,13 @@ public class guadanOrderController : ApiController
|
|||||||
public RegionRoomBed bed { get; set; } = null;
|
public RegionRoomBed bed { get; set; } = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class guadan_order_search_dto
|
||||||
|
{
|
||||||
|
public DateTime? startDate { get; set; }
|
||||||
|
public DateTime? endDate { get; set; }
|
||||||
|
public string guadanUser { get; set; }
|
||||||
|
public int page { get; set; } = 1;
|
||||||
|
public int pageSize { get; set; } = 10;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -39,8 +39,9 @@ public class regionController : ApiController
|
|||||||
var startDate = filter.StartDate.Date;
|
var startDate = filter.StartDate.Date;
|
||||||
var endDate = filter.EndDate.Date;
|
var endDate = filter.EndDate.Date;
|
||||||
|
|
||||||
var query = _db.Region
|
var query = _db.Region//区域状态是否启用这里只设置了过滤了有客房的区域,是否要过滤所有
|
||||||
.Where(r => !r.IsDeleted)
|
.Where(r => !r.IsDeleted)
|
||||||
|
.Where(r => r.IsActive)
|
||||||
.Where(r => r.Room.Any());
|
.Where(r => r.Room.Any());
|
||||||
|
|
||||||
if (filter.Gender != null)
|
if (filter.Gender != null)
|
||||||
@@ -373,6 +374,10 @@ public class regionController : ApiController
|
|||||||
var region = _db.Region.FirstOrDefault(r => r.Uuid == dto.Uuid);
|
var region = _db.Region.FirstOrDefault(r => r.Uuid == dto.Uuid);
|
||||||
if (region == null)
|
if (region == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
if(dto.RoomCount < region.Room.Count())
|
||||||
|
{
|
||||||
|
return BadRequest("客房數量小於已存在的客房數量");
|
||||||
|
}
|
||||||
region.Name = dto.Name;
|
region.Name = dto.Name;
|
||||||
region.Description = dto.Description;
|
region.Description = dto.Description;
|
||||||
region.SortOrder = dto.SortOrder;
|
region.SortOrder = dto.SortOrder;
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ public class regionRoomBedController : ApiController
|
|||||||
RoomUuid = roomUuid,
|
RoomUuid = roomUuid,
|
||||||
CheckInAt = allocationStart,
|
CheckInAt = allocationStart,
|
||||||
CheckOutAt = allocationEnd,
|
CheckOutAt = allocationEnd,
|
||||||
|
StatusCode = "401",
|
||||||
};
|
};
|
||||||
_db.GuaDanOrderGuest.Add(guest);
|
_db.GuaDanOrderGuest.Add(guest);
|
||||||
|
|
||||||
@@ -396,7 +397,8 @@ public class regionRoomBedController : ApiController
|
|||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
CreatedBy = "系统自动分配",
|
CreatedBy = "系统自动分配",
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
|
Title = "掛單"
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
||||||
}
|
}
|
||||||
@@ -413,7 +415,8 @@ public class regionRoomBedController : ApiController
|
|||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
CreatedBy = "系统自动分配",
|
CreatedBy = "系统自动分配",
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
|
Title = "掛單"
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,15 @@ public class regionRoomController : ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("請輸入床位數量");
|
return BadRequest("請輸入床位數量");
|
||||||
}
|
}
|
||||||
|
var region = _db.Region.Find(room.RegionUuid);
|
||||||
|
if(region == null)
|
||||||
|
{
|
||||||
|
return BadRequest("未找到客房所屬的區域");
|
||||||
|
}
|
||||||
|
if(region.Room.Count() >= region.RoomCount)
|
||||||
|
{
|
||||||
|
return BadRequest("當前區域客房數量已經達到上限");
|
||||||
|
}
|
||||||
var newRoom = new Room();
|
var newRoom = new Room();
|
||||||
newRoom.Name = room.Name;
|
newRoom.Name = room.Name;
|
||||||
newRoom.RegionUuid = room.RegionUuid;
|
newRoom.RegionUuid = room.RegionUuid;
|
||||||
@@ -103,15 +112,43 @@ public class regionRoomController : ApiController
|
|||||||
[Route("api/region/room/delete")]
|
[Route("api/region/room/delete")]
|
||||||
public async Task<IHttpActionResult> deleteRoom([FromBody] Room rm)
|
public async Task<IHttpActionResult> deleteRoom([FromBody] Room rm)
|
||||||
{
|
{
|
||||||
var room = await _db.Room.FindAsync(rm.Uuid);
|
using (var transaction = _db.Database.BeginTransaction())
|
||||||
if (room == null) return BadRequest("房間不存在");
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var room = await _db.Room.FindAsync(rm.Uuid);
|
||||||
|
if (room == null) return BadRequest("房間不存在");
|
||||||
|
|
||||||
var beds = _db.RegionRoomBed.Where(b => b.RoomUuid == room.Uuid);
|
var beds = _db.RegionRoomBed.Where(b => b.RoomUuid == room.Uuid);
|
||||||
_db.RegionRoomBed.RemoveRange(beds);
|
_db.RegionRoomBed.RemoveRange(beds);
|
||||||
|
|
||||||
_db.Room.Remove(room);
|
_db.Room.Remove(room);
|
||||||
await _db.SaveChangesAsync();
|
|
||||||
return Ok(new { message = "刪除成功" });
|
await _db.SaveChangesAsync();
|
||||||
|
transaction.Commit();
|
||||||
|
|
||||||
|
return Ok(new { message = "刪除成功" });
|
||||||
|
}
|
||||||
|
catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
|
||||||
|
// 判断是否为外键约束错误
|
||||||
|
if (ex.InnerException?.InnerException is System.Data.SqlClient.SqlException sqlEx &&
|
||||||
|
sqlEx.Number == 547) // 547 = 外键冲突
|
||||||
|
{
|
||||||
|
return BadRequest("房間或床位正在被使用,不能刪除");
|
||||||
|
}
|
||||||
|
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1146,6 +1146,10 @@
|
|||||||
.then(res => {
|
.then(res => {
|
||||||
this.resetAutomaticBedAllocation();
|
this.resetAutomaticBedAllocation();
|
||||||
this.getGuadanOrderGuestByOrderNo();
|
this.getGuadanOrderGuestByOrderNo();
|
||||||
|
}).catch((error) => {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: (error.response?.data?.message || error.message)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,13 +20,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-item">
|
<div class="form-item">
|
||||||
<label>入住日期区间:</label>
|
<label>入住日期區間:</label>
|
||||||
<input type="date" v-model="search.searchCheckInDateStart"> -
|
<input type="date" v-model="search.searchCheckInDateStart"> -
|
||||||
<input type="date" v-model="search.searchCheckInDateEnd">
|
<input type="date" v-model="search.searchCheckInDateEnd">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-item">
|
<div class="form-item">
|
||||||
<label>退房日期区间:</label>
|
<label>退房日期區間:</label>
|
||||||
<input type="date" v-model="search.searchCheckOutDateStart"> -
|
<input type="date" v-model="search.searchCheckOutDateStart"> -
|
||||||
<input type="date" v-model="search.searchCheckOutDateEnd">
|
<input type="date" v-model="search.searchCheckOutDateEnd">
|
||||||
</div>
|
</div>
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
<style>
|
<style>
|
||||||
.search-bar {
|
.search-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -142,10 +142,10 @@ button:hover {
|
|||||||
loading: false,
|
loading: false,
|
||||||
search: {
|
search: {
|
||||||
searchName: null,
|
searchName: null,
|
||||||
searchCheckInDateStart: null,//入住日期开始
|
searchCheckInDateStart: null,//入住日期開始
|
||||||
searchCheckInDateEnd: null,//入住日期的结束
|
searchCheckInDateEnd: null,//入住日期的結束
|
||||||
searchCheckOutDateStart: null,//退房日期的开始
|
searchCheckOutDateStart: null,//退房日期的開始
|
||||||
searchCheckOutDateEnd: null,//退房日期的结束
|
searchCheckOutDateEnd: null,//退房日期的結束
|
||||||
searchCheckInDate: null,
|
searchCheckInDate: null,
|
||||||
searchCheckOutDate: null,
|
searchCheckOutDate: null,
|
||||||
|
|
||||||
|
|||||||
@@ -6,16 +6,29 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<a href="create.aspx" class="btn btn-primary" >新建掛單</a>
|
<a href="create.aspx" class="btn btn-primary" >新建掛單</a>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="me-10">
|
<div class="d-flex align-items-center gap-3">
|
||||||
<button class="btn btn-primary" type="button">查询</button>
|
<label class="mb-0">掛單登記人</label>
|
||||||
|
<input class="form-control w-auto" style="width:150px;" v-model="search.guadanUser" />
|
||||||
|
|
||||||
|
<label class="mb-0">開始時間</label>
|
||||||
|
<input class="form-control w-auto" style="width:150px;" type="date" v-model="search.startDate" />
|
||||||
|
|
||||||
|
<label class="mb-0">結束時間</label>
|
||||||
|
<input class="form-control w-auto" style="width:150px;" type="date" v-model="search.endDate" />
|
||||||
|
|
||||||
|
<button class="btn btn-primary" type="button" @click="handleSearch">查詢</button>
|
||||||
|
<button class="btn btn-outline-primary" type="button" @click="clearSearch">清除條件</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
|
||||||
<div class="mx-5">
|
<div class="mx-5">
|
||||||
<v-data-table
|
<v-data-table
|
||||||
:items="items"
|
:items="items"
|
||||||
:headers="headers">
|
:headers="headers"
|
||||||
|
hide-default-footer>
|
||||||
<template #item.actions="{item}">
|
<template #item.actions="{item}">
|
||||||
<a :href="'create.aspx?orderId='+item.guaDanOrderNo" class="btn btn-secondary">編輯</a>
|
<a :href="'create.aspx?orderId='+item.guaDanOrderNo" class="btn btn-secondary">編輯</a>
|
||||||
<a class="btn btn-outline-danger" @click="deleteGuadanOrder(item)">取消</a>
|
<a class="btn btn-outline-danger" @click="deleteGuadanOrder(item)">取消</a>
|
||||||
@@ -39,6 +52,41 @@
|
|||||||
{{item.created_at | timeString('YYYY/MM/DD HH:mm')}}
|
{{item.created_at | timeString('YYYY/MM/DD HH:mm')}}
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
|
<v-container>
|
||||||
|
<v-row class="align-baseline" wrap="false">
|
||||||
|
<v-col cols="12" md="8">
|
||||||
|
<v-pagination
|
||||||
|
v-model="options.page"
|
||||||
|
:length="pageCount">
|
||||||
|
</v-pagination>
|
||||||
|
</v-col>
|
||||||
|
<v-col class="text-truncate text-right" cols="12" md="2">
|
||||||
|
共 {{ total }} 筆, 頁數:
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6" md="1">
|
||||||
|
<v-text-field
|
||||||
|
v-model="options.page"
|
||||||
|
type="number"
|
||||||
|
hide-details
|
||||||
|
dense
|
||||||
|
min="1"
|
||||||
|
:max="pageCount"
|
||||||
|
@input="options.page = parseInt($event, 10)"
|
||||||
|
></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
<!-- 每页条数选择 -->
|
||||||
|
<v-col cols="12" md="1">
|
||||||
|
<v-select
|
||||||
|
v-model="options.itemsPerPage"
|
||||||
|
:items="[5, 10, 20, 50]"
|
||||||
|
label="每頁條數"
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
style="width: 100px;"
|
||||||
|
></v-select>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
<!-- 更新修改確認彈出視窗 -->
|
<!-- 更新修改確認彈出視窗 -->
|
||||||
<message-modal ref="messageModal"></message-modal>
|
<message-modal ref="messageModal"></message-modal>
|
||||||
@@ -69,17 +117,74 @@
|
|||||||
{ text: '備註', value: 'notes', align: 'center' },
|
{ text: '備註', value: 'notes', align: 'center' },
|
||||||
{ text: '操作', value: 'actions', align: 'center' }
|
{ text: '操作', value: 'actions', align: 'center' }
|
||||||
],
|
],
|
||||||
|
options: {
|
||||||
|
page: 1, // 當前頁
|
||||||
|
itemsPerPage: 10, // 每頁條數
|
||||||
|
sortBy: [],
|
||||||
|
sortDesc: []
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
guadanUser: null,
|
||||||
|
},
|
||||||
|
total: 0,
|
||||||
|
loading: false,
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
resetTableOptions() {
|
||||||
|
this.options = {
|
||||||
|
page: 1,
|
||||||
|
itemsPerPage: 10,
|
||||||
|
sortBy: [],
|
||||||
|
sortDesc: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleSearch() {
|
||||||
|
const val = this.search.guadanUser;
|
||||||
|
|
||||||
|
// 驗證是否包含空格
|
||||||
|
if (val && /\s/.test(val)) {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: '掛單登記人不能包含空格'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驗證長度
|
||||||
|
if (val && val.length > 10) {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: '掛單登記人不能超過 10 個字'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.resetTableOptions();
|
||||||
|
},
|
||||||
|
clearSearch() {
|
||||||
|
this.search.startDate = null;
|
||||||
|
this.search.endDate = null;
|
||||||
|
this.search.guadanUser = null;
|
||||||
|
this.resetTableOptions();
|
||||||
|
},
|
||||||
getGuadanOrder() {
|
getGuadanOrder() {
|
||||||
axios.get('/api/guadan/list')
|
if (this.loading) return;
|
||||||
|
axios.post('/api/guadan/list', {
|
||||||
|
startDate: this.search.startDate,
|
||||||
|
endDate: this.search.endDate,
|
||||||
|
guadanUser: this.search.guadanUser,
|
||||||
|
page: this.options.page,
|
||||||
|
pageSize: this.options.itemsPerPage
|
||||||
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.items = res.data;
|
this.items = res.data.data;
|
||||||
|
this.total = res.data.total;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
})
|
}).finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
deleteGuadanOrder(order) {
|
deleteGuadanOrder(order) {
|
||||||
this.$refs.confirmModal.open({
|
this.$refs.confirmModal.open({
|
||||||
@@ -105,11 +210,21 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
options: {
|
||||||
|
handler() {
|
||||||
|
this.getGuadanOrder(); // 監聽分頁、排序變化,自動載入數據
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getGuadanOrder();
|
this.getGuadanOrder();
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
pageCount() {
|
||||||
|
return Math.ceil(this.total / this.options.itemsPerPage)
|
||||||
|
},
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
|
|||||||
@@ -907,6 +907,10 @@
|
|||||||
this.currentSelectRoom = null;
|
this.currentSelectRoom = null;
|
||||||
this.room_bed.bed_items = [];
|
this.room_bed.bed_items = [];
|
||||||
//清空 beds
|
//清空 beds
|
||||||
|
}).catch((error) => {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: (error.response?.data?.message || error.message)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
confirmRoomDelete() {
|
confirmRoomDelete() {
|
||||||
|
|||||||
Reference in New Issue
Block a user