Merge remote-tracking branch 'origin/hkj1003'
This commit is contained in:
@@ -66,6 +66,7 @@ public class guadanGuestQueryController: ApiController
|
|||||||
checkoutdate = a.CheckOutAt,
|
checkoutdate = a.CheckOutAt,
|
||||||
guadanorderno = a.GuaDanOrderNo,
|
guadanorderno = a.GuaDanOrderNo,
|
||||||
roomName = GetRoomAndBedString(a.RegionRoomBed),
|
roomName = GetRoomAndBedString(a.RegionRoomBed),
|
||||||
|
statusName = a.RegionRoomBedStatus.Name
|
||||||
}).ToList();
|
}).ToList();
|
||||||
return Ok(new
|
return Ok(new
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,10 +20,19 @@ public class guadanOrderController : ApiController
|
|||||||
[Route("api/guadan/list")]
|
[Route("api/guadan/list")]
|
||||||
public async Task<IHttpActionResult> getGuadanList([FromBody] guadan_order_search_dto search)
|
public async Task<IHttpActionResult> getGuadanList([FromBody] guadan_order_search_dto search)
|
||||||
{
|
{
|
||||||
|
var lastCheckoutTime = _db.GuadanTimeSetting.FirstOrDefault();
|
||||||
|
string lastCheckoutTimeStr = null;
|
||||||
|
if (lastCheckoutTime != null)
|
||||||
|
{
|
||||||
|
lastCheckoutTimeStr = lastCheckoutTime.LatestCheckOut;
|
||||||
|
}
|
||||||
var query = _db.GuaDanOrder
|
var query = _db.GuaDanOrder
|
||||||
.Where(a => a.IsCancel == false)
|
.Where(a => a.IsCancel == false)
|
||||||
.Where(a => a.IsDeleted == false);
|
.Where(a => a.IsDeleted == false);
|
||||||
|
if(!string.IsNullOrEmpty(search.guaDanOrderNo))
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.GuaDanOrderNo == search.guaDanOrderNo);
|
||||||
|
}
|
||||||
if (search.guadanUser != null)
|
if (search.guadanUser != null)
|
||||||
{
|
{
|
||||||
query = query.Where(order => order.BookerName == search.guadanUser);
|
query = query.Where(order => order.BookerName == search.guadanUser);
|
||||||
@@ -45,7 +54,8 @@ public class guadanOrderController : ApiController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var total = query.Count();
|
var total = query.Count();
|
||||||
var data = await query
|
var data1 = await query.ToListAsync();
|
||||||
|
var data = data1
|
||||||
.OrderByDescending(b => b.CreatedAt)
|
.OrderByDescending(b => b.CreatedAt)
|
||||||
.Select(a => new
|
.Select(a => new
|
||||||
{
|
{
|
||||||
@@ -56,6 +66,14 @@ public class guadanOrderController : ApiController
|
|||||||
created_at = a.CreatedAt,
|
created_at = a.CreatedAt,
|
||||||
updated_at = a.UpdatedAt,
|
updated_at = a.UpdatedAt,
|
||||||
notes = a.Notes,
|
notes = a.Notes,
|
||||||
|
is_timeout = !string.IsNullOrEmpty(lastCheckoutTimeStr) &&
|
||||||
|
_db.GuaDanOrderGuest
|
||||||
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && !g.IsDeleted && g.StatusCode == GuaDanOrderGuest.STATUS_CHECKED_IN)
|
||||||
|
.ToList()
|
||||||
|
.Any(g =>
|
||||||
|
g.CheckOutAt.HasValue &&
|
||||||
|
DateTime.Parse(g.CheckOutAt.Value.ToString("yyyy-MM-dd") + " " + lastCheckoutTimeStr) < DateTime.Now
|
||||||
|
),
|
||||||
activity = _db.activities
|
activity = _db.activities
|
||||||
.Where(act => act.num == a.ActivityNum)
|
.Where(act => act.num == a.ActivityNum)
|
||||||
.Select(act => new
|
.Select(act => new
|
||||||
@@ -68,23 +86,23 @@ 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(),
|
||||||
statusName = _db.GuaDanOrderGuest
|
guadan_status = _db.GuaDanOrderGuest
|
||||||
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
||||||
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
.All(g => g.StatusCode == "401") ? "預約" :
|
.All(g => g.StatusCode == "401") ? new { code=501, name="預約" }:
|
||||||
_db.GuaDanOrderGuest
|
_db.GuaDanOrderGuest
|
||||||
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
||||||
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
.All(g => g.StatusCode == "403") ? "全部退房" :
|
.All(g => g.StatusCode == "403") ? new { code = 502, name = "全部退房" } :
|
||||||
_db.GuaDanOrderGuest
|
_db.GuaDanOrderGuest
|
||||||
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
||||||
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
.Any(g => g.StatusCode == "402" && a.IsCancel == false) ? "正在入住" :
|
.Any(g => g.StatusCode == "402" && a.IsCancel == false) ? new { code = 503, name = "正在入住" } :
|
||||||
"部分退房"
|
new { code = 504, name = "部分退房" }
|
||||||
})
|
})
|
||||||
.Skip((search.page - 1) * search.pageSize)
|
.Skip((search.page - 1) * search.pageSize)
|
||||||
.Take(search.pageSize)
|
.Take(search.pageSize)
|
||||||
.ToListAsync();
|
.ToList();
|
||||||
return Ok(new
|
return Ok(new
|
||||||
{
|
{
|
||||||
total,
|
total,
|
||||||
@@ -214,7 +232,7 @@ public class guadanOrderController : ApiController
|
|||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
if (_db.GuaDanOrderGuest.Any(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo))
|
if (_db.GuaDanOrderGuest.Any(a => (a.GuaDanOrderNo == guadan.GuaDanOrderNo) && a.StatusCode != "404"))
|
||||||
{
|
{
|
||||||
return BadRequest($"該掛單已經存在掛單蓮友,不能取消!");
|
return BadRequest($"該掛單已經存在掛單蓮友,不能取消!");
|
||||||
}
|
}
|
||||||
@@ -280,6 +298,7 @@ public class guadanOrderController : ApiController
|
|||||||
public string guadanUser { get; set; }
|
public string guadanUser { get; set; }
|
||||||
public int page { get; set; } = 1;
|
public int page { get; set; } = 1;
|
||||||
public int pageSize { get; set; } = 10;
|
public int pageSize { get; set; } = 10;
|
||||||
|
public string guaDanOrderNo { get; set; } = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
</v-pagination>
|
</v-pagination>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col class="text-truncate text-right" cols="12" md="2">
|
<v-col class="text-truncate text-right" cols="12" md="2">
|
||||||
共 {{ }} 筆, 頁數:
|
共 {{ total }} 筆, 頁數:
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="6" md="1">
|
<v-col cols="6" md="1">
|
||||||
<v-text-field
|
<v-text-field
|
||||||
@@ -162,6 +162,7 @@ button:hover {
|
|||||||
{ text: '入住日期', value: 'checkindate' },
|
{ text: '入住日期', value: 'checkindate' },
|
||||||
{ text: '退房日期', value: 'checkoutdate' },
|
{ text: '退房日期', value: 'checkoutdate' },
|
||||||
{ text: '房間號', value: 'roomName' },
|
{ text: '房間號', value: 'roomName' },
|
||||||
|
{ text: '狀態', value: 'statusName'},
|
||||||
|
|
||||||
],
|
],
|
||||||
guests: [], // 表格數據
|
guests: [], // 表格數據
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
<a href="create.aspx" class="btn btn-primary" >新建掛單</a>
|
<a href="create.aspx" class="btn btn-primary" >新建掛單</a>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex align-items-center gap-3">
|
<div class="d-flex align-items-center gap-3">
|
||||||
|
<label class="mb-0">掛單單號</label>
|
||||||
|
<input class="form-control w-auto" style="width:150px;" v-model="search.guaDanOrderNo" />
|
||||||
<label class="mb-0">掛單登記人</label>
|
<label class="mb-0">掛單登記人</label>
|
||||||
<input class="form-control w-auto" style="width:150px;" v-model="search.guadanUser" />
|
<input class="form-control w-auto" style="width:150px;" v-model="search.guadanUser" />
|
||||||
|
|
||||||
@@ -28,10 +30,21 @@
|
|||||||
<v-data-table
|
<v-data-table
|
||||||
:items="items"
|
:items="items"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
|
:item-class="item => item.is_timeout ? 'row-timeout' : ''"
|
||||||
hide-default-footer>
|
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="'view.aspx?orderId='+item.guaDanOrderNo" class="btn btn-primary">查看</a>
|
||||||
<a class="btn btn-outline-danger" @click="deleteGuadanOrder(item)">取消</a>
|
<a :href="'create.aspx?orderId='+item.guaDanOrderNo" class="btn btn-secondary"
|
||||||
|
:style="item.guadan_status?.code == 502 ? 'pointer-events: none; opacity: 0.5; cursor: not-allowed;' : ''">編輯</a>
|
||||||
|
<a
|
||||||
|
class="btn btn-outline-danger"
|
||||||
|
href="#"
|
||||||
|
:style="item.guest_count != 0 ? 'pointer-events: none; opacity: 0.5; cursor: not-allowed;' : ''"
|
||||||
|
@click.prevent="item.guest_count != 0 ? null : deleteGuadanOrder(item)"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</a>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<template #item.room="{item}">
|
<template #item.room="{item}">
|
||||||
{{item.room.name}}
|
{{item.room.name}}
|
||||||
@@ -39,8 +52,8 @@
|
|||||||
<template #item.bed="{item}">
|
<template #item.bed="{item}">
|
||||||
{{item.bed.name}}
|
{{item.bed.name}}
|
||||||
</template>
|
</template>
|
||||||
<template #item.status="{item}">
|
<template #item.guadan_status="{item}">
|
||||||
{{item.status}}
|
{{item.guadan_status?.name}}
|
||||||
</template>
|
</template>
|
||||||
<template #item.start_date="{item}">
|
<template #item.start_date="{item}">
|
||||||
{{item.start_date | timeString('YYYY/MM/DD')}}
|
{{item.start_date | timeString('YYYY/MM/DD')}}
|
||||||
@@ -54,6 +67,9 @@
|
|||||||
<template #item.activity="{item}">
|
<template #item.activity="{item}">
|
||||||
{{item.activity?.subject}}
|
{{item.activity?.subject}}
|
||||||
</template>
|
</template>
|
||||||
|
<template #item.is_timeout="{item}">
|
||||||
|
{{item.is_timeout ? '已超時': '否'}}
|
||||||
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
<v-container>
|
<v-container>
|
||||||
<v-row class="align-baseline" wrap="false">
|
<v-row class="align-baseline" wrap="false">
|
||||||
@@ -77,7 +93,7 @@
|
|||||||
@input="options.page = parseInt($event, 10)"
|
@input="options.page = parseInt($event, 10)"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
</v-col>
|
</v-col>
|
||||||
<!-- 每页条数选择 -->
|
<!-- 每頁條數選擇 -->
|
||||||
<v-col cols="12" md="1">
|
<v-col cols="12" md="1">
|
||||||
<v-select
|
<v-select
|
||||||
v-model="options.itemsPerPage"
|
v-model="options.itemsPerPage"
|
||||||
@@ -97,7 +113,6 @@
|
|||||||
<confirm-modal ref="confirmModal"></confirm-modal>
|
<confirm-modal ref="confirmModal"></confirm-modal>
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
<div>test</div>
|
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
<script>
|
<script>
|
||||||
@@ -111,13 +126,15 @@
|
|||||||
return {
|
return {
|
||||||
items: [],
|
items: [],
|
||||||
headers: [
|
headers: [
|
||||||
{ text: '登记挂单莲友', value: 'bookerName' },
|
{ text: '登記掛單蓮友', value: 'bookerName' },
|
||||||
|
{ text: '掛單單號', value: 'guaDanOrderNo'},
|
||||||
{ 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' },
|
||||||
{ text: '狀態', value: 'statusName', align: 'center' },
|
{ text: '狀態', value: 'guadan_status', align: 'center' },
|
||||||
{ text: '建立時間', value: 'created_at', align: 'center' },
|
{ text: '建立時間', value: 'created_at', align: 'center' },
|
||||||
{ text: '關聯活動', value: 'activity', align: 'center' },
|
{ text: '關聯活動', value: 'activity', align: 'center' },
|
||||||
|
{ text: '超時退房', value: 'is_timeout', align: 'center' },
|
||||||
{ text: '操作', value: 'actions', align: 'center' }
|
{ text: '操作', value: 'actions', align: 'center' }
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
@@ -130,6 +147,7 @@
|
|||||||
startDate: null,
|
startDate: null,
|
||||||
endDate: null,
|
endDate: null,
|
||||||
guadanUser: null,
|
guadanUser: null,
|
||||||
|
guaDanOrderNo: null,
|
||||||
},
|
},
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: false,
|
loading: false,
|
||||||
@@ -146,6 +164,12 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
|
|
||||||
|
let orderNo = this.search.guaDanOrderNo;
|
||||||
|
if (orderNo) {
|
||||||
|
orderNo = orderNo.replace(/\s+/g, '');
|
||||||
|
this.search.guaDanOrderNo = orderNo;
|
||||||
|
}
|
||||||
const val = this.search.guadanUser;
|
const val = this.search.guadanUser;
|
||||||
|
|
||||||
// 驗證是否包含空格
|
// 驗證是否包含空格
|
||||||
@@ -169,6 +193,7 @@
|
|||||||
this.search.startDate = null;
|
this.search.startDate = null;
|
||||||
this.search.endDate = null;
|
this.search.endDate = null;
|
||||||
this.search.guadanUser = null;
|
this.search.guadanUser = null;
|
||||||
|
this.search.guaDanOrderNo = null;
|
||||||
this.resetTableOptions();
|
this.resetTableOptions();
|
||||||
},
|
},
|
||||||
getGuadanOrder() {
|
getGuadanOrder() {
|
||||||
@@ -177,6 +202,7 @@
|
|||||||
startDate: this.search.startDate,
|
startDate: this.search.startDate,
|
||||||
endDate: this.search.endDate,
|
endDate: this.search.endDate,
|
||||||
guadanUser: this.search.guadanUser,
|
guadanUser: this.search.guadanUser,
|
||||||
|
guaDanOrderNo: this.search.guaDanOrderNo,
|
||||||
page: this.options.page,
|
page: this.options.page,
|
||||||
pageSize: this.options.itemsPerPage
|
pageSize: this.options.itemsPerPage
|
||||||
})
|
})
|
||||||
@@ -230,5 +256,10 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</asp:Content>
|
<style>
|
||||||
|
.row-timeout {
|
||||||
|
background-color: #ffdddd !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</asp:Content>
|
||||||
539
web/admin/guadan/view.aspx
Normal file
539
web/admin/guadan/view.aspx
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="view.aspx.cs" Inherits="admin_guadan_view" %>
|
||||||
|
|
||||||
|
<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">
|
||||||
|
<fieldset class="border rounded p-4 mb-5 shadow-sm bg-white">
|
||||||
|
<legend class="w-auto px-3 font-weight-bold text-primary">掛單資訊</legend>
|
||||||
|
<!-- 🟢 區塊一:掛單資訊 -->
|
||||||
|
<div class="border rounded p-3 bg-white shadow-sm" style="pointer-events: none; user-select: none; background: #1c5bd9; padding: 5px;">
|
||||||
|
<h6 class="text-secondary mb-3">📝掛單資訊</h6>
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<label class="col-sm-2 col-form-label text-center">掛單單號(不可修改)</label>
|
||||||
|
<div class="col-sm-4 text-left">
|
||||||
|
<input class="form-control" v-model="guadanorder.order_form.orderNo" readonly />
|
||||||
|
</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 class="form-group row mt-3">
|
||||||
|
<label class="col-sm-2 col-form-label text-center">
|
||||||
|
預約開始日期
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-4 text-left">
|
||||||
|
<input class="form-control" type="date" v-model="guadanorder.order_form.startdate" />
|
||||||
|
</div>
|
||||||
|
<label class="col-sm-2 col-form-label text-center">
|
||||||
|
預約結束日期
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input class="form-control" type="date" v-model="guadanorder.order_form.enddate" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<label class="col-sm-2 col-form-label text-center">預定人姓名</label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input class="form-control" v-model="guadanorder.order_form.bookerName" />
|
||||||
|
</div>
|
||||||
|
<label class="col-sm-2 col-form-label text-center">預定人電話</label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input class="form-control" v-model="guadanorder.order_form.bookerPhone" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<label class="col-sm-2 col-form-label text-center">備註</label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<textarea class="form-control" v-model="guadanorder.order_form.note"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="border rounded p-4 mb-5 shadow-sm bg-white">
|
||||||
|
<!-- 表格標題緊貼表格上方,居中 -->
|
||||||
|
<div class="d-flex align-items-center mb-3">
|
||||||
|
<!-- 中間標題(flex-grow撐開居中) -->
|
||||||
|
<div class="flex-grow-1 text-center">
|
||||||
|
<h5 class="text-primary fw-bold mb-0">
|
||||||
|
<i class="bi bi-people-fill me-2"></i>掛單蓮友
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- v-data-table 表格 -->
|
||||||
|
<v-data-table :headers="guadanguest.headers" :items="guadanguest.items" class="elevation-1 rounded" dense>
|
||||||
|
<template #item.checkinat="{item}">
|
||||||
|
{{item.checkinat |timeString('YYYY-MM-DD')}}
|
||||||
|
</template>
|
||||||
|
<template #item.checkoutat="{item}">
|
||||||
|
{{item.checkoutat |timeString('YYYY-MM-DD')}}
|
||||||
|
</template>
|
||||||
|
<template v-slot:item.name="{item}">
|
||||||
|
{{item.follower?.u_name}}
|
||||||
|
</template>
|
||||||
|
<template v-slot:item.sex="{item}">
|
||||||
|
{{item.follower?.sex}}
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
</fieldset>
|
||||||
|
</asp:Content>
|
||||||
|
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<style>
|
||||||
|
/* 調整 fieldset 風格 */
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #0d6efd;
|
||||||
|
width: auto;
|
||||||
|
padding: 0 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按鈕置右 */
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 選擇床位相關 */
|
||||||
|
.tree,
|
||||||
|
.tree ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
width: 1rem;
|
||||||
|
display: inline-block;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-item-label {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-item-label.selected {
|
||||||
|
background-color: #eaf4ff;
|
||||||
|
color: #0d6efd;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-room {
|
||||||
|
background-color: #cce5ff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 選擇床位相關 */
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
Vue.component('region-item', {
|
||||||
|
props: ['item', 'selectedId', 'selectedType', 'expandAll', 'collapseAll'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expanded: false, // 預設全部收起
|
||||||
|
selectedRoomId: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
expandAll(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.expanded = true;
|
||||||
|
// 執行完後發事件通知父組件清除標誌
|
||||||
|
this.$nextTick(() => this.$emit('clear-expand-all'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapseAll(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.expanded = false;
|
||||||
|
this.$nextTick(() => this.$emit('clear-collapse-all'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasChildren() {
|
||||||
|
return this.item.children && this.item.children.length > 0;
|
||||||
|
},
|
||||||
|
icon() {
|
||||||
|
// 無論有無子節點,皆可點擊展開/收起
|
||||||
|
return this.expanded ? '▼' : '▶';
|
||||||
|
},
|
||||||
|
isSelected() {
|
||||||
|
return this.selectedType === 'region' && this.item.uuid === this.selectedId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
this.expanded = !this.expanded;
|
||||||
|
},
|
||||||
|
select() {
|
||||||
|
this.$emit('select-region', this.item);
|
||||||
|
},
|
||||||
|
selectRoom(room) {
|
||||||
|
this.selectedRoomId = room.uuid;
|
||||||
|
this.$emit('select-room', room); // 可以發事件給父組件
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<div>
|
||||||
|
<span class="toggle-icon" @click="toggle">{{ icon }}</span>
|
||||||
|
<span @click="select"
|
||||||
|
class="region-item-label"
|
||||||
|
:class="{ 'selected': isSelected }">
|
||||||
|
{{ item.rooms.length>0 ? (item.name + '(' + item.rooms.length + '房)'): item.name }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 子區域列表 -->
|
||||||
|
<ul v-if="hasChildren && expanded">
|
||||||
|
<li v-for="(child, index) in item.children" :key="child.id + '-' + index">
|
||||||
|
<region-item
|
||||||
|
:item="child"
|
||||||
|
:selected-id="selectedId"
|
||||||
|
:selected-type="selectedType"
|
||||||
|
:expand-all="expandAll"
|
||||||
|
:collapse-all="collapseAll"
|
||||||
|
@select-region="$emit('select-region', $event)"
|
||||||
|
@select-room="$emit('select-room', $event)"
|
||||||
|
@clear-expand-all="$emit('clear-expand-all')"
|
||||||
|
@clear-collapse-all="$emit('clear-collapse-all')"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- 客房列表:無論是否有子區域,只要展開就顯示 -->
|
||||||
|
<ul v-if="item.rooms && item.rooms.length > 0 && expanded">
|
||||||
|
<li v-for="room in item.rooms" :key="'room-' + room.uuid"
|
||||||
|
@click="selectRoom(room)"
|
||||||
|
:class="{ 'selected-room': selectedType === 'room' && selectedId === room.uuid }"
|
||||||
|
style="cursor: pointer;">
|
||||||
|
<span class="bed-label">
|
||||||
|
🛏️ {{ room.name + ' (' + room.beds.length + '床) ' + (room.gender === true ? '(男客房)' : room.gender === false ? '(女客房)' : '') }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
});
|
||||||
|
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 {
|
||||||
|
activityList: [],
|
||||||
|
availableBedCount: {
|
||||||
|
male: 0,
|
||||||
|
female: 0,
|
||||||
|
},
|
||||||
|
guadanorder: {
|
||||||
|
order_form: {
|
||||||
|
uuid: '<%= Request.QueryString["orderid"] %>' || null,
|
||||||
|
startdate: null,
|
||||||
|
enddate: null,
|
||||||
|
note: null,
|
||||||
|
orderNo: null,
|
||||||
|
bookerName: null,
|
||||||
|
bookerPhone: null,
|
||||||
|
bookerFollowerNum: null,
|
||||||
|
activityNum: null,
|
||||||
|
},
|
||||||
|
status_items: [],
|
||||||
|
},
|
||||||
|
guadanguest: {
|
||||||
|
guest: {
|
||||||
|
uuid: null, // int?
|
||||||
|
fullName: '', // string
|
||||||
|
gender: null, // int?
|
||||||
|
phone: '', // string
|
||||||
|
idNumber: '', // string
|
||||||
|
birthday: null, // Date (建議用 date picker)
|
||||||
|
email: '', // string
|
||||||
|
address: '', // string
|
||||||
|
emergencyContact: '', // string
|
||||||
|
emergencyPhone: '', // string
|
||||||
|
status: null, // int?
|
||||||
|
notes: '' // string
|
||||||
|
},
|
||||||
|
headers: [{
|
||||||
|
text: '姓名',
|
||||||
|
value: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '性別',
|
||||||
|
value: 'sex'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '掛單開始時間',
|
||||||
|
value: 'checkinat'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '掛單結束時間',
|
||||||
|
value: 'checkoutat'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '床位',
|
||||||
|
value: 'bedName'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '狀態',
|
||||||
|
value: 'statusName'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '備註',
|
||||||
|
value: 'note'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
value: 'actions'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
items: [],
|
||||||
|
showCreateGuestModal: false,
|
||||||
|
xuzhu: {
|
||||||
|
showXuzhuGuestModal: false,
|
||||||
|
currentCheckoutDate: null,
|
||||||
|
newCheckoutDate: null,
|
||||||
|
guestUuid: null,
|
||||||
|
guestBedUuid: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
checkInGuest: {
|
||||||
|
showSelectGuadanOrderGuest: false,
|
||||||
|
isEdit: false,
|
||||||
|
|
||||||
|
inGuest: {
|
||||||
|
uuid: null,
|
||||||
|
orderNo: null,
|
||||||
|
followerNum: null,
|
||||||
|
roomUuid: null,
|
||||||
|
bedUuid: null,
|
||||||
|
checkInAt: null,
|
||||||
|
checkOutAt: null,
|
||||||
|
statuscode: null,
|
||||||
|
},
|
||||||
|
status: [],
|
||||||
|
},
|
||||||
|
region_modal: {
|
||||||
|
regions: [],
|
||||||
|
currentSelectRegion: null,
|
||||||
|
currentSelectRoom: null,
|
||||||
|
currentSelectBeds: [],
|
||||||
|
currentSelectBed: null,
|
||||||
|
showSelectBedModal: false,
|
||||||
|
selectedId: null, // 被選中項目ID
|
||||||
|
selectedType: null, // 'region' 或 'room'
|
||||||
|
expandAllFlag: false, // 控制全部展開
|
||||||
|
collapseAllFlag: false, // 控制全部收起
|
||||||
|
currentSelectBedText: null,
|
||||||
|
},
|
||||||
|
selectGuestModal: {
|
||||||
|
showSelectGuestModal: false,
|
||||||
|
currentSelectedGuest: null,
|
||||||
|
fullNameText: null,
|
||||||
|
|
||||||
|
headers: [{
|
||||||
|
text: '姓名',
|
||||||
|
value: 'u_name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '電話',
|
||||||
|
value: 'phone'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
value: 'actions'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
items: [],
|
||||||
|
|
||||||
|
options: { //v-data-table參數
|
||||||
|
page: 1,
|
||||||
|
itemsPerPage: 10,
|
||||||
|
sortBy: [],
|
||||||
|
sortDesc: [],
|
||||||
|
multiSort: false,
|
||||||
|
},
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
count: 0,
|
||||||
|
footer: {
|
||||||
|
showFirstLastPage: true,
|
||||||
|
disableItemsPerPage: true,
|
||||||
|
itemsPerPageAllText: '',
|
||||||
|
itemsPerPageText: '',
|
||||||
|
},
|
||||||
|
searchNameOrPhone: null,
|
||||||
|
},
|
||||||
|
automaticBedAllocation: {
|
||||||
|
showModal: false,
|
||||||
|
|
||||||
|
// 蓮友選擇彈出視窗
|
||||||
|
followerModal: {
|
||||||
|
showModal: false,
|
||||||
|
followerList: [],
|
||||||
|
selectedFollowerItems: [],
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
totalCount: 0,
|
||||||
|
searchNameOrPhone: '',
|
||||||
|
headers: [
|
||||||
|
{ text: '姓名', value: 'u_name' },
|
||||||
|
{ text: '電話', value: 'phone' },
|
||||||
|
{ text: '操作', value: 'actions', sortable: false }
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// 已選擇的待分配列表
|
||||||
|
selectedFollowers: [],
|
||||||
|
preBeds: [],
|
||||||
|
headers: [
|
||||||
|
{ text: '姓名', value: 'u_name' },
|
||||||
|
{ text: '電話', value: 'phone' },
|
||||||
|
{ text: '性別', value: 'sex' },
|
||||||
|
{ text: '預分配床位', value: 'prebed' },
|
||||||
|
{ text: '', value: 'actions' }
|
||||||
|
],
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getActivityList() {
|
||||||
|
axios.post('/api/activity/GetList?page=1&pageSize=500', { kind: 0, subject: "" })
|
||||||
|
.then((res) => {
|
||||||
|
this.activityList = res.data.list
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//掛單相關方法-------------------start
|
||||||
|
validateOrderForm() {
|
||||||
|
if (!this.guadanorder.order_form.startdate) {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: '請輸入必填資訊'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this.guadanorder.order_form.enddate) {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: '請輸入必填資訊'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this.guadanorder.order_form.bookerName) {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: '請輸入姓名'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.guadanorder.order_form.bookerPhone && !/^\d{2,4}-?\d{3,4}-?\d{3,4}$/.test(this.guadanorder.order_form.bookerPhone)) {
|
||||||
|
this.$refs.messageModal.open({
|
||||||
|
message: '電話輸入有誤'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
},
|
||||||
|
getGuadanOrderById() {
|
||||||
|
if (this.guadanorder.order_form.uuid) {
|
||||||
|
axios.get('/api/guadan/getorderbyid', {
|
||||||
|
params: {
|
||||||
|
orderId: this.guadanorder.order_form.uuid
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
this.guadanorder.order_form.note = res.data.notes;
|
||||||
|
this.guadanorder.order_form.startdate = res.data.startDate;
|
||||||
|
this.guadanorder.order_form.enddate = res.data.endDate;
|
||||||
|
this.guadanorder.order_form.orderNo = res.data.guaDanOrderNo;
|
||||||
|
this.guadanorder.order_form.bookerName = res.data.bookerName;
|
||||||
|
this.guadanorder.order_form.bookerPhone = res.data.bookerPhone;
|
||||||
|
this.guadanorder.order_form.bookerFollowerNum = res.data.bookerFollowerNum;
|
||||||
|
this.guadanorder.order_form.uuid = res.data.uuid;
|
||||||
|
this.guadanorder.order_form.activityNum = res.data.activityNum;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getGuadanOrderGuestByOrderNo() {
|
||||||
|
if (this.guadanorder.order_form.orderNo) {
|
||||||
|
axios.get('/api/guadanorderguest/getbyorderno', {
|
||||||
|
params: {
|
||||||
|
orderNo: this.guadanorder.order_form.orderNo
|
||||||
|
}
|
||||||
|
}).then((res => {
|
||||||
|
this.guadanguest.items = res.data;
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//掛單相關方法-------------------end
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'guadanorder.order_form.orderNo'(newValue, oldValue) {
|
||||||
|
if (newValue) {
|
||||||
|
this.getGuadanOrderGuestByOrderNo();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'selectGuestModal.options': {
|
||||||
|
handler() {
|
||||||
|
this.getGuadanFollowers();
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
|
// 分頁變化時自動刷新
|
||||||
|
'automaticBedAllocation.followerModal.page': function () {
|
||||||
|
this.getMultiSelectFollowers();
|
||||||
|
},
|
||||||
|
'automaticBedAllocation.followerModal.pageSize': function () {
|
||||||
|
this.getMultiSelectFollowers();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.guadanorder.order_form.uuid) {
|
||||||
|
this.getGuadanOrderById();
|
||||||
|
this.getGuadanOrderGuestByOrderNo();
|
||||||
|
}
|
||||||
|
this.getActivityList();
|
||||||
|
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pageCount() {
|
||||||
|
return Math.ceil(this.selectGuestModal.count / this.selectGuestModal.pageSize)
|
||||||
|
},
|
||||||
|
pageCount2: function () {
|
||||||
|
var fm = this.automaticBedAllocation.followerModal;
|
||||||
|
return Math.ceil(fm.totalCount / fm.pageSize) || 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</asp:Content>
|
||||||
14
web/admin/guadan/view.aspx.cs
Normal file
14
web/admin/guadan/view.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_view : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user