Files
17168ERP/web/admin/guadan/apply.vue
T
2026-10-30 17:47:01 +08:00

632 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="container-fluid">
<v-tabs>
<v-tab value="tab-1" @click="tab='tab-1'">
掛單資訊
</v-tab>
<v-tab value="tab-2" @click="tab='tab-2'">
掛單明細
</v-tab>
</v-tabs>
<v-tabs-items v-model="tab">
<v-tab-item value="tab-1">
<div class="border rounded p-3 bg-white shadow-sm ">
<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="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 class="row mt-3">
<button v-if="guadanorder.order_form.uuid" type="button" class="btn btn-primary mx-auto" style="width: 120px;" @click="updateGuadanOrder">存檔</button>
<button v-else v-on:click="createGuadanOrder" type="button" class="btn btn-primary mx-auto" style="width: 120px;">儲存</button>
</div>
</div>
</v-tab-item>
<v-tab-item value="tab-2">
<!-- 表格標題緊貼表格上方,居中 -->
<div class="d-flex align-items-center mb-3">
<!-- 左側按鈕 -->
<v-btn color="primary" variant="elevated" @click="showCheckInModal" class="me-3">
<v-icon start>mdi-plus</v-icon>
設定人數
</v-btn>
<v-btn @click="showAutomaticBedAllocation">
自動分配床位
</v-btn>
<!-- 中間標題(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.fullname}}
</template>
<template v-slot:item.sex="{item}">
{{item.gender}}
</template>
<template v-slot:item.specialNeeds="{item}">
{{item.specialNeeds}}
</template>
<template #item.actions="{ item }">
<div>
<!-- 取消預訂 -->
<v-btn color="red"
variant="outlined"
size="small"
class="me-2"
: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'"
@click="showXuzhuGuestModalMethod(item)">
續住
</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-tab-item>
</v-tabs-items>
<v-dialog v-model="message_dialog"
max-width="1280"
min-height="900"
hide-overlay
transition="dialog-bottom-transition">
<v-card>
<v-card-text">
{{message}}
</v-card-text">
</v-card>
</v-dialog>
<v-dialog v-model="confirm_dialog"
max-width="1280"
min-height="900"
hide-overlay
transition="dialog-bottom-transition">
<v-card>
<v-card-text">
{{confirm}}
</v-card-text">
</v-card>
</v-dialog>
<v-dialog v-model="checkInGuest.showSelectGuadanOrderGuest"
max-width="720"
min-height="300"
hide-overlay
transition="dialog-bottom-transition">
<v-card>
<v-card-text>
<v-container>
<v-row>
<v-col>
<v-text-field label="人數" v-model="e4"></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field label="開始日期" v-model="s_date"></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field label="結束日期" v-model="e_date"></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col>
<v-select :items="e2" v-model="e5"
label="性別"></v-select>
</v-col>
</v-row>
<v-row>
<v-col>
<v-select v-model="e6"
:items="states"
:menu-props="{ maxHeight: '400' }"
label="特殊需求"
multiple
hint="選擇條件"
persistent-hint></v-select>
</v-col>
</v-row>
<v-row>
<v-col>
<v-btn color="primary" @click="checkInGuest.showSelectGuadanOrderGuest = false">
關閉
</v-btn>
<v-btn color="primary" @click.prevent="genGuestList">產生</v-btn>
</v-col>
</v-container>
</v-card-text>
</v-card>
</v-dialog>
</div>
</template>
<script>
module.exports = {
name: "apply-component",
data() {
return {
e1: null,
e2: ['請選擇', '男眾', '女眾'],
e4: "",
e5: "",
e6: [],
s_date: null,
e_date: null,
states: [
'無特殊需求',
'需要輪椅',
'需要拐杖',
'需要陪同人員',
'需要特別飲食',
'其他需求'
],
message_dialog: false,
message: "",
confirm_dialog: false,
confirm: "",
tab: "tab-1",
activityList: [],
availableBedCount: {
male: 0,
female: 0,
},
activityNum: null,
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
specialNeeds: '', // 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: 'specialNeeds'
},
{
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' }
],
},
}
},
watch: {
activityNum: {
handler(newVal, oldVal) {
console.log('使用者資料更新了!', newVal);
let act = this.activityList.find(activity => activity.num == newVal);
if (act) {
console.log('找到對應的活動:', act);
this.guadanorder.order_form.startdate = act.startDate;
this.guadanorder.order_form.enddate = act.endDate;
}
},
deep: true, // 監聽 userProfile.name 或 age 的變化
immediate: true
}
},
mounted() {
this.getActivityList()
},
methods: {
genGuestList() {//產生掛單明細
console.log('產生掛單明細', this.e4, this.e5, this.e6);
for (let i = 0; i < this.e4; i++) {
this.guadanguest.items.push({
uuid: null, // int?
fullName: '', // string
gender: this.e5, // int?
specialNeeds: this.e6.join(",") // string
});
}
},
getActivityList() {//新增修改取得未過期的法會,查看則依照抓到的去讀取
const params = {
page: '1', pageSize: 10000,
};
axios.post(HTTP_HOST + 'api/activity/GetListNewYet', {
up_time1: moment(new Date()).format('YYYY-MM-DD')
}, { params: params }).then((res) => {
console.log(res);
if (res.status == 200 && res.data && res.data.list) {
this.activityList = res.data.list;
}
})
},
createGuadanOrder() {
if (!this.validateOrderForm()) {
return;
}
axios.post(HTTP_HOST + 'api/guadan/create', this.guadanorder.order_form)
.then((res => {
//this.$refs.messageModal.open({
// title: '掛單提示',
// message: '掛單資料建立成功'
//})
this.message_dialog = true
this.message = '掛單資料建立成功'
this.guadanorder.order_form.uuid = res.data.uuid;
this.guadanorder.order_form.orderNo = res.data.guaDanOrderNo;
console.log(this.guadanorder.order_form.uuid);
// 跳转到当前 URL 加上 ?orderId=UUID
const currentUrl = window.location.origin + window.location.pathname;
window.location.href = `${currentUrl}?orderId=${res.data.guaDanOrderNo}`;
})).catch((error) => {
//this.$refs.messageModal.open({
// title: '錯誤',
// message: '建立掛單資料失敗:' + (error.response?.data?.message || error.message)
//});
this.message_dialog = true
this.message = '建立掛單資料失敗:' + (error.response?.data?.message || error.message)
});
},
updateGuadanOrder() {
if (!this.validateOrderForm()) {
return;
}
axios.post(HTTP_HOST + 'api/guadan/update', this.guadanorder.order_form)
.then((res => {
//this.$refs.messageModal.open({
// title: '掛單提示',
// message: '掛單資料更新成功'
//})
this.message_dialog = true
this.message = '掛單資料更新成功'
this.guadanorder.order_form.uuid = res.data.uuid;
console.log(this.guadanorder.order_form.uuid);
})).catch((error) => {
//this.$refs.messageModal.open({
// title: '錯誤',
// message: '建立掛單資料失敗:' + (error.response?.data?.message || error.message)
//});
this.message_dialog = true
this.message = '建立掛單資料失敗:' + (error.response?.data?.message || error.message)
});
},
showCheckInModal() {
console.log('showCheckInModal called');
if (!this.guadanorder.order_form.uuid) {
//this.$refs.messageModal.open({
// message: '請先創建掛單',
//});
this.message_dialog = true;
this.message = '請先儲存掛單資訊';
return;
}
this.checkInGuest.inGuest.checkInAt = this.guadanorder.order_form.startdate || null;
this.checkInGuest.inGuest.checkOutAt = this.guadanorder.order_form.enddate || null;
this.checkInGuest.inGuest.orderNo = this.guadanorder.order_form.orderNo;
this.checkInGuest.showSelectGuadanOrderGuest = true;
},
showAutomaticBedAllocation() {
if (!this.guadanorder.order_form.uuid) {
//this.$refs.messageModal.open({
// message: '請先儲存掛單資訊',
//});
this.message_dialog = true;
this.message = '請先儲存掛單資訊';
return;
}
this.automaticBedAllocation.showModal = true;
this.getavailablebedcountbytime(this.guadanorder.order_form.startdate, this.guadanorder.order_form.enddate);
},
getavailablebedcountbytime(startTime, endTime) {
axios.get(HTTP_HOST + 'api/region/bed/getavailablebedcountbytime', {
params: {
startTime: startTime,
endTime: endTime
}
}).then((res) => {
this.availableBedCount = res.data;
})
},
}
}
</script>
<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>