957 lines
42 KiB
Plaintext
957 lines
42 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.statusuuid="{item}">
|
||
{{getBedStatusNameById(item.statusuuid)}}
|
||
</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.statusuuid">
|
||
<option v-for="status in room_bed.bed_status" :value="status.uuid">
|
||
{{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>
|
||
<!-- 更新修改確認彈出視窗 -->
|
||
<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 {
|
||
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: 'statusuuid' },
|
||
{ text: '是否啟用', value: 'isactive' },
|
||
{ text: '', value: 'action' },
|
||
],
|
||
newBedForm: {
|
||
uuid: null,
|
||
RegionUuid: null,
|
||
Name: '',
|
||
statusuuid: null,
|
||
IsActive: true,
|
||
Gender: null,
|
||
},
|
||
showBedModal: false,
|
||
bed_status: [], //床位狀態列表
|
||
}
|
||
};
|
||
},
|
||
methods: {
|
||
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;
|
||
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 ? '/api/region/update' : '/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) => {
|
||
this.$refs.messageModal.open({
|
||
title: '更新提示',
|
||
message: error.response?.data?.message || "儲存失敗,請稍後再試。",
|
||
});
|
||
});
|
||
},
|
||
deleteRegion() {
|
||
this.$refs.confirmModal.open({
|
||
titil: '刪除提示',
|
||
message: '確定要刪除該區域嗎?刪除區域會一併刪除該區域下的所有區域和床位',
|
||
onConfirm: () => {
|
||
this.confirmDeleteRegion();
|
||
}
|
||
});
|
||
},
|
||
confirmDeleteRegion() {
|
||
axios.post('/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: '',
|
||
statusuuid: null,
|
||
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('/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,
|
||
statusuuid: bed.statusuuid,
|
||
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,
|
||
statusuuid: updated.statusuuid,
|
||
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 (err) {
|
||
console.log(err)
|
||
this.$refs.messageModal.open({
|
||
title: '錯誤',
|
||
message: err.response?.data?.message || '更新失敗'
|
||
});
|
||
}
|
||
},
|
||
getBedStatus() {
|
||
//獲取床位狀態
|
||
axios.get('/api/region/bed/status/list')
|
||
.then((res) => {
|
||
this.room_bed.bed_status = res.data;
|
||
})
|
||
},
|
||
getBedStatusNameById(id) {
|
||
console.log(id)
|
||
//傳入一個Id,獲取該Id對應的名稱
|
||
const status = this.room_bed.bed_status.find(i => i.uuid == id);
|
||
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);
|
||
this.$refs.messageModal.open({
|
||
message: (error.response?.data?.message || error.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
|
||
});
|
||
},
|
||
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>
|