Quellcode durchsuchen

房型做完
房间管理部分

qh vor 2 Jahren
Ursprung
Commit
34194d72cf

+ 55 - 0
src/api/roomBuildingApi.js

@@ -0,0 +1,55 @@
+import api from './index'
+import { axios } from '@/utils/request'
+
+/**
+ * 新增楼栋
+ * @param {Object} parameter 保存参数
+ * @returns Axios Promise
+ */
+export function save(parameter) {
+    return axios({
+        url: '/rooms/cesRoomBuildingFloor/save',
+        method: 'post',
+        data: parameter
+    })
+}
+
+/**
+ * 编辑楼栋/楼层
+ * @param {Object} parameter edit param
+ * @returns Axios Promise
+ */
+ export function modify(parameter) {
+    return axios({
+        url: '/rooms/cesRoomBuildingFloor/modify',
+        method: 'put',
+        data: parameter
+    })
+}
+
+/**
+ * 删除楼栋/楼层
+ * @param {String} parameter edit param
+ * @returns Axios Promise
+ */
+ export function remove(id) {
+    return axios({
+        url: '/rooms/cesRoomBuildingFloor/delete',
+        method: 'delete',
+        params: id
+    })
+}
+
+/**
+ * 获取楼栋楼层树
+ * @param {Object} param 
+ * @returns Axios Promise
+ */
+export function buildingTree (param) {
+    return axios({
+        url: '/rooms/cesRoomBuildingFloor/tree',
+        method: 'get',
+        params: param
+    })
+}
+

+ 16 - 0
src/api/roomLayout.js

@@ -1,6 +1,22 @@
 import api from './index'
 import { axios } from '@/utils/request'
 
