1013 lines
45 KiB
Plaintext
1013 lines
45 KiB
Plaintext
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="admin_region_index" %>
|
|
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
|
|
|
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server"></asp:Content>
|
|
|
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
|
<nav class="mb-2 ps-3">
|
|
<button class="btn btn-primary me-2" @click="newRegion" type="button">
|
|
<i class="mdi mdi-plus"></i> 新增主區域
|
|
</button>
|
|
<button class="btn btn-secondary me-2" @click="expandAll" type="button">
|
|
<i class="mdi mdi-arrow-expand-all"></i> 全部展開
|
|
</button>
|
|
<button class="btn btn-secondary" @click="collapseAll" type="button">
|
|
<i class="mdi mdi-arrow-collapse-all"></i> 全部收起
|
|
</button>
|
|
</nav>
|
|
<nav v-if="form && selectedType==null">
|
|
<button class="btn btn-primary me-2" @click="saveRegion" type="button">
|
|
<i class="bi bi-save me-1"></i> 儲存區域資料
|
|
</button>
|
|
</nav>
|
|
<nav class="btn-group mb-2 ps-3 pe-3" role="group" v-if="form && selectedType=='region'">
|
|
|
|
<button class="btn btn-primary me-2" @click="saveRegion" type="button">
|
|
<i class="bi bi-save me-1"></i> 儲存區域資料
|
|
</button>
|
|
<div v-if="selectedRegionId">
|
|
<button class="btn btn-success me-2" @click="createSubRegion" type="button" >
|
|
<i class="mdi mdi-arrow-down-right"></i> 新增下層區域
|
|
</button>
|
|
<button class="btn btn-success me-2" type="button" @click="room.showCreateRoomDialog=true" >
|
|
<i class="mdi mdi-arrow-down-right"></i> 新建客房
|
|
</button>
|
|
<button class="btn btn-outline-danger" @click="deleteRegion" type="button">
|
|
<i class="mdi mdi-delete"></i> 刪除
|
|
</button>
|
|
</div>
|
|
</nav>
|
|
<nav class="btn-group mb-2 ps-3 pe-3" role="group" v-if="currentSelectRoom && selectedType=='room'">
|
|
|
|
<button class="btn btn-primary me-2" type="button" @click="roomUpdate">
|
|
<i class="bi bi-save me-1"></i> 儲存客房資料
|
|
</button>
|
|
<button class="btn btn-outline-danger" @click="confirmRoomDelete" type="button" v-if="currentSelectRoom">
|
|
<i class="mdi mdi-delete"></i> 刪除客房
|
|
</button>
|
|
</nav>
|
|
</asp:Content>
|
|
|
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
|
<uc1:alert runat="server" ID="L_msg" Text="" />
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-sm-4 col-lg-3">
|
|
<div class="card shadow-sm my-2">
|
|
<div class="card-header">區域列表</div>
|
|
<div class="card-body">
|
|
<ul class="tree">
|
|
<li v-for="region in regions" :key="region.uuid">
|
|
<region-item
|
|
:item="region"
|
|
:selected-id="selectedId"
|
|
:selected-type="selectedType"
|
|
@select-region="selectRegion"
|
|
@select-room="selectRoom"
|
|
:expand-all="expandAllFlag"
|
|
:collapse-all="collapseAllFlag"
|
|
@clear-expand-all="expandAllFlag = false"
|
|
@clear-collapse-all="collapseAllFlag = false"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-4 col-lg-6" v-if="!currentSelectRoom">
|
|
<div class="card shadow-sm my-2"style="position: sticky; top: 20px;">
|
|
<div class="card-header">
|
|
<span>区域</span>
|
|
<span class="fw-bold" v-if="currentSelectRegion">
|
|
{{ ' ' + currentSelectRegion.name + ' ' }}
|
|
</span>
|
|
<span>
|
|
资料
|
|
</span>
|
|
以下 * 欄位為必填欄位
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row mt-5">
|
|
<div class="form-group col-5">
|
|
<label>區域名稱*</label>
|
|
<input type="text" class="form-control" v-model="form.name" />
|
|
</div>
|
|
<div class="form-group col-5">
|
|
<label>上層區域</label>
|
|
<select class="form-control" v-model="form.parentUuid">
|
|
<option :value="null">無</option>
|
|
<option v-for="r in flatRegions"
|
|
:value="r.uuid"
|
|
:disabled="disabledParentOptions.includes(r.uuid)">{{ r.name }}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-5">
|
|
<div class="form-group col-5">
|
|
<label>排序</label>
|
|
<input type="number" class="form-control" v-model="form.sortOrder" />
|
|
</div>
|
|
|
|
<div class="form-group col-5">
|
|
<label>區域類型</label>
|
|
<select class="form-control" v-model="form.regionTypeUuid">
|
|
<option :value="null">無</option>
|
|
<option v-for="type in regionTypes" :value="type.uuid">
|
|
{{ type.name }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-5">
|
|
<div class="form-group col-5">
|
|
<label>客房數量</label>
|
|
<input type="number" class="form-control" v-model="form.roomCount" />
|
|
</div>
|
|
<div class="form-group col-5">
|
|
<label>描述</label>
|
|
<textarea class="form-control" v-model="form.description"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="form-group form-check form-switch mb-3 mt-3 col-5">
|
|
<input type="checkbox" class="form-check-input" id="isActiveCheck" v-model="form.isActive" />
|
|
<label class="form-check-label" for="isActiveCheck">是否啟用</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<!-- 客房編輯區 -->
|
|
<div class="col-sm-4 col-lg-6" v-else>
|
|
<div style="position: sticky; top: 20px;" >
|
|
<div class="card shadow-sm my-2">
|
|
<div class="card-header">
|
|
<span>客房</span>
|
|
<span class="fw-bold" v-if="currentSelectRoom">
|
|
{{ ' ' + currentSelectRoom.name + ' ' }}
|
|
</span>
|
|
<span>资料</span>
|
|
以下 * 欄位為必填欄位
|
|
</div>
|
|
<div class="card-body shadow">
|
|
<div class="row mt-5">
|
|
<div class="form-group col-5">
|
|
<label>客房名稱*</label>
|
|
<input v-model="room.room_form.name" class="form-control"/>
|
|
</div>
|
|
<div class="form-group col-5">
|
|
<label>床位數量</label>
|
|
<input v-model="room.room_form.bedCount" class="form-control"/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-5">
|
|
<div class="form-group col-5">
|
|
<label>客房所属区域</label>
|
|
<select class="form-control" v-model="room.room_form.regionUuid">
|
|
<option v-for="r in flatRegions"
|
|
:value="r.uuid"
|
|
>{{ r.name }}</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group form-check form-switch mb-3 mt-3 col-5 ms-5">
|
|
<input type="checkbox" class="form-check-input" id="roomIsActive" v-model="room.room_form.isActive" />
|
|
<label class="form-check-label" for="roomIsActive">是否啟用</label>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-5">
|
|
<div class="mb-3">
|
|
<div class="form-check form-check-inline">
|
|
<input class="form-check-input"
|
|
type="radio"
|
|
name="gender"
|
|
id="roomMale"
|
|
:value="true"
|
|
v-model="room.room_form.gender"
|
|
required>
|
|
<label class="form-check-label" for="roomMale">男眾客房</label>
|
|
</div>
|
|
<div class="form-check form-check-inline">
|
|
<input class="form-check-input"
|
|
type="radio"
|
|
name="gender"
|
|
id="roomFemale"
|
|
:value="false"
|
|
v-model="room.room_form.gender"
|
|
required>
|
|
<label class="form-check-label" for="roomFemale">女眾客房</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card shadow-sm my-2" v-if="currentSelectRoom">
|
|
<div>如果有修改編輯區域的資料,請先儲存後再進行床位操作</div>
|
|
<div class="card-header d-flex align-items-center justify-content-between">
|
|
<span class="fw-bold">床位列表</span>
|
|
<button type="button" class="btn btn-primary" @click="newBed">新增床位</button>
|
|
</div>
|
|
<div class="card-body">
|
|
<v-data-table
|
|
:headers="room_bed.bed_headers"
|
|
:items ="room_bed.bed_items"
|
|
>
|
|
<template #item.isactive="{item}">
|
|
{{item.isactive ? '啟用' : '停用'}}
|
|
</template>
|
|
<template #item.statuscode="{item}">
|
|
{{getBedStatusNameById(item.statuscode)}}
|
|
</template>
|
|
<template #item.action ="{item}">
|
|
<button type="button" class="btn btn-primary" @click="editBed(item)">
|
|
編輯
|
|
</button>
|
|
<button type="button" class="btn btn-outline-danger" @click="deleteBed(item)">
|
|
刪除
|
|
</button>
|
|
</template>
|
|
</v-data-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- 床位編輯 Modal -->
|
|
<v-dialog v-model="room_bed.showBedModal" max-width="500px" transition="none">
|
|
<v-card>
|
|
<v-card-title>
|
|
<span class="headline">{{room_bed.mode == 'create' ? '新增床位' : '編輯床位'}}</span>
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<div class="mb-3">
|
|
<label class="form-label">床位名稱<span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" v-model="room_bed.newBedForm.Name" required />
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">狀態</label>
|
|
<select class="form-control" v-model="room_bed.newBedForm.statuscode" disabled>
|
|
<option v-for="status in room_bed.bed_status" :value="status.code">
|
|
{{status.name}}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-check form-switch mb-3">
|
|
<input type="checkbox" class="form-check-input" id="isActiveCheck" v-model="room_bed.newBedForm.IsActive" />
|
|
<label class="form-check-label" for="isActiveCheck">是否啟用</label>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label d-block">性別 <span class="text-danger">*</span></label>
|
|
<div class="form-check form-check-inline">
|
|
<input class="form-check-input"
|
|
type="radio"
|
|
name="bedGender"
|
|
id="bedMale"
|
|
:value="true"
|
|
v-model="room_bed.newBedForm.Gender"
|
|
required>
|
|
<label class="form-check-label" for="bedMale">男眾床位</label>
|
|
</div>
|
|
<div class="form-check form-check-inline">
|
|
<input class="form-check-input"
|
|
type="radio"
|
|
name="bedGender"
|
|
id="bedFemale"
|
|
:value="false"
|
|
v-model="room_bed.newBedForm.Gender"
|
|
required>
|
|
<label class="form-check-label" for="bedFemale">女眾床位</label>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-spacer></v-spacer>
|
|
<v-btn text @click="room_bed.showBedModal = false">取消</v-btn>
|
|
<v-btn color="primary" @click="room_bed.mode === 'create' ? saveBed() : saveEditBed()">儲存</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
|
|
<!--
|
|
新建客房dialog
|
|
-->
|
|
<v-dialog width="50%" max-width="80%" transition="none" v-model="room.showCreateRoomDialog">
|
|
<v-card style="min-height: 500px; max-height: 80vh; overflow-y: auto;font-size: 30px;">
|
|
<v-card-title>
|
|
<span style=" font-size:30px;">
|
|
新建客房
|
|
</span>
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<div class="mb-3" style=" font-size:30px;">
|
|
<label class="form-label">客房名稱<span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" v-model="room.room_form.name" required />
|
|
</div>
|
|
<div class="mb-3" style=" font-size:25px;">
|
|
<label>床位数量</label>
|
|
<input type="number" class="form-control" v-model="room.room_form.bedCount" />
|
|
</div>
|
|
<div class="form-check form-switch mb-3" style=" font-size:25px;">
|
|
<input type="checkbox" class="form-check-input" v-model="room.room_form.isActive" />
|
|
<label class="form-check-label">是否啟用</label>
|
|
</div>
|
|
<div class="mb-3" style=" font-size:25px;">
|
|
<label class="form-label d-block">性別 <span class="text-danger">*</span></label>
|
|
<div class="form-check form-check-inline">
|
|
<input class="form-check-input"
|
|
type="radio"
|
|
name="creatRoomGender"
|
|
v-model="room.room_form.gender"
|
|
:value="1"
|
|
required>
|
|
<label class="form-check-label" style=" font-size:25px;">男眾客房</label>
|
|
</div>
|
|
<div class="form-check form-check-inline" style=" font-size:25px;">
|
|
<input class="form-check-input"
|
|
type="radio"
|
|
name="creatRoomGender"
|
|
v-model="room.room_form.gender"
|
|
:value="0"
|
|
required>
|
|
<label class="form-check-label" style=" font-size:25px;">女眾客房</label>
|
|
</div>
|
|
</div>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-spacer></v-spacer>
|
|
<v-btn text @click="room.showCreateRoomDialog = false" style=" font-size:25px;">取消</v-btn>
|
|
<v-btn color="primary" @click="roomCreate" style=" font-size:25px;">儲存</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
|
|
<!-- 停用區域如果有床位正在掛單提示彈出視窗 -->
|
|
<div v-if="bed_is_used_modal" style="position:fixed; top:0; left:0; width:100%; height:100%;
|
|
background:rgba(0,0,0,0.5); display:flex; align-items:center; justify-content:center; z-index:9999;">
|
|
<div style="background:#fff; padding:20px; border-radius:8px; width:300px; text-align:center;">
|
|
<p style="margin-bottom:15px;">{{bed_is_used_modal_message}}</p>
|
|
<div style="display:flex; justify-content:flex-end; gap:10px;">
|
|
<button @click="closeBedInUsedModal"
|
|
class="btn btn-danger"
|
|
type="button" style="padding:6px 12px; border:none; border-radius:4px; cursor:pointer;">关闭</button>
|
|
<a :href="bed_is_used_modal_link" target="_blank" class="btn btn-primary">
|
|
前往处理
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 更新修改確認彈出視窗 -->
|
|
<message-modal ref="messageModal"></message-modal>
|
|
<!-- 刪除確認彈出視窗 -->
|
|
<confirm-modal ref="confirmModal"></confirm-modal>
|
|
|
|
|
|
</asp:Content>
|
|
|
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server"></asp:Content>
|
|
|
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
|
<style>
|
|
.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 in item.children" :key="child.uuid">
|
|
<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 +'床)'}}</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
`
|
|
});
|
|
new Vue({
|
|
el: '#app',
|
|
vuetify: new Vuetify(vuetify_options),
|
|
data() {
|
|
return {
|
|
bed_is_used_modal: false,
|
|
bed_is_used_modal_message: null,
|
|
bed_is_used_modal_link: "handle_bed_in_used.aspx", // 默认链接
|
|
selectedId: null, // 被選中項目ID
|
|
selectedType: null, // 'region' 或 'room'
|
|
expandAllFlag: false, // 控制全部展開
|
|
collapseAllFlag: false, // 控制全部收起
|
|
showModal: false,
|
|
showDeleteModal: false,
|
|
modalMessage: '',
|
|
deleteModalMessage: '',
|
|
selectedRegionId: null,
|
|
regions: [],
|
|
flatRegions: [],
|
|
disabledParentOptions: [],
|
|
regionTypes: [],
|
|
currentSelectRegion: null,
|
|
currentSelectRoom: null,
|
|
form: {
|
|
uuid: null,
|
|
name: '',
|
|
description: '',
|
|
sortOrder: 0,
|
|
parentUuid: null,
|
|
regionTypeUuid: null,
|
|
isActive: true,
|
|
roomCount: null,
|
|
},
|
|
room: {
|
|
//room相關的變數放在這裡
|
|
room_form: {
|
|
uuid: null,
|
|
name: '',
|
|
gender: null,
|
|
isActive: true,
|
|
regionUuid: null,
|
|
bedCount: null,
|
|
regionUuid: null,
|
|
},
|
|
showCreateRoomDialog: false, //显示新建客房对话框
|
|
},
|
|
room_bed: {
|
|
mode: 'create', // 'create' or 'edit'
|
|
bed_items: [],
|
|
bed_headers: [
|
|
{ text: '床位編號', value: 'uuid' },
|
|
{ text: '床位名稱', value: 'name' },
|
|
{ text: '床位狀態', value: 'statuscode' },
|
|
{ text: '是否啟用', value: 'isactive' },
|
|
{ text: '', value: 'action' },
|
|
],
|
|
newBedForm: {
|
|
uuid: null,
|
|
RegionUuid: null,
|
|
Name: '',
|
|
statuscode: null,
|
|
IsActive: true,
|
|
Gender: null,
|
|
},
|
|
showBedModal: false,
|
|
bed_status: [], //床位狀態列表
|
|
}
|
|
};
|
|
},
|
|
methods: {
|
|
closeBedInUsedModal() {
|
|
this.bed_is_used_modal = false;
|
|
this.bed_is_used_modal_message = null;
|
|
this.bed_is_used_modal_link = "handle_bed_in_used.aspx"; // 默认链接
|
|
},
|
|
expandAll() {
|
|
this.expandAllFlag = true;
|
|
this.collapseAllFlag = false;
|
|
},
|
|
collapseAll() {
|
|
this.collapseAllFlag = true;
|
|
this.expandAllFlag = false;
|
|
},
|
|
async loadRegions() {
|
|
const res = await axios.post('/api/region/getRegionList');
|
|
this.regions = res.data;
|
|
this.flatRegions = this.flatten(res.data);
|
|
if (this.currentSelectRoom) {
|
|
|
|
}
|
|
},
|
|
loadRegionType() {
|
|
axios.post('/api/region/getRegionType')
|
|
.then(res => {
|
|
this.regionTypes = res.data
|
|
});
|
|
},
|
|
flatten(data, list = []) {
|
|
data.forEach(item => {
|
|
list.push({ uuid: item.uuid, name: item.name });
|
|
if (item.children && item.children.length) {
|
|
this.flatten(item.children, list);
|
|
}
|
|
});
|
|
return list;
|
|
},
|
|
selectRegion(region) {
|
|
this.selectedId = region.uuid;
|
|
this.selectedType = 'region';
|
|
this.selectedRegionId = region.uuid;
|
|
this.currentSelectRegion = region;
|
|
console.log(this.currentSelectRegion)
|
|
this.currentSelectRoom = null;
|
|
this.resetRoomForm();
|
|
this.form = {
|
|
uuid: region.uuid,
|
|
name: region.name,
|
|
description: region.description,
|
|
sortOrder: region.sortOrder,
|
|
parentUuid: region.parentUuid,
|
|
regionTypeUuid: region.regionTypeUuid,
|
|
isActive: region.isActive !== false, // 若為 null 也視為啟用
|
|
roomCount: region.roomCount,
|
|
};
|
|
// 禁止選擇自己與所有子孫作為上層
|
|
const node = this.findRegionById(this.regions, region.uuid);
|
|
this.disabledParentOptions = this.getAllDescendants(node);
|
|
},
|
|
|
|
newRegion() {
|
|
this.selectedRegionId = null;
|
|
this.form = {
|
|
uuid: null,
|
|
name: '',
|
|
description: '',
|
|
sortOrder: 0,
|
|
parentUuid: null,
|
|
isActive: true
|
|
};
|
|
this.disabledParentOptions = [];
|
|
this.currentSelectRegion = null;
|
|
this.currentSelectRoom = null;
|
|
},
|
|
createSubRegion() {
|
|
if (!this.selectedRegionId) return;
|
|
this.form = {
|
|
uuid: null,
|
|
name: '',
|
|
description: '',
|
|
sortOrder: 0,
|
|
parentUuid: this.selectedRegionId,
|
|
isActive: true
|
|
|
|
};
|
|
},
|
|
saveRegion() {
|
|
if (!this.form.name || this.form.name.trim() === '') {
|
|
this.$refs.messageModal.open({
|
|
title: "錯誤",
|
|
message: "請輸入區域名稱",
|
|
});
|
|
return;
|
|
}
|
|
const url = this.form.uuid
|
|
? HTTP_HOST + '/api/region/update'
|
|
: HTTP_HOST + '/api/region/create';
|
|
|
|
axios.post(url, this.form)
|
|
.then((res) => {
|
|
//alert('儲存成功');
|
|
this.loadRegions();
|
|
//this.newRegion();
|
|
this.form.uuid = res.data.uuid;
|
|
this.selectedRegionId = res.data.uuid;
|
|
this.currentSelectRegion = JSON.parse(JSON.stringify(this.form));
|
|
this.$refs.messageModal.open({
|
|
title: "更新",
|
|
message: "更新成功",
|
|
});
|
|
})
|
|
.catch((error) => {
|
|
console.error('更新失敗', error);
|
|
const code = error.response?.data?.code;
|
|
const message = error.response?.data?.message || error.message ||
|
|
"未知錯誤,請稍後再試";
|
|
if (code === "BED_IS_USED") {
|
|
this.bed_is_used_modal = true;
|
|
this.bed_is_used_modal_message = message
|
|
this.bed_is_used_modal_link = this.bed_is_used_modal_link + '?region=' + this.form.uuid
|
|
|
|
} else {
|
|
this.$refs.messageModal.open({
|
|
message: (message)
|
|
});
|
|
}
|
|
});
|
|
},
|
|
deleteRegion() {
|
|
this.$refs.confirmModal.open({
|
|
titil: '刪除提示',
|
|
message: '確定要刪除該區域嗎?刪除區域會一併刪除該區域下的所有區域和床位',
|
|
onConfirm: () => {
|
|
this.confirmDeleteRegion();
|
|
}
|
|
});
|
|
},
|
|
confirmDeleteRegion() {
|
|
axios.post(HTTP_HOST + 'api/region/delete', { Uuid: this.form.uuid })
|
|
.then(() => {
|
|
this.showDeleteModal = false;
|
|
this.$refs.messageModal.open({
|
|
title: "刪除",
|
|
message: "刪除成功",
|
|
});
|
|
this.room_bed.bed_items = [];
|
|
this.currentSelectRegion = null;
|
|
this.currentSelectRoom = null;
|
|
this.loadRegions();
|
|
this.newRegion();
|
|
});
|
|
},
|
|
|
|
getAllDescendants(node) {
|
|
//尋找某個區域的所有子區域
|
|
const ids = [];
|
|
const dfs = (n) => {
|
|
ids.push(n.uuid);
|
|
if (n.children) {
|
|
n.children.forEach(child => dfs(child));
|
|
}
|
|
};
|
|
dfs(node);
|
|
return ids;
|
|
},
|
|
findRegionById(list, uuid) {
|
|
for (const item of list) {
|
|
if (item.uuid === uuid) return item;
|
|
if (item.children) {
|
|
const found = this.findRegionById(item.children, uuid);
|
|
if (found) return found;
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
//下面是床位相關的操作函數
|
|
newBed() {
|
|
//添加床位
|
|
if (!this.currentSelectRoom) {
|
|
this.$refs.messageModal.open({
|
|
title: '提示',
|
|
message: '請先選擇一個客房'
|
|
})
|
|
return;
|
|
}
|
|
this.room_bed.mode = 'create';
|
|
this.room_bed.newBedForm = {
|
|
uuid: null,
|
|
RoomUuid: this.currentSelectRoom.uuid,
|
|
Name: '',
|
|
statuscode: "101",
|
|
IsActive: true,
|
|
Gender: this.currentSelectRoom.gender, // 不設預設值,強制選擇
|
|
};
|
|
this.room_bed.showBedModal = true;
|
|
},
|
|
async saveBed() {
|
|
if (!this.room_bed.newBedForm.Name || this.room_bed.newBedForm.Name.trim() === '') {
|
|
this.$refs.messageModal.open({
|
|
title: '錯誤',
|
|
message: '請輸入床位名稱'
|
|
});
|
|
return;
|
|
}
|
|
try {
|
|
var res = await axios.post(HTTP_HOST + 'api/region/bed/create', this.room_bed.newBedForm);
|
|
this.room_bed.showBedModal = false;
|
|
this.$refs.messageModal.open({
|
|
title: '成功',
|
|
message: '新增床位成功'
|
|
});
|
|
// 重新載入區域資料
|
|
await this.loadRegions();
|
|
this.room_bed.bed_items.push({
|
|
...res.data
|
|
})
|
|
} catch (err) {
|
|
this.$refs.messageModal.open({
|
|
title: '錯誤',
|
|
message: err.response?.data?.message || '新增失敗'
|
|
});
|
|
}
|
|
},
|
|
deleteBed(bed) {
|
|
this.$refs.confirmModal.open({
|
|
titil: '刪除提示',
|
|
message: '確定要刪除該床位嗎',
|
|
onConfirm: () => {
|
|
this.confirmDeleteBed(bed);
|
|
}
|
|
});
|
|
},
|
|
confirmDeleteBed(bed) {
|
|
axios.post('/api/region/bed/delete', null, {
|
|
params: { uuid: bed.uuid }
|
|
}) // 假設後端吃的是 id
|
|
.then(() => {
|
|
// 成功後從本地列表移除
|
|
this.room_bed.bed_items = this.room_bed.bed_items.filter(item => item.uuid !== bed.uuid);
|
|
this.$refs.messageModal.open({
|
|
title: '刪除成功',
|
|
message: `已刪除床位「${bed.name}」`
|
|
});
|
|
})
|
|
.catch(err => {
|
|
this.$refs.messageModal.open({
|
|
title: '錯誤',
|
|
message: err.response?.data?.message || '刪除失敗'
|
|
});
|
|
});
|
|
},
|
|
editBed(bed) {
|
|
if (!this.currentSelectRoom) {
|
|
this.$refs.messageModal.open({
|
|
title: '提示',
|
|
message: '請先選擇一個客房'
|
|
})
|
|
return;
|
|
}
|
|
this.room_bed.mode = 'edit';
|
|
this.room_bed.newBedForm = {
|
|
uuid: bed.uuid,
|
|
RegionUuid: bed.regionUuid,
|
|
RoomUuid: bed.roomUuid,
|
|
Name: bed.name,
|
|
statuscode: bed.statuscode,
|
|
IsActive: bed.isactive,
|
|
Gender: bed.gender,
|
|
};
|
|
this.room_bed.showBedModal = true;
|
|
},
|
|
async saveEditBed() {
|
|
|
|
try {
|
|
await axios.post('/api/region/bed/update', this.room_bed.newBedForm);
|
|
this.room_bed.showBedModal = false;
|
|
|
|
const updated = this.room_bed.newBedForm;
|
|
const index = this.room_bed.bed_items.findIndex(b => b.uuid === updated.uuid);
|
|
|
|
if (index !== -1) {
|
|
this.$set(this.room_bed.bed_items, index, {
|
|
...this.room_bed.bed_items[index], // 保留原本未更新欄位
|
|
roomUuid: updated.RoomUuid,
|
|
name: updated.Name,
|
|
statuscode: updated.statuscode,
|
|
isactive: updated.IsActive
|
|
});
|
|
}
|
|
|
|
|
|
this.$refs.messageModal.open({
|
|
title: '成功',
|
|
message: '更新床位成功'
|
|
});
|
|
await this.loadRegions();
|
|
this.room_bed.bed_items = this.currentSelectRoom.beds;
|
|
//this.selectRegion(this.findRegionById(this.regions, this.form.id));
|
|
} catch (error) {
|
|
console.error('更新失敗', error);
|
|
const code = error.response?.data?.code;
|
|
const message = error.response?.data?.message || error.message ||
|
|
"未知錯誤,請稍後再試";
|
|
if (code === "BED_IS_USED") {
|
|
this.bed_is_used_modal = true;
|
|
this.bed_is_used_modal_message = message;
|
|
this.bed_is_used_modal_link = this.bed_is_used_modal_link + '?bed=' + this.room_bed.newBedForm.uuid
|
|
} else {
|
|
this.$refs.messageModal.open({
|
|
message: (message)
|
|
});
|
|
}
|
|
}
|
|
},
|
|
getBedStatus() {
|
|
//獲取床位狀態
|
|
axios.get('/api/region/bed/status/list')
|
|
.then((res) => {
|
|
this.room_bed.bed_status = res.data;
|
|
})
|
|
},
|
|
getBedStatusNameById(statuscode) {
|
|
const status = this.room_bed.bed_status.find(i => i.code == statuscode);
|
|
if (status) {
|
|
return status.name;
|
|
}
|
|
return "";
|
|
},
|
|
//------------------------------------------------
|
|
//room相關的函數
|
|
roomGet() {
|
|
|
|
},
|
|
roomCreate() {
|
|
this.room.room_form['regionUuid'] = this.currentSelectRegion.uuid
|
|
if (this.room.room_form.gender === null) {
|
|
this.$refs.messageModal.open({
|
|
message: "請選擇性別"
|
|
});
|
|
return;
|
|
}
|
|
axios.post('/api/region/room/create', this.room.room_form)
|
|
.then((res) => {
|
|
this.room.showCreateRoomDialog = false;
|
|
this.currentSelectRegion.rooms.push(res.data);
|
|
this.$refs.messageModal.open({
|
|
title: '提示',
|
|
message: '客房新建成功',
|
|
});
|
|
this.resetRoomForm();
|
|
}).catch((error) => {
|
|
this.$refs.messageModal.open({
|
|
message: (error.response?.data?.message || error.message)
|
|
});
|
|
})
|
|
},
|
|
async roomUpdate() {
|
|
try {
|
|
const res = await axios.post('/api/region/room/update', this.room.room_form);
|
|
this.$refs.messageModal.open({
|
|
message: '客房資料更新成功'
|
|
});
|
|
this.loadRegions();
|
|
this.currentSelectRoom = {
|
|
...this.room.room_form
|
|
};
|
|
} catch (error) {
|
|
console.error('更新失敗', error);
|
|
const code = error.response?.data?.code;
|
|
const message = error.response?.data?.message || error.message ||
|
|
"未知錯誤,請稍後再試";
|
|
if (code === "BED_IS_USED") {
|
|
this.bed_is_used_modal = true;
|
|
this.bed_is_used_modal_message = message;
|
|
this.bed_is_used_modal_link = this.bed_is_used_modal_link + '?room=' + this.room.room_form.uuid
|
|
} else {
|
|
this.$refs.messageModal.open({
|
|
message: (message)
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
roomDelete() {
|
|
axios.post('/api/region/room/delete', { uuid: this.currentSelectRoom.uuid })
|
|
.then((res) => {
|
|
const region = this.findRegionById(this.regions, this.currentSelectRoom.regionUuid)//當前room所在的region
|
|
if (region) {
|
|
const index = region.rooms.findIndex(item => item.uuid === this.currentSelectRoom.uuid)
|
|
if (index !== -1) {
|
|
|
|
region.rooms.splice(index, 1); // 直接修改原數組
|
|
}
|
|
}
|
|
this.currentSelectRoom = null;
|
|
this.room_bed.bed_items = [];
|
|
//清空 beds
|
|
}).catch((error) => {
|
|
this.$refs.messageModal.open({
|
|
message: (error.response?.data?.message || error.message)
|
|
});
|
|
});
|
|
},
|
|
confirmRoomDelete() {
|
|
this.$refs.confirmModal.open({
|
|
title: '確認刪除',
|
|
message: '確認刪除該房間嗎?刪除房間會一併刪除房間床位,刪除後不可恢復',
|
|
onConfirm: () => {
|
|
this.roomDelete();
|
|
}
|
|
})
|
|
},
|
|
selectRoom(room) {
|
|
this.selectedId = room.uuid;
|
|
this.selectedType = 'room';
|
|
this.currentSelectRoom = room;
|
|
this.currentSelectRegion = null;
|
|
this.room.room_form = {
|
|
...this.currentSelectRoom
|
|
}
|
|
this.room_bed.bed_items = this.currentSelectRoom.beds;
|
|
},
|
|
resetRoomForm() {
|
|
this.room.room_form = {
|
|
uuid: null,
|
|
name: '',
|
|
gender: null,
|
|
isActive: true,
|
|
regionUuid: null,
|
|
bedCount: null,
|
|
}
|
|
},
|
|
//結束room相關的函數
|
|
//------------------------------------------------
|
|
|
|
},
|
|
watch: {
|
|
|
|
},
|
|
mounted() {
|
|
this.loadRegions();
|
|
this.loadRegionType();
|
|
this.getBedStatus();
|
|
}
|
|
});
|
|
</script>
|
|
</asp:Content>
|