+
+/**
+ * 获取全部房型
+ * @returns 
+ */
+export function  getAllLayouts() { 
+    return axios({
+        url: '/rooms/cesRoomLayout/list',
+        method: 'get',
+        params: {
+            pageSize: 99999,
+            pageNo: 1
+        }
+    })
+ }
+
 /**
  * 启用状态(App)
  * @param {String||Number} parameter layoutId

+ 1 - 1
src/components/tools/HeaderNotice.vue

@@ -123,7 +123,7 @@
     mounted() {
       this.loadData();
       //this.timerFun();
-      this.initWebSocket();
+      // this.initWebSocket();
      // this.heartCheckFun();
     },
     destroyed: function () { // 离开页面生命周期函数

+ 2 - 1
src/utils/excloudHotelIdParamPath/CesRoomLayoutPriceController.js

@@ -1,6 +1,7 @@
 export default {
     name: '房价管理模块',
     excloudUrls: [
-        '/sys/randomImage'
+        '/sys/randomImage',
+        '/rooms/cesRoomBuildingFloor/delete'
     ]
 }

+ 1 - 0
src/views/settings/components/roomModules/RoomLayoutFormDetailModal.vue

@@ -51,6 +51,7 @@
         },
         onSaveOk() {
           this.$emit("saveOk")
+          this.visible = false
         }
     }
   }

+ 17 - 5
src/views/settings/components/roomModules/roomLayoutDetailForm.vue

@@ -1,15 +1,15 @@
 <template>
-    <a-tabs default-active-key="1" @change="()=>{}">
+    <a-tabs default-active-key="1" @change="onTabChange">
         <a-tab-pane key="1" tab="房型详情">
-          <detail ref="detail" @saveOk="onSaveOk"></detail>
+            <detail ref="detail" @saveOk="onSaveOk"></detail>
         </a-tab-pane>
         <a-tab-pane key="2" tab="设备服务">
-          <device ref="device"></device>
+            <device ref="device" @saveOk="onSaveOk"></device>
         </a-tab-pane>
         <a-tab-pane key="3" tab="房型图片">
-          <layout-image ref="img"></layout-image>
+            <layout-image ref="img" @saveOk="onSaveOk"></layout-image>
         </a-tab-pane>
-      </a-tabs>
+    </a-tabs>
 </template>
 
 <script>
@@ -90,6 +90,18 @@ export default {
         onSaveOk() {
             this.$emit('saveOk')
         },
+        onTabChange(e) {
+            console.log(e);
+            setTimeout(() => {
+                if (e == 2) {
+                    this.$refs.device.setData(this.model)
+                } else if (e == 3) {
+                    this.$refs.img.setData(this.model)
+                } else {
+                    this.$refs.detail.setData(this.model)
+                }
+            }, 500)
+        },
         setRaw(item) {
             this.model = JSON.parse(JSON.stringify(item))
             this.$refs.detail.setData(this.model)

+ 139 - 31
src/views/settings/components/roomModules/roomLayoutDetailForm/roomLayoutDevice.vue

@@ -35,42 +35,42 @@
                             <span style="display: inline-block;width: 20px;height:1px;"></span>
                             <a-time-picker :open.sync="open1" v-model="beforeTime1" format="HH:mm">
                                 <a-button slot="addon" size="small" type="primary" @click="open1 = false">
-                                  确定
+                                    确定
                                 </a-button>
-                              </a-time-picker>
-                              <span>前可取消</span>
-                            </span>
+                            </a-time-picker>
+                            <span>前可取消</span>
+                        </span>
                     </a-radio>
                     <a-radio :style="radioStyle" :value="2">
                         <span style="display: inline-block;">
                             <span style="width: 76px;display:inline-block;">入住前</span>
                             <span style="display: inline-block;width: 20px;height:1px;"></span>
-                            <a-input-number id="inputNumber" v-model="cancelDay1" :min="1" />
+                            <a-input-number  v-model="cancelDay1" :min="0" />
                             <span>天</span>
                             <a-time-picker :open.sync="open2" v-model="beforeTime2" format="HH:mm">
                                 <a-button slot="addon" size="small" type="primary" @click="open2 = false">
-                                  确定
+                                    确定
                                 </a-button>
-                              </a-time-picker>
-                              <span>前可取消</span>
-                            </span>
+                            </a-time-picker>
+                            <span>前可取消</span>
+                        </span>
                     </a-radio>
                     <a-radio :style="radioStyle" :value="3">
                         <span style="display: inline-block;">
                             <span style="width: 76px;display:inline-block;">入住前</span>
                             <span style="display: inline-block;width: 20px;height:1px;"></span>
-                            <a-input-number id="inputNumber" v-model="cancelDay1" :min="1" />
+                            <a-input-number  v-model="cancelDay2" :min="0" />
                             <span>天</span>
-                            <a-time-picker :open.sync="open2" v-model="beforeTime2" format="HH:mm">
-                                <a-button slot="addon" size="small" type="primary" @click="open2 = false">
-                                  确定
+                            <a-time-picker :open.sync="open3" v-model="beforeTime3" format="HH:mm">
+                                <a-button slot="addon" size="small" type="primary" @click="open3 = false">
+                                    确定
                                 </a-button>
-                              </a-time-picker>
-                              <span>前可取消,</span>
-                              <span>收取</span>
-                              <a-input-number id="inputNumber" v-model="model.cancelMoney" :min="0" />
-                              %罚金
-                            </span>
+                            </a-time-picker>
+                            <span>前可取消,</span>
+                            <span>收取</span>
+                            <a-input-number v-model="model.cancelMoney" :min="0" />
+                            %罚金
+                        </span>
                     </a-radio>
                     <a-radio :style="radioStyle" :value="4">
                         不可取消
@@ -87,13 +87,16 @@
 </template>
 
 <script>
+var splitChar = '⛔'
+import { modify } from '@/api/roomLayout'
+import moment from 'moment';
 export default {
     name: 'HotelSaasTenantFrontendRoomLayoutDetail',
 
     data() {
         return {
-            cancelDay1: 1,
-            cancelDay2: 1,
+            cancelDay1: null,
+            cancelDay2: null,
             beforeTime1: null,
             beforeTime2: null,
             beforeTime3: null,
@@ -142,14 +145,11 @@ export default {
             model: {
                 id: null,
                 tags: [],
-                facilities: null,
-                cancelRule: null,
+                facilities: null, // 房间设施
+                cancelRule: null, // 取消规则
                 windows: null,
                 cancelBeforeTime: null,
                 cancelMoney: 0,
-                area: 0,
-                bedSize: 0,
-                remark: ''
             },
             validatorRules: {
                 windows: [{ required: true, message: "请选择是否有窗" }],
@@ -164,6 +164,50 @@ export default {
     },
 
     methods: {
+        setData(data) {
+            this.model = JSON.parse(JSON.stringify(data))
+            // 房间标签
+            if (this.model.tags) {
+                this.model.tags = this.model.tags.split(splitChar)
+
+            } else {
+                this.model.tags = []
+            }
+            // 房间设施
+            if (this.model.facilities) {
+                this.model.facilities = this.model.facilities.split(',')
+                this.defvals = this.model.facilities
+            } else {
+                this.model.facilities = null
+            }
+
+            // 取消规则渲染
+            if (this.model.cancelRule) {
+                if (this.model.cancelRule == 1) {  //入住当天 补充当天时间赋值
+                    if (this.model.cancelBeforeTime) {
+                        this.beforeTime1 = moment(this.model.cancelBeforeTime, "HH:mm").utcOffset(8)
+                    }
+                } else if (this.model.cancelRule == 2) { // 入住前N天可取消
+                    if (this.model.cancelDayNum || this.model.cancelDayNum == 0) {
+                        this.cancelDay1 = this.model.cancelDayNum
+                    }
+                    if (this.model.cancelBeforeTime) {
+                        this.beforeTime2 = moment(this.model.cancelBeforeTime, "HH:mm").utcOffset(8)
+                    }
+                } else if (this.model.cancelRule == 3) { // 入住前N天包含罚金比率
+                    if (this.model.cancelDayNum || this.model.cancelDayNum == 0) {
+                        this.cancelDay2 = this.model.cancelDayNum
+                    }
+                    if (this.model.cancelBeforeTime) {
+                        this.beforeTime3 = moment(this.model.cancelBeforeTime, "HH:mm").utcOffset(8)
+                    }
+                    this.model.cancelMoney = this.model.cancelMoney ? this.model.cancelMoney : 0
+                }
+            }
+
+
+
+        },
         onTagClose(item) {
             delete this.model.tags[item]
         },
@@ -189,12 +233,76 @@ export default {
             // 触发表单验证
             this.$refs.form.validate((valid) => {
                 if (valid) {
-                    that.confirmLoading = true;
-                    if (this.model.id && this.model.id != '') {
-                        this.doModify()
-                    } else {
-                        this.doCreate()
+                    let data = JSON.parse(JSON.stringify(this.model))
+                    data.checkType = (data.checkType || []).toString()
+                    data.facilities = (data.facilities || []).toString()
+                    data.tags = data.tags.join(splitChar)
+
+
+                    if (this.model.cancelRule) {
+                        if (this.model.cancelRule == 1) {  //入住当天 补充当天时间赋值
+                            if (this.beforeTime1) {
+                                data.cancelBeforeTime = this.beforeTime1.format("HH:mm")
+                            } else {
+                                this.$message.error('请选择最后取消时间')
+                                return
+                            }
+                        } else if (this.model.cancelRule == 2) { // 入住前N天可取消
+                            if (this.cancelDay1 || this.cancelDay1 == 0) {
+                                data.cancelDayNum = this.cancelDay1
+                            } else {
+                                this.$message.error('请输入取消前天数')
+                                return
+                            }
+                            if (this.beforeTime2) {
+                                data.cancelBeforeTime = this.beforeTime2.format("HH:mm")
+                            } else {
+                                this.$message.error('请选择最后取消时间')
+                                return
+                            }
+                        } else if (this.model.cancelRule == 3) { // 入住前N天包含罚金比率
+                            if (this.cancelDay2 || this.cancelDay2 == 0) {
+                                data.cancelDayNum = this.cancelDay2
+                            } else {
+                                this.$message.error('请输入取消前天数')
+                                return
+                            }
+                            if (this.beforeTime3) {
+                                data.cancelBeforeTime = this.beforeTime3.format("HH:mm")
+                            } else {
+                                this.$message.error('请选择最后取消时间')
+                                return
+                            }
+                            if(!this.model.cancelMoney || this.model.cancelMoney < 0) {
+                                this.$message.error('罚金比率必须大于1')
+                                return
+                            }
+                        }
                     }
+                    that.confirmLoading = true;
+                    modify({
+                        id: data.id,
+                        hotelId: data.hotelId,
+                        name: data.name,
+                        marketPrice: data.marketPrice,
+                        canLivePersonNum: data.canLivePersonNum,
+                        breakfastNum: data.breakfastNum,
+                        lunchNum: data.lunchNum,
+                        dinnerNum: data.dinnerNum,
+                        tags: data.tags,
+                        facilities: data.facilities,
+                        cancelRule: data.cancelRule,
+                        cancelDayNum: data.cancelDayNum,
+                        cancelBeforeTime: data.cancelBeforeTime,
+                        cancelMoney: data.cancelMoney
+                    }).then(res => {
+                        if (res.code == 200) {
+                            this.$emit('saveOk')
+                            this.$message.success("保存成功")
+                        }
+                    }).finally(_=>{
+                        that.confirmLoading = false;
+                    })
                 }
             });
 

+ 28 - 9
src/views/settings/components/roomModules/roomLayoutDetailForm/roomLayoutImage.vue

@@ -2,10 +2,10 @@
     <div>
         <a-form-model ref="form" :model="model" :rules="validatorRules">
             <a-form-model-item label="房型大图" >
-                <j-image-upload class="avatar-uploader" text="上传" v-model="model.ewm" ></j-image-upload>
+                <j-image-upload class="avatar-uploader" text="上传" v-model="model.cover" ></j-image-upload>
               </a-form-model-item>
               <a-form-model-item label="图片" >
-                <j-image-upload class="avatar-uploader" text="上传" v-model="model.imgList" :isMultiple="true"></j-image-upload>
+                <j-image-upload class="avatar-uploader" text="上传" v-model="model.picture" :isMultiple="true"></j-image-upload>
               </a-form-model-item>
               <a-button :disabled="submitLoading" :loading="submitLoading" @click="submitForm"
                 type="primary">保存</a-button>
@@ -14,6 +14,7 @@
 </template>
 
 <script>
+import { modify } from '@/api/roomLayout'
 export default {
     name: 'HotelSaasTenantFrontendRoomLayoutImage',
 
@@ -22,8 +23,8 @@ export default {
             submitLoading: false,
             model: {
                 id: 0,
-                ewm: null,
-                imgList: null
+                cover: null,
+                picture: null
             },
             validatorRules: {
 
@@ -36,17 +37,35 @@ export default {
     },
 
     methods: {
+        setData(data) {
+            this.model = JSON.parse(JSON.stringify(data))
+        },
         submitForm() {
             const that = this;
             // 触发表单验证
             this.$refs.form.validate((valid) => {
                 if (valid) {
+                    let data = JSON.parse(JSON.stringify(this.model))
                     that.confirmLoading = true;
-                    if (this.model.id && this.model.id != '') {
-                        this.doModify()
-                    } else {
-                        this.doCreate()
-                    }
+                    modify({
+                        id: data.id,
+                        hotelId: data.hotelId,
+                        name: data.name,
+                        marketPrice: data.marketPrice,
+                        canLivePersonNum: data.canLivePersonNum,
+                        breakfastNum: data.breakfastNum,
+                        lunchNum: data.lunchNum,
+                        dinnerNum: data.dinnerNum,
+                        cover: data.cover,
+                        picture: data.picture
+                    }).then(res => {
+                        if (res.code == 200) {
+                            this.$emit('saveOk')
+                            this.$message.success("保存成功")
+                        }
+                    }).finally(_ => {
+                        that.confirmLoading = false;
+                    })
                 }
             });
 

+ 1 - 1
src/views/settings/components/roomModules/roomLayoutList.vue

@@ -53,7 +53,7 @@
                         :checked="record.appState == 1" @change="changeAppState($event, record)" />
                 </template>
                 <template slot="pictureSlot" slot-scope="text, record, index">
-                    <img :src="record.picture" style="width:40px;height40px;" />
+                    <img :src="record.cover" style="width:40px;height40px;" />
                 </template>
                 <template slot="htmlSlot" slot-scope="text">
                     <div v-html="text"></div>

+ 256 - 0
src/views/settings/components/roomModules/roomNumSettings/roomNumForm.vue

@@ -0,0 +1,256 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+        slot="detail"
+      >
+        <a-form-model-item
+          label="房间楼层"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="floorId"
+        >
+          <a-select
+            placeholder="请选择"
+            style="width: 200px"
+            v-model="model.floorId"
+            @change="onFloorChange($event)"
+          >
+            <template v-for="item in buildingTreeData">
+              <a-select-opt-group v-if="item.children" :key="item.id">
+                <span slot="label"><a-icon type="tags" />{{ item.name }}</span>
+                <a-select-option
+                  :value="child.id"
+                  v-for="child in item.children"
+                  :key="child.id"
+                >
+                  {{ child.name }}
+                </a-select-option>
+              </a-select-opt-group>
+            </template>
+          </a-select>
+        </a-form-model-item>
+        <a-form-model-item
+          label="房间房型"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="layoutId"
+        >
+          <a-select
+            placeholder="请选择"
+            style="width: 200px"
+            v-model="model.layoutId"
+          >
+            <a-select-option
+              :value="item.id"
+              v-for="item in layouts"
+              :key="item.id"
+            >
+              {{ item.name }}
+            </a-select-option>
+          </a-select>
+        </a-form-model-item>
+        <a-form-model-item
+          label="房间前缀"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="prefix"
+        >
+          <a-input
+            style="width: 50%"
+            v-model="model.prefix"
+            placeholder="请填写房间前缀"
+          />
+        </a-form-model-item>
+
+        <a-form-model-item
+          label="房间房号"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="name"
+        >
+          <a-input
+            style="width: 50%"
+            v-model="model.name"
+            placeholder="请填写房号"
+          />
+        </a-form-model-item>
+
+        <a-form-model-item
+          label="房间描述"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="remark"
+        >
+          <a-textarea
+            style="width: 50%"
+            v-model="model.remark"
+            placeholder="请填写房间描述"
+          />
+        </a-form-model-item>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+<script>
+import { getRoomPlans, getSelectList } from "@/api/api";
+import { buildingTree } from "@/api/roomBuildingApi";
+import { getAllLayouts } from "../../../../../api/roomLayout";
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+export default {
+  name: "BusMarketMemberForm",
+  props: {
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {
+        id: "",
+        floorId: undefined,
+        buildId: null,
+        layoutId: undefined,
+        prefix: null,
+        name: null,
+        remark: null,
+      },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        name: [{ required: true, message: "请输入房型!" }],
+        floorId: [{ required: true, message: "请选择楼层!" }],
+        layoutId: [{ required: true, message: "请选择房型!" }],
+      },
+      url: {
+        add: "/rooms/cesRooms/save",
+        edit: "/rooms/cesRooms/modify",
+        queryById: "/rooms/cesRooms/queryById",
+      },
+      iconChooseVisible: false,
+      roomPlans: [],
+      members: [],
+      buildingTreeData: [],
+      layouts: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    buildingTree().then((res) => {
+      if (res.code == 200) {
+        this.buildingTreeData = res.result;
+      }
+    });
+    getAllLayouts().then((res) => {
+      if (res.code == 200) {
+        this.layouts = res.result.records;
+      }
+    });
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+      this.initData();
+    }
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    // 下拉框改变之后找到楼栋id
+    onFloorChange(e) {
+      this.buildingTreeData.forEach((s) => {
+        if (s.children) {
+          s.children.forEach((t) => {
+            if (t.id == e) this.model.buildId = s.id;
+          });
+        }
+      });
+    },
+    initData() {
+      getRoomPlans(this.model.hotelId, null).then((res) => {
+        if (res.success) {
+          this.roomPlans = res.result;
+        }
+      });
+    },
+    selectIcons() {
+      this.iconChooseVisible = true;
+    },
+    handleIconCancel() {
+      this.iconChooseVisible = false;
+    },
+    handleIconChoose(value) {
+      console.log(value);
+      this.model.icon = value;
+      this.iconChooseVisible = false;
+    },
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+      getSelectList({ id: this.model.id }).then((res) => {
+        if (res.success) {
+          this.members = res.result;
+        }
+      });
+    },
+    submitForm() {
+      const that = this;
+      // 触发表单验证
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          that.confirmLoading = true;
+          let httpurl = "";
+          let method = "";
+          if (!this.model.id) {
+            httpurl += this.url.add;
+            method = "post";
+          } else {
+            httpurl += this.url.edit;
+            method = "put";
+          }
+          if (this.model.payFlag == 0) {
+            this.model.payAmount = 0;
+          }
+          httpAction(httpurl, this.model, method)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>
+<style scoped>
+.avatar-uploader > .ant-upload {
+  width: 104px;
+  height: 104px;
+}
+</style>

+ 263 - 0
src/views/settings/components/roomModules/roomNumSettings/roomNumList.vue

@@ -0,0 +1,263 @@
+<template>
+  <div>
+    <div class="page-wrapper">
+      <div class="left-wrapper">
+        <a-input
+          style="width: 140px; margin-right: 10px"
+          v-model="newBuildingName"
+          placeholder="请填写楼栋名称"
+        ></a-input>
+        <a-button
+          :disabled="saveBtnLoading"
+          :loading="saveBtnLoading"
+          @click="saveNewBuilding"
+          type="primary"
+          >新增楼栋</a-button
+        >
+        <div class="building-tree">
+          <div v-if="buildingTree && buildingTree.length > 0">
+            <a-tree
+              class="draggable-tree"
+              :tree-data="buildingTree"
+              :default-expand-all="true"
+              blockNode
+              style="width: 400px"
+              :replaceFields="{
+                children: 'children',
+                title: 'name',
+                key: 'id',
+              }"
+            >
+              <div
+                slot="title"
+                slot-scope="item"
+                style="display: flex;align-items: center;height: 100%;overflow: hidden;"
+              >
+                <a-button
+                  style="font-size: 12px"
+                  type="link"
+                  @click="
+                    () => {
+                      $message.success(item.name);
+                    }
+                  "
+                  >{{ item.name }}</a-button
+                >
+                <div style="flex: 1; height: 1px"></div>
+                <a-button
+                  style="font-size: 12px; padding: 0 5px"
+                  type="link"
+                  v-if="item.parentId == 0"
+                  @click="onAddFlowerClick(item)"
+                  >添加楼层</a-button
+                >
+                <a-button
+                  style="font-size: 12px; padding: 0 5px"
+                  type="link"
+                  @click="onTreeEditClick(item)"
+                  >编辑</a-button
+                >
+
+                <a-popconfirm placement="topLeft" ok-text="是的" cancel-text="取消" @confirm="onTreeDeleteClick(item)">
+                    <template slot="title">
+                      确定删除吗?
+                    </template>
+                    <a-button
+                    style="font-size: 12px; padding: 0 5px"
+                    type="link"
+                    >删除</a-button>
+                  </a-popconfirm>
+               
+                
+              </div>
+            </a-tree>
+          </div>
+          <div v-else class="empty-data"></div>
+        </div>
+      </div>
+      <div class="right-wrapper">
+        <room-num-table></room-num-table>
+      </div>
+    </div>
+    <!-- 添加楼层 -->
+    <a-modal
+      width="300px"
+      title="楼栋楼层编辑"
+      :visible.sync="fVisible"
+      :confirm-loading="fSaveLoading"
+      @ok="saveFlow"
+      @cancel="fVisible = false"
+    >
+      <a-input
+        style="width: 240px; margin-right: 10px"
+        v-model="flowData.name"
+        placeholder="请填写楼层/楼栋名称"
+      ></a-input>
+    </a-modal>
+  </div>
+</template>
+
+
+<script>
+import { save, buildingTree, modify, remove } from "@/api/roomBuildingApi";
+import roomNumTable from './roomNumTable.vue'
+export default {
+    components: {
+        roomNumTable  
+    },
+  data() {
+    return {
+      flowData: {
+        id: null,
+        hotelId: null,
+        name: "",
+        parentId: null,
+        type: 2,
+      },
+      currentBuildingId: null,
+      fVisible: false,
+      fSaveLoading: false,
+      currentHotel: JSON.parse(localStorage.getItem("storeInfo")),
+      newBuildingName: "",
+      saveBtnLoading: false,
+      model: {
+        dis: 1,
+      },
+      buildingTree: [],
+    };
+  },
+  mounted() {
+    this.loadBuildingTreeData();
+  },
+  methods: {
+    // 获取楼栋树
+    loadBuildingTreeData() {
+      buildingTree().then((res) => {
+        this.buildingTree = res.result;
+      });
+    },
+    // 点击楼栋添加楼层事件
+    onAddFlowerClick(building) {
+
+      this.currentBuildingId = building.id;
+      this.flowData.parentId = building.id;
+      this.flowData.name = '';
+      this.flowData.hotelId = this.currentHotel.id;
+      this.flowData.type = 2;
+      this.flowData.id = null;
+      this.fVisible = true;
+    },
+    // 点击tree节点编辑事件
+    onTreeEditClick(item) {
+      if (item.parentId == 0) {
+        this.flowData.type = 1;
+        this.flowData.name = item.name;
+      } else {
+        this.flowData.type = 2;
+        this.flowData.name = item.name;
+      }
+      this.flowData.id = item.id;
+      this.flowData.hotelId = this.currentHotel.id;
+      this.flowData.parentId = item.parentId;
+      this.fVisible = true;
+    },
+    // 确定删除楼层/楼栋
+    onTreeDeleteClick(item) {
+        remove({
+            id: item.id
+        }).then(res => {
+            if(res.code == 200) {
+                this.$message.success('删除成功')
+                this.loadBuildingTreeData()
+            }
+        })
+    },
+    // 保存楼栋信息
+    saveNewBuilding() {
+      if (!this.newBuildingName) {
+        this.$message.error("名称不能为空");
+        return;
+      }
+      this.saveBtnLoading = true;
+      save({
+        hotelId: this.currentHotel.id,
+        name: this.newBuildingName,
+        parentId: "0",
+        type: 1,
+      })
+        .then((res) => {
+          if (res.code == 200) {
+            this.newBuildingName = "";
+            this.$message.success("楼栋保存成功");
+            this.loadBuildingTreeData();
+          }
+        })
+        .finally((_) => {
+          this.saveBtnLoading = false;
+        });
+    },
+    // 保存楼栋都层信息
+    saveFlow() {
+      if (!this.flowData.name) {
+        this.$message.error("名称不能为空");
+        return;
+      }
+      this.fSaveLoading = true;
+
+      if (this.flowData.id) {
+        // edit
+
+        modify(this.flowData).then((res) => {
+          if (res.code == 200) {
+            this.flowData.name = "";
+            this.flowData.type = 1;
+            this.flowData.parentId = null;
+            this.flowData.id = null;
+            this.$message.success("保存成功");
+            this.loadBuildingTreeData();
+            this.fVisible = false;
+          }
+        }).finally(_ => {
+            this.fSaveLoading = false;
+        });
+
+        return;
+      }
+      // add flow
+      save(this.flowData)
+        .then((res) => {
+          if (res.code == 200) {
+            this.flowData.name = "";
+            this.$message.success("楼层保存成功");
+            this.loadBuildingTreeData();
+            this.fVisible = false;
+          }
+        })
+        .finally((_) => {
+          this.fSaveLoading = false;
+        });
+    },
+  },
+};
+</script>
+
+
+<style scoped>
+.page-wrapper{
+    display: flex;
+}
+.right-wrapper{
+    flex: 1;
+}
+.left-wrapper {
+  width: 30%;
+}
+.building-tree {
+  width: 100%;
+  height: 300px;
+  overflow-y: auto;
+}
+.empty-data {
+  height: 100%;
+}
+</style>

+ 64 - 0
src/views/settings/components/roomModules/roomNumSettings/roomNumModal.vue

@@ -0,0 +1,64 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
+    @cancel="handleCancel"
+    cancelText="关闭"
+  >
+    <room-num-form
+      ref="realForm"
+      @ok="submitCallback"
+      :disabled="disableSubmit"
+    ></room-num-form>
+  </j-modal>
+</template>
+  
+  <script>
+import roomNumForm from "./roomNumForm.vue";
+export default {
+  name: "roomNumModal",
+  components: {
+    roomNumForm,
+  },
+  data() {
+    return {
+      title: "",
+      width: 800,
+      visible: false,
+      disableSubmit: false,
+    };
+  },
+  methods: {
+    add() {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.add();
+      });
+    },
+    edit(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.edit(record);
+      });
+    },
+    close() {
+      this.$emit("close");
+      this.visible = false;
+    },
+    handleOk() {
+      this.$refs.realForm.submitForm();
+    },
+    submitCallback() {
+      this.$emit("ok");
+      this.visible = false;
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

+ 196 - 0
src/views/settings/components/roomModules/roomNumSettings/roomNumTable.vue

@@ -0,0 +1,196 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus"
+        >新增房间</a-button
+      >
+      <a-button @click="onAddBatch" type="primary" icon="plus"
+        >批量新增</a-button
+      >
+      <a-button @click="onDelAll" type="primary" icon="plus">全部删除</a-button>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-button style="margin-left: 8px">
+          批量操作 <a-icon type="down"
+        /></a-button>
+      </a-dropdown>
+      <a-button type="primary" @click="searchQuery" icon="search"
+        >查询</a-button
+      >
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+
+        <template slot="layoutId" slot-scope="text, record">
+          {{ getLayoutName(record) }}
+        </template>
+        <template slot="prefix_name" slot-scope="text, record">
+          {{ (record.prefix || "") + record.name }}
+        </template>
+        <template slot="pictureSlot" slot-scope="text, record">
+          <img :src="record.cover" style="width:40px;height40px;" />
+        </template>
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+       
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-popconfirm
+            title="确定删除吗?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+          <a-divider type="vertical" />
+          <a @click="handleImage(record)">图片</a>
+        </span>
+      </a-table>
+    </div>
+    <room-num-modal ref="modalForm" @ok="modalFormOk"></room-num-modal>
+  </a-card>
+</template>
+  
+<script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import roomNumModal from "./roomNumModal.vue"; // todo roomLayoutForm 需要替换成房型的表单弹窗
+
+import { getAllLayouts } from "@/api/roomLayout";
+let hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+export default {
+  mixins: [JeecgListMixin],
+  components: {
+    roomNumModal,
+  },
+  data() {
+    return {
+      layouts: [],
+      queryParam: {},
+      // 分页参数
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        pageSizeOptions: ["10", "20", "30"],
+        showTotal: (total, range) => {
+          return range[0] + "-" + range[1] + " 共" + total + "条";
+        },
+        showQuickJumper: true,
+        showSizeChanger: true,
+        total: 0,
+      },
+      // 表头
+      columns: [
+        {
+          title: "商家",
+          align: "center",
+          dataIndex: "hotelName",
+        },
+        {
+          title: "楼栋",
+          align: "center",
+          dataIndex: "buildName",
+        },
+        {
+          title: "楼层",
+          align: "center",
+          dataIndex: "floorName",
+        },
+        {
+          title: "房型",
+          align: "center",
+          dataIndex: "layoutId",
+          scopedSlots: { customRender: "layoutId" },
+        },
+        {
+          title: "房号",
+          align: "center",
+          dataIndex: "name",
+          scopedSlots: { customRender: "prefix_name" },
+        },
+        {
+          title: "创建时间",
+          align: "center",
+          dataIndex: "createAt",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        // list: 'org.jeecg.modules.business/busMarketMember/list',
+        list: "/rooms/cesRooms/list",
+        delete: "/rooms/cesRooms/remove",
+        deleteBatch: "/rooms/cesRooms/deleteBatch",
+        exportXlsUrl: "/rooms/cesRooms/exportXls",
+        importExcelUrl: "rooms/cesRooms/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+    };
+  },
+  created() {
+    // this.loadData()
+    getAllLayouts().then((res) => {
+      if (res.code == 200) {
+        this.layouts = res.result.records;
+        this.loadData();
+      }
+    });
+  },
+  methods: {
+    getLayoutName(row) {
+      let i = this.layouts.findIndex((s) => s.id == row.layoutId);
+      if (i > -1) {
+        return this.layouts[i].name;
+      }
+      return "";
+    },
+    // 批量添加按钮
+    onAddBatch() {},
+    // 全部删除
+    onDelAll() {},
+    // 显示图片弹窗
+    handleImage(row) {
+
+    },
+    onSaveOk() {
+      this.loadData();
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 7 - 4
src/views/settings/roomSettings.vue

@@ -13,7 +13,8 @@
                     <a-icon type="audit" />
                     房号设置
                 </span>
-                <room-gen></room-gen>
+                <!-- <room-gen></room-gen> -->
+                <room-num-list></room-num-list>
             </a-tab-pane>
             <a-tab-pane key="3">
                 <span slot="tab">
@@ -28,13 +29,15 @@
 
 <script>
 import roomLayoutList from "./components/roomModules/roomLayoutList.vue"
-import roomGen from "./components/roomModules/roomGen.vue";
+// import roomGen from "./components/roomModules/roomGen.vue";
 import goodList from "./components/roomModules/goodList.vue";
+import roomNumList from "./components/roomModules/roomNumSettings/roomNumList.vue";
 export default {
     components: {
         roomLayoutList,
-        roomGen,
-        goodList
+        // roomGen,
+        goodList,
+        roomNumList
     },
     data() {
         return {